diff --git a/.github/update.log b/.github/update.log index 3fb6f932c5..a49f2c353b 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1161,3 +1161,4 @@ Update On Tue Oct 21 20:38:48 CEST 2025 Update On Wed Oct 22 20:43:37 CEST 2025 Update On Thu Oct 23 20:39:01 CEST 2025 Update On Fri Oct 24 20:39:40 CEST 2025 +Update On Sat Oct 25 20:37:45 CEST 2025 diff --git a/clash-nyanpasu/.github/workflows/ci.yml b/clash-nyanpasu/.github/workflows/ci.yml index 1bcc2a7b62..f46d4f23db 100644 --- a/clash-nyanpasu/.github/workflows/ci.yml +++ b/clash-nyanpasu/.github/workflows/ci.yml @@ -53,7 +53,7 @@ jobs: xcode-version: 'latest-stable' - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 @@ -140,7 +140,7 @@ jobs: xcode-version: 'latest-stable' - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 @@ -231,7 +231,7 @@ jobs: xcode-version: 'latest-stable' - name: Install Node.js - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 diff --git a/clash-nyanpasu/.github/workflows/daily.yml b/clash-nyanpasu/.github/workflows/daily.yml index 0ad880bed3..3e8406a636 100644 --- a/clash-nyanpasu/.github/workflows/daily.yml +++ b/clash-nyanpasu/.github/workflows/daily.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout uses: actions/checkout@v5 - name: Install Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: '22' @@ -55,7 +55,7 @@ jobs: with: ref: dev - name: Install Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: '22' diff --git a/clash-nyanpasu/.github/workflows/deps-build-linux.yaml b/clash-nyanpasu/.github/workflows/deps-build-linux.yaml index 04647bddcb..c0c4a5c142 100644 --- a/clash-nyanpasu/.github/workflows/deps-build-linux.yaml +++ b/clash-nyanpasu/.github/workflows/deps-build-linux.yaml @@ -80,7 +80,7 @@ jobs: sudo apt-get install -y libwebkit2gtk-4.1-dev libxdo-dev libappindicator3-dev librsvg2-dev patchelf openssl - name: Install Node latest - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 diff --git a/clash-nyanpasu/.github/workflows/deps-build-macos.yaml b/clash-nyanpasu/.github/workflows/deps-build-macos.yaml index acc4ba0761..2d26d9c18f 100644 --- a/clash-nyanpasu/.github/workflows/deps-build-macos.yaml +++ b/clash-nyanpasu/.github/workflows/deps-build-macos.yaml @@ -66,7 +66,7 @@ jobs: rustup target add aarch64-apple-darwin - name: Install Node latest - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 - uses: denoland/setup-deno@v2 diff --git a/clash-nyanpasu/.github/workflows/deps-build-windows-nsis.yaml b/clash-nyanpasu/.github/workflows/deps-build-windows-nsis.yaml index a3a958b314..1f81a8f1a9 100644 --- a/clash-nyanpasu/.github/workflows/deps-build-windows-nsis.yaml +++ b/clash-nyanpasu/.github/workflows/deps-build-windows-nsis.yaml @@ -86,7 +86,7 @@ jobs: rustup target add ${{ inputs.arch }}-pc-windows-msvc - name: Install Node latest - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 diff --git a/clash-nyanpasu/.github/workflows/deps-create-updater.yaml b/clash-nyanpasu/.github/workflows/deps-create-updater.yaml index 9cd6020b3c..c7bdde31f0 100644 --- a/clash-nyanpasu/.github/workflows/deps-create-updater.yaml +++ b/clash-nyanpasu/.github/workflows/deps-create-updater.yaml @@ -43,7 +43,7 @@ jobs: - name: Fetch git tags run: git fetch --tags - name: Install Node latest - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 diff --git a/clash-nyanpasu/.github/workflows/deps-message-telegram.yaml b/clash-nyanpasu/.github/workflows/deps-message-telegram.yaml index 000ee550ad..90d14eacb6 100644 --- a/clash-nyanpasu/.github/workflows/deps-message-telegram.yaml +++ b/clash-nyanpasu/.github/workflows/deps-message-telegram.yaml @@ -25,7 +25,7 @@ jobs: - name: Checkout repository uses: actions/checkout@v5 - - uses: actions/setup-node@v4 + - uses: actions/setup-node@v6 with: node-version: 22 diff --git a/clash-nyanpasu/.github/workflows/macos-aarch64.yaml b/clash-nyanpasu/.github/workflows/macos-aarch64.yaml index 0ea1aa0400..c979bf32df 100644 --- a/clash-nyanpasu/.github/workflows/macos-aarch64.yaml +++ b/clash-nyanpasu/.github/workflows/macos-aarch64.yaml @@ -8,7 +8,7 @@ env: jobs: macos-aarch64: - runs-on: macos-14 + runs-on: macos-15 steps: - name: Checkout repository uses: actions/checkout@v5 @@ -32,7 +32,7 @@ jobs: rustup target add aarch64-apple-darwin - name: Install Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: '22' diff --git a/clash-nyanpasu/.github/workflows/publish.yml b/clash-nyanpasu/.github/workflows/publish.yml index 4e0146b44d..d196b09684 100644 --- a/clash-nyanpasu/.github/workflows/publish.yml +++ b/clash-nyanpasu/.github/workflows/publish.yml @@ -29,7 +29,7 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} fetch-depth: 0 - name: Prepare Node - uses: actions/setup-node@v4 + uses: actions/setup-node@v6 with: node-version: 22 - uses: pnpm/action-setup@v4 diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index 7148a4fd3b..1498065c6f 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -56,7 +56,7 @@ "@csstools/normalize.css": "12.1.1", "@emotion/babel-plugin": "11.13.5", "@emotion/react": "11.14.0", - "@iconify/json": "2.2.397", + "@iconify/json": "2.2.400", "@monaco-editor/react": "4.7.0", "@tanstack/react-query": "5.90.5", "@tanstack/react-router": "1.133.13", diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index fc2d8586a9..522058c789 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.15", - "mihomo_alpha": "alpha-8701639", + "mihomo_alpha": "alpha-90f47a6", "clash_rs": "v0.9.1", "clash_premium": "2023-09-05-gdcc8d87", "clash_rs_alpha": "0.9.1-alpha+sha.90b204c" @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-10-20T22:21:09.185Z" + "updated_at": "2025-10-24T22:21:14.736Z" } diff --git a/clash-nyanpasu/package.json b/clash-nyanpasu/package.json index 26d9e03774..dae8c4933c 100644 --- a/clash-nyanpasu/package.json +++ b/clash-nyanpasu/package.json @@ -58,8 +58,8 @@ "lodash-es": "4.17.21" }, "devDependencies": { - "@commitlint/cli": "19.8.1", - "@commitlint/config-conventional": "19.8.1", + "@commitlint/cli": "20.1.0", + "@commitlint/config-conventional": "20.0.0", "@eslint/compat": "1.4.0", "@eslint/eslintrc": "3.3.1", "@ianvs/prettier-plugin-sort-imports": "4.7.0", @@ -67,8 +67,8 @@ "@types/fs-extra": "11.0.4", "@types/lodash-es": "4.17.12", "@types/node": "24.8.1", - "@typescript-eslint/eslint-plugin": "8.46.1", - "@typescript-eslint/parser": "8.46.1", + "@typescript-eslint/eslint-plugin": "8.46.2", + "@typescript-eslint/parser": "8.46.2", "autoprefixer": "10.4.21", "conventional-changelog-conventionalcommits": "9.1.0", "cross-env": "10.1.0", @@ -83,10 +83,10 @@ "eslint-plugin-promise": "7.2.1", "eslint-plugin-react": "7.37.5", "eslint-plugin-react-compiler": "19.1.0-rc.2", - "eslint-plugin-react-hooks": "5.2.0", + "eslint-plugin-react-hooks": "7.0.1", "globals": "16.4.0", - "knip": "5.66.0", - "lint-staged": "16.2.4", + "knip": "5.66.3", + "lint-staged": "16.2.6", "neostandard": "0.12.2", "npm-run-all2": "8.0.4", "postcss": "8.5.6", @@ -97,7 +97,7 @@ "prettier-plugin-ember-template-tag": "2.1.0", "prettier-plugin-tailwindcss": "0.7.1", "prettier-plugin-toml": "2.0.6", - "react-devtools": "6.1.5", + "react-devtools": "7.0.1", "stylelint": "16.25.0", "stylelint-config-html": "1.1.0", "stylelint-config-recess-order": "7.4.0", @@ -108,7 +108,7 @@ "tailwindcss": "4.1.14", "tsx": "4.20.6", "typescript": "5.9.3", - "typescript-eslint": "8.46.1" + "typescript-eslint": "8.46.2" }, "packageManager": "pnpm@10.18.3", "engines": { diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index 23e3ce4b06..56a8e6ac8a 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -23,11 +23,11 @@ importers: version: 4.17.21 devDependencies: '@commitlint/cli': - specifier: 19.8.1 - version: 19.8.1(@types/node@24.8.1)(typescript@5.9.3) + specifier: 20.1.0 + version: 20.1.0(@types/node@24.8.1)(typescript@5.9.3) '@commitlint/config-conventional': - specifier: 19.8.1 - version: 19.8.1 + specifier: 20.0.0 + version: 20.0.0 '@eslint/compat': specifier: 1.4.0 version: 1.4.0(eslint@9.38.0(jiti@2.6.0)) @@ -50,11 +50,11 @@ importers: specifier: 24.8.1 version: 24.8.1 '@typescript-eslint/eslint-plugin': - specifier: 8.46.1 - version: 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + specifier: 8.46.2 + version: 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) '@typescript-eslint/parser': - specifier: 8.46.1 - version: 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + specifier: 8.46.2 + version: 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) autoprefixer: specifier: 10.4.21 version: 10.4.21(postcss@8.5.6) @@ -75,13 +75,13 @@ importers: version: 10.1.8(eslint@9.38.0(jiti@2.6.0)) eslint-import-resolver-alias: specifier: 1.1.2 - version: 1.1.2(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))) + version: 1.1.2(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))) eslint-plugin-html: specifier: 8.1.3 version: 8.1.3 eslint-plugin-import: specifier: 2.32.0 - version: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)) + version: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)) eslint-plugin-n: specifier: 17.23.1 version: 17.23.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) @@ -98,20 +98,20 @@ importers: specifier: 19.1.0-rc.2 version: 19.1.0-rc.2(eslint@9.38.0(jiti@2.6.0)) eslint-plugin-react-hooks: - specifier: 5.2.0 - version: 5.2.0(eslint@9.38.0(jiti@2.6.0)) + specifier: 7.0.1 + version: 7.0.1(eslint@9.38.0(jiti@2.6.0)) globals: specifier: 16.4.0 version: 16.4.0 knip: - specifier: 5.66.0 - version: 5.66.0(@types/node@24.8.1)(typescript@5.9.3) + specifier: 5.66.3 + version: 5.66.3(@types/node@24.8.1)(typescript@5.9.3) lint-staged: - specifier: 16.2.4 - version: 16.2.4 + specifier: 16.2.6 + version: 16.2.6 neostandard: specifier: 0.12.2 - version: 0.12.2(@typescript-eslint/utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + version: 0.12.2(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) npm-run-all2: specifier: 8.0.4 version: 8.0.4 @@ -140,8 +140,8 @@ importers: specifier: 2.0.6 version: 2.0.6(prettier@3.6.2) react-devtools: - specifier: 6.1.5 - version: 6.1.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + specifier: 7.0.1 + version: 7.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) stylelint: specifier: 16.25.0 version: 16.25.0(typescript@5.9.3) @@ -173,8 +173,8 @@ importers: specifier: 5.9.3 version: 5.9.3 typescript-eslint: - specifier: 8.46.1 - version: 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + specifier: 8.46.2 + version: 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) frontend/interface: dependencies: @@ -346,8 +346,8 @@ importers: specifier: 11.14.0 version: 11.14.0(@types/react@19.2.2)(react@19.2.0) '@iconify/json': - specifier: 2.2.397 - version: 2.2.397 + specifier: 2.2.400 + version: 2.2.400 '@monaco-editor/react': specifier: 4.7.0 version: 4.7.0(monaco-editor@0.54.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -1359,73 +1359,73 @@ packages: '@bufbuild/protobuf@2.5.2': resolution: {integrity: sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg==} - '@commitlint/cli@19.8.1': - resolution: {integrity: sha512-LXUdNIkspyxrlV6VDHWBmCZRtkEVRpBKxi2Gtw3J54cGWhLCTouVD/Q6ZSaSvd2YaDObWK8mDjrz3TIKtaQMAA==} + '@commitlint/cli@20.1.0': + resolution: {integrity: sha512-pW5ujjrOovhq5RcYv5xCpb4GkZxkO2+GtOdBW2/qrr0Ll9tl3PX0aBBobGQl3mdZUbOBgwAexEQLeH6uxL0VYg==} engines: {node: '>=v18'} hasBin: true - '@commitlint/config-conventional@19.8.1': - resolution: {integrity: sha512-/AZHJL6F6B/G959CsMAzrPKKZjeEiAVifRyEwXxcT6qtqbPwGw+iQxmNS+Bu+i09OCtdNRW6pNpBvgPrtMr9EQ==} + '@commitlint/config-conventional@20.0.0': + resolution: {integrity: sha512-q7JroPIkDBtyOkVe9Bca0p7kAUYxZMxkrBArCfuD3yN4KjRAenP9PmYwnn7rsw8Q+hHq1QB2BRmBh0/Z19ZoJw==} engines: {node: '>=v18'} - '@commitlint/config-validator@19.8.1': - resolution: {integrity: sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==} + '@commitlint/config-validator@20.0.0': + resolution: {integrity: sha512-BeyLMaRIJDdroJuYM2EGhDMGwVBMZna9UiIqV9hxj+J551Ctc6yoGuGSmghOy/qPhBSuhA6oMtbEiTmxECafsg==} engines: {node: '>=v18'} - '@commitlint/ensure@19.8.1': - resolution: {integrity: sha512-mXDnlJdvDzSObafjYrOSvZBwkD01cqB4gbnnFuVyNpGUM5ijwU/r/6uqUmBXAAOKRfyEjpkGVZxaDsCVnHAgyw==} + '@commitlint/ensure@20.0.0': + resolution: {integrity: sha512-WBV47Fffvabe68n+13HJNFBqiMH5U1Ryls4W3ieGwPC0C7kJqp3OVQQzG2GXqOALmzrgAB+7GXmyy8N9ct8/Fg==} engines: {node: '>=v18'} - '@commitlint/execute-rule@19.8.1': - resolution: {integrity: sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==} + '@commitlint/execute-rule@20.0.0': + resolution: {integrity: sha512-xyCoOShoPuPL44gVa+5EdZsBVao/pNzpQhkzq3RdtlFdKZtjWcLlUFQHSWBuhk5utKYykeJPSz2i8ABHQA+ZZw==} engines: {node: '>=v18'} - '@commitlint/format@19.8.1': - resolution: {integrity: sha512-kSJj34Rp10ItP+Eh9oCItiuN/HwGQMXBnIRk69jdOwEW9llW9FlyqcWYbHPSGofmjsqeoxa38UaEA5tsbm2JWw==} + '@commitlint/format@20.0.0': + resolution: {integrity: sha512-zrZQXUcSDmQ4eGGrd+gFESiX0Rw+WFJk7nW4VFOmxub4mAATNKBQ4vNw5FgMCVehLUKG2OT2LjOqD0Hk8HvcRg==} engines: {node: '>=v18'} - '@commitlint/is-ignored@19.8.1': - resolution: {integrity: sha512-AceOhEhekBUQ5dzrVhDDsbMaY5LqtN8s1mqSnT2Kz1ERvVZkNihrs3Sfk1Je/rxRNbXYFzKZSHaPsEJJDJV8dg==} + '@commitlint/is-ignored@20.0.0': + resolution: {integrity: sha512-ayPLicsqqGAphYIQwh9LdAYOVAQ9Oe5QCgTNTj+BfxZb9b/JW222V5taPoIBzYnAP0z9EfUtljgBk+0BN4T4Cw==} engines: {node: '>=v18'} - '@commitlint/lint@19.8.1': - resolution: {integrity: sha512-52PFbsl+1EvMuokZXLRlOsdcLHf10isTPlWwoY1FQIidTsTvjKXVXYb7AvtpWkDzRO2ZsqIgPK7bI98x8LRUEw==} + '@commitlint/lint@20.0.0': + resolution: {integrity: sha512-kWrX8SfWk4+4nCexfLaQT3f3EcNjJwJBsSZ5rMBw6JCd6OzXufFHgel2Curos4LKIxwec9WSvs2YUD87rXlxNQ==} engines: {node: '>=v18'} - '@commitlint/load@19.8.1': - resolution: {integrity: sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==} + '@commitlint/load@20.1.0': + resolution: {integrity: sha512-qo9ER0XiAimATQR5QhvvzePfeDfApi/AFlC1G+YN+ZAY8/Ua6IRrDrxRvQAr+YXUKAxUsTDSp9KXeXLBPsNRWg==} engines: {node: '>=v18'} - '@commitlint/message@19.8.1': - resolution: {integrity: sha512-+PMLQvjRXiU+Ae0Wc+p99EoGEutzSXFVwQfa3jRNUZLNW5odZAyseb92OSBTKCu+9gGZiJASt76Cj3dLTtcTdg==} + '@commitlint/message@20.0.0': + resolution: {integrity: sha512-gLX4YmKnZqSwkmSB9OckQUrI5VyXEYiv3J5JKZRxIp8jOQsWjZgHSG/OgEfMQBK9ibdclEdAyIPYggwXoFGXjQ==} engines: {node: '>=v18'} - '@commitlint/parse@19.8.1': - resolution: {integrity: sha512-mmAHYcMBmAgJDKWdkjIGq50X4yB0pSGpxyOODwYmoexxxiUCy5JJT99t1+PEMK7KtsCtzuWYIAXYAiKR+k+/Jw==} + '@commitlint/parse@20.0.0': + resolution: {integrity: sha512-j/PHCDX2bGM5xGcWObOvpOc54cXjn9g6xScXzAeOLwTsScaL4Y+qd0pFC6HBwTtrH92NvJQc+2Lx9HFkVi48cg==} engines: {node: '>=v18'} - '@commitlint/read@19.8.1': - resolution: {integrity: sha512-03Jbjb1MqluaVXKHKRuGhcKWtSgh3Jizqy2lJCRbRrnWpcM06MYm8th59Xcns8EqBYvo0Xqb+2DoZFlga97uXQ==} + '@commitlint/read@20.0.0': + resolution: {integrity: sha512-Ti7Y7aEgxsM1nkwA4ZIJczkTFRX/+USMjNrL9NXwWQHqNqrBX2iMi+zfuzZXqfZ327WXBjdkRaytJ+z5vNqTOA==} engines: {node: '>=v18'} - '@commitlint/resolve-extends@19.8.1': - resolution: {integrity: sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==} + '@commitlint/resolve-extends@20.1.0': + resolution: {integrity: sha512-cxKXQrqHjZT3o+XPdqDCwOWVFQiae++uwd9dUBC7f2MdV58ons3uUvASdW7m55eat5sRiQ6xUHyMWMRm6atZWw==} engines: {node: '>=v18'} - '@commitlint/rules@19.8.1': - resolution: {integrity: sha512-Hnlhd9DyvGiGwjfjfToMi1dsnw1EXKGJNLTcsuGORHz6SS9swRgkBsou33MQ2n51/boIDrbsg4tIBbRpEWK2kw==} + '@commitlint/rules@20.0.0': + resolution: {integrity: sha512-gvg2k10I/RfvHn5I5sxvVZKM1fl72Sqrv2YY/BnM7lMHcYqO0E2jnRWoYguvBfEcZ39t+rbATlciggVe77E4zA==} engines: {node: '>=v18'} - '@commitlint/to-lines@19.8.1': - resolution: {integrity: sha512-98Mm5inzbWTKuZQr2aW4SReY6WUukdWXuZhrqf1QdKPZBCCsXuG87c+iP0bwtD6DBnmVVQjgp4whoHRVixyPBg==} + '@commitlint/to-lines@20.0.0': + resolution: {integrity: sha512-2l9gmwiCRqZNWgV+pX1X7z4yP0b3ex/86UmUFgoRt672Ez6cAM2lOQeHFRUTuE6sPpi8XBCGnd8Kh3bMoyHwJw==} engines: {node: '>=v18'} - '@commitlint/top-level@19.8.1': - resolution: {integrity: sha512-Ph8IN1IOHPSDhURCSXBz44+CIu+60duFwRsg6HqaISFHQHbmBtxVw4ZrFNIYUzEP7WwrNPxa2/5qJ//NK1FGcw==} + '@commitlint/top-level@20.0.0': + resolution: {integrity: sha512-drXaPSP2EcopukrUXvUXmsQMu3Ey/FuJDc/5oiW4heoCfoE5BdLQyuc7veGeE3aoQaTVqZnh4D5WTWe2vefYKg==} engines: {node: '>=v18'} - '@commitlint/types@19.8.1': - resolution: {integrity: sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==} + '@commitlint/types@20.0.0': + resolution: {integrity: sha512-bVUNBqG6aznYcYjTjnc3+Cat/iBgbgpflxbIBTnsHTX0YVpnmINPEkSRWymT2Q8aSH3Y7aKnEbunilkYe8TybA==} engines: {node: '>=v18'} '@cryptography/aes@0.1.1': @@ -1825,8 +1825,8 @@ packages: prettier-plugin-ember-template-tag: optional: true - '@iconify/json@2.2.397': - resolution: {integrity: sha512-osoLxaGe85Vxec/fGOlx3NwKzdN3JWH8fNITn4o4P+i2UBYGMJTDGSjgl6CIM0OX50IAAFz5jYQebtxInsRnSQ==} + '@iconify/json@2.2.400': + resolution: {integrity: sha512-L8cy1YE/H0LFO4Pu7hfyylkrQmawL8sTOCH2PcBDydWA1FpoKijeIzweRJ6e9grvn2li9Yu+Pe32Jq9x4MKpaw==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -3559,52 +3559,40 @@ packages: '@types/yauzl@2.10.3': resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@typescript-eslint/eslint-plugin@8.46.1': - resolution: {integrity: sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==} + '@typescript-eslint/eslint-plugin@8.46.2': + resolution: {integrity: sha512-ZGBMToy857/NIPaaCucIUQgqueOiq7HeAKkhlvqVV4lm089zUFW6ikRySx2v+cAhKeUCPuWVHeimyk6Dw1iY3w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.46.1 + '@typescript-eslint/parser': ^8.46.2 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.46.1': - resolution: {integrity: sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==} + '@typescript-eslint/parser@8.46.2': + resolution: {integrity: sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.44.1': - resolution: {integrity: sha512-ycSa60eGg8GWAkVsKV4E6Nz33h+HjTXbsDT4FILyL8Obk5/mx4tbvCNsLf9zret3ipSumAOG89UcCs/KRaKYrA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.46.1': resolution: {integrity: sha512-FOIaFVMHzRskXr5J4Jp8lFVV0gz5ngv3RHmn+E4HYxSJ3DgDzU7fVI1/M7Ijh1zf6S7HIoaIOtln1H5y8V+9Zg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.44.1': - resolution: {integrity: sha512-NdhWHgmynpSvyhchGLXh+w12OMT308Gm25JoRIyTZqEbApiBiQHD/8xgb6LqCWCFcxFtWwaVdFsLPQI3jvhywg==} + '@typescript-eslint/project-service@8.46.2': + resolution: {integrity: sha512-PULOLZ9iqwI7hXcmL4fVfIsBi6AN9YxRc0frbvmg8f+4hQAjQ5GYNKK0DIArNo+rOKmR/iBYwkpBmnIwin4wBg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/scope-manager@8.46.1': resolution: {integrity: sha512-weL9Gg3/5F0pVQKiF8eOXFZp8emqWzZsOJuWRUNtHT+UNV2xSJegmpCNQHy37aEQIbToTq7RHKhWvOsmbM680A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.44.1': - resolution: {integrity: sha512-B5OyACouEjuIvof3o86lRMvyDsFwZm+4fBOqFHccIctYgBjqR3qT39FBYGN87khcgf0ExpdCBeGKpKRhSFTjKQ==} + '@typescript-eslint/scope-manager@8.46.2': + resolution: {integrity: sha512-LF4b/NmGvdWEHD2H4MsHD8ny6JpiVNDzrSZr3CsckEgCbAGZbYM4Cqxvi9L+WqDMT+51Ozy7lt2M+d0JLEuBqA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' - - '@typescript-eslint/tsconfig-utils@8.46.0': - resolution: {integrity: sha512-WrYXKGAHY836/N7zoK/kzi6p8tXFhasHh8ocFL9VZSAkvH956gfeRfcnhs3xzRy8qQ/dq3q44v1jvQieMFg2cw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/tsconfig-utils@8.46.1': resolution: {integrity: sha512-X88+J/CwFvlJB+mK09VFqx5FE4H5cXD+H/Bdza2aEWkSb8hnWIQorNcscRl4IEo1Cz9VI/+/r/jnGWkbWPx54g==} @@ -3612,8 +3600,14 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.46.1': - resolution: {integrity: sha512-+BlmiHIiqufBxkVnOtFwjah/vrkF4MtKKvpXrKSPLCkCtAp8H01/VV43sfqA98Od7nJpDcFnkwgyfQbOG0AMvw==} + '@typescript-eslint/tsconfig-utils@8.46.2': + resolution: {integrity: sha512-a7QH6fw4S57+F5y2FIxxSDyi5M4UfGF+Jl1bCGd7+L4KsaUY80GsiF/t0UoRFDHAguKlBaACWJRmdrc6Xfkkag==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + typescript: '>=4.8.4 <6.0.0' + + '@typescript-eslint/type-utils@8.46.2': + resolution: {integrity: sha512-HbPM4LbaAAt/DjxXaG9yiS9brOOz6fabal4uvUmaUYe6l3K1phQDMQKBRUrr06BQkxkvIZVVHttqiybM9nJsLA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -3623,23 +3617,13 @@ packages: resolution: {integrity: sha512-9EwxsWdVqh42afLbHP90n2VdHaWU/oWgbH2P0CfcNfdKL7CuKpwMQGjwev56vWu9cSKU7FWSu6r9zck6CVfnag==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.44.1': - resolution: {integrity: sha512-Lk7uj7y9uQUOEguiDIDLYLJOrYHQa7oBiURYVFqIpGxclAFQ78f6VUOM8lI2XEuNOKNB7XuvM2+2cMXAoq4ALQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@typescript-eslint/types@8.46.0': - resolution: {integrity: sha512-bHGGJyVjSE4dJJIO5yyEWt/cHyNwga/zXGJbJJ8TiO01aVREK6gCTu3L+5wrkb1FbDkQ+TKjMNe9R/QQQP9+rA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.46.1': resolution: {integrity: sha512-C+soprGBHwWBdkDpbaRC4paGBrkIXxVlNohadL5o0kfhsXqOC6GYH2S/Obmig+I0HTDl8wMaRySwrfrXVP8/pQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.44.1': - resolution: {integrity: sha512-qnQJ+mVa7szevdEyvfItbO5Vo+GfZ4/GZWWDRRLjrxYPkhM+6zYB2vRYwCsoJLzqFCdZT4mEqyJoyzkunsZ96A==} + '@typescript-eslint/types@8.46.2': + resolution: {integrity: sha512-lNCWCbq7rpg7qDsQrd3D6NyWYu+gkTENkG5IKYhUIcxSb59SQC/hEQ+MrG4sTgBVghTonNWq42bA/d4yYumldQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/typescript-estree@8.46.1': resolution: {integrity: sha512-uIifjT4s8cQKFQ8ZBXXyoUODtRoAd7F7+G8MKmtzj17+1UbdzFl52AzRyZRyKqPHhgzvXunnSckVu36flGy8cg==} @@ -3647,11 +3631,10 @@ packages: peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.44.1': - resolution: {integrity: sha512-DpX5Fp6edTlocMCwA+mHY8Mra+pPjRZ0TfHkXI8QFelIKcbADQz1LUPNtzOFUriBB2UYqw4Pi9+xV4w9ZczHFg==} + '@typescript-eslint/typescript-estree@8.46.2': + resolution: {integrity: sha512-f7rW7LJ2b7Uh2EiQ+7sza6RDZnajbNbemn54Ob6fRwQbgcIn+GWfyuHDHRYgRoZu1P4AayVScrRW+YfbTvPQoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/utils@8.46.1': @@ -3661,14 +3644,21 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.44.1': - resolution: {integrity: sha512-576+u0QD+Jp3tZzvfRfxon0EA2lzcDt3lhUbsC6Lgzy9x2VR4E+JUiNyGHi5T8vk0TV+fpJ5GLG1JsJuWCaKhw==} + '@typescript-eslint/utils@8.46.2': + resolution: {integrity: sha512-sExxzucx0Tud5tE0XqR0lT0psBQvEpnpiul9XbGUB1QwpWJJAps1O/Z7hJxLGiZLBKMCutjTzDgmd1muEhBnVg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + peerDependencies: + eslint: ^8.57.0 || ^9.0.0 + typescript: '>=4.8.4 <6.0.0' '@typescript-eslint/visitor-keys@8.46.1': resolution: {integrity: sha512-ptkmIf2iDkNUjdeu2bQqhFPV1m6qTnFFjg7PPDjxKWaMaP0Z6I9l30Jr3g5QqbZGdw8YdYvLp+XnqnWWZOg/NA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@typescript-eslint/visitor-keys@8.46.2': + resolution: {integrity: sha512-tUFMXI4gxzzMXt4xpGJEsBsTox0XbNQ1y94EwlD/CuZwFcQP79xfQqMhau9HsRc/J0cAPA/HZt1dZPtGn9V/7w==} + engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} @@ -5117,9 +5107,9 @@ packages: peerDependencies: eslint: '>=7' - eslint-plugin-react-hooks@5.2.0: - resolution: {integrity: sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg==} - engines: {node: '>=10'} + eslint-plugin-react-hooks@7.0.1: + resolution: {integrity: sha512-O0d0m04evaNzEPoSW+59Mezf8Qt0InfgGIBJnpC0h3NH/WjUAR7BIKUfysC6todmtiZ/A0oUVS8Gce0WhBrHsA==} + engines: {node: '>=18'} peerDependencies: eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0 @@ -5748,6 +5738,7 @@ packages: intersection-observer@0.12.2: resolution: {integrity: sha512-7m1vEcPCxXYI8HqnL8CKI6siDyD+eIWSwgB3DZA+ZTogxk9I4CDnj4wilt9x/+/QbHI4YG5YZNmC6458/e9Ktg==} + deprecated: The Intersection Observer polyfill is no longer needed and can safely be removed. Intersection Observer has been Baseline since 2019. ip-address@9.0.5: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} @@ -6171,8 +6162,8 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} - knip@5.66.0: - resolution: {integrity: sha512-b1IR8sEgeywrnzhl0ePDM6euAjrC3Jefdpg6EpUc2z+WSYO0UChGQhftZIbnSNTeqYi//7/5vh+lLAxwO1AoVQ==} + knip@5.66.3: + resolution: {integrity: sha512-BEe9ZCI8fm4TJzehnrCt+L/Faqu6qfMH6VrwSfck+lCGotQzf0jh5dVXysPWjWqMpdUSr6+MpMu9JW/G6wiAcQ==} engines: {node: '>=18.18.0'} hasBin: true peerDependencies: @@ -6272,13 +6263,13 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - lint-staged@16.2.4: - resolution: {integrity: sha512-Pkyr/wd90oAyXk98i/2KwfkIhoYQUMtss769FIT9hFM5ogYZwrk+GRE46yKXSg2ZGhcJ1p38Gf5gmI5Ohjg2yg==} + lint-staged@16.2.6: + resolution: {integrity: sha512-s1gphtDbV4bmW1eylXpVMk2u7is7YsrLl8hzrtvC70h4ByhcMLZFY01Fx05ZUDNuv1H8HO4E+e2zgejV1jVwNw==} engines: {node: '>=20.17'} hasBin: true - listr2@9.0.4: - resolution: {integrity: sha512-1wd/kpAdKRLwv7/3OKC8zZ5U8e/fajCfWMxacUvB79S5nLrYGPtUI/8chMQhn3LQjsRVErTb9i1ECAwW0ZIHnQ==} + listr2@9.0.5: + resolution: {integrity: sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==} engines: {node: '>=20.0.0'} local-pkg@1.1.1: @@ -7189,11 +7180,11 @@ packages: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true - react-devtools-core@6.1.5: - resolution: {integrity: sha512-ePrwPfxAnB+7hgnEr8vpKxL9cmnp7F322t8oqcPshbIQQhDKgFDW4tjhF2wjVbdXF9O/nyuy3sQWd9JGpiLPvA==} + react-devtools-core@7.0.1: + resolution: {integrity: sha512-C3yNvRHaizlpiASzy7b9vbnBGLrhvdhl1CbdU6EnZgxPNbai60szdLtl+VL76UNOt5bOoVTOz5rNWZxgGt+Gsw==} - react-devtools@6.1.5: - resolution: {integrity: sha512-yp7kADDET5neqMMBtwRIPqJ1tcVXWP88RsSCdOrwYsxGGL/pS5Za4jOCYekiZb0m7nzTbSH158ugGyNnBaDJvQ==} + react-devtools@7.0.1: + resolution: {integrity: sha512-I2UXoJlsqNeN3uCrlrJw0V+K6HTHU5Q1x+BWJlF99hBC6A/lKhe+IuITZXyKb8BluMReSBYUhUYGkJGgr2KPQQ==} hasBin: true react-dom@19.2.0: @@ -8218,8 +8209,8 @@ packages: typedarray-to-buffer@3.1.5: resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - typescript-eslint@8.46.1: - resolution: {integrity: sha512-VHgijW803JafdSsDO8I761r3SHrgk4T00IdyQ+/UsthtgPRsBWQLqoSxOolxTpxRKi1kGXK0bSz4CoAc9ObqJA==} + typescript-eslint@8.46.2: + resolution: {integrity: sha512-vbw8bOmiuYNdzzV3lsiWv6sRwjyuKJMQqWulBOU7M0RrxedXledX8G8kBbQeiOYDnTfiXz0Y4081E1QMNB6iQg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -8726,6 +8717,12 @@ packages: peerDependencies: zod: ^3.18.0 + zod-validation-error@4.0.2: + resolution: {integrity: sha512-Q6/nZLe6jxuU80qb/4uJ4t5v2VEZ44lzQjPDhYJNztRQ4wyWc6VF3D3Kb/fAuPetZQnhS3hnajCf9CsWesghLQ==} + engines: {node: '>=18.0.0'} + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + zod@3.24.4: resolution: {integrity: sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==} @@ -8877,7 +8874,7 @@ snapshots: '@babel/generator@7.28.0': dependencies: - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/types': 7.28.4 '@jridgewell/gen-mapping': 0.3.12 '@jridgewell/trace-mapping': 0.3.29 @@ -9728,7 +9725,7 @@ snapshots: '@babel/template@7.27.0': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/types': 7.28.4 '@babel/template@7.27.2': @@ -9758,7 +9755,7 @@ snapshots: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 '@babel/types': 7.28.4 debug: 4.4.3 @@ -9812,63 +9809,63 @@ snapshots: '@bufbuild/protobuf@2.5.2': {} - '@commitlint/cli@19.8.1(@types/node@24.8.1)(typescript@5.9.3)': + '@commitlint/cli@20.1.0(@types/node@24.8.1)(typescript@5.9.3)': dependencies: - '@commitlint/format': 19.8.1 - '@commitlint/lint': 19.8.1 - '@commitlint/load': 19.8.1(@types/node@24.8.1)(typescript@5.9.3) - '@commitlint/read': 19.8.1 - '@commitlint/types': 19.8.1 + '@commitlint/format': 20.0.0 + '@commitlint/lint': 20.0.0 + '@commitlint/load': 20.1.0(@types/node@24.8.1)(typescript@5.9.3) + '@commitlint/read': 20.0.0 + '@commitlint/types': 20.0.0 tinyexec: 1.0.1 yargs: 17.7.2 transitivePeerDependencies: - '@types/node' - typescript - '@commitlint/config-conventional@19.8.1': + '@commitlint/config-conventional@20.0.0': dependencies: - '@commitlint/types': 19.8.1 + '@commitlint/types': 20.0.0 conventional-changelog-conventionalcommits: 7.0.2 - '@commitlint/config-validator@19.8.1': + '@commitlint/config-validator@20.0.0': dependencies: - '@commitlint/types': 19.8.1 + '@commitlint/types': 20.0.0 ajv: 8.17.1 - '@commitlint/ensure@19.8.1': + '@commitlint/ensure@20.0.0': dependencies: - '@commitlint/types': 19.8.1 + '@commitlint/types': 20.0.0 lodash.camelcase: 4.3.0 lodash.kebabcase: 4.1.1 lodash.snakecase: 4.1.1 lodash.startcase: 4.4.0 lodash.upperfirst: 4.3.1 - '@commitlint/execute-rule@19.8.1': {} + '@commitlint/execute-rule@20.0.0': {} - '@commitlint/format@19.8.1': + '@commitlint/format@20.0.0': dependencies: - '@commitlint/types': 19.8.1 + '@commitlint/types': 20.0.0 chalk: 5.4.1 - '@commitlint/is-ignored@19.8.1': + '@commitlint/is-ignored@20.0.0': dependencies: - '@commitlint/types': 19.8.1 + '@commitlint/types': 20.0.0 semver: 7.7.3 - '@commitlint/lint@19.8.1': + '@commitlint/lint@20.0.0': dependencies: - '@commitlint/is-ignored': 19.8.1 - '@commitlint/parse': 19.8.1 - '@commitlint/rules': 19.8.1 - '@commitlint/types': 19.8.1 + '@commitlint/is-ignored': 20.0.0 + '@commitlint/parse': 20.0.0 + '@commitlint/rules': 20.0.0 + '@commitlint/types': 20.0.0 - '@commitlint/load@19.8.1(@types/node@24.8.1)(typescript@5.9.3)': + '@commitlint/load@20.1.0(@types/node@24.8.1)(typescript@5.9.3)': dependencies: - '@commitlint/config-validator': 19.8.1 - '@commitlint/execute-rule': 19.8.1 - '@commitlint/resolve-extends': 19.8.1 - '@commitlint/types': 19.8.1 + '@commitlint/config-validator': 20.0.0 + '@commitlint/execute-rule': 20.0.0 + '@commitlint/resolve-extends': 20.1.0 + '@commitlint/types': 20.0.0 chalk: 5.4.1 cosmiconfig: 9.0.0(typescript@5.9.3) cosmiconfig-typescript-loader: 6.1.0(@types/node@24.8.1)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) @@ -9879,45 +9876,45 @@ snapshots: - '@types/node' - typescript - '@commitlint/message@19.8.1': {} + '@commitlint/message@20.0.0': {} - '@commitlint/parse@19.8.1': + '@commitlint/parse@20.0.0': dependencies: - '@commitlint/types': 19.8.1 + '@commitlint/types': 20.0.0 conventional-changelog-angular: 7.0.0 conventional-commits-parser: 5.0.0 - '@commitlint/read@19.8.1': + '@commitlint/read@20.0.0': dependencies: - '@commitlint/top-level': 19.8.1 - '@commitlint/types': 19.8.1 + '@commitlint/top-level': 20.0.0 + '@commitlint/types': 20.0.0 git-raw-commits: 4.0.0 minimist: 1.2.8 tinyexec: 1.0.1 - '@commitlint/resolve-extends@19.8.1': + '@commitlint/resolve-extends@20.1.0': dependencies: - '@commitlint/config-validator': 19.8.1 - '@commitlint/types': 19.8.1 + '@commitlint/config-validator': 20.0.0 + '@commitlint/types': 20.0.0 global-directory: 4.0.1 import-meta-resolve: 4.1.0 lodash.mergewith: 4.6.2 resolve-from: 5.0.0 - '@commitlint/rules@19.8.1': + '@commitlint/rules@20.0.0': dependencies: - '@commitlint/ensure': 19.8.1 - '@commitlint/message': 19.8.1 - '@commitlint/to-lines': 19.8.1 - '@commitlint/types': 19.8.1 + '@commitlint/ensure': 20.0.0 + '@commitlint/message': 20.0.0 + '@commitlint/to-lines': 20.0.0 + '@commitlint/types': 20.0.0 - '@commitlint/to-lines@19.8.1': {} + '@commitlint/to-lines@20.0.0': {} - '@commitlint/top-level@19.8.1': + '@commitlint/top-level@20.0.0': dependencies: find-up: 7.0.0 - '@commitlint/types@19.8.1': + '@commitlint/types@20.0.0': dependencies: '@types/conventional-commits-parser': 5.0.0 chalk: 5.4.1 @@ -10279,7 +10276,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/json@2.2.397': + '@iconify/json@2.2.400': dependencies: '@iconify/types': 2.0.0 pathe: 2.0.3 @@ -11229,7 +11226,7 @@ snapshots: '@stylistic/eslint-plugin@2.11.0(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': dependencies: - '@typescript-eslint/utils': 8.44.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) eslint: 9.38.0(jiti@2.6.0) eslint-visitor-keys: 4.2.1 espree: 10.4.0 @@ -11973,14 +11970,14 @@ snapshots: '@types/node': 24.8.1 optional: true - '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': + '@typescript-eslint/eslint-plugin@8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) - '@typescript-eslint/scope-manager': 8.46.1 - '@typescript-eslint/type-utils': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.1 + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/type-utils': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.2 eslint: 9.38.0(jiti@2.6.0) graphemer: 1.4.0 ignore: 7.0.5 @@ -11990,27 +11987,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': + '@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': dependencies: - '@typescript-eslint/scope-manager': 8.46.1 - '@typescript-eslint/types': 8.46.1 - '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3) - '@typescript-eslint/visitor-keys': 8.46.1 + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) + '@typescript-eslint/visitor-keys': 8.46.2 debug: 4.4.3 eslint: 9.38.0(jiti@2.6.0) typescript: 5.9.3 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.44.1(typescript@5.9.3)': - dependencies: - '@typescript-eslint/tsconfig-utils': 8.46.0(typescript@5.9.3) - '@typescript-eslint/types': 8.46.0 - debug: 4.4.3 - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/project-service@8.46.1(typescript@5.9.3)': dependencies: '@typescript-eslint/tsconfig-utils': 8.46.1(typescript@5.9.3) @@ -12020,33 +12008,38 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.44.1': + '@typescript-eslint/project-service@8.46.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3) + '@typescript-eslint/types': 8.46.2 + debug: 4.4.3 + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color '@typescript-eslint/scope-manager@8.46.1': dependencies: '@typescript-eslint/types': 8.46.1 '@typescript-eslint/visitor-keys': 8.46.1 - '@typescript-eslint/tsconfig-utils@8.44.1(typescript@5.9.3)': + '@typescript-eslint/scope-manager@8.46.2': dependencies: - typescript: 5.9.3 - - '@typescript-eslint/tsconfig-utils@8.46.0(typescript@5.9.3)': - dependencies: - typescript: 5.9.3 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/visitor-keys': 8.46.2 '@typescript-eslint/tsconfig-utils@8.46.1(typescript@5.9.3)': dependencies: typescript: 5.9.3 - '@typescript-eslint/type-utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': + '@typescript-eslint/tsconfig-utils@8.46.2(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.46.1 - '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + typescript: 5.9.3 + + '@typescript-eslint/type-utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': + dependencies: + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) debug: 4.4.3 eslint: 9.38.0(jiti@2.6.0) ts-api-utils: 2.1.0(typescript@5.9.3) @@ -12056,27 +12049,9 @@ snapshots: '@typescript-eslint/types@8.41.0': {} - '@typescript-eslint/types@8.44.1': {} - - '@typescript-eslint/types@8.46.0': {} - '@typescript-eslint/types@8.46.1': {} - '@typescript-eslint/typescript-estree@8.44.1(typescript@5.9.3)': - dependencies: - '@typescript-eslint/project-service': 8.44.1(typescript@5.9.3) - '@typescript-eslint/tsconfig-utils': 8.44.1(typescript@5.9.3) - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/visitor-keys': 8.44.1 - debug: 4.4.3 - fast-glob: 3.3.3 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.7.3 - ts-api-utils: 2.1.0(typescript@5.9.3) - typescript: 5.9.3 - transitivePeerDependencies: - - supports-color + '@typescript-eslint/types@8.46.2': {} '@typescript-eslint/typescript-estree@8.46.1(typescript@5.9.3)': dependencies: @@ -12094,13 +12069,18 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.44.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': + '@typescript-eslint/typescript-estree@8.46.2(typescript@5.9.3)': dependencies: - '@eslint-community/eslint-utils': 4.8.0(eslint@9.38.0(jiti@2.6.0)) - '@typescript-eslint/scope-manager': 8.44.1 - '@typescript-eslint/types': 8.44.1 - '@typescript-eslint/typescript-estree': 8.44.1(typescript@5.9.3) - eslint: 9.38.0(jiti@2.6.0) + '@typescript-eslint/project-service': 8.46.2(typescript@5.9.3) + '@typescript-eslint/tsconfig-utils': 8.46.2(typescript@5.9.3) + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/visitor-keys': 8.46.2 + debug: 4.4.3 + fast-glob: 3.3.3 + is-glob: 4.0.3 + minimatch: 9.0.5 + semver: 7.7.3 + ts-api-utils: 2.1.0(typescript@5.9.3) typescript: 5.9.3 transitivePeerDependencies: - supports-color @@ -12116,16 +12096,27 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.44.1': + '@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3)': dependencies: - '@typescript-eslint/types': 8.44.1 - eslint-visitor-keys: 4.2.1 + '@eslint-community/eslint-utils': 4.8.0(eslint@9.38.0(jiti@2.6.0)) + '@typescript-eslint/scope-manager': 8.46.2 + '@typescript-eslint/types': 8.46.2 + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) + eslint: 9.38.0(jiti@2.6.0) + typescript: 5.9.3 + transitivePeerDependencies: + - supports-color '@typescript-eslint/visitor-keys@8.46.1': dependencies: '@typescript-eslint/types': 8.46.1 eslint-visitor-keys: 4.2.1 + '@typescript-eslint/visitor-keys@8.46.2': + dependencies: + '@typescript-eslint/types': 8.46.2 + eslint-visitor-keys: 4.2.1 + '@ungap/structured-clone@1.2.0': {} '@unrs/resolver-binding-android-arm-eabi@1.10.1': @@ -13705,9 +13696,9 @@ snapshots: optionalDependencies: unrs-resolver: 1.10.1 - eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))): + eslint-import-resolver-alias@1.1.2(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))): dependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)) eslint-import-resolver-node@0.3.9: dependencies: @@ -13717,7 +13708,7 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0)): + eslint-import-resolver-typescript@3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0)): dependencies: '@nolyfill/is-core-module': 1.0.39 debug: 4.4.3 @@ -13728,16 +13719,16 @@ snapshots: tinyglobby: 0.2.14 unrs-resolver: 1.10.1 optionalDependencies: - eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)) + eslint-plugin-import: 2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)) transitivePeerDependencies: - supports-color - eslint-module-utils@2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)): + eslint-module-utils@2.12.1(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)): dependencies: debug: 3.2.7 optionalDependencies: - '@typescript-eslint/parser': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) eslint: 9.38.0(jiti@2.6.0) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: @@ -13754,7 +13745,7 @@ snapshots: dependencies: htmlparser2: 10.0.0 - eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)): + eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)): dependencies: '@typescript-eslint/types': 8.41.0 comment-parser: 1.4.1 @@ -13767,12 +13758,12 @@ snapshots: stable-hash-x: 0.2.0 unrs-resolver: 1.10.1 optionalDependencies: - '@typescript-eslint/utils': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) eslint-import-resolver-node: 0.3.9 transitivePeerDependencies: - supports-color - eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)): + eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)): dependencies: '@rtsao/scc': 1.1.0 array-includes: 3.1.9 @@ -13783,7 +13774,7 @@ snapshots: doctrine: 2.1.0 eslint: 9.38.0(jiti@2.6.0) eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)) + eslint-module-utils: 2.12.1(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)) hasown: 2.0.2 is-core-module: 2.16.1 is-glob: 4.0.3 @@ -13795,7 +13786,7 @@ snapshots: string.prototype.trimend: 1.0.9 tsconfig-paths: 3.15.0 optionalDependencies: - '@typescript-eslint/parser': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) transitivePeerDependencies: - eslint-import-resolver-typescript - eslint-import-resolver-webpack @@ -13842,9 +13833,16 @@ snapshots: transitivePeerDependencies: - supports-color - eslint-plugin-react-hooks@5.2.0(eslint@9.38.0(jiti@2.6.0)): + eslint-plugin-react-hooks@7.0.1(eslint@9.38.0(jiti@2.6.0)): dependencies: + '@babel/core': 7.28.4 + '@babel/parser': 7.28.4 eslint: 9.38.0(jiti@2.6.0) + hermes-parser: 0.25.1 + zod: 4.1.12 + zod-validation-error: 4.0.2(zod@4.1.12) + transitivePeerDependencies: + - supports-color eslint-plugin-react@7.37.5(eslint@9.38.0(jiti@2.6.0)): dependencies: @@ -14954,7 +14952,7 @@ snapshots: kind-of@6.0.3: {} - knip@5.66.0(@types/node@24.8.1)(typescript@5.9.3): + knip@5.66.3(@types/node@24.8.1)(typescript@5.9.3): dependencies: '@nodelib/fs.walk': 1.2.8 '@types/node': 24.8.1 @@ -15049,17 +15047,17 @@ snapshots: lines-and-columns@1.2.4: {} - lint-staged@16.2.4: + lint-staged@16.2.6: dependencies: commander: 14.0.1 - listr2: 9.0.4 + listr2: 9.0.5 micromatch: 4.0.8 nano-spawn: 2.0.0 pidtree: 0.6.0 string-argv: 0.3.2 yaml: 2.8.1 - listr2@9.0.4: + listr2@9.0.5: dependencies: cli-truncate: 5.1.0 colorette: 2.0.20 @@ -15566,20 +15564,20 @@ snapshots: sax: 1.3.0 optional: true - neostandard@0.12.2(@typescript-eslint/utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3): + neostandard@0.12.2(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3): dependencies: '@humanwhocodes/gitignore-to-minimatch': 1.0.2 '@stylistic/eslint-plugin': 2.11.0(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) eslint: 9.38.0(jiti@2.6.0) - eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0)) - eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)) + eslint-import-resolver-typescript: 3.10.1(eslint-plugin-import-x@4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)))(eslint-plugin-import@2.32.0(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0)))(eslint@9.38.0(jiti@2.6.0)) + eslint-plugin-import-x: 4.16.1(@typescript-eslint/utils@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint-import-resolver-node@0.3.9)(eslint@9.38.0(jiti@2.6.0)) eslint-plugin-n: 17.23.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) eslint-plugin-promise: 7.2.1(eslint@9.38.0(jiti@2.6.0)) eslint-plugin-react: 7.37.5(eslint@9.38.0(jiti@2.6.0)) find-up: 5.0.0 globals: 15.15.0 peowly: 1.3.2 - typescript-eslint: 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + typescript-eslint: 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) transitivePeerDependencies: - '@typescript-eslint/utils' - eslint-import-resolver-node @@ -16088,7 +16086,7 @@ snapshots: minimist: 1.2.8 strip-json-comments: 2.0.1 - react-devtools-core@6.1.5(bufferutil@4.0.8)(utf-8-validate@5.0.10): + react-devtools-core@7.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: shell-quote: 1.8.1 ws: 7.5.10(bufferutil@4.0.8)(utf-8-validate@5.0.10) @@ -16096,13 +16094,13 @@ snapshots: - bufferutil - utf-8-validate - react-devtools@6.1.5(bufferutil@4.0.8)(utf-8-validate@5.0.10): + react-devtools@7.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10): dependencies: cross-spawn: 5.1.0 electron: 23.3.13 internal-ip: 6.2.0 minimist: 1.2.8 - react-devtools-core: 6.1.5(bufferutil@4.0.8)(utf-8-validate@5.0.10) + react-devtools-core: 7.0.1(bufferutil@4.0.8)(utf-8-validate@5.0.10) update-notifier: 2.5.0 transitivePeerDependencies: - bufferutil @@ -17273,12 +17271,12 @@ snapshots: dependencies: is-typedarray: 1.0.0 - typescript-eslint@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3): + typescript-eslint@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3): dependencies: - '@typescript-eslint/eslint-plugin': 8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) - '@typescript-eslint/parser': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) - '@typescript-eslint/typescript-estree': 8.46.1(typescript@5.9.3) - '@typescript-eslint/utils': 8.46.1(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/eslint-plugin': 8.46.2(@typescript-eslint/parser@8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3))(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/parser': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) + '@typescript-eslint/typescript-estree': 8.46.2(typescript@5.9.3) + '@typescript-eslint/utils': 8.46.2(eslint@9.38.0(jiti@2.6.0))(typescript@5.9.3) eslint: 9.38.0(jiti@2.6.0) typescript: 5.9.3 transitivePeerDependencies: @@ -17855,6 +17853,10 @@ snapshots: dependencies: zod: 3.24.4 + zod-validation-error@4.0.2(zod@4.1.12): + dependencies: + zod: 4.1.12 + zod@3.24.4: {} zod@3.25.76: {} diff --git a/lede/package/system/opkg/Makefile b/lede/package/system/opkg/Makefile index 83c9dab1b0..5b8d4958b6 100644 --- a/lede/package/system/opkg/Makefile +++ b/lede/package/system/opkg/Makefile @@ -7,14 +7,14 @@ include $(TOPDIR)/rules.mk include $(INCLUDE_DIR)/kernel.mk PKG_NAME:=opkg -PKG_RELEASE:=$(AUTORELEASE) +PKG_RELEASE:=1 PKG_FLAGS:=essential PKG_SOURCE_PROTO:=git PKG_SOURCE_URL=$(PROJECT_GIT)/project/opkg-lede.git -PKG_SOURCE_DATE:=2022-02-24 -PKG_SOURCE_VERSION:=d038e5b6d155784575f62a66a8bb7e874173e92e -PKG_MIRROR_HASH:=e5ec4ae93f6529f7f0b9acc22a9a63c1b2f27d3b30b4a82041fcd58b9bc7cdf3 +PKG_SOURCE_DATE:=2024-10-16 +PKG_SOURCE_VERSION:=38eccbb1fd694d4798ac1baf88f9ba83d1eac616 +PKG_MIRROR_HASH:=993ce77170db0dc62bdc9938fbc30212a77de01e76dbaba4e3a856784199d6df PKG_LICENSE:=GPL-2.0 PKG_LICENSE_FILES:=COPYING @@ -28,6 +28,8 @@ PKG_CONFIG_DEPENDS += \ HOST_BUILD_DEPENDS:=libubox/host +PKG_BUILD_FLAGS:=gc-sections + include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/host-build.mk include $(INCLUDE_DIR)/cmake.mk @@ -57,7 +59,6 @@ define Package/opkg/conffiles /etc/opkg/customfeeds.conf endef -TARGET_CFLAGS += -ffunction-sections -fdata-sections EXTRA_CFLAGS += $(TARGET_CPPFLAGS) CMAKE_OPTIONS += \ diff --git a/lede/package/system/opkg/files/20_migrate-feeds b/lede/package/system/opkg/files/20_migrate-feeds index 38cc57c467..a4bd725758 100644 --- a/lede/package/system/opkg/files/20_migrate-feeds +++ b/lede/package/system/opkg/files/20_migrate-feeds @@ -1,6 +1,6 @@ #!/bin/sh -[ -f /etc/opkg.conf ] && grep -q "src\/" /etc/opkg.conf || exit 0 +[ -f /etc/opkg.conf ] && grep -q "src/" /etc/opkg.conf || exit 0 echo -e "# Old feeds from previous image\n# Uncomment to reenable\n" >> /etc/opkg/customfeeds.conf sed -n "s/.*\(src\/.*\)/# \1/p" /etc/opkg.conf >> /etc/opkg/customfeeds.conf diff --git a/openwrt-packages/luci-app-ddns-go/Makefile b/openwrt-packages/luci-app-ddns-go/Makefile index 64664c8c16..b5ae5035e5 100644 --- a/openwrt-packages/luci-app-ddns-go/Makefile +++ b/openwrt-packages/luci-app-ddns-go/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ddns-go -PKG_VERSION:=1.6.2 -PKG_RELEASE:=20251024 +PKG_VERSION:=1.6.3 +PKG_RELEASE:=20251025 PKG_MAINTAINER:=sirpdboy PKG_CONFIG_DEPENDS:= @@ -17,6 +17,11 @@ LUCI_TITLE:=LuCI Support for Dynamic ddns-go Client LUCI_DEPENDS:=+ddns-go LUCI_PKGARCH:=all +define Package/$(PKG_NAME)/conffiles +/etc/config/ddns-go +/etc/ddns-go/ddns-go-config.yaml +endef + include $(TOPDIR)/feeds/luci/luci.mk # call BuildPackage - OpenWrt buildroot signature diff --git a/openwrt-packages/luci-app-ddns-go/po/templates/ddns-go.pot b/openwrt-packages/luci-app-ddns-go/po/templates/ddns-go.pot index ccbab9154d..4a88c63f06 100644 --- a/openwrt-packages/luci-app-ddns-go/po/templates/ddns-go.pot +++ b/openwrt-packages/luci-app-ddns-go/po/templates/ddns-go.pot @@ -73,7 +73,7 @@ msgstr "" msgid "Delayed Start (seconds)" msgstr "" -msgid "Update Program" +msgid "Update kernel" msgstr "" msgid "Check and update DDNS-Go to the latest version" @@ -100,5 +100,23 @@ msgstr "" msgid "SUCCESS:" msgstr "" -msgid "Reset admin password successfully to admin12345" -msgstr "" \ No newline at end of file +msgid "Password reset successfully to admin12345" +msgstr "" + +msgid "Password Reset Successful" +msgstr "" + +msgid "User password has been reset to: admin12345" +msgstr "" + +msgid "You need to restart DDNS-Go service for the changes to take effect." +msgstr "" + +msgid "Restart Service Now" +msgstr "" + +msgid "Restart Later" +msgstr "" + +msgid "" +msgstr "" diff --git a/openwrt-packages/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json b/openwrt-packages/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json index 38e4cd59cf..875d3b830d 100644 --- a/openwrt-packages/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json +++ b/openwrt-packages/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json @@ -6,6 +6,7 @@ "file": { "/etc/init.d/ddns-go": [ "exec" ], "/usr/libexec/ddns-go-call": [ "exec" ], + "/usr/share/rpcd/ucode/luci.ddns-go": [ "exec" ], "/bin/pidof": [ "exec" ], "/bin/ps": [ "exec" ], "/bin/ash": [ "exec" ], @@ -28,4 +29,5 @@ "uci": ["ddns-go"] } } -} + +} \ No newline at end of file diff --git a/openwrt-packages/luci-app-ddns-go/root/usr/share/rpcd/ucode/luci.ddns-go b/openwrt-packages/luci-app-ddns-go/root/usr/share/rpcd/ucode/luci.ddns-go new file mode 100644 index 0000000000..8b9a86c60a --- /dev/null +++ b/openwrt-packages/luci-app-ddns-go/root/usr/share/rpcd/ucode/luci.ddns-go @@ -0,0 +1,135 @@ +#!/usr/bin/ucode +/* + * SPDX-License-Identifier: GPL-2.0-only + * + * Copyright (C) 2021-2025 sirpdboy https://github.com/sirpdboy/luci-app-ddns-go + */ + +'use strict'; + +import { access, error, lstat, popen, readfile, writefile } from 'fs'; + +/* Kanged from ucode/luci */ +function shellquote(s) { + return `'${replace(s, "'", "'\\''")}'`; +} +function get_current_version() { + if (!access('/usr/bin/ddns-go')) + return null; + + const fd = popen('/usr/bin/ddns-go -v'); + if (fd) { + let version_output = fd.read('all'); + fd.close(); + + if (!version_output || length(version_output) === 0) + return null; + + try { + // 去除开头的 'v' 字符 + version_output = replace(trim(version_output), /^v/, ''); + return version_output; + } catch(e) { + return null; + } + } + return null; +} + +const methods = { + get_ver: { + call: function() { + let current_version = get_current_version(); + if (!current_version) + return { ver: {}, error: 'ddns-go not found or version check failed' }; + + return { ver: { version: current_version } }; + } + }, + + last_update: { + call: function() { + if (!access('/usr/bin/ddns-go')) + return { update: {}, error: 'ddns-go not found' }; + let version_before = get_current_version(); + + const fd = popen('/usr/bin/ddns-go -u'); + if (fd) { + let output = fd.read('all'); + fd.close(); + + if (!output || length(output) === 0) + return { update: {}, error: 'empty response' }; + + try { + output = trim(output); + let update_info = { + raw_output: output, + version_before: version_before, + version_after: null, + has_update: false, + update_successful: false, + current_version: '', + latest_version: '', + status: 'unknown', + message: output + }; + + update_info.version_after = get_current_version(); + + if (version_before && update_info.version_after && version_before !== update_info.version_after) { + update_info.update_successful = true; + update_info.has_update = false; // 已经更新完成,所以没有待更新了 + update_info.status = 'updated'; + update_info.message = `更新成功: ${version_before} → ${update_info.version_after}`; + } + else if (match(output, /Current version.*is the latest/)) { + update_info.status = 'latest'; + update_info.has_update = false; + let version_match = match(output, /v[\d.]+/); + if (version_match) { + update_info.current_version = replace(version_match[0], /^v/, ''); + update_info.latest_version = update_info.current_version; + } + update_info.message = '已是最新版本 ' + (update_info.current_version || ''); + + } else if (match(output, /new version.*available/)) { + update_info.status = 'update_available'; + update_info.has_update = true; + + let versions = match(output, /v[\d.]+/, 'g'); + if (versions && length(versions) >= 2) { + update_info.current_version = replace(versions[0], /^v/, ''); + update_info.latest_version = replace(versions[1], /^v/, ''); + } else if (version_before) { + update_info.current_version = version_before; + } + update_info.message = '有新版本可用: ' + (update_info.latest_version || ''); + + } else if (match(output, /download.*failed/)) { + update_info.status = 'download_failed'; + update_info.has_update = false; + update_info.message = '下载更新失败'; + + } else if (match(output, /check.*failed/)) { + update_info.status = 'check_failed'; + update_info.has_update = false; + update_info.message = '检查更新失败'; + + } else { + update_info.status = 'unknown'; + update_info.message = output; + } + + return { update: update_info }; + } catch(e) { + return { update: {}, error: 'Parse error: ' + e }; + } + } else { + return { update: {}, error: 'failed to execute ddns-go command' }; + } + } + } +}; + +return { 'luci.ddns-go': methods }; \ No newline at end of file diff --git a/openwrt-packages/luci-theme-material3/Makefile b/openwrt-packages/luci-theme-material3/Makefile index b5dd2fd8bd..a0354c226d 100644 --- a/openwrt-packages/luci-theme-material3/Makefile +++ b/openwrt-packages/luci-theme-material3/Makefile @@ -7,9 +7,9 @@ include $(TOPDIR)/rules.mk LUCI_TITLE:=Material3 Theme -LUCI_DEPENDS:=+luci-base -PKG_VERSION:=alpha-0.0.5 -PKG_RELEASE:=20250102 +LUCI_DEPENDS:= +PKG_VERSION:=1.0 +PKG_RELEASE:=20250617 PKG_LICENSE:=Apache-2.0 @@ -20,12 +20,14 @@ define Package/luci-theme-material3/postrm uci -q delete luci.themes.Material3Blue uci -q delete luci.themes.Material3Green uci -q delete luci.themes.Material3Red + uci set luci.main.mediaurlbase='/luci-static/bootstrap' # uci -q delete luci.themes.Material3Dark # uci -q delete luci.themes.Material3Light uci commit luci } endef +LUCI_MINIFY_CSS:=0 include $(TOPDIR)/feeds/luci/luci.mk -# call BuildPackage - OpenWrt buildroot signature +# call BuildPackage - OpenWrt buildroot signature \ No newline at end of file diff --git a/openwrt-packages/luci-theme-material3/Readme.md b/openwrt-packages/luci-theme-material3/Readme.md index 5601d691b5..f96a44913a 100644 --- a/openwrt-packages/luci-theme-material3/Readme.md +++ b/openwrt-packages/luci-theme-material3/Readme.md @@ -27,7 +27,7 @@ This is a personal project based on the LuCI Bootstrap theme, imitating the Mate ## 📝 ToDo -- [ ] Dark themes +- [X] Dark themes - [ ] Fix some style issues - [ ] Add more color schemes - [ ] Improve to be closer to MD3 principles diff --git a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/cascade.css b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/cascade.css index 4ac1f25863..2f3aa6447f 100644 --- a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/cascade.css +++ b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/cascade.css @@ -1,1404 +1,1567 @@ -/*! - * LuCI Bootstrap Theme - * Copyright 2012 Nut & Bolt - * By David Menting - * Based on Bootstrap v1.4.0 - * - * Copyright 2011 Twitter, Inc - * Licensed under the Apache License v2.0 - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Designed and built with all the love in the world @twitter by @mdo and @fat. - * - * LuCI Material3 Theme - * Copyright 2024 AngelaCooljx - * By AngelaCooljx - * Based on LuCI Bootstrap Theme - * 还没改完 QAQ,细节太多了 - */ -:root, -pre { - --border-color-h: var(--background-color-h); - --border-color-s: var(--background-color-s) -} - -address, -dl dd, -dl dt, -li, -pre { - line-height: 18px -} - -.tab-content>.active, -address, -pre { - display: block -} - -.cbi-dropdown[open]>ul.dropdown>li>input.create-item-input:first-child:last-child, -.cbi-dynlist>.add-item>.cbi-dropdown, -.cbi-filebrowser .upload>div>input, -.cbi-section-create>*>input, -.cbi-value>.cbi-section, -.cbi-value>.cbi-tblsection, -.container, -.table[width="100%"], -.td>.cbi-dropdown:not(.btn):not(.cbi-button), -.td>input[type=password], -.td>input[type=text], -.td>select, -.td[width="100%"], -.th[width="100%"] { - width: 100% -} - -.table, -table { - border-collapse: collapse -} - -header .brand, -ul.unstyled { - margin-left: 0 -} - -.cbi-dropdown, -.cbi-dropdown[open], -.cbi-dynlist>.item, -.cbi-select, -.dropdown, -.dropdown-menu li, -.table, -li.menu, -sub, -sup { - position: relative -} - -a:hover, -footer a { - color: var(--primary-color-low) -} - -#tabmenu, -footer span { - margin-bottom: 1em -} - -.btn.disabled, -.btn[disabled], -button[disabled], -input[type=button][disabled], -input[type=reset][disabled], -input[type=submit][disabled] { - opacity: var(--disabled-opacity) -} - -.cbi-dropdown>ul>li img, -.cbi-page-actions>*, -.ifacebadge img, -.table .td, -.table .th, -.table.valign-middle .td, -.td.cbi-section-actions { - vertical-align: middle -} - -.breadcrumb li, -.cbi-dropdown>ul, -.nav, -ul.unstyled { - list-style: none -} - -.menu-btn.active span::before, -.nav>li>a::after { - transform: rotate(45deg) -} - -:root { - --background-color-delta-l-sign: -1; - --background-color-h: 0; - --background-color-s: 0%; - --background-color-l: 100%; - --background-color-high-hsl: var(--background-color-h), var(--background-color-s), var(--background-color-l); - --background-color-high: hsl(var(--background-color-high-hsl)); - --background-color-medium-hsl: var(--background-color-h), var(--background-color-s), calc(var(--background-color-l) + var(--background-color-delta-l-sign) * 2.35%); - --background-color-medium: hsl(var(--background-color-medium-hsl)); - --background-color-low-hsl: var(--background-color-h), var(--background-color-s), calc(var(--background-color-l) + var(--background-color-delta-l-sign) * 3.92%); - --background-color-low: hsl(var(--background-color-low-hsl)); - --text-color-delta-l-sign: 1; - --text-color-h: 0; - --text-color-s: 0%; - --text-color-l: 0%; - --text-color-highest-hsl: var(--text-color-h), var(--text-color-s), var(--text-color-l); - --text-color-highest: hsl(var(--text-color-highest-hsl)); - --text-color-high-hsl: var(--text-color-h), var(--text-color-s), calc(var(--text-color-l) + var(--text-color-delta-l-sign) * 25.1%); - --text-color-high: hsl(var(--text-color-high-hsl)); - --text-color-medium-hsl: var(--text-color-h), var(--text-color-s), calc(var(--text-color-l) + var(--text-color-delta-l-sign) * 50.2%); - --text-color-medium: hsl(var(--text-color-medium-hsl)); - --text-color-low-hsl: var(--text-color-h), var(--text-color-s), calc(var(--text-color-l) + var(--text-color-delta-l-sign) * 74.9%); - --text-color-low: hsl(var(--text-color-low-hsl)); - --border-color-delta-l-sign: -1; - --border-color-l: var(--background-color-l); - --border-color-high-hsl: var(--border-color-h), var(--border-color-s), calc(var(--border-color-l) + var(--border-color-delta-l-sign) * 20%); - --border-color-high: hsl(var(--border-color-high-hsl)); - --border-color-medium-hsl: var(--border-color-h), var(--border-color-s), calc(var(--border-color-l) + var(--border-color-delta-l-sign) * 13.33%); - --border-color-medium: hsl(var(--border-color-medium-hsl)); - --border-color-low-hsl: var(--border-color-h), var(--border-color-s), calc(var(--border-color-l) + var(--border-color-delta-l-sign) * 6.67%); - --border-color-low: hsl(var(--border-color-low-hsl)); - --primary-color-high: #1976d2; - --primary-color-medium: #1564c0; - --primary-color-low: #0d46a1; - --on-primary-color: var(--background-color-high); - --error-color-high-rgb: 246, 43, 18; - --error-color-high: rgb(var(--error-color-high-rgb)); - --error-color-medium: #e8210d; - --error-color-low: #d00000; - --on-error-color: var(--background-color-high); - --success-color-high-rgb: 0, 172, 89; - --success-color-high: rgb(var(--success-color-high-rgb)); - --success-color-medium: #009a4c; - --success-color-low: #007936; - --on-success-color: var(--background-color-high); - --warn-color-high: #efbd0b; - --warn-color-medium: #f0c629; - --warn-color-low: #f2d24f; - --on-warn-color: var(--text-color-highest); - --disabled-opacity: .7; - color-scheme: light; - --sidebar-width: 280px; - --header-height: 4rem; - - --md-sys-color-primary: hsl(256, 34%, 48%); - --md-sys-color-primary-container: hsl(263, 65%, 92%); - --md-sys-color-primary-container-hover: #d8cfe8; - - --md-sys-color-surface: #fef7ff; - --md-sys-color-surface-translucent: #fef7ffbb; - - --md-sys-color-card: #f7f2fa; - --md-sys-color-card-translucent: #f7f2fabb; - - --md-sys-color-progressbar: #e6e0e9; - - --md-sys-color-dropdown: #f3edf7; - --md-sys-color-dropdown-selected: #e3dde7; - --md-sys-color-dropdown-hover: #e2dce6; - - --md-sys-color-refresh-button: #beb6d1; - --md-sys-color-refresh-button-hover: #a9a0c2; - --md-sys-color-font: #000; - --md-sys-color-light: #fff; -} - -:root[data-theme="blue"] { - --md-sys-color-primary: #0061a4; - --md-sys-color-primary-container: #d7e3f8; - --md-sys-color-primary-container-hover: #c7d3e8; - - --md-sys-color-surface: #fdfcff; - --md-sys-color-surface-translucent: #fdfcffbb; - - --md-sys-color-card: #f4f3f7; - --md-sys-color-card-translucent: #f4f3f7bb; - - --md-sys-color-progressbar: #e2e2e6; - - --md-sys-color-dropdown: #eeedf1; - --md-sys-color-dropdown-selected: #dedde1; - --md-sys-color-dropdown-hover: #dddce0; - - --md-sys-color-refresh-button: #b6bec1; - --md-sys-color-refresh-button-hover: #a0a9c2; - --md-sys-color-font: #000; - --md-sys-color-light: #fff; -} - -:root[data-theme="green"] { - --md-sys-color-primary: #006c48; - --md-sys-color-primary-container: #d5e8cf; - --md-sys-color-primary-container-hover: #c5d8c0; - - --md-sys-color-surface: #fcfdf6; - --md-sys-color-surface-translucent: #fcfdf6bb; - - --md-sys-color-card: #f3f4ee; - --md-sys-color-card-translucent: #f3f4eebb; - - --md-sys-color-progressbar: #e2e3dd; - - --md-sys-color-dropdown: #eeeee8; - --md-sys-color-dropdown-selected: #deded8; - --md-sys-color-dropdown-hover: #ddddd8; - - --md-sys-color-refresh-button: #b6c1b9; - --md-sys-color-refresh-button-hover: #a0c2a9; - --md-sys-color-font: #000; - --md-sys-color-light: #fff; -} - -:root[data-theme="red"] { - --md-sys-color-primary: #bb1614; - --md-sys-color-primary-container: #ffdad5; - --md-sys-color-primary-container-hover: #efccc6; - - --md-sys-color-surface: #fffbff; - --md-sys-color-surface-translucent: #fffbffbb; - - --md-sys-color-card: #fef1ef; - --md-sys-color-card-translucent: #fef1efbb; - - --md-sys-color-progressbar: #ede0de; - - --md-sys-color-dropdown: #f8ebe9; - --md-sys-color-dropdown-selected: #e8dbd9; - --md-sys-color-dropdown-hover: #e8dbd9; - - --md-sys-color-refresh-button: #c1b6b6; - --md-sys-color-refresh-button-hover: #c2a0a0; - --md-sys-color-font: #000; - --md-sys-color-light: #fff; -} - -:root[data-darkmode=true] { - --background-color-delta-l-sign: 1; - --background-color-h: 0; - --background-color-s: 0%; - --background-color-l: 13.33%; - --text-color-delta-l-sign: -1; - --text-color-h: 0; - --text-color-s: 0%; - --text-color-l: 100%; - --border-color-delta-l-sign: 1; - --primary-color-high: #4da1c0; - --primary-color-medium: #448da6; - --primary-color-low: #3c7a8d; - --error-color-high-rgb: 209, 86, 83; - --error-color-medium: #bf4e4c; - --error-color-low: #b14946; - --success-color-high-rgb: 0, 166, 108; - --success-color-medium: #00945e; - --success-color-low: #008252; - --warn-color-high: #a69461; - --warn-color-medium: #a68d45; - --warn-color-low: #a68732; - --on-warn-color: var(--background-color-high); - --disabled-opacity: .4; - color-scheme: dark -} - -* { - scroll-margin-top: 40px -} - -*, -::after, -::before { - margin: 0; - padding: 0; - border: 0; - box-sizing: border-box -} - -abbr[title], -acronym[title] { - border-bottom: 1px dotted; - font-weight: inherit; - cursor: help -} - -table { - border-spacing: 0 -} - -html { - font-size: 100%; - -webkit-text-size-adjust: 100%; - -ms-text-size-adjust: 100%; - height: 100% -} - -a:active, -a:hover { - outline: 0 -} - -sub, -sup { - font-size: 75%; - line-height: 0; - vertical-align: baseline -} - -sup { - top: -.5em -} - -sub { - bottom: -.25em -} - -img { - -ms-interpolation-mode: bicubic -} - -button, -input, -option, -select, -textarea { - font-size: 100%; - margin: 0; - box-sizing: border-box; - vertical-align: baseline; - line-height: 2em -} - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0 -} - -button, -input[type=button], -input[type=reset], -input[type=submit] { - cursor: pointer; - -webkit-appearance: button; - word-break: break-all -} - -input[type=search] { - -webkit-appearance: textfield; - box-sizing: content-box -} - -input[type=search]::-webkit-search-decoration { - -webkit-appearance: none -} - -.control-group { - display: inline-flex; - gap: .2em -} - -.control-group>input+:not(input):not(select), -.control-group>select+:not(input):not(select) { - border-radius: 1rem; - padding: 0 10px; - line-height: 26px -} - -body { - display: grid; - grid-template-areas: "header header" "sidebar main" "footer footer"; - grid-template-columns: var(--sidebar-width) 1fr; - grid-template-rows: var(--header-height) 1fr; - min-height: 100vh; - margin: 0; - padding: 0; - background: var(--background-color-medium); - font-size: 13px; - font-weight: 400; - min-height: 100%; - flex-direction: column; - overflow-y: scroll; - -webkit-tap-highlight-color: transparent; -} - -.container { - margin-left: auto; - margin-right: auto; - zoom: 1 -} - -a { - color: var(--primary-color-high); - text-decoration: none; - line-height: inherit; - font-weight: inherit -} - -.actions .secondary-action a:hover, -.cbi-page-actions .secondary-action a:hover, -a:hover { - text-decoration: underline -} - -.actions .secondary-action, -.cbi-page-actions .secondary-action, -.pull-right { - float: right -} - -.pull-left { - float: left -} - -.nowrap { - white-space: nowrap -} - -.cbi-map-descr, -.cbi-section-descr, -.table .tr.cbi-section-table-descr .th, -p { - font-size: 13px; - font-weight: 400; - line-height: 18px; - margin-bottom: 9px -} - -h1, -h3, -h4, -h5, -h6, -legend { - line-height: 36px -} - -address, -dl, -h1 { - margin-bottom: 18px -} - -p small { - font-size: 11px; - color: var(--text-color-low) -} - -h1, -h2, -h3, -h4, -h5, -h6, -legend { - font-weight: 700; - color: var(--text-color-high) -} - -h1 small, -h2 small, -h3 small, -h4 small, -h5 small, -h6, -h6 small { - color: var(--text-color-low) -} - -h1 { - font-size: 30px -} - -h1 small { - font-size: 18px -} - -h2 { - font-size: 1.875em; - line-height: 1.875em -} - -h2 small, -h3 small, -h5 { - font-size: 14px -} - -h3, -legend { - font-size: 1.5em; - margin: .75em 0 -} - -h4 { - font-size: 16px -} - -h4 small { - font-size: 12px -} - -h6 { - font-size: 13px; - text-transform: uppercase -} - -ol, -ul { - margin: 0 0 18px 25px -} - -ol ol, -ol ul, -ul ol, -ul ul { - margin-bottom: 0 -} - -ul { - list-style: disc -} - -ol { - list-style: decimal -} - -li { - /* color: var(--text-color-medium); */ -} - -.cbi-button-down, -.cbi-button-download, -.cbi-button-find, -.cbi-button-link, -.cbi-button-neutral, -.cbi-button-up, -.cbi-dynlist>.item, -.cbi-select select option, -.cbi-value label.cbi-value-title, -.dropdown-menu>li.active>a, -.dropdown-menu>li>a:hover, -.ifacebadge, -.ifacebox .ifacebox-head, -.nav .dropdown-menu li a, -.nav>li>a, -.zonebadge, -code, -fieldset legend { - color: var(--text-color-high) -} - -dl dt { - font-weight: 700 -} - -dl dd { - margin-left: 9px -} - -hr { - margin: 20px 0 19px; - border: 0; - border-bottom: 1px solid var(--border-color-low) -} - -strong { - font-style: inherit; - font-weight: 700 -} - -em { - font-style: italic; - font-weight: inherit; - line-height: inherit -} - -small { - font-size: .9em -} - -code, -pre { - font-size: 12px; - padding: 0 3px 2px; - font-family: Monaco, Andale Mono, Courier New, monospace; - border-radius: 3px -} - -code { - background-color: var(--border-color-low); - padding: 1px 3px -} - -.cbi-section-table .tr:hover .td, -.cbi-section-table .tr:hover .th, -.cbi-section-table .tr:hover::before, -pre { - background-color: var(--background-color-low) -} - -pre { - --border-color-delta-l: 100%; - --border-color-l: calc(var(--background-color-l) + var(--background-color-delta-l-sign) * var(--border-color-delta-l)); - --border-color-a: 0.15; - --border-color: hsla(var(--border-color-hsl), var(--border-color-a)); - padding: 8.5px; - margin: 0 0 18px; - border: 1px solid var(--border-color); - border-radius: 3px; - white-space: pre; - white-space: pre-wrap; - word-wrap: break-word -} - -fieldset { - margin-bottom: 9px; - padding-top: 9px -} - -fieldset legend { - display: block; - font-size: 19.5px; - line-height: 1; - padding-top: 20px -} - -button, -input, -label, -select { - font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; - font-size: 13px; - font-weight: 400; - line-height: normal -} - -.cbi-value, -.network-status-table, -.uci-change-legend, -.zone-forwards { - display: flex; - flex-wrap: wrap -} - -.cbi-value-field { - margin-left: 20px; - flex: 1 -} - -.cbi-value label.cbi-value-title { - padding-top: 6px; - font-size: 13px; - line-height: 18px; - flex: 0 0 180px; - text-align: right -} - -label>input[type=checkbox], -label>input[type=radio] { - vertical-align: text-top; - margin: 0 -} - -.nav>li>a::after, -footer ul.breadcrumb { - margin-left: auto -} - -label[for], -th[data-sortable-row] { - cursor: pointer -} - -.cbi-dropdown:not(.btn):not(.cbi-button), -.cbi-select, -input, -select, -textarea { - display: inline-block; - width: 210px; - padding: 4px; - background: var(--background-color-high); - color: var(--text-color-high); - font-size: 13px; - line-height: 18px; - border: 1px solid var(--border-color-high); - border-radius: 1rem -} - -.cbi-dropdown:not(.btn):not(.cbi-button), -.cbi-page-actions .cbi-button-apply, -.cbi-select, -input, -select { - height: 30px -} - -.cbi-dropdown:not(.btn):not(.cbi-button), -.cbi-dynlist { - min-width: 210px; - max-width: 400px; - width: auto -} - -.cbi-dynlist { - height: auto; - min-height: 30px; - display: inline-flex; - flex-direction: column -} - -.cbi-dynlist>.item { - margin-bottom: 4px; - box-shadow: 0 0 2px var(--border-color-high); - background: var(--background-color-high); - border: 1px solid var(--border-color-high); - pointer-events: none; - overflow: hidden; - word-break: break-all -} - -.cbi-select, -.cbi-select::before { - background: linear-gradient(var(--background-color-high), var(--border-color-low)) -} - -.cbi-dynlist>.item::after { - content: "×"; - position: absolute; - display: inline-flex; - align-items: center; - top: -1px; - right: -1px; - bottom: -1px; - padding: 0 6px; - border: 1px solid var(--border-color-high); - border-radius: 0 3px 3px 0; - font-weight: 700; - color: #c44; - pointer-events: auto -} - -.cbi-dynlist>.add-item, -.nav, -.nav>li>a, -.td.cbi-section-actions>* { - display: flex -} - -.cbi-dynlist>.add-item>button, -.cbi-dynlist>.add-item>input { - flex: 1 1 auto; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap -} - -.cbi-value-field>.cbi-checkbox, -.cbi-value-field>div>.cbi-radio { - height: 30px; - display: inline-flex; - align-items: center -} - -.cbi-radio { - cursor: pointer; - gap: .125em -} - -.cbi-select { - padding: 0 -} - -.cbi-select select, -.cbi-select select:focus { - -webkit-appearance: none; - appearance: none; - outline: 0; - border: none; - background: 0 0; - height: 100%; - width: 100%; - padding: 0 .3em; - cursor: pointer; - margin-right: .6em -} - -.cbi-select::before { - position: absolute; - top: 0; - right: 0; - bottom: 0; - content: "▾"; - padding: 0 .3em; - pointer-events: none; - border-radius: 3px; - display: flex; - flex-direction: column; - justify-content: center -} - -.cbi-select select option { - background: var(--background-color-low) -} - -.cbi-select select option:hover { - background: var(--primary-color-low); - color: var(--on-primary-color) -} - -.cbi-select select option:checked { - background: var(--primary-color-medium); - color: var(--on-primary-color) -} - -input[type=file] { - padding: initial; - border: initial; - line-height: initial; - box-shadow: none; - width: auto !important -} - -input[type=button], -input[type=reset], -input[type=submit] { - width: auto; - height: auto -} - -select[multiple] { - height: inherit; - background-color: #fff -} - -input[type=checkbox], -input[type=radio] { - --bd-color: var(--border-color-high); - --fg-color: var(--text-color-high); - appearance: none; - -webkit-appearance: none; - width: 14px; - height: 14px; - color: var(--fg-color); - position: relative; - display: inline-block; - cursor: pointer; - background: 0 0; - border: none -} - -input[type=checkbox]::after, -input[type=checkbox]::before, -input[type=radio]::after, -input[type=radio]::before { - position: absolute; - content: "" -} - -input[type=checkbox]::before, -input[type=radio]::before { - top: 0; - left: 0; - width: 14px; - height: 14px; - background: linear-gradient(var(--background-color-high), var(--background-color-low)); - border: 1px solid var(--bd-color); - border-radius: 2px -} - -input[type=radio], -input[type=radio]::before { - border-radius: 50% -} - -input[type=checkbox]::after, -input[type=radio]::after { - top: 2px; - left: 2px; - width: 10px; - height: 10px -} - -input[type=checkbox]:checked::after, -input[type=radio]:checked::after { - --checkmark-icon: url("data:image/svg+xml,"); - -webkit-mask: var(--checkmark-icon) center/cover no-repeat; - mask: var(--checkmark-icon) center/cover no-repeat; - background: var(--fg-color) -} - -input[type=radio]:checked:after { - --checkmark-icon: url("data:image/svg+xml,") -} - -input[type=checkbox].cbi-input-invalid, -input[type=radio].cbi-input-invalid { - --bd-color: var(--error-color-medium); - --fg-color: var(--error-color-high) -} - -::placeholder { - color: var(--text-color-medium) -} - -.btn, -.cbi-button, -.cbi-dropdown, -.cbi-dynlist>.item, -.cbi-select, -.item::after, -button, -input, -input[type=checkbox]::before, -input[type=radio]::before, -select, -textarea { - transition: border .2s linear, box-shadow .2s linear; - box-shadow: inset 0 1px 3px hsla(var(--border-color-low-hsl), .01) -} - -.btn:focus, -.btn:hover, -.cbi-button:focus, -.cbi-button:hover, -.cbi-dropdown:focus, -.cbi-dropdown[open], -.cbi-dynlist>.item:focus, -.cbi-select.focus, -.item:hover::after, -button:hover, -input:focus, -input[type=checkbox]:focus::before, -input[type=radio]:focus::before, -select:focus, -textarea:focus { - --focus-color-rgb: 82, 168, 236; - outline: 0; - border-color: rgba(var(--focus-color-rgb), .8) !important; - box-shadow: inset 0 1px 3px hsla(var(--border-color-low-hsl), .01), 0 0 8px rgba(var(--focus-color-rgb), .6); - text-decoration: none -} - -.cbi-input-invalid:focus, -.cbi-select.cbi-input-invalid, -input[type=checkbox].cbi-input-invalid:focus::before, -input[type=radio].cbi-input-invalid:focus::before { - --focus-color-rgb: var(--error-color-high-rgb) -} - -.cbi-dropdown[disabled]:not(.btn):not(.cbi-button), -.cbi-select[disabled]::before, -button[disabled], -input[disabled], -input[type=checkbox][disabled]::after, -input[type=checkbox][disabled]::before, -input[type=radio][disabled]::after, -input[type=radio][disabled]::before, -select[disabled], -textarea[disabled] { - opacity: var(--disabled-opacity); - pointer-events: none; - cursor: default -} - -input[readonly], -select[readonly], -textarea[readonly] { - border-color: hsla(var(--border-color-high-hsl), var(--disabled-opacity)); - pointer-events: auto; - cursor: auto -} - -.cbi-optionals, -.cbi-section-create { - padding: 5px 0 -} - -.cbi-section-create { - margin: -3px; - display: inline-flex; - align-items: center -} - -.cbi-section-create>* { - margin: 3px; - flex: 1 1 auto -} - -.actions, -.cbi-page-actions { - margin-bottom: 18px; - border-top: 1px solid var(--border-color-medium); - border-radius: 0 0 3px 3px; - text-align: right -} - -.actions .secondary-action a, -.cbi-page-actions .secondary-action a { - line-height: 30px -} - -.cbi-page-actions>form { - display: inline; - margin: 0 -} - -.tr { - display: table-row -} - -.table[width="33%"], -.td[width="33%"], -.th[width="33%"] { - width: 33% -} - -.table { - display: table; - width: 100%; - padding: 0; - font-size: 13px -} - -.table .td, -.table .th { - display: table-cell; - padding: 10px 10px 9px; - line-height: 18px; - text-align: left; - border-top: 1px solid var(--border-color-medium) -} - -.table .tr:first-child .th { - padding-top: 9px; - font-weight: 700; - vertical-align: top -} - -.cbi-section-table .tr.cbi-section-table-descr .th, -header .brand { - font-weight: 400 -} - -.tr.placeholder { - height: calc(3em + 20px) -} - -.tr.placeholder>.td { - position: absolute; - left: 0; - right: 0; - bottom: 0; - text-align: center; - line-height: 3em -} - -.tr.drag-over-above, -.tr.drag-over-below { - border: 2px solid #0069d6; - border-width: 2px 0 0 -} - -.tr.drag-over-below { - border-width: 0 0 2px -} - -header { - grid-area: header; - position: sticky; - top: 0; - z-index: 800; - height: var(--header-height); - background: var(--md-sys-color-surface-translucent); - backdrop-filter: blur(15px); - display: flex; - align-items: center; - justify-content: space-between; - transition: box-shadow .3s; - background: linear-gradient(#333, #222); - box-shadow: 0 1px 3px hsla(var(--border-color-low-hsl), .25), inset 0 -1px 0 hsla(var(--border-color-low-hsl), .01); - padding: 0 -} - -header a { - color: #bfbfbf; - text-shadow: 0 -1px 0 hsla(var(--border-color-low-hsl), .25) -} - -header .brand:hover, -header ul .active>a { - background-color: rgba(255, 255, 255, .05); - color: var(--md-sys-color-primary); - text-decoration: none -} - -header .brand { - flex: 0 1 auto; - text-align: center; - float: left; - display: block; - color: #404040 -} - -header .pull-right { - /* flex: 0 0 auto; */ - margin: 0 12px; -} - -header p { - margin: 0; - line-height: 40px -} - -.nav, -.zone-forwards .zone-dest, -.zone-forwards .zone-src { - display: flex; - flex-direction: column -} - -.dropdown-menu { - background-color: #fff; - float: left; - position: absolute; - top: 40px; - left: -9999px; - z-index: 900; - min-width: 160px; - max-width: 220px; - zoom: 1; - border-width: 0 1px 1px; - box-shadow: 0 2px 4px rgba(0, 0, 0, .2); - background-clip: padding-box; - transition: height .3s ease-in-out; - overflow: hidden -} - -.dropdown-menu li { - float: none; - display: block; - overflow: hidden; - /* margin: 4px 0; */ -} - -.dropdown-menu a { - display: block; - padding: 4px 15px; - clear: both; - font-weight: 400; - line-height: 18px; - color: grey; - text-shadow: 0 0 0 #fff -} - -.dropdown-menu a:hover { - background-color: #ddd; - background-repeat: repeat-x; - background-image: linear-gradient(to bottom, #eee, #ddd); - color: #404040; - text-decoration: none; - box-shadow: inset 0 1px 0 rgba(0, 0, 0, .025), inset 0 -1px rgba(0, 0, 0, .025) -} - -.dropdown:hover ul.dropdown-menu { - left: 0 -} - -.dropdown-menu .dropdown-menu { - position: absolute; - left: 159px -} - -#tabmenu { + /*! + * LuCI Bootstrap Theme + * Copyright 2012 Nut & Bolt + * By David Menting + * Based on Bootstrap v1.4.0 + * + * Copyright 2011 Twitter, Inc + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Designed and built with all the love in the world @twitter by @mdo and @fat. + * + * LuCI Material3 Theme + * Copyright 2024 AngelaCooljx + * By AngelaCooljx + * Based on LuCI Bootstrap Theme + * 还没改完 QAQ,细节太多了 + */ + :root, + pre { + --border-color-h: var(--background-color-h); + --border-color-s: var(--background-color-s) + } + + address, + dl dd, + dl dt, + li, + pre { + line-height: 18px + } + + .tab-content>.active, + address, + pre { + display: block + } + + .cbi-dropdown[open]>ul.dropdown>li>input.create-item-input:first-child:last-child, + .cbi-dynlist>.add-item>.cbi-dropdown, + .cbi-filebrowser .upload>div>input, + .cbi-section-create>*>input, + .cbi-value>.cbi-section, + .cbi-value>.cbi-tblsection, + .container, + .table[width="100%"], + .td>.cbi-dropdown:not(.btn):not(.cbi-button), + .td>input[type=password], + .td>input[type=text], + .td>select, + .td[width="100%"], + .th[width="100%"] { + width: 100% + } + + .table, + table { + border-collapse: collapse + } + + header .brand, + ul.unstyled { + margin-left: 0 + } + + .cbi-dropdown, + .cbi-dropdown[open], + .cbi-dynlist>.item, + .cbi-select, + .dropdown, + .dropdown-menu li, + .table, + li.menu, + sub, + sup { + position: relative + } + + a:hover, + footer a { + color: var(--primary-color-low) + } + + #tabmenu, + footer span { + margin-bottom: 1em + } + + .btn.disabled, + .btn[disabled], + button[disabled], + input[type=button][disabled], + input[type=reset][disabled], + input[type=submit][disabled] { + opacity: var(--disabled-opacity) + } + + .cbi-dropdown>ul>li img, + .cbi-page-actions>*, + .ifacebadge img, + .table .td, + .table .th, + .table.valign-middle .td, + .td.cbi-section-actions { + vertical-align: middle + } + + .breadcrumb li, + .cbi-dropdown>ul, + .nav, + ul.unstyled { + list-style: none + } + + .menu-btn.active span::before, + .nav>li>a::after { + transform: rotate(45deg) + } + + :root { + /* 新增暗黑模式专用变量 */ + --md-sys-color-on-primary: var(--background-color-high); + --md-sys-color-on-surface: var(--text-color-highest); + --md-sys-color-surface-dim: hsl(var(--background-color-h), var(--background-color-s), calc(var(--background-color-l) - 5%)); + --md-sys-color-surface-bright: hsl(var(--background-color-h), var(--background-color-s), calc(var(--background-color-l) + 5%)); + /* 状态层透明度 (Material3标准) */ + --state-layer-hover-opacity: 0.08; + --state-layer-focus-opacity: 0.12; + --state-layer-pressed-opacity: 0.12; + --transition-color: 0.2s cubic-bezier(0.4, 0, 0.2, 1); + --transition-elevation: 0.3s cubic-bezier(0.4, 0, 0.2, 1); + --background-color-delta-l-sign: -1; + --background-color-h: 0; + --background-color-s: 0%; + --background-color-l: 100%; + --background-color-high-hsl: var(--background-color-h), var(--background-color-s), var(--background-color-l); + --background-color-high: hsl(var(--background-color-high-hsl)); + --background-color-medium-hsl: var(--background-color-h), var(--background-color-s), calc(var(--background-color-l) + var(--background-color-delta-l-sign) * 2.35%); + --background-color-medium: hsl(var(--background-color-medium-hsl)); + --background-color-low-hsl: var(--background-color-h), var(--background-color-s), calc(var(--background-color-l) + var(--background-color-delta-l-sign) * 3.92%); + --background-color-low: hsl(var(--background-color-low-hsl)); + --text-color-delta-l-sign: 1; + --text-color-h: 0; + --text-color-s: 0%; + --text-color-l: 0%; + --text-color-highest-hsl: var(--text-color-h), var(--text-color-s), var(--text-color-l); + --text-color-highest: hsl(var(--text-color-highest-hsl)); + --text-color-high-hsl: var(--text-color-h), var(--text-color-s), calc(var(--text-color-l) + var(--text-color-delta-l-sign) * 25.1%); + --text-color-high: hsl(var(--text-color-high-hsl)); + --text-color-medium-hsl: var(--text-color-h), var(--text-color-s), calc(var(--text-color-l) + var(--text-color-delta-l-sign) * 50.2%); + --text-color-medium: hsl(var(--text-color-medium-hsl)); + --text-color-low-hsl: var(--text-color-h), var(--text-color-s), calc(var(--text-color-l) + var(--text-color-delta-l-sign) * 74.9%); + --text-color-low: hsl(var(--text-color-low-hsl)); + --border-color-delta-l-sign: -1; + --border-color-l: var(--background-color-l); + --border-color-high-hsl: var(--border-color-h), var(--border-color-s), calc(var(--border-color-l) + var(--border-color-delta-l-sign) * 20%); + --border-color-high: hsl(var(--border-color-high-hsl)); + --border-color-medium-hsl: var(--border-color-h), var(--border-color-s), calc(var(--border-color-l) + var(--border-color-delta-l-sign) * 13.33%); + --border-color-medium: hsl(var(--border-color-medium-hsl)); + --border-color-low-hsl: var(--border-color-h), var(--border-color-s), calc(var(--border-color-l) + var(--border-color-delta-l-sign) * 6.67%); + --border-color-low: hsl(var(--border-color-low-hsl)); + --primary-color-high: #1976d2; + --primary-color-medium: #1564c0; + --primary-color-low: #0d46a1; + --on-primary-color: var(--background-color-high); + --error-color-high-rgb: 246, 43, 18; + --error-color-high: rgb(var(--error-color-high-rgb)); + --error-color-medium: #e8210d; + --error-color-low: #d00000; + --on-error-color: var(--background-color-high); + --success-color-high-rgb: 0, 172, 89; + --success-color-high: rgb(var(--success-color-high-rgb)); + --success-color-medium: #009a4c; + --success-color-low: #007936; + --on-success-color: var(--background-color-high); + --warn-color-high: #efbd0b; + --warn-color-medium: #f0c629; + --warn-color-low: #f2d24f; + --on-warn-color: var(--text-color-highest); + --disabled-opacity: .7; + color-scheme: light; + --sidebar-width: 280px; + --header-height: 4rem; + --md-sys-color-primary: hsl(256, 34%, 48%); + --md-sys-color-primary-container: hsl(263, 65%, 92%); + --md-sys-color-primary-container-hover: #d8cfe8; + --md-sys-color-surface: #fef7ff; + --md-sys-color-surface-translucent: #fef7ffbb; + --md-sys-color-card: #f7f2fa; + --md-sys-color-card-translucent: #f7f2fabb; + --md-sys-color-progressbar: #e6e0e9; + --md-sys-color-dropdown: #f3edf7; + --md-sys-color-dropdown-selected: #e3dde7; + --md-sys-color-dropdown-hover: #e2dce6; + --md-sys-color-refresh-button: #beb6d1; + --md-sys-color-refresh-button-hover: #a9a0c2; + --md-sys-color-font: #000; + --md-sys-color-light: #fff; + } + + :root[data-theme="blue"] { + --md-sys-color-primary: #0061a4; + --md-sys-color-primary-container: #d7e3f8; + --md-sys-color-primary-container-hover: #c7d3e8; + --md-sys-color-surface: #fdfcff; + --md-sys-color-surface-translucent: #fdfcffbb; + --md-sys-color-card: #f4f3f7; + --md-sys-color-card-translucent: #f4f3f7bb; + --md-sys-color-progressbar: #e2e2e6; + --md-sys-color-dropdown: #eeedf1; + --md-sys-color-dropdown-selected: #dedde1; + --md-sys-color-dropdown-hover: #dddce0; + --md-sys-color-refresh-button: #b6bec1; + --md-sys-color-refresh-button-hover: #a0a9c2; + --md-sys-color-font: #000; + --md-sys-color-light: #fff; + } + + :root[data-theme="green"] { + --md-sys-color-primary: #006c48; + --md-sys-color-primary-container: #d5e8cf; + --md-sys-color-primary-container-hover: #c5d8c0; + --md-sys-color-surface: #fcfdf6; + --md-sys-color-surface-translucent: #fcfdf6bb; + --md-sys-color-card: #f3f4ee; + --md-sys-color-card-translucent: #f3f4eebb; + --md-sys-color-progressbar: #e2e3dd; + --md-sys-color-dropdown: #eeeee8; + --md-sys-color-dropdown-selected: #deded8; + --md-sys-color-dropdown-hover: #ddddd8; + --md-sys-color-refresh-button: #b6c1b9; + --md-sys-color-refresh-button-hover: #a0c2a9; + --md-sys-color-font: #000; + --md-sys-color-light: #fff; + } + + :root[data-theme="red"] { + --md-sys-color-primary: #bb1614; + --md-sys-color-primary-container: #ffdad5; + --md-sys-color-primary-container-hover: #efccc6; + --md-sys-color-surface: #fffbff; + --md-sys-color-surface-translucent: #fffbffbb; + --md-sys-color-card: #fef1ef; + --md-sys-color-card-translucent: #fef1efbb; + --md-sys-color-progressbar: #ede0de; + --md-sys-color-dropdown: #f8ebe9; + --md-sys-color-dropdown-selected: #e8dbd9; + --md-sys-color-dropdown-hover: #e8dbd9; + --md-sys-color-refresh-button: #c1b6b6; + --md-sys-color-refresh-button-hover: #c2a0a0; + --md-sys-color-font: #000; + --md-sys-color-light: #fff; + } + + /* ========== 暗色主题颜色继承 ========== */ + [data-darkmode=true] { + --md-sys-color-primary: hsl(256, 34%, 48%); + --md-sys-color-primary-container: hsl(265, 80%, 70%); + --primary-color-high: var(--md-sys-color-primary); + --md-sys-color-refresh-button: color-mix(in srgb, var(--md-sys-color-primary-container) 80%, transparent); + --md-sys-color-refresh-button-hover: color-mix(in srgb, var(--md-sys-color-primary) 50%, transparent); + --md-sys-color-dropdown-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 20%, transparent); + --md-sys-color-primary-container-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 50%, transparent); + } + + [data-darkmode=true][data-theme="blue"] { + --md-sys-color-primary: #a8c8ff; + --primary-color-high: #5d9bc7; + --md-sys-color-primary-container: #1d4a7a; + --md-sys-color-refresh-button: color-mix(in srgb, var(--md-sys-color-primary-container) 80%, transparent); + --md-sys-color-refresh-button-hover: color-mix(in srgb, var(--md-sys-color-primary) 50%, transparent); + --md-sys-color-dropdown-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 20%, transparent); + --md-sys-color-primary-container-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 50%, transparent); + } + + [data-darkmode=true][data-theme="green"] { + --md-sys-color-primary: #8fdcb4; + --primary-color-high: #5cb48a; + --md-sys-color-primary-container: #005538; + --md-sys-color-refresh-button: color-mix(in srgb, var(--md-sys-color-primary-container) 80%, transparent); + --md-sys-color-refresh-button-hover: color-mix(in srgb, var(--md-sys-color-primary) 50%, transparent); + --md-sys-color-dropdown-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 20%, transparent); + --md-sys-color-primary-container-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 50%, transparent); + } + + [data-darkmode=true][data-theme="red"] { + --md-sys-color-primary: #ffb4ab; + --primary-color-high: #d68b83; + --md-sys-color-primary-container: #93000a; + --md-sys-color-refresh-button: color-mix(in srgb, var(--md-sys-color-primary-container) 80%, transparent); + --md-sys-color-refresh-button-hover: color-mix(in srgb, var(--md-sys-color-primary) 50%, transparent); + --md-sys-color-dropdown-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 20%, transparent); + --md-sys-color-primary-container-hover: color-mix(in srgb, var(--md-sys-color-primary-container) 50%, transparent); + } + + :root[data-darkmode=true] { + /* 修正基础色相 */ + --background-color-h: 240; + --background-color-s: 5%; + /* Material3暗色表面系统 */ + --md-sys-color-surface: hsl(var(--background-color-h), var(--background-color-s), 12%); + --md-sys-color-surface-translucent: hsla(var(--background-color-h), var(--background-color-s), 12%, 0.84); + --md-sys-color-card: color-mix(in srgb, var(--md-sys-color-primary) 20%, transparent); + /* 组件颜色适配 */ + --md-sys-color-dropdown: hsl(var(--background-color-h), var(--background-color-s), 20%); + --md-sys-color-dropdown-selected: hsl(var(--background-color-h), var(--background-color-s), 24%); + --md-sys-color-progressbar: hsl(var(--background-color-h), var(--background-color-s), 18%); + /* 文字对比度增强 */ + --text-color-medium-hsl: var(--text-color-h), var(--text-color-s), 85%; + --text-color-low-hsl: var(--text-color-h), var(--text-color-s), 65%; + /* 强制文字颜色为Material3的on-surface色系 */ + --text-color-highest: hsl(0, 0%, 100%); + /* 纯白 - 主要文字 */ + --text-color-high: hsl(0, 0%, 90%); + /* 高强调文字 */ + --text-color-medium: hsl(0, 0%, 80%); + /* 中等强调文字 */ + --text-color-low: hsl(0, 0%, 60%); + /* 禁用/辅助文字 */ + /* 确保所有文本元素继承新变量 */ + color: var(--text-color-high); + } + + /* ========== 全局组件 ========== */ + [data-darkmode=true] { + /* 基础文本元素 */ + body, p, td, th, li, div, strong{ + color: var(--text-color-high); + -webkit-font-smoothing: antialiased; + text-rendering: optimizeLegibility; + } + /* 头部品牌颜色 */ + header .brand { + color: #ffffff; + } + /* 按钮颜色 */ + .btn.primary, .cbi-button-action.important, .cbi-page-actions .cbi-button-apply, .cbi-section-actions .cbi-button-edit { + background: var(--md-sys-color-primary-container); + color: #fff; + border: 1px solid var(--md-sys-color-primary); + } + /* 保存按钮颜色 */ + .cbi-page-actions .cbi-button-apply+.cbi-button-save { + background: var(--md-sys-color-primary); + color: #ffffff; + border: 1px solid var(--md-sys-color-primary-container); + } + /* 操作按钮颜色 */ + .td.cbi-section-actions>*>:last-child { + border-radius: 1rem; + background: var(--md-sys-color-primary-container); + color: var(--text-color-highest); + } + /* 下拉框颜色 */ + .cbi-dropdown:not(.btn):not(.cbi-button) { + background: var(--md-sys-color-primary); + color: var(--text-color-highest); + } + + .cbi-value-field em { + color: var(--text-color-highest); + } + /* 链接颜色 */ + .nav .dropdown-menu .active a { + color: #fff; + } + + .nav>li>a { + color: white; + } + + a:hover { + color: color-mix(in srgb, var(--primary-color-high) 85%, white); + } + /* 标题类 */ + h1, h2, h3, h4, h5, h6, + .cbi-section-title, .alert-message h4 { + color: var(--text-color-highest); + } + + /* 输入框文字 */ + .cbi-input-text, + .cbi-input-select, + .cbi-input-password, + textarea { + color: var(--text-color-high); + background: #00000000; + --placeholder-color: var(--text-color-low); + } + + /* 表格特殊处理 */ + .table td, .table th { + color: var(--text-color-high); + } + + /* 输入框 */ + .cbi-input-text, .cbi-input-select { + background-color: var(--md-sys-color-dropdown); + --placeholder-color: var(--text-color-low); + } + + .cbi-tabmenu>li, .tabs>li { + color: #fff; + } + /* 表格 */ + .table { + --row-stripe-bg: hsla(var(--background-color-h), 30%, 18%, 0.5); + --row-hover-bg: hsla(var(--primary-color-h), 50%, 30%, 0.2); + } + + /* 卡片 */ + .cbi-section, .cbi-map { + background-color: #00000000; + --text-color-high: hsl(0, 0%, 95%); + } + + .cbi-section-node { + padding: 4px 8px + } + + .cbi-section-node, + .create-item-input, + .ifacebox, + .table, + table { + background: var(--md-sys-color-card); + border-radius: 16px; + box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%); + margin: 1px; + width: calc(100% - 2px); + } + + /* 禁用状态文字 */ + .cbi-button-disabled, + input:disabled { + opacity: 0.5; + color: var(--text-color-medium) !important; + } + + /* 按钮状态层 */ + .btn:hover { + background-color: color-mix( + in srgb, + var(--primary-color-high) + calc(100% - (var(--state-layer-hover-opacity) * 100)),var(--md-sys-color-on-primary)); + } + } + + .btn { + transition: background-color var(--transition-color), + box-shadow var(--transition-elevation); + } + + * { + scroll-margin-top: 40px + } + + *, + ::after, + ::before { + margin: 0; + padding: 0; + border: 0; + box-sizing: border-box + } + + abbr[title], + acronym[title] { + border-bottom: 1px dotted; + font-weight: inherit; + cursor: help + } + + table { + border-spacing: 0 + } + + html { + font-size: 100%; + -webkit-text-size-adjust: 100%; + -ms-text-size-adjust: 100%; + height: 100% + } + + a:active, + a:hover { + outline: 0 + } + + sub, + sup { + font-size: 75%; + line-height: 0; + vertical-align: baseline + } + + sup { + top: -.5em + } + + sub { + bottom: -.25em + } + + img { + -ms-interpolation-mode: bicubic + } + + button, + input, + option, + select, + textarea { + font-size: 100%; + margin: 0; + box-sizing: border-box; + vertical-align: baseline; + line-height: 2em + } + + button::-moz-focus-inner, + input::-moz-focus-inner { + border: 0; + padding: 0 + } + + button, + input[type=button], + input[type=reset], + input[type=submit] { + cursor: pointer; + -webkit-appearance: button; + word-break: break-all + } + + input[type=search] { + -webkit-appearance: textfield; + box-sizing: content-box + } + + input[type=search]::-webkit-search-decoration { + -webkit-appearance: none + } + + .control-group { + display: inline-flex; + gap: .2em + } + + .control-group>input+:not(input):not(select), + .control-group>select+:not(input):not(select) { + border-radius: 1rem; + padding: 0 10px; + line-height: 26px + } + + body { + display: grid; + grid-template-areas: "header header" "sidebar main" "footer footer"; + grid-template-columns: var(--sidebar-width) 1fr; + grid-template-rows: var(--header-height) 1fr; + min-height: 100vh; + margin: 0; + padding: 0; + background: var(--background-color-medium); + font-size: 13px; + font-weight: 400; + min-height: 100%; + flex-direction: column; + overflow-y: scroll; + -webkit-tap-highlight-color: transparent; + } + + .container { + margin-left: auto; + margin-right: auto; + zoom: 1 + } + + a { + color: var(--primary-color-high); + text-decoration: none; + line-height: inherit; + font-weight: inherit + } + + .actions .secondary-action a:hover, + .cbi-page-actions .secondary-action a:hover, + a:hover { + text-decoration: underline + } + + .actions .secondary-action, + .cbi-page-actions .secondary-action, + .pull-right { + float: right + } + + .pull-left { + float: left + } + + .nowrap { + white-space: nowrap + } + + .cbi-map-descr, + .cbi-section-descr, + .table .tr.cbi-section-table-descr .th, + p { + font-size: 13px; + font-weight: 400; + line-height: 18px; + margin-bottom: 9px + } + + h1, + h3, + h4, + h5, + h6, + legend { + line-height: 36px + } + + address, + dl, + h1 { + margin-bottom: 18px + } + + p small { + font-size: 11px; + color: var(--text-color-low) + } + + h1, + h2, + h3, + h4, + h5, + h6, + legend { + font-weight: 700; + color: var(--text-color-high) + } + + h1 small, + h2 small, + h3 small, + h4 small, + h5 small, + h6, + h6 small { + color: var(--text-color-low) + } + + h1 { + font-size: 30px + } + + h1 small { + font-size: 18px + } + + h2 { + font-size: 1.875em; + line-height: 1.875em + } + + h2 small, + h3 small, + h5 { + font-size: 14px + } + + h3, + legend { + font-size: 1.5em; + margin: .75em 0 + } + + h4 { + font-size: 16px + } + + h4 small { + font-size: 12px + } + + h6 { + font-size: 13px; + text-transform: uppercase + } + + ol, + ul { + margin: 0 0 18px 25px + } + + ol ol, + ol ul, + ul ol, + ul ul { + margin-bottom: 0 + } + + ul { + list-style: disc + } + + ol { + list-style: decimal + } + + li { + /* color: var(--text-color-medium); */ + } + + .cbi-button-down, + .cbi-button-download, + .cbi-button-find, + .cbi-button-link, + .cbi-button-neutral, + .cbi-button-up, + .cbi-dynlist>.item, + .cbi-select select option, + .cbi-value label.cbi-value-title, + .dropdown-menu>li.active>a, + .dropdown-menu>li>a:hover, + .ifacebadge, + .ifacebox .ifacebox-head, + .nav .dropdown-menu li a, + .nav>li>a, + .zonebadge, + code, + fieldset legend { + color: var(--text-color-high); + } + + dl dt { + font-weight: 700 + } + + dl dd { + margin-left: 9px + } + + hr { + margin: 20px 0 19px; + border: 0; + border-bottom: 1px solid var(--border-color-low) + } + + strong { + font-style: inherit; + font-weight: 700 + } + + em { + font-style: italic; + font-weight: inherit; + line-height: inherit + } + + small { + font-size: .9em + } + + code, + pre { + font-size: 12px; + padding: 0 3px 2px; + font-family: Monaco, Andale Mono, Courier New, monospace; + border-radius: 3px + } + + code { + color: black; + background-color: var(--border-color-low); + padding: 1px 3px + } + + .cbi-section-table .tr:hover .td, + .cbi-section-table .tr:hover .th, + .cbi-section-table .tr:hover::before, + pre { + background-color: var(--background-color-low) + } + + pre { + --border-color-delta-l: 100%; + --border-color-l: calc(var(--background-color-l) + var(--background-color-delta-l-sign) * var(--border-color-delta-l)); + --border-color-a: 0.15; + --border-color: hsla(var(--border-color-hsl), var(--border-color-a)); + padding: 8.5px; + margin: 0 0 18px; + border: 1px solid var(--border-color); + border-radius: 3px; + white-space: pre; + white-space: pre-wrap; + word-wrap: break-word + } + + fieldset { + margin-bottom: 9px; + padding-top: 9px + } + + fieldset legend { + display: block; + font-size: 19.5px; + line-height: 1; + padding-top: 20px + } + + button, + input, + label, + select { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 13px; + font-weight: 400; + line-height: normal + } + + .cbi-value, + .network-status-table, + .uci-change-legend, + .zone-forwards { + display: flex; + flex-wrap: wrap + } + + .cbi-value-field { + margin-left: 20px; + flex: 1 + } + + .cbi-value label.cbi-value-title { + padding-top: 6px; + font-size: 13px; + line-height: 18px; + flex: 0 0 180px; + text-align: right + } + + label>input[type=checkbox], + label>input[type=radio] { + vertical-align: text-top; + margin: 0 + } + + .nav>li>a::after, + footer ul.breadcrumb { + margin-left: auto + } + + label[for], + th[data-sortable-row] { + cursor: pointer + } + + .cbi-dropdown:not(.btn):not(.cbi-button), + .cbi-select, + input, + select, + textarea { + display: inline-block; + width: 210px; + padding: 4px; + background: var(--background-color-high); + color: var(--text-color-high); + font-size: 13px; + line-height: 18px; + border: 1px solid var(--border-color-high); + border-radius: 1rem + } + + .cbi-dropdown:not(.btn):not(.cbi-button), + .cbi-page-actions .cbi-button-apply, + .cbi-select, + input, + select { + height: 30px + } + + .cbi-dropdown:not(.btn):not(.cbi-button), + .cbi-dynlist { + min-width: 210px; + max-width: 400px; + width: auto + } + + .cbi-dynlist { + height: auto; + min-height: 30px; + display: inline-flex; + flex-direction: column + } + + .cbi-dynlist>.item { + margin-bottom: 4px; + box-shadow: 0 0 2px var(--border-color-high); + background: var(--background-color-high); + border: 1px solid var(--border-color-high); + pointer-events: none; + overflow: hidden; + word-break: break-all + } + + .cbi-select, + .cbi-select::before { + background: linear-gradient(var(--background-color-high), var(--border-color-low)) + } + + .cbi-dynlist>.item::after { + content: "×"; + position: absolute; + display: inline-flex; + align-items: center; + top: -1px; + right: -1px; + bottom: -1px; + padding: 0 6px; + border: 1px solid var(--border-color-high); + border-radius: 0 3px 3px 0; + font-weight: 700; + color: #c44; + pointer-events: auto + } + + .cbi-dynlist>.add-item, + .nav, + .nav>li>a, + .td.cbi-section-actions>* { + display: flex + } + + .cbi-dynlist>.add-item>button, + .cbi-dynlist>.add-item>input { + flex: 1 1 auto; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap + } + + .cbi-value-field>.cbi-checkbox, + .cbi-value-field>div>.cbi-radio { + height: 30px; + display: inline-flex; + align-items: center + } + + .cbi-radio { + cursor: pointer; + gap: .125em + } + + .cbi-select { + padding: 0 + } + + .cbi-select select, + .cbi-select select:focus { + -webkit-appearance: none; + appearance: none; + outline: 0; + border: none; + background: 0 0; + height: 100%; + width: 100%; + padding: 0 .3em; + cursor: pointer; + margin-right: .6em + } + + .cbi-select::before { + position: absolute; + top: 0; + right: 0; + bottom: 0; + content: "▾"; + padding: 0 .3em; + pointer-events: none; + border-radius: 3px; + display: flex; + flex-direction: column; + justify-content: center + } + + .cbi-select select option { + background: var(--background-color-low) + } + + .cbi-select select option:hover { + background: var(--primary-color-low); + color: var(--on-primary-color) + } + + .cbi-select select option:checked { + background: var(--primary-color-medium); + color: var(--on-primary-color) + } + + input[type=file] { + padding: initial; + border: initial; + line-height: initial; + box-shadow: none; + width: auto !important + } + + input[type=button], + input[type=reset], + input[type=submit] { + width: auto; + height: auto + } + + select[multiple] { + height: inherit; + background-color: #fff + } + + input[type=checkbox], + input[type=radio] { + --bd-color: var(--border-color-high); + --fg-color: var(--text-color-high); + appearance: none; + -webkit-appearance: none; + width: 14px; + height: 14px; + color: var(--fg-color); + position: relative; + display: inline-block; + cursor: pointer; + background: 0 0; + border: none + } + + input[type=checkbox]::after, + input[type=checkbox]::before, + input[type=radio]::after, + input[type=radio]::before { + position: absolute; + content: "" + } + + input[type=checkbox]::before, + input[type=radio]::before { + top: 0; + left: 0; + width: 14px; + height: 14px; + background: linear-gradient(var(--background-color-high), var(--background-color-low)); + border: 1px solid var(--bd-color); + border-radius: 2px + } + + input[type=radio], + input[type=radio]::before { + border-radius: 50% + } + + input[type=checkbox]::after, + input[type=radio]::after { + top: 2px; + left: 2px; + width: 10px; + height: 10px + } + + input[type=checkbox]:checked::after, + input[type=radio]:checked::after { + --checkmark-icon: url("data:image/svg+xml,"); + -webkit-mask: var(--checkmark-icon) center/cover no-repeat; + mask: var(--checkmark-icon) center/cover no-repeat; + background: var(--fg-color) + } + + input[type=radio]:checked:after { + --checkmark-icon: url("data:image/svg+xml,") + } + + input[type=checkbox].cbi-input-invalid, + input[type=radio].cbi-input-invalid { + --bd-color: var(--error-color-medium); + --fg-color: var(--error-color-high) + } + + ::placeholder { + color: var(--text-color-medium) + } + + .btn, + .cbi-button, + .cbi-dropdown, + .cbi-dynlist>.item, + .cbi-select, + .item::after, + button, + input, + input[type=checkbox]::before, + input[type=radio]::before, + select, + textarea { + transition: border .2s linear, box-shadow .2s linear; + box-shadow: inset 0 1px 3px hsla(var(--border-color-low-hsl), .01) + } + + .btn:focus, + .btn:hover, + .cbi-button:focus, + .cbi-button:hover, + .cbi-dropdown:focus, + .cbi-dropdown[open], + .cbi-dynlist>.item:focus, + .cbi-select.focus, + .item:hover::after, + button:hover, + input:focus, + input[type=checkbox]:focus::before, + input[type=radio]:focus::before, + select:focus, + textarea:focus { + --focus-color-rgb: 82, 168, 236; + outline: 0; + border-color: rgba(var(--focus-color-rgb), .8) !important; + box-shadow: inset 0 1px 3px hsla(var(--border-color-low-hsl), .01), 0 0 8px rgba(var(--focus-color-rgb), .6); + text-decoration: none + } + + .cbi-input-invalid:focus, + .cbi-select.cbi-input-invalid, + input[type=checkbox].cbi-input-invalid:focus::before, + input[type=radio].cbi-input-invalid:focus::before { + --focus-color-rgb: var(--error-color-high-rgb) + } + + .cbi-dropdown[disabled]:not(.btn):not(.cbi-button), + .cbi-select[disabled]::before, + button[disabled], + input[disabled], + input[type=checkbox][disabled]::after, + input[type=checkbox][disabled]::before, + input[type=radio][disabled]::after, + input[type=radio][disabled]::before, + select[disabled], + textarea[disabled] { + opacity: var(--disabled-opacity); + pointer-events: none; + cursor: default + } + + input[readonly], + select[readonly], + textarea[readonly] { + border-color: hsla(var(--border-color-high-hsl), var(--disabled-opacity)); + pointer-events: auto; + cursor: auto + } + + .cbi-optionals, + .cbi-section-create { + padding: 5px 0 + } + + .cbi-section-create { + margin: -3px; + display: inline-flex; + align-items: center + } + + .cbi-section-create>* { + margin: 3px; + flex: 1 1 auto + } + + .actions, + .cbi-page-actions { + margin-bottom: 18px; + border-top: 1px solid var(--border-color-medium); + border-radius: 0 0 3px 3px; + text-align: right + } + + .actions .secondary-action a, + .cbi-page-actions .secondary-action a { + line-height: 30px + } + + .cbi-page-actions>form { + display: inline; + margin: 0 + } + + .tr { + display: table-row + } + + .table[width="33%"], + .td[width="33%"], + .th[width="33%"] { + width: 33% + } + + .table { + display: table; + width: 100%; + padding: 0; + font-size: 13px + } + + .table .td, + .table .th { + display: table-cell; + padding: 10px 10px 9px; + line-height: 18px; + text-align: left; + border-top: 1px solid var(--border-color-medium) + } + + .table .tr:first-child .th { + padding-top: 9px; + font-weight: 700; + vertical-align: top + } + + .cbi-section-table .tr.cbi-section-table-descr .th, + header .brand { + font-weight: 400 + } + + .tr.placeholder { + height: calc(3em + 20px) + } + + .tr.placeholder>.td { + position: absolute; + left: 0; + right: 0; + bottom: 0; + text-align: center; + line-height: 3em + } + + .tr.drag-over-above, + .tr.drag-over-below { + border: 2px solid #0069d6; + border-width: 2px 0 0 + } + + .tr.drag-over-below { + border-width: 0 0 2px + } + + header { + grid-area: header; + position: sticky; + top: 0; + z-index: 800; + height: var(--header-height); + background: var(--md-sys-color-surface-translucent); + backdrop-filter: blur(15px); + display: flex; + align-items: center; + justify-content: space-between; + transition: box-shadow .3s; + background: linear-gradient(#333, #222); + box-shadow: 0 1px 3px hsla(var(--border-color-low-hsl), .25), inset 0 -1px 0 hsla(var(--border-color-low-hsl), .01); + padding: 0 + } + + header a { + color: #bfbfbf; + text-shadow: 0 -1px 0 hsla(var(--border-color-low-hsl), .25) + } + + header .brand:hover, + header ul .active>a { + background-color: rgba(255, 255, 255, .05); + color: var(--md-sys-color-primary); + text-decoration: none + } + + header .brand { + flex: 0 1 auto; + text-align: center; + float: left; + display: block; + color: #404040 + } + + header .pull-right { + /* flex: 0 0 auto; */ + margin: 0 12px; + } + + header p { + margin: 0; + line-height: 40px + } + + .nav, + .zone-forwards .zone-dest, + .zone-forwards .zone-src { + display: flex; + flex-direction: column + } + + .dropdown-menu { + background-color: #fff; + float: left; + position: absolute; + top: 40px; + left: -9999px; + z-index: 900; + min-width: 160px; + max-width: 220px; + zoom: 1; + border-width: 0 1px 1px; + box-shadow: 0 2px 4px rgba(0, 0, 0, .2); + background-clip: padding-box; + transition: height .3s ease-in-out; + overflow: hidden + } + + .dropdown-menu li { + float: none; + display: block; + overflow: hidden; + /* margin: 4px 0; */ + } + + .dropdown-menu a { + display: block; + padding: 4px 15px; + clear: both; + font-weight: 400; + line-height: 18px; + color: grey; + text-shadow: 0 0 0 #fff + } + + .dropdown-menu a:hover { + background-color: #ddd; + background-repeat: repeat-x; + background-image: linear-gradient(to bottom, #eee, #ddd); + color: #404040; + text-decoration: none; + box-shadow: inset 0 1px 0 rgba(0, 0, 0, .025), inset 0 -1px rgba(0, 0, 0, .025) + } + + .dropdown:hover ul.dropdown-menu { + left: 0 + } + + .dropdown-menu .dropdown-menu { + position: absolute; + left: 159px + } + + #tabmenu { text-align: center; width: 100% -} + } -.cbi-tabmenu, -.tabs { - --tab-bar-background-color: var(--background-color-high); - --tab-inactive-background-color-h: var(--border-color-low-h); - --tab-inactive-background-color-s: var(--border-color-low-s); - --tab-inactive-background-color-l: var(--border-color-low-l); - --tab-inactive-background-color: var(--border-color-low); - --tab-inactive-border-color: var(--border-color-medium); - --tab-inactive-text-color-delta-l: 33.33%; - --tab-inactive-text-color-l: calc(var(--tab-inactive-background-color-l) + var(--background-color-delta-l-sign) * var(--tab-inactive-text-color-delta-l)); - --tab-inactive-text-color: hsl(var(--tab-inactive-background-color-hsl)); - --tab-inactive-hover-background-color: var(--background-color-high); - --tab-active-background-color: var(--background-color-high); - --tab-active-text-color: #0069d6; - --tab-active-border-color: var(--border-color-medium); - margin: 0 0px 10px; - /* padding: 0 2px; */ - list-style: none; - display: inline-flex; - flex-wrap: wrap; - justify-content: center; - background: var(--md-sys-color-card); - border-radius: 1rem -} + .cbi-tabmenu, + .tabs { + --tab-bar-background-color: var(--background-color-high); + --tab-inactive-background-color-h: var(--border-color-low-h); + --tab-inactive-background-color-s: var(--border-color-low-s); + --tab-inactive-background-color-l: var(--border-color-low-l); + --tab-inactive-background-color: var(--border-color-low); + --tab-inactive-border-color: var(--border-color-medium); + --tab-inactive-text-color-delta-l: 33.33%; + --tab-inactive-text-color-l: calc(var(--tab-inactive-background-color-l) + var(--background-color-delta-l-sign) * var(--tab-inactive-text-color-delta-l)); + --tab-inactive-text-color: hsl(var(--tab-inactive-background-color-hsl)); + --tab-inactive-hover-background-color: var(--background-color-high); + --tab-active-background-color: var(--background-color-high); + --tab-active-text-color: #0069d6; + --tab-active-border-color: var(--border-color-medium); + margin: 0 0px 10px; + /* padding: 0 2px; */ + list-style: none; + display: inline-flex; + flex-wrap: wrap; + justify-content: center; + background: var(--md-sys-color-card); + border-radius: 1rem + } -.cbi-tabmenu>li>a, -.tabs>li>a { - padding: 0 6px; - white-space: nowrap; - text-overflow: ellipsis; - color: inherit; - text-decoration: none; - line-height: 26px; - outline: 0 -} + .cbi-tabmenu>li>a, + .tabs>li>a { + padding: 0 6px; + white-space: nowrap; + text-overflow: ellipsis; + color: inherit; + text-decoration: none; + line-height: 26px; + outline: 0 + } -.cbi-tabmenu>li:hover, -.tabs>li:hover { - background: rgba(0, 0, 0, .05); - transition: .3s -} + .cbi-tabmenu>li:hover, + .tabs>li:hover { + background: rgba(0, 0, 0, .05); + transition: .3s + } -.cbi-tabmenu>li>a:focus-visible, -.tabs>li>a:focus-visible { - text-decoration: underline -} + .cbi-tabmenu>li>a:focus-visible, + .tabs>li>a:focus-visible { + text-decoration: underline + } -.close:hover, -.dropdown-menu>li>a:hover, -.nav>li.active>a, -.nav>li>a, -.nav>li>a:hover, -a.label:hover { - text-decoration: none -} + .close:hover, + .dropdown-menu>li>a:hover, + .nav>li.active>a, + .nav>li>a, + .nav>li>a:hover, + a.label:hover { + text-decoration: none + } -.cbi-tabmenu>.cbi-tab-disabled, -.tabs>li:not(.active) { - color: var(--tab-inactive-text-color); - background: 0 0; - border: none -} + .cbi-tabmenu>.cbi-tab-disabled, + .tabs>li:not(.active) { + color: var(--tab-inactive-text-color); + background: 0 0; + border: none + } -.breadcrumb .active a, -footer { - color: var(--text-color-medium) -} + .breadcrumb .active a, + footer { + color: var(--text-color-medium) + } -.dropdown-menu>li:hover, -.nav a.menu:hover, -.nav>li>a:hover, -.tabs>li:hover { - background: #11111111 -} + .dropdown-menu>li:hover, + .nav a.menu:hover, + .nav>li>a:hover, + .tabs>li:hover { + background: #11111111 + } -.cbi-tabmenu>li, -.tabs>li { - flex: 0 1 auto; - display: flex; - align-items: center; - background: var(--tab-active-background-color); - border: 1px solid var(--tab-active-border-color); - border-bottom: none; - color: var(--primary-color-high); - border: none; - margin: 0; - background: var(--md-sys-color-primary-container); - color: #000; - font-size: 14px; - height: 32px; - border-radius: 1rem; - padding: 0 12px; - display: flex; - align-items: center; - white-space: nowrap -} + .cbi-tabmenu>li, + .tabs>li { + flex: 0 1 auto; + display: flex; + align-items: center; + background: var(--tab-active-background-color); + border: 1px solid var(--tab-active-border-color); + border-bottom: none; + color: var(--primary-color-high); + border: none; + margin: 0; + background: var(--md-sys-color-primary-container); + color: #000; + font-size: 14px; + height: 32px; + border-radius: 1rem; + padding: 0 12px; + display: flex; + align-items: center; + white-space: nowrap + } -.cbi-dropdown.btn.spinning>ul:not(.dropdown), -.cbi-dropdown.cbi-button.spinning>ul:not(.dropdown), -.cbi-dropdown>ul { - margin: 0 !important -} + .cbi-dropdown.btn.spinning>ul:not(.dropdown), + .cbi-dropdown.cbi-button.spinning>ul:not(.dropdown), + .cbi-dropdown>ul { + margin: 0 !important + } -.cbi-tab-disabled[data-errors]::after { - content: attr(data-errors); - background: #c43c35; - color: #fff; - height: 16px; - min-width: 16px; - border-radius: 8px; - text-align: center; - margin: 0 5px 0 0; - padding: 3px 2px 1px; - display: inline-flex; - flex-direction: column; - justify-content: center; - font-size: 12px -} + .cbi-tab-disabled[data-errors]::after { + content: attr(data-errors); + background: #c43c35; + color: #fff; + height: 16px; + min-width: 16px; + border-radius: 8px; + text-align: center; + margin: 0 5px 0 0; + padding: 3px 2px 1px; + display: inline-flex; + flex-direction: column; + justify-content: center; + font-size: 12px + } -.cbi-tabmenu.map { - margin: 0 -} + .cbi-tabmenu.map { + margin: 0 + } -.cbi-tabmenu.map>li { - font-size: 16.5px; - font-weight: 700 -} + .cbi-tabmenu.map>li { + font-size: 16.5px; + font-weight: 700 + } -.cbi-tab-descr { - margin: -9px 0 18px -} + .cbi-tab-descr { + margin: -9px 0 18px + } -.tabs .dropdown-menu, -.tabs .menu-dropdown { - top: 35px; - border-width: 1px; - border-radius: 0 6px 6px -} + .tabs .dropdown-menu, + .tabs .menu-dropdown { + top: 35px; + border-width: 1px; + border-radius: 0 6px 6px + } -.tabs .dropdown-toggle:after, -.tabs a.menu:after { - border-top-color: #999; - margin-top: 15px; - margin-left: 5px -} + .tabs .dropdown-toggle:after, + .tabs a.menu:after { + border-top-color: #999; + margin-top: 15px; + margin-left: 5px + } -.tabs .open.dropdown .dropdown-toggle, -.tabs li.open.menu .menu { - border-color: #999 -} + .tabs .open.dropdown .dropdown-toggle, + .tabs li.open.menu .menu { + border-color: #999 + } -.tabs .dropdown.open .dropdown-toggle:after, -.tabs li.open a.menu:after { - border-top-color: #555 -} + .tabs .dropdown.open .dropdown-toggle:after, + .tabs li.open a.menu:after { + border-top-color: #555 + } -#modemenu li:last-child span.divider, -.cbi-dropdown>ul.preview, -.cbi-dropdown>ul>li .hide-close, -.cbi-dropdown[open]>ul.dropdown>li .hide-open, -.hidden, -.nav>li:last-child>a::after, -.tab-content>.tab-pane, -.tab-content>div { - display: none -} + #modemenu li:last-child span.divider, + .cbi-dropdown>ul.preview, + .cbi-dropdown>ul>li .hide-close, + .cbi-dropdown[open]>ul.dropdown>li .hide-open, + .hidden, + .nav>li:last-child>a::after, + .tab-content>.tab-pane, + .tab-content>div { + display: none + } -.breadcrumb { - padding: 7px 14px; - margin: 0 0 18px; - background: linear-gradient(to bottom, var(--background-color-high), var(--background-color-low)); - border: 1px solid var(--border-color-medium); - border-radius: 3px; - display: flex; - flex: 0 -} + .breadcrumb { + padding: 7px 14px; + margin: 0 0 18px; + background: linear-gradient(to bottom, var(--background-color-high), var(--background-color-low)); + border: 1px solid var(--border-color-medium); + border-radius: 3px; + display: flex; + flex: 0 + } -.breadcrumb li:not(:last-child)::after { - content: "|"; - padding: 0 5px -} + .breadcrumb li:not(:last-child)::after { + content: "|"; + padding: 0 5px + } -footer { - grid-area: footer; - padding-top: 17px; - margin-top: auto; - border-top: 1px solid var(--border-color-low); - display: flex; - flex-wrap: wrap; - align-items: baseline; - justify-content: space-between; - font-size: 12px; - padding-left: calc(36%) -} + footer { + grid-area: footer; + padding-top: 17px; + margin-top: auto; + border-top: 1px solid var(--border-color-low); + display: flex; + flex-wrap: wrap; + align-items: baseline; + justify-content: space-between; + font-size: 12px; + padding-left: calc(36%) + } -#modal_overlay { + #modal_overlay { position: fixed; top: 0; bottom: 0; @@ -1408,1865 +1571,1871 @@ footer { transition: opacity .125s ease-in; opacity: 0; visibility: hidden -} - -.modal { - width: 90%; - margin: 5em auto; - min-height: 32px; - max-width: 600px; - box-shadow: none; - background: var(--background-color-high); - border: 1px solid var(--border-color-low); - border-radius: 16px; - padding: 1em 1em .5em; - min-width: 270px; - backdrop-filter: blur(20px) -} - -.modal>* { - line-height: normal; - margin-bottom: .5em; - max-width: 100% -} - -.modal>pre, -.modal>textarea { - white-space: pre-wrap; - overflow: auto; - width: 100% -} - -body.modal-overlay-active { - overflow: hidden; - height: 100vh -} - -body.modal-overlay-active #modal_overlay { - left: 0; - right: 0; - opacity: 1; - visibility: visible; - backdrop-filter: blur(10px) -} - -.alert-message .close, -.btn .close { - font-family: Arial, sans-serif; - line-height: 18px -} - -.alert-message.danger, -.alert-message.error, -.btn.danger, -.btn.error, -.cbi-tooltip.error { - background: linear-gradient(var(--error-color-low), var(--error-color-medium)); - color: var(--on-error-color); - border-color: var(--error-color-high) var(--error-color-high) var(--error-color-low) -} - -.alert-message.success, -.btn.success, -.cbi-tooltip.success { - background: linear-gradient(var(--success-color-low), var(--success-color-medium)); - color: var(--on-error-color); - border-color: var(--success-color-high) var(--success-color-high) var(--success-color-low) -} - -.alert-message.info, -.btn.info, -.cbi-tooltip.info { - background: linear-gradient(var(--primary-color-low), var(--primary-color-medium)); - color: var(--on-primary-color); - border-color: var(--primary-color-high) var(--primary-color-high) var(--primary-color-low) -} - -.alert-message.notice, -.cbi-tooltip.notice { - background: linear-gradient(var(--background-color-low), var(--background-color-medium)); - border-color: var(--background-color-high) var(--background-color-high) var(--background-color-low); - color: var(--text-color-high) -} - -.alert-message.warning { - background: linear-gradient(var(--warn-color-low), var(--warn-color-medium)); - border-color: var(--warn-color-high) var(--warn-color-high) var(--warn-color-low); - color: var(--on-warn-color) -} - -.modal.alert-message { - color: var(--text-color-high); - border-radius: 1rem -} - -.btn, -.cbi-button, -.item::after { - --default-btn-background: linear-gradient(var(--background-color-high), var(--background-color-high) 25%, var(--background-color-low)); - --on-color: var(--text-color-high); - cursor: pointer; - display: inline-block; - background: var(--default-btn-background); - padding: 0 14px; - color: var(--on-color); - font-size: 13px; - line-height: 2em; - border-radius: 4px; - white-space: pre -} - -#maincontent, -.cbi-tooltip { - background: var(--background-color-high) -} - -.cbi-input-invalid, -.cbi-input-invalid.cbi-dropdown:not(.btn):not(.cbi-button), -.cbi-input-invalid.cbi-dropdown:not([open])>ul>li, -.cbi-value-error input { - color: var(--error-color-high); - border-color: var(--error-color-medium) -} - -.cbi-button-add, -.cbi-button-fieldadd, -.cbi-button-positive, -.cbi-button-save { - --on-color: var(--success-color-high); - border-color: var(--on-color) -} - -.btn.primary, -.cbi-button-action, -.cbi-button-apply, -.cbi-button-edit, -.cbi-button-reload { - --on-color: var(--primary-color-high); - border-color: var(--on-color) -} - -.cbi-button-negative, -.cbi-button-remove, -.cbi-button-reset, -.cbi-section-remove .cbi-button { - --on-color: var(--error-color-high); - border-color: var(--on-color); - color: var(--on-color) -} - -.cbi-page-actions::after { - display: table; - content: ""; - clear: both -} - -.cbi-page-actions>:not([method=post]):not(.cbi-button-apply):not(.cbi-button-negative):not(.cbi-button-save):not(.cbi-button-reset) { - float: left; - margin-right: .4em -} - -.btn.primary, -.cbi-button-action.important, -.cbi-page-actions .cbi-button-apply, -.cbi-section-actions .cbi-button-edit { - --on-color: var(--on-primary-color) -} - -.cbi-button-positive.important, -.cbi-page-actions .cbi-button-save { - --on-color: var(--on-success-color); - background: var(--md-sys-color-primary-container); - border-color: var(--md-sys-color-primary-container); - color: #000; -} - -.cbi-button-negative.important { - --on-color: var(--on-error-color); - background: linear-gradient(var(--error-color-medium), var(--error-color-low)); - border-color: var(--error-color-high); - color: #fff -} - -.cbi-page-actions .cbi-button-apply+.cbi-button-save, -.cbi-page-actions .cbi-button-negative+.cbi-button-save { - --on-color: var(--success-color-high); - border-color: var(--on-color); - background: var(--default-btn-background) -} - -.cbi-dropdown { - display: inline-flex !important; - cursor: pointer; - height: auto; - padding: 0 !important -} - -.cbi-dropdown:not(.btn):not(.cbi-button) { - background: linear-gradient(var(--background-color-high) 0, var(--border-color-low) 100%); - border: 1px solid var(--border-color-high); - color: var(--text-color-high) -} - -.cbi-dropdown>ul { - padding: 0; - overflow-x: hidden; - overflow-y: hidden; - display: flex; - width: 100% -} - -.cbi-dropdown.btn>ul:not(.dropdown), -.cbi-dropdown.cbi-button>ul:not(.dropdown) { - margin: 0 0 0 13px !important -} - -.cbi-dropdown>.more, -.cbi-dropdown>.open { - flex-grow: 0; - flex-shrink: 0; - display: flex; - flex-direction: column; - justify-content: center; - text-align: center; - line-height: 2em; - padding: 0 .3em -} - -.cbi-dropdown.btn>.open, -.cbi-dropdown.cbi-button>.open { - padding: 0 .5em; - margin-left: .5em; - border-left: 1px solid -} - -.cbi-dropdown:not(.btn):not(.cbi-button)>ul>li[placeholder], -.cbi-dropdown>.more { - color: var(--text-color-medium); - display: none -} - -.cbi-dropdown>ul>li { - display: none; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - flex-shrink: 1; - flex-grow: 1; - align-items: center; - align-self: center -} - -.cbi-dropdown:not(.btn):not(.cbi-button)>ul>li, -.cbi-dropdown>ul.dropdown>li { - min-height: 20px; - padding: .25em; - color: var(--text-color-high) -} - -.cbi-dropdown>ul>li .hide-open, -.cbi-dropdown[open]>ul.dropdown>li .hide-close { - display: initial -} - -.cbi-dropdown>ul>li[display]:not([display="0"]) { - border-left: 1px solid var(--border-color-high) -} - -.cbi-dropdown[empty]>ul { - max-width: 1px -} - -.cbi-dropdown>ul>li>form { - display: none; - margin: 0; - padding: 0; - pointer-events: none -} - -.cbi-dropdown>ul>li img, -.cbi-filebrowser .cbi-button-positive { - margin-right: .25em -} - -.cbi-dropdown>ul>li>form>input[type=checkbox] { - margin: 0 .25em 0 0 -} - -.cbi-dropdown[open]>ul.dropdown { - display: block; - background: var(--md-sys-color-dropdown); - position: absolute; - z-index: 1100; - max-width: none; - min-width: 100%; - width: auto; - transition: max-height .125s ease-in; - overflow-y: auto; - box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%); - border-radius: .25rem; - left: 0 !important -} - -.cbi-dropdown>ul>li[display], -.cbi-dropdown[multiple]>ul>li>label, -.cbi-dropdown[multiple][empty]>.more, -.cbi-dropdown[multiple][more]>.more, -.cbi-dropdown[multiple][open]>ul.dropdown>li, -.cbi-dropdown[open]>ul.dropdown>li, -.cbi-dropdown[open]>ul.preview { - flex-grow: 1; - display: flex !important; - /* color: #fff; */ -} - -.cbi-dropdown>ul>li[display] { - /* color: var(--md-sys-color-primary); */ -} - -.cbi-value-field em { - color: var(--md-sys-color-primary); -} - -.uci-dialog .cbi-dropdown>ul>li[display] { - color: #000; -} - -.cbi-dropdown[multiple]>ul>li>label, -.cbi-dropdown[multiple][open]>ul.dropdown>li, -.nav .dropdown-menu .active a { - color: #000 -} - -.cbi-dropdown[empty]>ul>li, -.cbi-dropdown[optional][open]>ul.dropdown>li[placeholder] { - display: block !important -} - -.cbi-dropdown[multiple][open]>ul.dropdown>li>form { - display: flex !important -} - -.cbi-dropdown[open]>ul.dropdown>li { - border: none; - padding: 8px; - color: #000 -} - -.cbi-dropdown[open]>ul.dropdown>li[selected].focus { - background: var(--md-sys-color-dropdown-selected); - /* color: #000 */ -} - -.cbi-dropdown[open]>ul.dropdown>li:hover, -.cbi-dropdown[open]>ul.dropdown>li[selected]:hover { - background: var(--md-sys-color-dropdown-hover); -} - -.cbi-dropdown[open]>ul.dropdown>li:last-child { - margin-bottom: 0; - border-bottom: none -} - -.cbi-dropdown[open]>ul.dropdown>li[unselectable] { - opacity: .7 -} - -.cbi-title-ref { - color: #37c -} - -.cbi-title-ref::after { - content: "➙" -} - -.cbi-tooltip-container { - cursor: help -} - -.cbi-tooltip { - position: absolute; - z-index: 1000; - left: -10000px; - box-shadow: 0 0 2px var(--border-color-high); - border-radius: 3px; - white-space: pre; - padding: 2px 5px; - opacity: 0; - transition: opacity .25s ease-in -} - -.cbi-tooltip-container:hover .cbi-tooltip:not(:empty) { - left: auto; - opacity: 1; - transition: opacity .25s ease-in -} - -.cbi-progressbar { - border: 1px solid var(--border-color-high); - position: relative; - min-width: 170px; - height: 4px; - margin: 1.4em 0 4px; - background: var(--background-color-medium) -} - -.cbi-progressbar>div { - background: var(--md-sys-color-primary); - height: 100%; - transition: width .25s ease-in; - width: 0% -} - -.cbi-progressbar::before { - position: absolute; - top: -1.4em; - left: 0; - content: attr(title); - white-space: pre; - overflow: hidden; - text-overflow: ellipsis -} - -.zonebadge .cbi-tooltip { - padding: 1px; - background: inherit; - margin: -1.6em 0 0 -5px; - border-radius: 3px; - pointer-events: none; - box-shadow: 0 0 3px #444 -} - -.zonebadge .cbi-tooltip>* { - margin: 1px; - z-index: 2; - position: relative -} - -.zone-forwards>* { - flex: 1 1 40%; - padding: 1px -} - -.zone-forwards>span { - flex-basis: 10%; - text-align: center -} - -.btn.active, -.btn:active { - box-shadow: inset 0 2px 4px hsla(var(--border-color-low-hsl), .25), 0 1px 2px rgba(0, 0, 0, .05) -} - -.btn.disabled, -.btn[disabled] { - cursor: default; - box-shadow: none -} - -.btn.large { - font-size: 15px; - line-height: normal; - padding: 9px 14px; - border-radius: 6px -} - -.btn.small { - padding: 7px 9px; - font-size: 11px -} - -button.btn::-moz-focus-inner, -input[type=submit].btn::-moz-focus-inner { - padding: 0; - border: 0 -} - -.close { - float: right; - color: #000; - font-size: 20px; - font-weight: 700; - line-height: 13.5px; - text-shadow: 0 1px 0 #fff; - opacity: .25 -} - -.close:hover { - color: #000; - opacity: .4 -} - -.alert-message { - position: relative; - padding: .5em .5em .25em; - margin-bottom: .5em; - color: var(--on-warn-color); - background: linear-gradient(#fceec1, #eedc94); - border: 1px solid var(--border-color-low); - border-color: var(--border-color-high) var(--border-color-high) var(--border-color-low); - border-radius: 4px; - box-shadow: 1px 1px 1px var(--border-color-low); - white-space: unset -} - -.alert-message .close { - margin-top: 1px -} - -.alert-message h4, -.alert-message h5, -.alert-message li, -.alert-message p, -.alert-message pre, -.alert-message ul { - color: inherit; - border: none; - line-height: inherit; - background: 0 0; - padding: 0; - margin: .25em 0 -} - -.alert-message button { - margin: .25em 0 -} - -.label, -header [data-indicator] { - font-weight: 700; - color: var(--text-color-high); - text-transform: uppercase; - white-space: nowrap; - border-radius: 16px; - text-shadow: none; - margin: .125em 0 .125em .4em; - text-align: center -} - -.ifacebadge, -.ifacebox .ifacebox-head[style], -.zonebadge { - text-shadow: 0 1px 1px hsla(var(--background-color-high-hsl), .75) -} - -header [data-indicator][data-clickable] { - cursor: pointer; - transition: .3s -} - -.nav .dropdown-menu a.menu, -a.label:link, -a.label:visited { - color: #fff -} - -.label.important { - background-color: var(--primary-color-high); - color: var(--on-primary-color) -} - -.label.warning { - background-color: var(--warn-color-high); - color: var(--on-warn-color) -} - -.label.success { - background-color: var(--success-color-high); - color: var(--on-success-color) -} - -.label.notice, -header [data-indicator][data-style=active] { - color: var(--on-primary-color); - background-color: var(--primary-color-high) -} - -form.inline { - display: inline; - margin-bottom: 0 -} - -#syslog { + } + + .modal { + width: 90%; + margin: 5em auto; + min-height: 32px; + max-width: 600px; + box-shadow: none; + background: var(--background-color-high); + border: 1px solid var(--border-color-low); + border-radius: 16px; + padding: 1em 1em .5em; + min-width: 270px; + backdrop-filter: blur(20px) + } + + .modal>* { + line-height: normal; + margin-bottom: .5em; + max-width: 100% + } + + .modal>pre, + .modal>textarea { + white-space: pre-wrap; + overflow: auto; + width: 100% + } + + body.modal-overlay-active { + overflow: hidden; + height: 100vh + } + + body.modal-overlay-active #modal_overlay { + left: 0; + right: 0; + opacity: 1; + visibility: visible; + backdrop-filter: blur(10px) + } + + .alert-message .close, + .btn .close { + font-family: Arial, sans-serif; + line-height: 18px + } + + .alert-message.danger, + .alert-message.error, + .btn.danger, + .btn.error, + .cbi-tooltip.error { + background: linear-gradient(var(--error-color-low), var(--error-color-medium)); + color: var(--on-error-color); + border-color: var(--error-color-high) var(--error-color-high) var(--error-color-low) + } + + .alert-message.success, + .btn.success, + .cbi-tooltip.success { + background: linear-gradient(var(--success-color-low), var(--success-color-medium)); + color: var(--on-error-color); + border-color: var(--success-color-high) var(--success-color-high) var(--success-color-low) + } + + .alert-message.info, + .btn.info, + .cbi-tooltip.info { + background: linear-gradient(var(--primary-color-low), var(--primary-color-medium)); + color: var(--on-primary-color); + border-color: var(--primary-color-high) var(--primary-color-high) var(--primary-color-low) + } + + .alert-message.notice, + .cbi-tooltip.notice { + background: linear-gradient(var(--background-color-low), var(--background-color-medium)); + border-color: var(--background-color-high) var(--background-color-high) var(--background-color-low); + color: var(--text-color-high) + } + + .alert-message.warning { + background: linear-gradient(var(--warn-color-low), var(--warn-color-medium)); + border-color: var(--warn-color-high) var(--warn-color-high) var(--warn-color-low); + color: var(--on-warn-color) + } + + .modal.alert-message { + color: var(--text-color-high); + border-radius: 1rem + } + + .btn, + .cbi-button, + .item::after { + --default-btn-background: linear-gradient(var(--background-color-high), var(--background-color-high) 25%, var(--background-color-low)); + --on-color: var(--text-color-high); + cursor: pointer; + display: inline-block; + background: var(--default-btn-background); + padding: 0 14px; + color: var(--on-color); + font-size: 13px; + line-height: 2em; + border-radius: 4px; + white-space: pre + } + + #maincontent, + .cbi-tooltip { + background: var(--background-color-high) + } + + .cbi-input-invalid, + .cbi-input-invalid.cbi-dropdown:not(.btn):not(.cbi-button), + .cbi-input-invalid.cbi-dropdown:not([open])>ul>li, + .cbi-value-error input { + color: var(--error-color-high); + border-color: var(--error-color-medium) + } + + .cbi-button-add, + .cbi-button-fieldadd, + .cbi-button-positive, + .cbi-button-save { + --on-color: var(--success-color-high); + border-color: var(--on-color) + } + + .btn.primary, + .cbi-button-action, + .cbi-button-apply, + .cbi-button-edit, + .cbi-button-reload { + --on-color: var(--primary-color-high); + border-color: var(--on-color) + } + + .cbi-button-negative, + .cbi-button-remove, + .cbi-button-reset, + .cbi-section-remove .cbi-button { + --on-color: var(--error-color-high); + border-color: var(--on-color); + color: var(--on-color) + } + + .cbi-page-actions::after { + display: table; + content: ""; + clear: both + } + + .cbi-page-actions>:not([method=post]):not(.cbi-button-apply):not(.cbi-button-negative):not(.cbi-button-save):not(.cbi-button-reset) { + float: left; + margin-right: .4em + } + + .btn.primary, + .cbi-button-action.important, + .cbi-page-actions .cbi-button-apply, + .cbi-section-actions .cbi-button-edit { + --on-color: var(--on-primary-color) + } + + .cbi-button-positive.important, + .cbi-page-actions .cbi-button-save { + --on-color: var(--on-success-color); + background: var(--md-sys-color-primary-container); + border-color: var(--md-sys-color-primary-container); + color: #000; + } + + .cbi-button-negative.important { + --on-color: var(--on-error-color); + background: linear-gradient(var(--error-color-medium), var(--error-color-low)); + border-color: var(--error-color-high); + color: #fff + } + + .cbi-page-actions .cbi-button-apply+.cbi-button-save, + .cbi-page-actions .cbi-button-negative+.cbi-button-save { + --on-color: var(--success-color-high); + border-color: var(--on-color); + background: var(--default-btn-background) + } + + .cbi-dropdown { + display: inline-flex !important; + cursor: pointer; + height: auto; + padding: 0 !important + } + + .cbi-dropdown:not(.btn):not(.cbi-button) { + background: linear-gradient(var(--background-color-high) 0, var(--border-color-low) 100%); + border: 1px solid var(--border-color-high); + color: var(--text-color-high) + } + + .cbi-dropdown>ul { + padding: 0; + overflow-x: hidden; + overflow-y: hidden; + display: flex; + width: 100% + } + + .cbi-dropdown.btn>ul:not(.dropdown), + .cbi-dropdown.cbi-button>ul:not(.dropdown) { + margin: 0 0 0 13px !important + } + + .cbi-dropdown>.more, + .cbi-dropdown>.open { + flex-grow: 0; + flex-shrink: 0; + display: flex; + flex-direction: column; + justify-content: center; + text-align: center; + line-height: 2em; + padding: 0 .3em + } + + .cbi-dropdown.btn>.open, + .cbi-dropdown.cbi-button>.open { + padding: 0 .5em; + margin-left: .5em; + border-left: 1px solid + } + + .cbi-dropdown:not(.btn):not(.cbi-button)>ul>li[placeholder], + .cbi-dropdown>.more { + color: var(--text-color-medium); + display: none + } + + .cbi-dropdown>ul>li { + display: none; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex-shrink: 1; + flex-grow: 1; + align-items: center; + align-self: center + } + + .cbi-dropdown:not(.btn):not(.cbi-button)>ul>li, + .cbi-dropdown>ul.dropdown>li { + min-height: 20px; + padding: .25em; + color: var(--text-color-high) + } + + .cbi-dropdown>ul>li .hide-open, + .cbi-dropdown[open]>ul.dropdown>li .hide-close { + display: initial + } + + .cbi-dropdown>ul>li[display]:not([display="0"]) { + border-left: 1px solid var(--border-color-high) + } + + .cbi-dropdown[empty]>ul { + max-width: 1px + } + + .cbi-dropdown>ul>li>form { + display: none; + margin: 0; + padding: 0; + pointer-events: none + } + + .cbi-dropdown>ul>li img, + .cbi-filebrowser .cbi-button-positive { + margin-right: .25em + } + + .cbi-dropdown>ul>li>form>input[type=checkbox] { + margin: 0 .25em 0 0 + } + + .cbi-dropdown[open]>ul.dropdown { + display: block; + background: var(--md-sys-color-dropdown); + position: absolute; + z-index: 1100; + max-width: none; + min-width: 100%; + width: auto; + transition: max-height .125s ease-in; + overflow-y: auto; + box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%); + border-radius: .25rem; + left: 0 !important + } + + .cbi-dropdown>ul>li[display], + .cbi-dropdown[multiple]>ul>li>label, + .cbi-dropdown[multiple][empty]>.more, + .cbi-dropdown[multiple][more]>.more, + .cbi-dropdown[multiple][open]>ul.dropdown>li, + .cbi-dropdown[open]>ul.dropdown>li, + .cbi-dropdown[open]>ul.preview { + flex-grow: 1; + display: flex !important; + /* color: #fff; */ + } + + .cbi-dropdown>ul>li[display] { + /* color: var(--md-sys-color-primary); */ + } + + .cbi-value-field em { + color: var(--md-sys-color-primary); + } + + .uci-dialog .cbi-dropdown>ul>li[display] { + color: #000; + } + + .cbi-dropdown[multiple]>ul>li>label, + .cbi-dropdown[multiple][open]>ul.dropdown>li, + .nav .dropdown-menu .active a { + color: #000 + } + + .cbi-dropdown[empty]>ul>li, + .cbi-dropdown[optional][open]>ul.dropdown>li[placeholder] { + display: block !important + } + + .cbi-dropdown[multiple][open]>ul.dropdown>li>form { + display: flex !important + } + + .cbi-dropdown[open]>ul.dropdown>li { + border: none; + padding: 8px; + color: #000 + } + + .cbi-dropdown[open]>ul.dropdown>li[selected].focus { + background: var(--md-sys-color-dropdown-selected); + /* color: #000 */ + } + + .cbi-dropdown[open]>ul.dropdown>li:hover, + .cbi-dropdown[open]>ul.dropdown>li[selected]:hover { + background: var(--md-sys-color-dropdown-hover); + } + + .cbi-dropdown[open]>ul.dropdown>li:last-child { + margin-bottom: 0; + border-bottom: none + } + + .cbi-dropdown[open]>ul.dropdown>li[unselectable] { + opacity: .7 + } + + .cbi-title-ref { + color: #37c + } + + .cbi-title-ref::after { + content: "➙" + } + + .cbi-tooltip-container { + cursor: help + } + + .cbi-tooltip { + position: absolute; + z-index: 1000; + left: -10000px; + box-shadow: 0 0 2px var(--border-color-high); + border-radius: 3px; + white-space: pre; + padding: 2px 5px; + opacity: 0; + transition: opacity .25s ease-in + } + + .cbi-tooltip-container:hover .cbi-tooltip:not(:empty) { + left: auto; + opacity: 1; + transition: opacity .25s ease-in + } + + .cbi-progressbar { + border: 1px solid var(--border-color-high); + position: relative; + min-width: 170px; + height: 4px; + margin: 1.4em 0 4px; + background: var(--background-color-medium) + } + + .cbi-progressbar>div { + background: var(--md-sys-color-primary); + height: 100%; + transition: width .25s ease-in; + width: 0% + } + + .cbi-progressbar::before { + position: absolute; + top: -1.4em; + left: 0; + content: attr(title); + white-space: pre; + overflow: hidden; + text-overflow: ellipsis + } + + .zonebadge .cbi-tooltip { + padding: 1px; + background: inherit; + margin: -1.6em 0 0 -5px; + border-radius: 3px; + pointer-events: none; + box-shadow: 0 0 3px #444 + } + + .zonebadge .cbi-tooltip>* { + margin: 1px; + z-index: 2; + position: relative + } + + .zone-forwards>* { + flex: 1 1 40%; + padding: 1px + } + + .zone-forwards>span { + flex-basis: 10%; + text-align: center + } + + .btn.active, + .btn:active { + box-shadow: inset 0 2px 4px hsla(var(--border-color-low-hsl), .25), 0 1px 2px rgba(0, 0, 0, .05) + } + + .btn.disabled, + .btn[disabled] { + cursor: default; + box-shadow: none + } + + .btn.large { + font-size: 15px; + line-height: normal; + padding: 9px 14px; + border-radius: 6px + } + + .btn.small { + padding: 7px 9px; + font-size: 11px + } + + button.btn::-moz-focus-inner, + input[type=submit].btn::-moz-focus-inner { + padding: 0; + border: 0 + } + + .close { + float: right; + color: #000; + font-size: 20px; + font-weight: 700; + line-height: 13.5px; + text-shadow: 0 1px 0 #fff; + opacity: .25 + } + + .close:hover { + color: #000; + opacity: .4 + } + + .alert-message { + position: relative; + padding: .5em .5em .25em; + margin-bottom: .5em; + color: var(--on-warn-color); + background: linear-gradient(#fceec1, #eedc94); + border: 1px solid var(--border-color-low); + border-color: var(--border-color-high) var(--border-color-high) var(--border-color-low); + border-radius: 4px; + box-shadow: 1px 1px 1px var(--border-color-low); + white-space: unset + } + + .alert-message .close { + margin-top: 1px + } + + .alert-message h4, + .alert-message h5, + .alert-message li, + .alert-message p, + .alert-message pre, + .alert-message ul { + color: inherit; + border: none; + line-height: inherit; + background: 0 0; + padding: 0; + margin: .25em 0 + } + + .alert-message button { + margin: .25em 0 + } + + .label, + header [data-indicator] { + font-weight: 700; + color: var(--text-color-high); + text-transform: uppercase; + white-space: nowrap; + border-radius: 16px; + text-shadow: none; + margin: .125em 0 .125em .4em; + text-align: center + } + + .ifacebadge, + .ifacebox .ifacebox-head[style], + .zonebadge { + text-shadow: 0 1px 1px hsla(var(--background-color-high-hsl), .75) + } + + header [data-indicator][data-clickable] { + cursor: pointer; + transition: .3s + } + + .nav .dropdown-menu a.menu, + a.label:link, + a.label:visited { + color: #fff + } + + .label.important { + background-color: var(--primary-color-high); + color: var(--on-primary-color) + } + + .label.warning { + background-color: var(--warn-color-high); + color: var(--on-warn-color) + } + + .label.success { + background-color: var(--success-color-high); + color: var(--on-success-color) + } + + .label.notice, + header [data-indicator][data-style=active] { + color: var(--on-primary-color); + background-color: var(--primary-color-high) + } + + form.inline { + display: inline; + margin-bottom: 0 + } + + #syslog { width: 100%; color: var(--text-color-highest); margin-bottom: 18px; font-family: consolas, monospace -} + } -.cbi-section-table-descr.named::before, -.cbi-section-table-row[data-title]::before, -.cbi-section-table-titles.named::before { - content: attr(data-title) " "; - display: table-cell; - padding: 10px 10px 9px; - line-height: 18px; - font-weight: 700; - vertical-align: middle -} + .cbi-section-table-descr.named::before, + .cbi-section-table-row[data-title]::before, + .cbi-section-table-titles.named::before { + content: attr(data-title) " "; + display: table-cell; + padding: 10px 10px 9px; + line-height: 18px; + font-weight: 700; + vertical-align: middle + } -.left { - text-align: left !important -} + .left { + text-align: left !important + } -.right { - text-align: right !important -} + .right { + text-align: right !important + } -.center { - text-align: center !important -} + .center { + text-align: center !important + } -.top { - vertical-align: top !important -} + .top { + vertical-align: top !important + } -.middle { - vertical-align: middle !important -} + .middle { + vertical-align: middle !important + } -.bottom { - vertical-align: bottom !important -} + .bottom { + vertical-align: bottom !important + } -.cbi-value-field table td, -table table td { - border: none -} + .cbi-value-field table td, + table table td { + border: none + } -.table.cbi-section-table .cbi-select, -.table.cbi-section-table input[type=password], -.table.cbi-section-table input[type=text], -.table.cbi-section-table select, -.table.cbi-section-table textarea { - width: 100%; - min-width: auto -} + .table.cbi-section-table .cbi-select, + .table.cbi-section-table input[type=password], + .table.cbi-section-table input[type=text], + .table.cbi-section-table select, + .table.cbi-section-table textarea { + width: 100%; + min-width: auto + } -.table.cbi-section-table .td.cbi-section-table-cell { - white-space: nowrap; - text-align: right -} + .table.cbi-section-table .td.cbi-section-table-cell { + white-space: nowrap; + text-align: right + } -.table.cbi-section-table .td.cbi-section-table-cell .cbi-select, -.table.cbi-section-table .td.cbi-section-table-cell select { - width: inherit -} + .table.cbi-section-table .td.cbi-section-table-cell .cbi-select, + .table.cbi-section-table .td.cbi-section-table-cell select { + width: inherit + } -.td.cbi-section-actions { - text-align: right; - width: 15% -} + .td.cbi-section-actions { + text-align: right; + width: 15% + } -.td.cbi-section-actions>*>form>*, -.td.cbi-section-actions>:not(.cbi-dropdown)>* { - flex: 1 1 4em; - border-radius: 1rem -} + .td.cbi-section-actions>*>form>*, + .td.cbi-section-actions>:not(.cbi-dropdown)>* { + flex: 1 1 4em; + border-radius: 1rem + } -.td.cbi-section-actions>*>form { - display: inline-flex; - margin: 0 -} + .td.cbi-section-actions>*>form { + display: inline-flex; + margin: 0 + } -.cbi-rowstyle-2, -.dropdown-menu>li>a:hover, -.tr.cbi-section-table-titles, -.tr.table-titles { - background: var(--background-color-medium) -} + .cbi-rowstyle-2, + .dropdown-menu>li>a:hover, + .tr.cbi-section-table-titles, + .tr.table-titles { + background: var(--background-color-medium) + } -th[data-sort-direction=asc]::after { - content: "\a0\25b2" -} + th[data-sort-direction=asc]::after { + content: "\a0\25b2" + } -th[data-sort-direction=desc]::after { - content: "\a0\25bc" -} + th[data-sort-direction=desc]::after { + content: "\a0\25bc" + } -.cbi-value-description { - margin: .25em 0 0 1.25em; - position: relative -} + .cbi-value-description { + margin: .25em 0 0 1.25em; + position: relative + } -.cbi-value-description:not(:empty)::before { - --help-icon: url("data:image/svg+xml,"); - position: absolute; - left: -1.25em; - content: "\a0"; - display: inline-block; - width: 1em; - height: 1em; - margin-right: .25em; - margin-top: .25em; - background: var(--primary-color-high); - mask-image: var(--help-icon); - mask-size: cover; - -webkit-mask-image: var(--help-icon); - -webkit-mask-size: cover -} + .cbi-value-description:not(:empty)::before { + --help-icon: url("data:image/svg+xml,"); + position: absolute; + left: -1.25em; + content: "\a0"; + display: inline-block; + width: 1em; + height: 1em; + margin-right: .25em; + margin-top: .25em; + background: var(--primary-color-high); + mask-image: var(--help-icon); + mask-size: cover; + -webkit-mask-image: var(--help-icon); + -webkit-mask-size: cover + } -.cbi-section-error { - border: 1px solid red; - border-radius: 3px; - background-color: #fce6e6; - padding: 5px; - margin-bottom: 18px -} + .cbi-section-error { + border: 1px solid red; + border-radius: 3px; + background-color: #fce6e6; + padding: 5px; + margin-bottom: 18px + } -.ifacebadge, -.ifacebox { - border: 1px solid var(--border-color-high); - line-height: 1.2em; - white-space: nowrap -} + .ifacebadge, + .ifacebox { + border: 1px solid var(--border-color-high); + line-height: 1.2em; + white-space: nowrap + } -.cbi-section-error ul { - margin: 0 0 0 20px -} + .cbi-section-error ul { + margin: 0 0 0 20px + } -.cbi-section-error ul li { - color: red; - font-weight: 700 -} + .cbi-section-error ul li { + color: red; + font-weight: 700 + } -.ifacebox { - text-align: center; - background: linear-gradient(var(--background-color-high), var(--background-color-medium)); - box-shadow: inset 0 1px 0 hsla(var(--text-color-low-hsl), .05); - display: inline-flex; - flex-direction: column; - min-width: 100px -} + .ifacebox { + text-align: center; + background: linear-gradient(var(--background-color-high), var(--background-color-medium)); + box-shadow: inset 0 1px 0 hsla(var(--text-color-low-hsl), .05); + display: inline-flex; + flex-direction: column; + min-width: 100px + } -.ifacebox .ifacebox-head { - border-bottom: 1px solid var(--border-color-high); - padding: 2px; - background: #eee -} + .ifacebox .ifacebox-head { + border-bottom: 1px solid var(--border-color-high); + padding: 2px; + background: #eee + } -[data-darkmode=true] .ifacebox-head[style], -[data-darkmode=true] .zonebadge[style] { - background: linear-gradient(rgba(var(--zone-color-rgb), .4), rgba(var(--zone-color-rgb), .3)) !important -} + [data-darkmode=true] .ifacebox-head[style], + [data-darkmode=true] .zonebadge[style] { + background: linear-gradient(rgba(var(--zone-color-rgb), .4), rgba(var(--zone-color-rgb), .3)) !important + } -.ifacebox .ifacebox-body { - padding: .25em -} + .ifacebox .ifacebox-body { + padding: .25em + } -.ifacebadge { - display: inline-block; - flex-direction: row; - box-shadow: inset 0 1px 0 hsla(var(--background-color-high-hsl), .05); - cursor: default -} + .ifacebadge { + display: inline-block; + flex-direction: row; + box-shadow: inset 0 1px 0 hsla(var(--background-color-high-hsl), .05); + cursor: default + } -.ifacebadge img { - width: 16px; - height: 16px -} + .ifacebadge img { + width: 16px; + height: 16px + } -.ifacebadge-active { - border-color: #000; - font-weight: 700 -} + .ifacebadge-active { + border-color: #000; + font-weight: 700 + } -.network-status-table .ifacebox { - margin: .5em; - flex-grow: 1 -} + .network-status-table .ifacebox { + margin: .5em; + flex-grow: 1 + } -.network-status-table .ifacebox-body { - display: flex; - flex-direction: column; - height: 100%; - text-align: left -} + .network-status-table .ifacebox-body { + display: flex; + flex-direction: column; + height: 100%; + text-align: left + } -.network-status-table .ifacebox-body>* { - margin: .25em -} + .network-status-table .ifacebox-body>* { + margin: .25em + } -.network-status-table .ifacebox-body>span { - flex: 10 10 auto; - height: 100% -} + .network-status-table .ifacebox-body>span { + flex: 10 10 auto; + height: 100% + } -.network-status-table .ifacebox-body>div { - margin: -.125em; - display: flex; - flex-wrap: wrap -} + .network-status-table .ifacebox-body>div { + margin: -.125em; + display: flex; + flex-wrap: wrap + } -#dsl_status_table .ifacebox-body span>strong { + #dsl_status_table .ifacebox-body span>strong { display: inline-block; min-width: 35% -} + } -.ifacebadge.large, -.network-status-table .ifacebox-body .ifacebadge { - display: flex; - flex: 1; - min-width: 220px; - margin: .125em -} + .ifacebadge.large, + .network-status-table .ifacebox-body .ifacebadge { + display: flex; + flex: 1; + min-width: 220px; + margin: .125em + } -.ifacebadge.large { - display: inline-flex -} + .ifacebadge.large { + display: inline-flex + } -.network-status-table .ifacebox-body .ifacebadge>span, -.uci-change-list>var>* { - overflow: hidden; - text-overflow: ellipsis -} + .network-status-table .ifacebox-body .ifacebadge>span, + .uci-change-list>var>* { + overflow: hidden; + text-overflow: ellipsis + } -.ifacebadge.large>*, -.ifacebadge>* { - margin: 0 .125em -} + .ifacebadge.large>*, + .ifacebadge>* { + margin: 0 .125em + } -.zonebadge { - padding: 2px; - border-radius: 1rem; - display: inline-block; - white-space: nowrap -} + .zonebadge { + padding: 2px; + border-radius: 1rem; + display: inline-block; + white-space: nowrap + } -.zonebadge>em, -.zonebadge>strong { - margin: 0 2px; - display: inline-block -} + .zonebadge>em, + .zonebadge>strong { + margin: 0 2px; + display: inline-block + } -.zonebadge input { - width: 6em -} + .zonebadge input { + width: 6em + } -.zonebadge>.ifacebadge { - margin-left: 2px -} + .zonebadge>.ifacebadge { + margin-left: 2px + } -.zonebadge-empty { - border: 1px dashed #aaa; - color: #aaa; - font-style: italic; - font-size: smaller -} + .zonebadge-empty { + border: 1px dashed #aaa; + color: #aaa; + font-style: italic; + font-size: smaller + } -.td.cbi-value-field var, -div.cbi-value var { - font-style: italic; - color: #0069d6 -} + .td.cbi-value-field var, + div.cbi-value var { + font-style: italic; + color: #0069d6 + } -.td.cbi-value-field var.cbi-tooltip-container, -.td.cbi-value-field var[data-tooltip], -div.cbi-value var.cbi-tooltip-container, -div.cbi-value var[data-tooltip] { - cursor: help; - border-bottom: 1px dotted #0069d6 -} + .td.cbi-value-field var.cbi-tooltip-container, + .td.cbi-value-field var[data-tooltip], + div.cbi-value var.cbi-tooltip-container, + div.cbi-value var[data-tooltip] { + cursor: help; + border-bottom: 1px dotted #0069d6 + } -.td.cbi-value-field var.cbi-tooltip-container .cbi-tooltip, -div.cbi-value var.cbi-tooltip-container { - font-style: normal; - white-space: normal; - color: var(--text-color-high) -} + .td.cbi-value-field var.cbi-tooltip-container .cbi-tooltip, + div.cbi-value var.cbi-tooltip-container { + font-style: normal; + white-space: normal; + color: var(--text-color-high) + } -#modal_overlay>.modal.cbi-modal, -#modal_overlay>.modal.uci-dialog { + #modal_overlay>.modal.cbi-modal, + #modal_overlay>.modal.uci-dialog { max-width: 900px -} + } -#modal_overlay>.modal.login>button.important { + #modal_overlay>.modal.login>button.important { font-size: 120% !important; margin-top: .5em; width: 100% -} + } -.uci-change-list { - line-height: 170%; - white-space: pre -} + .uci-change-list { + line-height: 170%; + white-space: pre + } -.cbi-filebrowser>*, -.dropdown-menu li a { - white-space: nowrap; - text-overflow: ellipsis -} + .cbi-filebrowser>*, + .dropdown-menu li a { + white-space: nowrap; + text-overflow: ellipsis + } -.uci-dialog div>del, -.uci-dialog div>ins, -.uci-dialog div>var { - margin-bottom: 2px; - border: 1px solid var(--border-color-high); - line-height: 15px; - overflow: hidden; - text-overflow: ellipsis; - padding: 2px; - position: relative; - background-color: var(--background-color-low) -} + .uci-dialog div>del, + .uci-dialog div>ins, + .uci-dialog div>var { + margin-bottom: 2px; + border: 1px solid var(--border-color-high); + line-height: 15px; + overflow: hidden; + text-overflow: ellipsis; + padding: 2px; + position: relative; + background-color: var(--background-color-low) + } -.nav .dropdown-menu li a, -.nav>li>a { - padding: 1rem 1.5rem; - line-height: 1.5rem; -} + .nav .dropdown-menu li a, + .nav>li>a { + padding: 1rem 1.5rem; + line-height: 1.5rem; + } -.uci-dialog div>ins { - background-color: rgba(var(--success-color-high-rgb), .3); - border-color: rgba(var(--success-color-high-rgb), .6) -} + .uci-dialog div>ins { + background-color: rgba(var(--success-color-high-rgb), .3); + border-color: rgba(var(--success-color-high-rgb), .6) + } -.uci-dialog div>del { - background-color: rgba(var(--error-color-high-rgb), .3); - border-color: rgba(var(--error-color-high-rgb), .6) -} + .uci-dialog div>del { + background-color: rgba(var(--error-color-high-rgb), .3); + border-color: rgba(var(--error-color-high-rgb), .6) + } -.uci-dialog var>ins { - background-color: rgba(var(--success-color-high-rgb), .3) -} + .uci-dialog var>ins { + background-color: rgba(var(--success-color-high-rgb), .3) + } -.uci-dialog var>del { - background-color: rgba(var(--error-color-high-rgb), .3) -} + .uci-dialog var>del { + background-color: rgba(var(--error-color-high-rgb), .3) + } -.uci-dialog del, -.uci-dialog ins, -.uci-dialog var { - text-decoration: none; - font-family: monospace; - font-style: normal; - color: var(--text-color-high); - display: block -} + .uci-dialog del, + .uci-dialog ins, + .uci-dialog var { + text-decoration: none; + font-family: monospace; + font-style: normal; + color: var(--text-color-high); + display: block + } -.uci-change-legend-label { - flex-basis: 150px; - margin: 2px; - display: flex; - align-items: center -} + .uci-change-legend-label { + flex-basis: 150px; + margin: 2px; + display: flex; + align-items: center + } -.uci-change-legend-label>del, -.uci-change-legend-label>ins, -.uci-change-legend-label>var { - margin-right: 4px; - width: 16px; - height: 16px; - display: flex -} + .uci-change-legend-label>del, + .uci-change-legend-label>ins, + .uci-change-legend-label>var { + margin-right: 4px; + width: 16px; + height: 16px; + display: flex + } -.uci-change-legend-label>*>* { - flex-basis: 100%; - padding: 1px -} + .uci-change-legend-label>*>* { + flex-basis: 100%; + padding: 1px + } -#applyreboot-section { + #applyreboot-section { line-height: 300% -} - -@keyframes flash { - - 0%, - 100% { - opacity: 1 } - 50% { - opacity: .5 + @keyframes flash { + + 0%, + 100% { + opacity: 1 + } + + 50% { + opacity: .5 + } } -} -.flash { - animation: .35s flash -} + .flash { + animation: .35s flash + } -#view>div.spinning:first-child { + #view>div.spinning:first-child { display: table; margin: 15vh auto -} - -.spinning { - position: relative; - padding-left: 32px !important -} - -.sidebar, -.sidebar-overlay { - position: fixed; - top: var(--header-height); - left: 0; - bottom: 0 -} - -.spinning::before { - --spinner-icon: url("data:image/svg+xml,"); - position: absolute; - top: calc(50% - 10px); - left: 6px; - width: 20px; - height: 20px; - content: " "; - background: var(--on-color, #000); - mask: var(--spinner-icon) center/cover no-repeat; - -webkit-mask: var(--spinner-icon) center/cover no-repeat -} - -[data-darkmode=true] .spinning::before { - background: var(--on-color, #fff) -} - -[data-tab-title] { - height: 0; - opacity: 0; - overflow: hidden -} - -.cbi-filebrowser.open, -[data-tab-active=true] { - opacity: 1; - height: auto; - overflow: visible; - transition: opacity .25s ease-in -} - -.cbi-filebrowser { - min-width: 210px; - max-width: 100%; - border: 1px solid #ccc; - border-radius: 3px; - display: flex; - flex-direction: column; - opacity: 0; - height: 0; - overflow: hidden -} - -.cbi-filebrowser>* { - max-width: 100%; - overflow: hidden; - padding: 0 0 .25em; - margin: .25em .25em 0; - border-bottom: 1px solid #ccc -} - -.cbi-filebrowser>div { - border-bottom: none -} - -.cbi-filebrowser>ul>li { - display: flex; - flex-direction: row -} - -.cbi-filebrowser>ul>li:hover { - background: #f5f5f5 -} - -.cbi-filebrowser>ul>li>div:first-child { - flex: 10; - overflow: hidden; - text-overflow: ellipsis -} - -.cbi-filebrowser>ul>li>div:last-child { - flex: 3; - text-align: right -} - -.cbi-filebrowser>ul>li>div:last-child>button { - padding: .125em .25em; - margin: 1px 0 1px .25em -} - -.cbi-filebrowser .upload { - display: flex; - flex-direction: row; - flex-wrap: wrap; - margin: 0 -.125em .25em; - padding: 0 0 .125em; - border-bottom: 1px solid #ccc -} - -.cbi-filebrowser .upload>* { - margin: .125em; - flex: 1 -} - -.cbi-filebrowser .upload>.btn { - flex-basis: 60px -} - -.cbi-filebrowser .upload>div { - flex: 10; - min-width: 150px -} - -@keyframes fade-in { - 0% { - opacity: 0 } - 100% { - opacity: 1 - } -} - -@keyframes fade-out { - 0% { - opacity: 1 + .spinning { + position: relative; + padding-left: 32px !important } - 100% { - opacity: 0 + .sidebar, + .sidebar-overlay { + position: fixed; + top: var(--header-height); + left: 0; + bottom: 0 } -} -.fade-in { - animation: .4s fade-in -} + .spinning::before { + --spinner-icon: url("data:image/svg+xml,"); + position: absolute; + top: calc(50% - 10px); + left: 6px; + width: 20px; + height: 20px; + content: " "; + background: var(--on-color, #000); + mask: var(--spinner-icon) center/cover no-repeat; + -webkit-mask: var(--spinner-icon) center/cover no-repeat + } -.fade-out { - animation: .4s fade-out -} + [data-darkmode=true] .spinning::before { + background: var(--on-color, #fff) + } -.assoclist .ifacebadge { - display: flex; - flex-direction: column; - align-items: center; - white-space: normal; - text-align: center -} + [data-tab-title] { + height: 0; + opacity: 0; + overflow: hidden + } -.assoclist .ifacebadge>img { - margin: .2em -} + .cbi-filebrowser.open, + [data-tab-active=true] { + opacity: 1; + height: auto; + overflow: visible; + transition: opacity .25s ease-in + } -.assoclist .td:nth-of-type(3), -.assoclist .td:nth-of-type(5) { - width: 25% -} + .cbi-filebrowser { + min-width: 210px; + max-width: 100%; + border: 1px solid #ccc; + border-radius: 3px; + display: flex; + flex-direction: column; + opacity: 0; + height: 0; + overflow: hidden + } -.assoclist .td:nth-of-type(6) button { - word-break: normal -} + .cbi-filebrowser>* { + max-width: 100%; + overflow: hidden; + padding: 0 0 .25em; + margin: .25em .25em 0; + border-bottom: 1px solid #ccc + } -[data-darkmode=true] [data-page=admin-statistics-graphs] [data-plugin] img { - filter: invert(100%) hue-rotate(150deg) -} + .cbi-filebrowser>div { + border-bottom: none + } -[data-page=admin-system-admin-sshkeys] .cbi-dynlist { - max-width: none -} + .cbi-filebrowser>ul>li { + display: flex; + flex-direction: row + } -[data-page=admin-status-iptables] .cbi-tabmenu { - margin-top: 28px -} + .cbi-filebrowser>ul>li:hover { + background: #f5f5f5 + } -[data-page=admin-status-processes] .table .td { - word-break: break-all -} + .cbi-filebrowser>ul>li>div:first-child { + flex: 10; + overflow: hidden; + text-overflow: ellipsis + } -[data-darkmode=true] [data-page=admin-status-channel_analysis] #view>div>div>div>div>div[style], -[data-darkmode=true] [data-page=admin-status-realtime-bandwidth] #view>div>div>div>div[style], -[data-darkmode=true] [data-page=admin-status-realtime-connections] #view>div>div>div[style], -[data-darkmode=true] [data-page=admin-status-realtime-load] #view>div>div>div[style], -[data-darkmode=true] [data-page=admin-status-realtime-wireless] #view>div>div>div>div[style] { - background-color: var(--background-color-high) !important -} + .cbi-filebrowser>ul>li>div:last-child { + flex: 3; + text-align: right + } -[data-darkmode=true] [data-page=admin-status-channel_analysis] #view>div>div>div>div>div>svg>line[style], -[data-darkmode=true] [data-page=admin-status-realtime-bandwidth] #view>div>div>div>div>svg>line[style], -[data-darkmode=true] [data-page=admin-status-realtime-connections] #view>div>div>div>svg>line[style], -[data-darkmode=true] [data-page=admin-status-realtime-load] #view>div>div>div>svg>line[style], -[data-darkmode=true] [data-page=admin-status-realtime-wireless] #view>div>div>div>div>svg>line[style] { - stroke: #fff !important -} + .cbi-filebrowser>ul>li>div:last-child>button { + padding: .125em .25em; + margin: 1px 0 1px .25em + } -#maincontent { + .cbi-filebrowser .upload { + display: flex; + flex-direction: row; + flex-wrap: wrap; + margin: 0 -.125em .25em; + padding: 0 0 .125em; + border-bottom: 1px solid #ccc + } + + .cbi-filebrowser .upload>* { + margin: .125em; + flex: 1 + } + + .cbi-filebrowser .upload>.btn { + flex-basis: 60px + } + + .cbi-filebrowser .upload>div { + flex: 10; + min-width: 150px + } + + @keyframes fade-in { + 0% { + opacity: 0 + } + + 100% { + opacity: 1 + } + } + + @keyframes fade-out { + 0% { + opacity: 1 + } + + 100% { + opacity: 0 + } + } + + .fade-in { + animation: .4s fade-in + } + + .fade-out { + animation: .4s fade-out + } + + .assoclist .ifacebadge { + display: flex; + flex-direction: column; + align-items: center; + white-space: normal; + text-align: center + } + + .assoclist .ifacebadge>img { + margin: .2em + } + + .assoclist .td:nth-of-type(3), + .assoclist .td:nth-of-type(5) { + width: 25% + } + + .assoclist .td:nth-of-type(6) button { + word-break: normal + } + + [data-darkmode=true] [data-page=admin-statistics-graphs] [data-plugin] img { + filter: invert(100%) hue-rotate(150deg) + } + + [data-page=admin-system-admin-sshkeys] .cbi-dynlist { + max-width: none + } + + [data-page=admin-status-iptables] .cbi-tabmenu { + margin-top: 28px + } + + [data-page=admin-status-processes] .table .td { + word-break: break-all + } + + [data-darkmode=true] [data-page=admin-status-channel_analysis] #view>div>div>div>div>div[style], + [data-darkmode=true] [data-page=admin-status-realtime-bandwidth] #view>div>div>div>div[style], + [data-darkmode=true] [data-page=admin-status-realtime-connections] #view>div>div>div[style], + [data-darkmode=true] [data-page=admin-status-realtime-load] #view>div>div>div[style], + [data-darkmode=true] [data-page=admin-status-realtime-wireless] #view>div>div>div>div[style] { + background-color: var(--background-color-high) !important + } + + [data-darkmode=true] [data-page=admin-status-channel_analysis] #view>div>div>div>div>div>svg>line[style], + [data-darkmode=true] [data-page=admin-status-realtime-bandwidth] #view>div>div>div>div>svg>line[style], + [data-darkmode=true] [data-page=admin-status-realtime-connections] #view>div>div>div>svg>line[style], + [data-darkmode=true] [data-page=admin-status-realtime-load] #view>div>div>div>svg>line[style], + [data-darkmode=true] [data-page=admin-status-realtime-wireless] #view>div>div>div>div>svg>line[style] { + stroke: #fff !important + } + + #maincontent { grid-area: main; padding: 1rem; overflow-x: hidden; min-height: calc(100vh - var(--header-height)); width: 100%; box-sizing: border-box -} - -.sidebar { - grid-area: sidebar; - width: var(--sidebar-width); - background: var(--background-color-low); - border-right: 0px solid var(--border-color-medium); - padding: 0; - overflow-y: auto; - transition: transform .3s; - font-size: 1rem; -} - -.sidebar-overlay { - display: block; - right: 0; - background: rgba(0, 0, 0, .5); - z-index: 800; - transition: .3s; - opacity: 0; - visibility: hidden -} - -.nav { - flex-direction: column; - margin: 0; - padding: 1rem; - float: none -} - -.nav>li { - width: 100%; - float: none -} - -.nav>li>a { - align-items: center; - color: var(--text-color-high); - border-radius: 2rem -} - -.nav>li>a::before { - content: ''; - width: 1.5rem; - height: 1.5rem; - margin-right: 1rem; - background-color: var(--text-color-medium); - -webkit-mask: url("icons/other.svg") center/contain no-repeat; - mask: url("icons/other.svg") center/contain no-repeat; - transition: background-color .3s -} - -.nav>li[data-path="admin/status"]>a::before { - -webkit-mask: url("icons/status.svg") center/contain no-repeat; - mask: url("icons/status.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/system"]>a::before { - -webkit-mask: url("icons/system.svg") center/contain no-repeat; - mask: url("icons/system.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/services"]>a::before { - -webkit-mask: url("icons/services.svg") center/contain no-repeat; - mask: url("icons/services.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/network"]>a::before { - -webkit-mask: url("icons/network.svg") center/contain no-repeat; - mask: url("icons/network.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/nas"]>a::before { - -webkit-mask: url("icons/nas.svg") center/contain no-repeat; - mask: url("icons/nas.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/docker"]>a::before { - -webkit-mask: url("icons/docker.svg") center/contain no-repeat; - mask: url("icons/docker.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/modem"]>a::before { - -webkit-mask: url("icons/modem.svg") center/contain no-repeat; - mask: url("icons/modem.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/vpn"]>a::before { - -webkit-mask: url("icons/vpn.svg") center/contain no-repeat; - mask: url("icons/vpn.svg") center/contain no-repeat -} - -.nav>li[data-path="admin/logout"]>a::before { - -webkit-mask: url("icons/logout.svg") center/contain no-repeat; - mask: url("icons/logout.svg") center/contain no-repeat -} - -.nav>li.active>a::before, -.nav>li>a:hover::before { - background-color: var(--text-color-highest) -} - -.nav>li.active>a, -.nav>li>a:hover { - color: var(--text-color-highest) -} - -.nav .dropdown-menu li a:hover { - background-color: #191919; - background-repeat: repeat-x; - background-image: linear-gradient(to bottom, #292929, #191919); - color: #fff -} - -.nav>li.dropdown>a::after { - opacity: 1; - transition: transform .3s -} - -.nav>li.dropdown.open>a::after { - transform: rotate(225deg) -} - -.menu-btn { - display: none; - align-items: center; - justify-content: center; - width: 2.5rem; - height: 2.5rem; - margin-left: .5rem; - cursor: pointer; - color: var(--md-sys-color-font) -} - -.menu-btn span { - position: relative; - display: block; - width: 20px; - height: 2px; - background: currentColor; - transition: .3s -} - -.menu-btn span::after, -.menu-btn span::before { - content: ''; - position: absolute; - width: 100%; - height: 100%; - background: currentColor; - transition: .3s -} - -.menu-btn span::before { - transform: translateY(-6px) -} - -.menu-btn span::after { - transform: translateY(6px) -} - -.cbi-rowstyle-2, -.menu-btn.active span, -.tr.cbi-section-table-titles, -.tr.table-titles { - background: 0 0 -} - -.menu-btn.active span::after { - transform: rotate(-45deg) -} - -.nav>li>a { - align-items: center; - transition: .3s -} - -.nav>li>a::after { - content: ''; - width: .5rem; - height: .5rem; - border-right: 2px solid var(--text-color-medium); - border-bottom: 2px solid var(--text-color-medium); - transition: transform .3s; - opacity: 0 -} - -.nav>li>a:hover::after { - opacity: 1 -} - -.dropdown-menu { - background: var(--background-color-low); - background: var(--background-color-low); - padding: 0; - margin: 0; - border: none; - border-radius: 0; - box-shadow: none -} - -.dropdown-menu>li>a { - color: var(--text-color-medium); - transition: .3s; - padding: .6rem 1.5rem .6rem 3rem; - color: var(--text-color-medium); - display: block -} - -.dropdown-menu>li { - position: relative; - border-radius: 2rem; - transition: background-color .3s -} - -.dropdown-menu>li:hover { - background: rgba(0, 0, 0, .05); - border-radius: 2rem -} - -.dropdown-menu>li.active { - border-left-color: var(--primary-color-high); - background: var(--md-sys-color-primary-container); - transition: background-color .3s -} - -.dropdown-menu>li.active:hover { - background: var(--md-sys-color-primary-container-hover); - transition: background-color .3s -} - -body { - background: var(--md-sys-color-surface); - --background-color-high: var(--md-sys-color-surface); - --background-color-low: var(--md-sys-color-surface); - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale -} - -body, -button, -input { - font-family: "Segoe UI Variable Display", "Google Sans", "Product Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Ubuntu, sans-serif -} - -header .pull-right { - /* padding-top: 0; */ - /* display: flex; */ -} - -h1, -h2, -h3 { - font-weight: 350 -} - -header .brand { - /* padding: 0 57px 1px; */ - width: var(--sidebar-width); - font-size: 25px; - line-height: 40px -} - -.label, -header [data-indicator] { - font-size: 12px; - padding: 4px 8px -} - -.actions, -.cbi-page-actions { - border: none; - padding: 8px 16px -} - -.cbi-section-node { - padding: 4px 8px -} - -.cbi-section-node, -.create-item-input, -.ifacebox, -.table, -table { - background: var(--md-sys-color-card); - border-radius: 16px; - box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%); - margin: 1px; - width: calc(100% - 2px); -} - -.cbi-dropdown>ul>li input[type=text] { - height: 30px; - border-radius: 6px; - border: none -} - -.ifacebox .ifacebox-head { - border-radius: 1rem 1rem 0 0; - opacity: .9 -} - -.nav .dropdown-menu { - position: static !important; - float: none; - min-width: 100%; - padding: 0; - margin: 0; - border-radius: 0; - background: var(--background-color-medium); - height: 0; - transition: height .3s ease-in-out; - overflow: hidden -} - -.nav .dropdown-menu, -header { - border: none; - backdrop-filter: blur(15px); - box-shadow: none; - background: var(--md-sys-color-surface-translucent); -} - -#localtime, -.btn, -.cbi-button, -.cbi-dropdown, -.cbi-dropdown:not(.btn):not(.cbi-button), -.cbi-dynlist>.item, -.cbi-input-text, -.cbi-page-actions .cbi-button-apply, -.cbi-page-actions .cbi-button-apply+.cbi-button-save, -.cbi-page-actions .cbi-button-negative+.cbi-button-save, -select, -textarea { - border-radius: 1rem; - text-shadow: none; - padding: 1px 10px; - box-shadow: none; - /* color: var(--md-sys-color-primary); */ -} - -textarea { - overflow: auto; - vertical-align: top; - font-family: consolas, monospace; - color: var(--md-sys-color-font) -} - -.cbi-dynlist>.item { - padding: 6px 10px -} - -.cbi-dynlist>.item::after { - background: 0 0; - box-shadow: none; - border-left: none; -} - -.label.notice, -header [data-indicator][data-style=active] { - background: var(--md-sys-color-refresh-button); -} - -header [data-indicator][data-style=active]:hover { - background: var(--md-sys-color-refresh-button-hover); -} - -header [data-indicator][data-style=inactive]:hover { - background: rgba(0, 0, 0, .05) -} - -.dropdown-menu li a { - border-radius: 2rem; - overflow: hidden -} - -.dropdown-menu li a:hover { - border-radius: 2rem; - background: 0 0 !important; - color: var(--text-color-highest) !important -} - -.nav>li>.dropdown-menu { - padding-left: 2.5rem -} - -.nav>li.open>.dropdown-menu { - display: block; - background: 0 0 -} - -.nav>li:has(>.dropdown-menu>li.active) { - border-radius: 2rem 2rem 0 0 -} - -.nav>li:has(>.dropdown-menu>li.active)>a { - color: var(--text-color-highest) !important -} - -.cbi-progressbar { - background: var(--md-sys-color-progressbar); - border: none; - /* border-radius: 20px; */ -} - -.cbi-progressbar>div { - /* border-radius: 20px; */ -} - -.table .td, -.table .th { - border-top: none -} - -.td.cbi-section-actions>*>*, -.td.cbi-section-actions>*>form>* { - margin: 0; - border-radius: 0 -} - -.td.cbi-section-actions>*>:first-child { - border-radius: 1rem -} - -.td.cbi-section-actions>*>:last-child { - border-radius: 1rem; - border: none; - background: var(--md-sys-color-primary-container); - color: var(--md-sys-color-font) -} - -.ifacebadge, -.ifacebadge.large, -.network-status-table .ifacebox-body .ifacebadge { - padding: 8px; - border: 1px solid #aaa; - box-shadow: none; - border-radius: 1rem -} - -.network-status-table { - width: calc(100% + 16px); - position: relative; - left: -8px; - margin-bottom: 8px -} - -.ifacebox .ifacebox-head.active { - background: 0 0; - border: none; - color: var(--md-sys-color-font); - text-shadow: none -} - -.network-status-table .ifacebox { - border: none; - box-shadow: none; - padding: 8px; - box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%) -} - -[data-page^=admin-services-openclash] .tabs>li:last-child { - justify-content: center -} - -[data-page^=admin-services-openclash] ul li a { - margin: auto -} - -.cbi-section h3 { - padding-left: 0 -} - -.cbi-modal h4 { - text-align: center -} - -.cbi-value, -form .clearfix { - margin: 16px 0 -} - -.cbi-tabmenu>li, -.dropdown-menu>li>a, -.nav>li>a, -.tabs>li { - position: relative; - overflow: hidden -} - -.cbi-tabmenu>.cbi-tab:hover { - background: var(--md-sys-color-primary-container-hover); -} - -.ripple { - position: absolute; - width: 200px; - height: 200px; - margin-left: -100px; - margin-top: -100px; - border-radius: 50%; - background: rgba(0, 0, 0, .15); - transform: scale(0); - pointer-events: none; - animation: 1s ease-out ripple -} - -@keyframes ripple { - from { - transform: scale(0); + } + + .sidebar { + grid-area: sidebar; + width: var(--sidebar-width); + background: var(--background-color-low); + border-right: 0px solid var(--border-color-medium); + padding: 0; + overflow-y: auto; + transition: transform .3s; + font-size: 1rem; + } + + .sidebar-overlay { + display: block; + right: 0; + background: rgba(0, 0, 0, .5); + z-index: 800; + transition: .3s; + opacity: 0; + visibility: hidden + } + + .nav { + flex-direction: column; + margin: 0; + padding: 1rem; + float: none + } + + .nav>li { + width: 100%; + float: none + } + + .nav>li>a { + align-items: center; + color: var(--text-color-high); + border-radius: 2rem + } + + .nav>li>a::before { + content: ''; + width: 1.5rem; + height: 1.5rem; + margin-right: 1rem; + background-color: var(--text-color-medium); + -webkit-mask: url("icons/other.svg") center/contain no-repeat; + mask: url("icons/other.svg") center/contain no-repeat; + transition: background-color .3s + } + + .nav>li[data-path="admin/status"]>a::before { + -webkit-mask: url("icons/status.svg") center/contain no-repeat; + mask: url("icons/status.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/system"]>a::before { + -webkit-mask: url("icons/system.svg") center/contain no-repeat; + mask: url("icons/system.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/services"]>a::before { + -webkit-mask: url("icons/services.svg") center/contain no-repeat; + mask: url("icons/services.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/network"]>a::before { + -webkit-mask: url("icons/network.svg") center/contain no-repeat; + mask: url("icons/network.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/nas"]>a::before { + -webkit-mask: url("icons/nas.svg") center/contain no-repeat; + mask: url("icons/nas.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/docker"]>a::before { + -webkit-mask: url("icons/docker.svg") center/contain no-repeat; + mask: url("icons/docker.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/modem"]>a::before { + -webkit-mask: url("icons/modem.svg") center/contain no-repeat; + mask: url("icons/modem.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/vpn"]>a::before { + -webkit-mask: url("icons/vpn.svg") center/contain no-repeat; + mask: url("icons/vpn.svg") center/contain no-repeat + } + + .nav>li[data-path="admin/logout"]>a::before { + -webkit-mask: url("icons/logout.svg") center/contain no-repeat; + mask: url("icons/logout.svg") center/contain no-repeat + } + + .nav>li.active>a::before, + .nav>li>a:hover::before { + background-color: var(--text-color-highest) + } + + .nav>li.active>a, + .nav>li>a:hover { + color: var(--text-color-highest) + } + + .nav .dropdown-menu li a:hover { + background-color: #191919; + background-repeat: repeat-x; + background-image: linear-gradient(to bottom, #292929, #191919); + color: #fff + } + + .nav>li.dropdown>a::after { + opacity: 1; + transition: transform .3s + } + + .nav>li.dropdown.open>a::after { + transform: rotate(225deg) + } + + .menu-btn { + display: none; + align-items: center; + justify-content: center; + width: 2.5rem; + height: 2.5rem; + margin-left: .5rem; + cursor: pointer; + color: var(--md-sys-color-font) + } + + .menu-btn span { + position: relative; + display: block; + width: 20px; + height: 2px; + background: currentColor; + transition: .3s + } + + .menu-btn span::after, + .menu-btn span::before { + content: ''; + position: absolute; + width: 100%; + height: 100%; + background: currentColor; + transition: .3s + } + + .menu-btn span::before { + transform: translateY(-6px) + } + + .menu-btn span::after { + transform: translateY(6px) + } + + .cbi-rowstyle-2, + .menu-btn.active span, + .tr.cbi-section-table-titles, + .tr.table-titles { + background: 0 0 + } + + .menu-btn.active span::after { + transform: rotate(-45deg) + } + + .nav>li>a { + align-items: center; + transition: .3s + } + + .nav>li>a::after { + content: ''; + width: .5rem; + height: .5rem; + border-right: 2px solid var(--text-color-medium); + border-bottom: 2px solid var(--text-color-medium); + transition: transform .3s; + opacity: 0 + } + + .nav>li>a:hover::after { opacity: 1 } - to { - transform: scale(2.5); - opacity: 0 - } -} - -[data-darkmode=true] .ripple { - background: rgba(255, 255, 255, .15) -} - -header [data-indicator] { - padding: 5px 9px 5px 6px; - display: inline-flex; - align-items: center; - gap: 4px -} - -header [data-indicator="poll-status"]::before { - content: ''; - width: 16px; - height: 16px; - background-color: currentColor; - -webkit-mask: url("icons/refresh.svg") center/contain no-repeat; - mask: url("icons/refresh.svg") center/contain no-repeat -} - -header [data-indicator="uci-changes"]::before { - content: ''; - width: 16px; - height: 16px; - background-color: currentColor; - -webkit-mask: url("icons/changes.svg") center/contain no-repeat; - mask: url("icons/changes.svg") center/contain no-repeat -} - -header [data-indicator="poll-status"][data-style=active]::before { - animation: 5s linear infinite spin-with-pause -} - -@keyframes spin-with-pause { - 0% { - transform: rotate(0) + .dropdown-menu { + background: var(--background-color-low); + background: var(--background-color-low); + padding: 0; + margin: 0; + border: none; + border-radius: 0; + box-shadow: none } - 100%, - 20% { - transform: rotate(360deg) + .dropdown-menu>li>a { + color: var(--text-color-medium); + transition: .3s; + padding: .6rem 1.5rem .6rem 3rem; + color: var(--text-color-medium); + display: block } -} -#localtime, -.btn, -.cbi-button, -.cbi-dropdown, -.cbi-dropdown:not(.btn):not(.cbi-button), -.cbi-dynlist>.item, -.cbi-input-text, -.cbi-page-actions .cbi-button-apply, -.cbi-page-actions .cbi-button-apply+.cbi-button-save, -.cbi-page-actions .cbi-button-negative+.cbi-button-save, -select, -textarea { - /* background: var(--md-sys-color-light); */ - /* background: var(--md-sys-color-surface); */ - border: 1px solid var(--md-sys-color-primary); - color: var(--md-sys-color-primary); -} + .dropdown-menu>li { + position: relative; + border-radius: 2rem; + transition: background-color .3s + } -.cbi-input-text, -.cbi-input-password, -textarea { - background: var(--md-sys-color-light); - color: var(--md-sys-color-font); -} + .dropdown-menu>li:hover { + background: rgba(0, 0, 0, .05); + border-radius: 2rem + } -.cbi-page-actions .cbi-button-apply+.cbi-button-save, -.cbi-page-actions .cbi-button-negative+.cbi-button-save { - background: var(--md-sys-color-primary-container); - color: var(--md-sys-color-font); - border: 1px solid var(--md-sys-color-primary-container) -} + .dropdown-menu>li.active { + border-left-color: var(--primary-color-high); + background: var(--md-sys-color-primary-container); + transition: background-color .3s + } -.btn.primary, -.cbi-button-action.important, -.cbi-page-actions .cbi-button-apply, -.cbi-section-actions .cbi-button-edit { - background: var(--md-sys-color-primary); - color: #fff; - border: 1px solid var(--md-sys-color-primary) -} + .dropdown-menu>li.active:hover { + background: var(--md-sys-color-primary-container-hover); + transition: background-color .3s + } -@media screen and (max-width: 1300px) { - .table { - max-width: 100%; - /* table-layout: fixed; */ + body { + background: var(--md-sys-color-surface); + --background-color-high: var(--md-sys-color-surface); + --background-color-low: var(--md-sys-color-surface); + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale + } + + body, + button, + .cbi-section, + .table, + .cbi-input-text, + input { + font-family: "Segoe UI Variable Display", "Google Sans", "Product Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Ubuntu, sans-serif; + background-color var(--transition-color), + color var(--transition-color), + border-color var(--transition-color); + } + + header .pull-right { + /* padding-top: 0; */ + /* display: flex; */ + } + + h1, + h2, + h3 { + font-weight: 350 + } + + header .brand { + /* padding: 0 57px 1px; */ + width: var(--sidebar-width); + font-size: 25px; + line-height: 40px + } + + .label, + header [data-indicator] { + font-size: 12px; + padding: 4px 8px + } + + .actions, + .cbi-page-actions { + border: none; + padding: 8px 16px + } + + .cbi-section-node { + padding: 4px 8px + } + + .cbi-section-node, + .create-item-input, + .ifacebox, + .table, + table { + background: var(--md-sys-color-card); + border-radius: 16px; + box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%); + margin: 1px; + width: calc(100% - 2px); + } + + .cbi-dropdown>ul>li input[type=text] { + height: 30px; + border-radius: 6px; + border: none + } + + .ifacebox .ifacebox-head { + border-radius: 1rem 1rem 0 0; + opacity: .9 + } + + .nav .dropdown-menu { + position: static !important; + float: none; + min-width: 100%; + padding: 0; + margin: 0; + border-radius: 0; + background: var(--background-color-medium); + height: 0; + transition: height .3s ease-in-out; + overflow: hidden + } + + .nav .dropdown-menu, + header { + border: none; + backdrop-filter: blur(15px); + box-shadow: none; + background: var(--md-sys-color-surface-translucent); + } + + #localtime, + .btn, + .cbi-button, + .cbi-dropdown, + .cbi-dropdown:not(.btn):not(.cbi-button), + .cbi-dynlist>.item, + .cbi-input-text, + .cbi-page-actions .cbi-button-apply, + .cbi-page-actions .cbi-button-apply+.cbi-button-save, + .cbi-page-actions .cbi-button-negative+.cbi-button-save, + select, + textarea { + border-radius: 1rem; + text-shadow: none; + padding: 1px 10px; + box-shadow: none; + /* color: var(--md-sys-color-primary); */ + } + + textarea { + overflow: auto; + vertical-align: top; + font-family: consolas, monospace; + color: var(--md-sys-color-font) + } + + .cbi-dynlist>.item { + padding: 6px 10px + } + + .cbi-dynlist>.item::after { + background: 0 0; + box-shadow: none; + border-left: none; + } + + .label.notice, + header [data-indicator][data-style=active] { + background: var(--md-sys-color-refresh-button); + } + + header [data-indicator][data-style=active]:hover { + background: var(--md-sys-color-refresh-button-hover); + } + + header [data-indicator][data-style=inactive]:hover { + background: rgba(0, 0, 0, .05) + } + + .dropdown-menu li a { + border-radius: 2rem; + overflow: hidden + } + + .dropdown-menu li a:hover { + border-radius: 2rem; + background: 0 0 !important; + color: var(--text-color-highest) !important + } + + .nav>li>.dropdown-menu { + padding-left: 2.5rem + } + + .nav>li.open>.dropdown-menu { + display: block; + background: 0 0 + } + + .nav>li:has(>.dropdown-menu>li.active) { + border-radius: 2rem 2rem 0 0 + } + + .nav>li:has(>.dropdown-menu>li.active)>a { + color: var(--text-color-highest) !important + } + + .cbi-progressbar { + background: var(--md-sys-color-progressbar); + border: none; + /* border-radius: 20px; */ + } + + .cbi-progressbar>div { + /* border-radius: 20px; */ } .table .td, .table .th { - /* padding: 6px; */ - word-wrap: break-word; - overflow-wrap: break-word; - word-break: break-word; - hyphens: auto; + border-top: none } - /* 调整特定列的宽度 */ - .td.cbi-section-actions { - width: auto; - min-width: 120px; - white-space: normal; + .td.cbi-section-actions>*>*, + .td.cbi-section-actions>*>form>* { + margin: 0; + border-radius: 0 } - /* 确保按钮不会溢出 */ - .td.cbi-section-actions>* { - margin: 2px 0; + .td.cbi-section-actions>*>:first-child { + border-radius: 1rem } - .td.cbi-section-actions>*>* { - display: inline-block; - max-width: 100%; - margin: 2px; + .td.cbi-section-actions>*>:last-child { + border-radius: 1rem; + border: none; + background: var(--md-sys-color-primary-container); + color: var(--md-sys-color-font) } - /* 处理长文本 */ - .table .td[data-title]::before { - word-break: keep-all; - hyphens: none; - text-align: left; + .ifacebadge, + .ifacebadge.large, + .network-status-table .ifacebox-body .ifacebadge { + padding: 8px; + border: 1px solid #aaa; + box-shadow: none; + border-radius: 1rem } - /* 优化代码和路径显示 */ - .td pre, - .td code, - .td .ifacebadge { - white-space: pre-wrap; - word-break: break-all; + .network-status-table { + width: calc(100% + 16px); + position: relative; + left: -8px; + margin-bottom: 8px } - [data-page^=admin-services-openclash] #cbi-openclash { - overflow-x: scroll + .ifacebox .ifacebox-head.active { + background: 0 0; + border: none; + color: var(--md-sys-color-font); + text-shadow: none } - [data-page^=admin-services-openclash] #cbi-openclash .cbi-section { - width: calc(100% - 2px); + .network-status-table .ifacebox { + border: none; + box-shadow: none; + padding: 8px; + box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%) } - [data-page=admin-network-network] #cbi-network-interface { - overflow-x: scroll; + [data-page^=admin-services-openclash] .tabs>li:last-child { + justify-content: center } - [data-page=admin-network-network] #cbi-network-interface .cbi-section-create { - margin: 0 -3px; + [data-page^=admin-services-openclash] ul li a { + margin: auto } -} -select#themeSelect { - width: 64px; - margin: 1px; - padding: 4px; - font-size: 15px !important; -} \ No newline at end of file + .cbi-section h3 { + padding-left: 0 + } + + .cbi-modal h4 { + text-align: center + } + + .cbi-value, + form .clearfix { + margin: 16px 0 + } + + .cbi-tabmenu>li, + .dropdown-menu>li>a, + .nav>li>a, + .tabs>li { + position: relative; + overflow: hidden + } + + .cbi-tabmenu>.cbi-tab:hover { + background: var(--md-sys-color-primary-container-hover); + } + + .ripple { + position: absolute; + width: 200px; + height: 200px; + margin-left: -100px; + margin-top: -100px; + border-radius: 50%; + background: rgba(0, 0, 0, .15); + transform: scale(0); + pointer-events: none; + animation: 1s ease-out ripple + } + + @keyframes ripple { + from { + transform: scale(0); + opacity: 1 + } + + to { + transform: scale(2.5); + opacity: 0 + } + } + + [data-darkmode=true] .ripple { + background: rgba(255, 255, 255, .15) + } + + header [data-indicator] { + padding: 5px 9px 5px 6px; + display: inline-flex; + align-items: center; + gap: 4px + } + + header [data-indicator="poll-status"]::before { + content: ''; + width: 16px; + height: 16px; + background-color: currentColor; + -webkit-mask: url("icons/refresh.svg") center/contain no-repeat; + mask: url("icons/refresh.svg") center/contain no-repeat + } + + header [data-indicator="uci-changes"]::before { + content: ''; + width: 16px; + height: 16px; + background-color: currentColor; + -webkit-mask: url("icons/changes.svg") center/contain no-repeat; + mask: url("icons/changes.svg") center/contain no-repeat + } + + header [data-indicator="poll-status"][data-style=active]::before { + animation: 5s linear infinite spin-with-pause + } + + @keyframes spin-with-pause { + 0% { + transform: rotate(0) + } + + 100%, + 20% { + transform: rotate(360deg) + } + } + + #localtime, + .btn, + .cbi-button, + .cbi-dropdown, + .cbi-dropdown:not(.btn):not(.cbi-button), + .cbi-dynlist>.item, + .cbi-input-text, + .cbi-page-actions .cbi-button-apply, + .cbi-page-actions .cbi-button-apply+.cbi-button-save, + .cbi-page-actions .cbi-button-negative+.cbi-button-save, + select, + textarea { + /* background: var(--md-sys-color-light); */ + /* background: var(--md-sys-color-surface); */ + border: 1px solid var(--md-sys-color-primary); + color: var(--md-sys-color-primary); + } + + .cbi-input-text, + .cbi-input-password, + textarea { + background: var(--md-sys-color-light); + color: var(--md-sys-color-font); + } + + .cbi-page-actions .cbi-button-apply+.cbi-button-save, + .cbi-page-actions .cbi-button-negative+.cbi-button-save { + background: var(--md-sys-color-primary-container); + color: var(--md-sys-color-font); + border: 1px solid var(--md-sys-color-primary-container) + } + + .btn.primary, + .cbi-button-action.important, + .cbi-page-actions .cbi-button-apply, + .cbi-section-actions .cbi-button-edit { + background: var(--md-sys-color-primary); + color: #fff; + border: 1px solid var(--md-sys-color-primary) + } + + @media screen and (max-width: 1300px) { + .table { + max-width: 100%; + /* table-layout: fixed; */ + } + + .table .td, + .table .th { + /* padding: 6px; */ + word-wrap: break-word; + overflow-wrap: break-word; + word-break: break-word; + hyphens: auto; + } + + /* 调整特定列的宽度 */ + .td.cbi-section-actions { + width: auto; + min-width: 120px; + white-space: normal; + } + + /* 确保按钮不会溢出 */ + .td.cbi-section-actions>* { + margin: 2px 0; + } + + .td.cbi-section-actions>*>* { + display: inline-block; + max-width: 100%; + margin: 2px; + } + + /* 处理长文本 */ + .table .td[data-title]::before { + word-break: keep-all; + hyphens: none; + text-align: left; + } + + /* 优化代码和路径显示 */ + .td pre, + .td code, + .td .ifacebadge { + white-space: pre-wrap; + word-break: break-all; + } + + [ data-page^=admin-services-openclash] #cbi-openclash { + overflow-x: scroll + } + + [ data-page^=admin-services-openclash] #cbi-openclash .cbi-section { + width: calc(100% - 2px); + } + + [ data-page=admin-network-network] #cbi-network-interface { + overflow-x: scroll; + } + + [ data-page=admin-network-network] #cbi-network-interface .cbi-section-create { + margin: 0 -3px; + } + } + + select#themeSelect { + width: 64px; + margin: 1px; + padding: 4px; + font-size: 15px !important; + } diff --git a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/modem.svg b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/modem.svg index ffc216c38a..6325e580e0 100644 --- a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/modem.svg +++ b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/modem.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/nas.svg b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/nas.svg index e99cb69e5c..f389477057 100644 --- a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/nas.svg +++ b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/nas.svg @@ -1,4 +1 @@ - - - \ No newline at end of file + \ No newline at end of file diff --git a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/network.svg b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/network.svg index 89fbf14645..18bbaaed29 100644 --- a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/network.svg +++ b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/network.svg @@ -1,4 +1 @@ - - - \ No newline at end of file + \ No newline at end of file diff --git a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/vpn.svg b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/vpn.svg index b020c36d35..e881c890b3 100644 --- a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/vpn.svg +++ b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/icons/vpn.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/mobile.css b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/mobile.css index 12357c20d9..f86ed8cd1b 100644 --- a/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/mobile.css +++ b/openwrt-packages/luci-theme-material3/htdocs/luci-static/material3/mobile.css @@ -474,7 +474,7 @@ header h3 a { } header.with-shadow { - background: var(--md-sys-color-card-translucent); + background: var(--md-sys-color-card); box-shadow: 0 .5px 1.5px 0 rgba(0, 0, 0, 19%), 0 0 1px 0 rgba(0, 0, 0, 3.9%) } diff --git a/openwrt-packages/luci-theme-material3/htdocs/luci-static/resources/menu-material3.js b/openwrt-packages/luci-theme-material3/htdocs/luci-static/resources/menu-material3.js index cab4942fde..95088ddd57 100644 --- a/openwrt-packages/luci-theme-material3/htdocs/luci-static/resources/menu-material3.js +++ b/openwrt-packages/luci-theme-material3/htdocs/luci-static/resources/menu-material3.js @@ -108,7 +108,7 @@ return baseclass.extend({ className = 'tabmenu-item-%s %s'.format(children[i].name, activeClass); ul.appendChild(E('li', { 'class': className }, [ - E('a', { 'href': L.url(url, children[i].name) }, [_(children[i].title)])])); + E('a', { 'href': L.url(url, children[i].name) }, [children[i].name === 'nas' ? 'NAS' : _(children[i].title)])])); if (isActive) activeNode = children[i]; @@ -196,7 +196,7 @@ return baseclass.extend({ location.href = targetUrl; } }).bind(null, submenu, !!submenu.firstElementChild, linkurl) - }, [_(children[i].title)]), + }, [children[i].name === 'nas' ? 'NAS' : _(children[i].title)]), submenu ]); @@ -216,7 +216,7 @@ return baseclass.extend({ var isActive = (L.env.requestpath.length ? children[i].name == L.env.requestpath[0] : i == 0); ul.appendChild(E('li', { 'class': isActive ? 'active' : null }, [ - E('a', { 'href': L.url(children[i].name) }, [_(children[i].title)]) + E('a', { 'href': L.url(children[i].name) }, [children[i].name === 'nas' ? 'NAS' : _(children[i].title)]) ])); if (isActive) diff --git a/openwrt-packages/luci-theme-material3/root/etc/uci-defaults/30_luci-theme-material3 b/openwrt-packages/luci-theme-material3/root/etc/uci-defaults/30_luci-theme-material3 index c0516e5495..4c28e4cc74 100644 --- a/openwrt-packages/luci-theme-material3/root/etc/uci-defaults/30_luci-theme-material3 +++ b/openwrt-packages/luci-theme-material3/root/etc/uci-defaults/30_luci-theme-material3 @@ -1,31 +1,15 @@ #!/bin/sh -changed=0 - -set_opt() { - local key=$1 - local val=$2 - - if ! uci -q get "luci.$key" 2>/dev/null; then - uci set "luci.$key=$val" - changed=1 - fi -} - -set_opt themes.Material3 /luci-static/material3 - -if [ "$PKG_UPGRADE" != 1 ] && [ $changed = 1 ]; then - set_opt main.mediaurlbase /luci-static/material3 +if [ "$PKG_UPGRADE" != 1 ]; then + uci get luci.themes.Material3 >/dev/null 2>&1 || \ + uci batch <<-EOF + set luci.themes.Material3=/luci-static/material3 + set luci.main.mediaurlbase=/luci-static/material3 + set luci.themes.Material3Blue=/luci-static/material3-blue + set luci.themes.Material3Green=/luci-static/material3-green + set luci.themes.Material3Red=/luci-static/material3-red + commit luci + EOF fi -# set_opt themes.Material3Dark /luci-static/material3-dark -# set_opt themes.Material3Light /luci-static/material3-light -set_opt themes.Material3Blue /luci-static/material3-blue -set_opt themes.Material3Green /luci-static/material3-green -set_opt themes.Material3Red /luci-static/material3-red - -if [ $changed = 1 ]; then - uci commit luci -fi - -exit 0 +exit 0 \ No newline at end of file diff --git a/openwrt-packages/luci-theme-material3/ucode/template/themes/material3/header.ut b/openwrt-packages/luci-theme-material3/ucode/template/themes/material3/header.ut index 35238f5ed9..8cfcf5df40 100644 --- a/openwrt-packages/luci-theme-material3/ucode/template/themes/material3/header.ut +++ b/openwrt-packages/luci-theme-material3/ucode/template/themes/material3/header.ut @@ -9,7 +9,7 @@ import { getuid, getspnam } from 'luci.core'; const boardinfo = ubus.call('system', 'board'); - const darkpref = 'false'; + const darkpref = uci.get('luci', 'main', 'darkmode') || 'auto'; let themepref = null; switch (theme) { case 'material3-blue': themepref = 'blue'; break; @@ -21,20 +21,10 @@ -%} - + {{ striptags(`${boardinfo.hostname ?? '?'}${node ? ` - ${node.title}` : ''}`) }} - LuCI - {% if (!darkpref): %} - - {% endif %} @@ -47,6 +37,159 @@ {% endif %} + + + + + @@ -55,11 +198,113 @@ - - {{ striptags(boardinfo.hostname ?? '?') }} -
- + {{ striptags(boardinfo.hostname ?? '?') }} + + + + diff --git a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua index a1e8b1d77a..f5f29e367a 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua @@ -183,20 +183,21 @@ o.cfgvalue = function(t, n) type = type .. " " .. protocol end local address = m:get(n, "address") or "" - local port = m:get(n, "port") or m:get(n, "hysteria_hop") or m:get(n, "hysteria2_hop") or "" + local port = m:get(n, "port") or "" + local port_s = (port ~= "") and port or m:get(n, "hysteria_hop") or m:get(n, "hysteria2_hop") or "" str = str .. translate(type) .. ":" .. remarks - if address ~= "" and port ~= "" then - port = port:gsub(":", "-") + if address ~= "" and port_s ~= "" then + port_s = port_s:gsub(":", "-") if show_node_info == "1" then if datatypes.ip6addr(address) then - str = str .. string.format("([%s]:%s)", address, port) + str = str .. string.format("([%s]:%s)", address, port_s) else - str = str .. string.format("(%s:%s)", address, port) + str = str .. string.format("(%s:%s)", address, port_s) end end - str = str .. string.format("", appname, n, address) - str = str .. string.format("", appname, n, port) end + str = str .. string.format("", appname, n, address) + str = str .. string.format("", appname, n, port) return str end diff --git a/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm index ef64abace0..6ab4cd67ab 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm +++ b/openwrt-passwall/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm @@ -199,18 +199,12 @@ table td, .table .td { } function get_address_full(id) { - try { - var address = document.getElementById("cbid.passwall." + id + ".address").value; - var port = document.getElementById("cbid.passwall." + id + ".port").value; - } - catch(err){} + var address = (document.getElementById("cbid.passwall." + id + ".address") || {}).value || ""; + var port = (document.getElementById("cbid.passwall." + id + ".port") || {}).value || ""; //判断是否含有汉字 - var reg = new RegExp("[\\u4E00-\\u9FFF]+","g"); - if ((address != null && address != "") && (port != null && port != "") && reg.test(address) == false) { - return { address: address, port: port }; - } else { - return null; - } + var reg = /[\u4E00-\u9FFF]+/; + address = !reg.test(address) ? address : ""; + return { address: address, port: port }; } //获取当前使用的节点 @@ -285,7 +279,7 @@ table td, .table .td { function ping_node(cbi_id, dom, type) { var full = get_address_full(cbi_id); - if (full != null) { + if ((type == "icmp" && full.address != "" ) || (type == "tcping" && full.address != "" && full.port != "")) { dom.onclick = null dom.innerText = "<%:Check...%>"; XHR.get('<%=api.url("ping_node")%>', { @@ -320,7 +314,7 @@ table td, .table .td { for (var i = 0; i < ping_value.length; i++) { var cbi_id = ping_value[i].getAttribute("cbiid"); var full = get_address_full(cbi_id); - if (full != null) { + if ((auto_detection_time == "icmp" && full.address != "" ) || (auto_detection_time == "tcping" && full.address != "" && full.port != "")) { var flag = false; //当有多个相同地址和端口时合在一起 for (var j = 0; j < nodes.length; j++) { diff --git a/shadowsocks-rust/Cargo.lock b/shadowsocks-rust/Cargo.lock index d5b3a3406e..ede5d493de 100644 --- a/shadowsocks-rust/Cargo.lock +++ b/shadowsocks-rust/Cargo.lock @@ -1033,9 +1033,9 @@ checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127" [[package]] name = "flate2" -version = "1.1.4" +version = "1.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc5a4e564e38c699f2880d3fda590bedc2e69f3f84cd48b457bd892ce61d0aa9" +checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" dependencies = [ "crc32fast", "miniz_oxide", diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua index a1e8b1d77a..f5f29e367a 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/node_list.lua @@ -183,20 +183,21 @@ o.cfgvalue = function(t, n) type = type .. " " .. protocol end local address = m:get(n, "address") or "" - local port = m:get(n, "port") or m:get(n, "hysteria_hop") or m:get(n, "hysteria2_hop") or "" + local port = m:get(n, "port") or "" + local port_s = (port ~= "") and port or m:get(n, "hysteria_hop") or m:get(n, "hysteria2_hop") or "" str = str .. translate(type) .. ":" .. remarks - if address ~= "" and port ~= "" then - port = port:gsub(":", "-") + if address ~= "" and port_s ~= "" then + port_s = port_s:gsub(":", "-") if show_node_info == "1" then if datatypes.ip6addr(address) then - str = str .. string.format("([%s]:%s)", address, port) + str = str .. string.format("([%s]:%s)", address, port_s) else - str = str .. string.format("(%s:%s)", address, port) + str = str .. string.format("(%s:%s)", address, port_s) end end - str = str .. string.format("", appname, n, address) - str = str .. string.format("", appname, n, port) end + str = str .. string.format("", appname, n, address) + str = str .. string.format("", appname, n, port) return str end diff --git a/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm b/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm index ef64abace0..6ab4cd67ab 100644 --- a/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm +++ b/small/luci-app-passwall/luasrc/view/passwall/node_list/node_list.htm @@ -199,18 +199,12 @@ table td, .table .td { } function get_address_full(id) { - try { - var address = document.getElementById("cbid.passwall." + id + ".address").value; - var port = document.getElementById("cbid.passwall." + id + ".port").value; - } - catch(err){} + var address = (document.getElementById("cbid.passwall." + id + ".address") || {}).value || ""; + var port = (document.getElementById("cbid.passwall." + id + ".port") || {}).value || ""; //判断是否含有汉字 - var reg = new RegExp("[\\u4E00-\\u9FFF]+","g"); - if ((address != null && address != "") && (port != null && port != "") && reg.test(address) == false) { - return { address: address, port: port }; - } else { - return null; - } + var reg = /[\u4E00-\u9FFF]+/; + address = !reg.test(address) ? address : ""; + return { address: address, port: port }; } //获取当前使用的节点 @@ -285,7 +279,7 @@ table td, .table .td { function ping_node(cbi_id, dom, type) { var full = get_address_full(cbi_id); - if (full != null) { + if ((type == "icmp" && full.address != "" ) || (type == "tcping" && full.address != "" && full.port != "")) { dom.onclick = null dom.innerText = "<%:Check...%>"; XHR.get('<%=api.url("ping_node")%>', { @@ -320,7 +314,7 @@ table td, .table .td { for (var i = 0; i < ping_value.length; i++) { var cbi_id = ping_value[i].getAttribute("cbiid"); var full = get_address_full(cbi_id); - if (full != null) { + if ((auto_detection_time == "icmp" && full.address != "" ) || (auto_detection_time == "tcping" && full.address != "" && full.port != "")) { var flag = false; //当有多个相同地址和端口时合在一起 for (var j = 0; j < nodes.length; j++) { diff --git a/v2ray-core/.github/workflows/release.yml b/v2ray-core/.github/workflows/release.yml index 43ec255218..dc42139aca 100644 --- a/v2ray-core/.github/workflows/release.yml +++ b/v2ray-core/.github/workflows/release.yml @@ -195,7 +195,7 @@ jobs: openssl dgst -sha512 $FILE | sed 's/([^)]*)//g' >>$DGST - name: Upload ZIP file to Artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v5 with: name: v2ray-${{ steps.get_filename.outputs.ASSET_NAME }}.zip path: v2ray-${{ steps.get_filename.outputs.ASSET_NAME }}.zip @@ -225,7 +225,7 @@ jobs: go-version-file: ./go.mod cache-dependency-path: ./go.sum - - uses: actions/download-artifact@v5 + - uses: actions/download-artifact@v6 with: path: build_artifacts @@ -260,17 +260,17 @@ jobs: openssl dgst -sha256 $FILE | sed 's/([^)]*)//g' >>$DGST openssl dgst -sha512 $FILE | sed 's/([^)]*)//g' >>$DGST - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: Release.unsigned path: build_artifacts/Release.unsigned - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: Release.unsigned.dgst path: build_artifacts/Release.unsigned.dgst - - uses: actions/upload-artifact@v4 + - uses: actions/upload-artifact@v5 with: name: v2ray-extra.zip path: build_artifacts/v2ray-extra.zip diff --git a/v2rayn/v2rayN/Directory.Packages.props b/v2rayn/v2rayN/Directory.Packages.props index a339af4cdb..b9caf59f88 100644 --- a/v2rayn/v2rayN/Directory.Packages.props +++ b/v2rayn/v2rayN/Directory.Packages.props @@ -9,16 +9,16 @@ - + - + - + diff --git a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx index 095d8594d3..96c470c678 100644 --- a/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx +++ b/v2rayn/v2rayN/ServiceLib/Resx/ResUI.zh-Hans.resx @@ -427,7 +427,7 @@ 路由设置 - 配置文件 + 配置项 设置 diff --git a/v2rayn/v2rayN/v2rayN.Desktop/GlobalUsings.cs b/v2rayn/v2rayN/v2rayN.Desktop/GlobalUsings.cs index c9a2bc45dd..6a2f1d3be5 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/GlobalUsings.cs +++ b/v2rayn/v2rayN/v2rayN.Desktop/GlobalUsings.cs @@ -3,7 +3,7 @@ global using System.Collections.Generic; global using System.Globalization; global using System.IO; global using System.Linq; -global using System.Reactive.Disposables; +global using System.Reactive.Disposables.Fluent; global using System.Reactive.Linq; global using System.Text; global using System.Threading; @@ -17,7 +17,7 @@ global using Avalonia.Markup.Xaml; global using Avalonia.Media; global using Avalonia.Media.Imaging; global using Avalonia.Platform; -global using Avalonia.ReactiveUI; +global using ReactiveUI.Avalonia; global using Avalonia.Styling; global using Avalonia.Threading; global using ReactiveUI; diff --git a/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml b/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml index 14a2d1748b..6dc1815512 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml +++ b/v2rayn/v2rayN/v2rayN.Desktop/Views/ProfilesView.axaml @@ -75,6 +75,15 @@ + + - - - - - + diff --git a/v2rayn/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj b/v2rayn/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj index f6ff5735a5..6212ce12d6 100644 --- a/v2rayn/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj +++ b/v2rayn/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj @@ -15,7 +15,7 @@ - + diff --git a/v2rayn/v2rayN/v2rayN/GlobalUsings.cs b/v2rayn/v2rayN/v2rayN/GlobalUsings.cs index 21d8dbab3e..a8fa461d7d 100644 --- a/v2rayn/v2rayN/v2rayN/GlobalUsings.cs +++ b/v2rayn/v2rayN/v2rayN/GlobalUsings.cs @@ -6,7 +6,7 @@ global using System.Diagnostics; global using System.Globalization; global using System.IO; global using System.Linq; -global using System.Reactive.Disposables; +global using System.Reactive.Disposables.Fluent; global using System.Reactive.Linq; global using System.Runtime.InteropServices; global using System.Text; diff --git a/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml b/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml index 1a33966b98..f66db56975 100644 --- a/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml +++ b/v2rayn/v2rayN/v2rayN/Views/ProfilesView.xaml @@ -87,6 +87,15 @@ ToolTip="{x:Static resx:ResUI.menuFastRealPing}"> + - + Header="{x:Static resx:ResUI.menuRemoveInvalidServerResult}" /> + - - - - + =999999]+bestaudio/best'}) - ydl.sort_formats(info_dict) - ydl.process_ie_result(info_dict) - downloaded = ydl.downloaded_info_dicts[0] - self.assertEqual(downloaded['format_id'], '38') - - info_dict = _make_result(list(formats_order), extractor='youtube') - ydl = YDL({'format': 'bestvideo/best,bestaudio'}) - ydl.sort_formats(info_dict) - ydl.process_ie_result(info_dict) - downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts] - self.assertEqual(downloaded_ids, ['137', '141']) - - info_dict = _make_result(list(formats_order), extractor='youtube') - ydl = YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])+bestaudio'}) - ydl.sort_formats(info_dict) - ydl.process_ie_result(info_dict) - downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts] - self.assertEqual(downloaded_ids, ['137+141', '248+141']) - - info_dict = _make_result(list(formats_order), extractor='youtube') - ydl = YDL({'format': '(bestvideo[ext=mp4],bestvideo[ext=webm])[height<=720]+bestaudio'}) - ydl.sort_formats(info_dict) - ydl.process_ie_result(info_dict) - downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts] - self.assertEqual(downloaded_ids, ['136+141', '247+141']) - - info_dict = _make_result(list(formats_order), extractor='youtube') - ydl = YDL({'format': '(bestvideo[ext=none]/bestvideo[ext=webm])+bestaudio'}) - ydl.sort_formats(info_dict) - ydl.process_ie_result(info_dict) - downloaded_ids = [info['format_id'] for info in ydl.downloaded_info_dicts] - self.assertEqual(downloaded_ids, ['248+141']) - - for f1, f2 in itertools.pairwise(formats_order): - info_dict = _make_result([f1, f2], extractor='youtube') - ydl = YDL({'format': 'best/bestvideo'}) - ydl.sort_formats(info_dict) - ydl.process_ie_result(info_dict) - downloaded = ydl.downloaded_info_dicts[0] - self.assertEqual(downloaded['format_id'], f1['format_id']) - - info_dict = _make_result([f2, f1], extractor='youtube') - ydl = YDL({'format': 'best/bestvideo'}) - ydl.sort_formats(info_dict) - ydl.process_ie_result(info_dict) - downloaded = ydl.downloaded_info_dicts[0] - self.assertEqual(downloaded['format_id'], f1['format_id']) - def test_audio_only_extractor_format_selection(self): # For extractors with incomplete formats (all formats are audio-only or # video-only) best and worst should fallback to corresponding best/worst diff --git a/yt-dlp/yt_dlp/extractor/archiveorg.py b/yt-dlp/yt_dlp/extractor/archiveorg.py index 9a4e0b8c80..3746c58fb7 100644 --- a/yt-dlp/yt_dlp/extractor/archiveorg.py +++ b/yt-dlp/yt_dlp/extractor/archiveorg.py @@ -5,12 +5,9 @@ import re import urllib.parse from .common import InfoExtractor -from .youtube import YoutubeBaseInfoExtractor, YoutubeIE -from ..networking import HEADRequest -from ..networking.exceptions import HTTPError +from .youtube import YoutubeBaseInfoExtractor from ..utils import ( KNOWN_EXTENSIONS, - ExtractorError, bug_reports_message, clean_html, dict_get, @@ -21,18 +18,14 @@ from ..utils import ( join_nonempty, js_to_json, merge_dicts, - mimetype2ext, orderedSet, parse_duration, parse_qs, str_or_none, - str_to_int, traverse_obj, - try_get, unified_strdate, unified_timestamp, url_or_none, - urlhandle_detect_ext, ) @@ -471,7 +464,7 @@ class YoutubeWebArchiveIE(InfoExtractor): 'url': 'https://web.archive.org/web/20110712231407/http://www.youtube.com/watch?v=lTx3G6h2xyA', 'info_dict': { 'id': 'lTx3G6h2xyA', - 'ext': 'flv', + 'ext': 'mp4', 'title': 'Madeon - Pop Culture (live mashup)', 'upload_date': '20110711', 'uploader': 'Madeon', @@ -578,7 +571,7 @@ class YoutubeWebArchiveIE(InfoExtractor): 'url': 'https://web.archive.org/web/20110126141719/http://www.youtube.com/watch?v=Q_yjX80U7Yc', 'info_dict': { 'id': 'Q_yjX80U7Yc', - 'ext': 'flv', + 'ext': 'webm', 'title': 'Spray Paint Art by Clay Butler: Purple Fantasy Forest', 'uploader_id': 'claybutlermusic', 'description': 'md5:4595264559e3d0a0ceb3f011f6334543', @@ -680,6 +673,37 @@ class YoutubeWebArchiveIE(InfoExtractor): 'upload_date': '20120407', 'uploader_id': 'thecomputernerd01', }, + }, { + # Contains split audio/video formats + 'url': 'ytarchive:o_T_S_TU12M', + 'info_dict': { + 'id': 'o_T_S_TU12M', + 'ext': 'mp4', + 'title': 'Prairie Pulse 1218; Lin Enger, Paul Olson', + 'description': 'md5:36e7a34cdc8508e35a920ec042e799c7', + 'uploader': 'Prairie Public', + 'channel_id': 'UC4BOzQel6tvJm7OEDd3vZlw', + 'channel_url': 'https://www.youtube.com/channel/UC4BOzQel6tvJm7OEDd3vZlw', + 'duration': 1606, + 'upload_date': '20150213', + }, + }, { + # Video unavailable through wayback-fakeurl + 'url': 'ytarchive:SQCom7wjGDs', + 'info_dict': { + 'id': 'SQCom7wjGDs', + 'ext': 'mp4', + 'title': 'Jamin Warren from PBS Game/Show decides that Portal is a feminist Game [Top Hats and No Brain]', + 'description': 'md5:c0cb876dd075483ead9afcc86798efb0', + 'uploader': 'Top Hats and Champagne', + 'uploader_id': 'sparrowtm', + 'uploader_url': 'https://www.youtube.com/user/sparrowtm', + 'channel_id': 'UCW3T5nG4iEkI7HjG-Du3HQA', + 'channel_url': 'https://www.youtube.com/channel/UCW3T5nG4iEkI7HjG-Du3HQA', + 'duration': 1500, + 'thumbnail': 'https://web.archive.org/web/20160108040020if_/https://i.ytimg.com/vi/SQCom7wjGDs/maxresdefault.jpg', + 'upload_date': '20160107', + }, }, { 'url': 'https://web.archive.org/web/http://www.youtube.com/watch?v=kH-G_aIBlFw', 'only_matching': True, @@ -724,6 +748,113 @@ class YoutubeWebArchiveIE(InfoExtractor): _OLDEST_CAPTURE_DATE = 20050214000000 _NEWEST_CAPTURE_DATE = 20500101000000 + _FORMATS = { + '5': {'ext': 'flv', 'width': 400, 'height': 240, 'acodec': 'mp3', 'vcodec': 'h263'}, + '6': {'ext': 'flv', 'width': 450, 'height': 270, 'acodec': 'mp3', 'vcodec': 'h263'}, + '13': {'ext': '3gp', 'acodec': 'aac', 'vcodec': 'mp4v'}, + '17': {'ext': '3gp', 'width': 176, 'height': 144, 'acodec': 'aac', 'vcodec': 'mp4v'}, + '18': {'ext': 'mp4', 'width': 640, 'height': 360, 'acodec': 'aac', 'vcodec': 'h264'}, + '22': {'ext': 'mp4', 'width': 1280, 'height': 720, 'acodec': 'aac', 'vcodec': 'h264'}, + '34': {'ext': 'flv', 'width': 640, 'height': 360, 'acodec': 'aac', 'vcodec': 'h264'}, + '35': {'ext': 'flv', 'width': 854, 'height': 480, 'acodec': 'aac', 'vcodec': 'h264'}, + # itag 36 videos are either 320x180 (BaW_jenozKc) or 320x240 (__2ABJjxzNo), abr varies as well + '36': {'ext': '3gp', 'width': 320, 'acodec': 'aac', 'vcodec': 'mp4v'}, + '37': {'ext': 'mp4', 'width': 1920, 'height': 1080, 'acodec': 'aac', 'vcodec': 'h264'}, + '38': {'ext': 'mp4', 'width': 4096, 'height': 3072, 'acodec': 'aac', 'vcodec': 'h264'}, + '43': {'ext': 'webm', 'width': 640, 'height': 360, 'acodec': 'vorbis', 'vcodec': 'vp8'}, + '44': {'ext': 'webm', 'width': 854, 'height': 480, 'acodec': 'vorbis', 'vcodec': 'vp8'}, + '45': {'ext': 'webm', 'width': 1280, 'height': 720, 'acodec': 'vorbis', 'vcodec': 'vp8'}, + '46': {'ext': 'webm', 'width': 1920, 'height': 1080, 'acodec': 'vorbis', 'vcodec': 'vp8'}, + '59': {'ext': 'mp4', 'width': 854, 'height': 480, 'acodec': 'aac', 'vcodec': 'h264'}, + '78': {'ext': 'mp4', 'width': 854, 'height': 480, 'acodec': 'aac', 'vcodec': 'h264'}, + + + # 3D videos + '82': {'ext': 'mp4', 'height': 360, 'format_note': '3D', 'acodec': 'aac', 'vcodec': 'h264', 'preference': -20}, + '83': {'ext': 'mp4', 'height': 480, 'format_note': '3D', 'acodec': 'aac', 'vcodec': 'h264', 'preference': -20}, + '84': {'ext': 'mp4', 'height': 720, 'format_note': '3D', 'acodec': 'aac', 'vcodec': 'h264', 'preference': -20}, + '85': {'ext': 'mp4', 'height': 1080, 'format_note': '3D', 'acodec': 'aac', 'vcodec': 'h264', 'preference': -20}, + '100': {'ext': 'webm', 'height': 360, 'format_note': '3D', 'acodec': 'vorbis', 'vcodec': 'vp8', 'preference': -20}, + '101': {'ext': 'webm', 'height': 480, 'format_note': '3D', 'acodec': 'vorbis', 'vcodec': 'vp8', 'preference': -20}, + '102': {'ext': 'webm', 'height': 720, 'format_note': '3D', 'acodec': 'vorbis', 'vcodec': 'vp8', 'preference': -20}, + + # Apple HTTP Live Streaming + '91': {'ext': 'mp4', 'height': 144, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + '92': {'ext': 'mp4', 'height': 240, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + '93': {'ext': 'mp4', 'height': 360, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + '94': {'ext': 'mp4', 'height': 480, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + '95': {'ext': 'mp4', 'height': 720, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + '96': {'ext': 'mp4', 'height': 1080, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + '132': {'ext': 'mp4', 'height': 240, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + '151': {'ext': 'mp4', 'height': 72, 'format_note': 'HLS', 'acodec': 'aac', 'vcodec': 'h264'}, + + # DASH mp4 video + '133': {'ext': 'mp4', 'height': 240, 'vcodec': 'h264', 'acodec': 'none'}, + '134': {'ext': 'mp4', 'height': 360, 'vcodec': 'h264', 'acodec': 'none'}, + '135': {'ext': 'mp4', 'height': 480, 'vcodec': 'h264', 'acodec': 'none'}, + '136': {'ext': 'mp4', 'height': 720, 'vcodec': 'h264', 'acodec': 'none'}, + '137': {'ext': 'mp4', 'height': 1080, 'vcodec': 'h264', 'acodec': 'none'}, + '138': {'ext': 'mp4', 'vcodec': 'h264', 'acodec': 'none'}, # Height can vary (https://github.com/ytdl-org/youtube-dl/issues/4559) + '160': {'ext': 'mp4', 'height': 144, 'vcodec': 'h264', 'acodec': 'none'}, + '212': {'ext': 'mp4', 'height': 480, 'vcodec': 'h264', 'acodec': 'none'}, + '264': {'ext': 'mp4', 'height': 1440, 'vcodec': 'h264', 'acodec': 'none'}, + '298': {'ext': 'mp4', 'height': 720, 'vcodec': 'h264', 'fps': 60, 'acodec': 'none'}, + '299': {'ext': 'mp4', 'height': 1080, 'vcodec': 'h264', 'fps': 60, 'acodec': 'none'}, + '266': {'ext': 'mp4', 'height': 2160, 'vcodec': 'h264', 'acodec': 'none'}, + + # Dash mp4 audio + '139': {'ext': 'm4a', 'acodec': 'aac', 'vcodec': 'none'}, + '140': {'ext': 'm4a', 'acodec': 'aac', 'vcodec': 'none'}, + '141': {'ext': 'm4a', 'acodec': 'aac', 'vcodec': 'none'}, + '256': {'ext': 'm4a', 'acodec': 'aac', 'vcodec': 'none'}, + '258': {'ext': 'm4a', 'acodec': 'aac', 'vcodec': 'none'}, + '325': {'ext': 'm4a', 'acodec': 'dtse', 'vcodec': 'none'}, + '328': {'ext': 'm4a', 'acodec': 'ec-3', 'vcodec': 'none'}, + + # Dash webm + '167': {'ext': 'webm', 'height': 360, 'width': 640, 'vcodec': 'vp8'}, + '168': {'ext': 'webm', 'height': 480, 'width': 854, 'vcodec': 'vp8'}, + '169': {'ext': 'webm', 'height': 720, 'width': 1280, 'vcodec': 'vp8'}, + '170': {'ext': 'webm', 'height': 1080, 'width': 1920, 'vcodec': 'vp8'}, + '218': {'ext': 'webm', 'height': 480, 'width': 854, 'vcodec': 'vp8'}, + '219': {'ext': 'webm', 'height': 480, 'width': 854, 'vcodec': 'vp8'}, + '278': {'ext': 'webm', 'height': 144, 'vcodec': 'vp9', 'acodec': 'none'}, + '242': {'ext': 'webm', 'height': 240, 'vcodec': 'vp9', 'acodec': 'none'}, + '243': {'ext': 'webm', 'height': 360, 'vcodec': 'vp9', 'acodec': 'none'}, + '244': {'ext': 'webm', 'height': 480, 'vcodec': 'vp9', 'acodec': 'none'}, + '245': {'ext': 'webm', 'height': 480, 'vcodec': 'vp9', 'acodec': 'none'}, + '246': {'ext': 'webm', 'height': 480, 'vcodec': 'vp9', 'acodec': 'none'}, + '247': {'ext': 'webm', 'height': 720, 'vcodec': 'vp9', 'acodec': 'none'}, + '248': {'ext': 'webm', 'height': 1080, 'vcodec': 'vp9', 'acodec': 'none'}, + '271': {'ext': 'webm', 'height': 1440, 'vcodec': 'vp9', 'acodec': 'none'}, + # itag 272 videos are either 3840x2160 (e.g. RtoitU2A-3E) or 7680x4320 (sLprVF6d7Ug) + '272': {'ext': 'webm', 'height': 2160, 'vcodec': 'vp9', 'acodec': 'none'}, + '302': {'ext': 'webm', 'height': 720, 'vcodec': 'vp9', 'fps': 60, 'acodec': 'none'}, + '303': {'ext': 'webm', 'height': 1080, 'vcodec': 'vp9', 'fps': 60, 'acodec': 'none'}, + '308': {'ext': 'webm', 'height': 1440, 'vcodec': 'vp9', 'fps': 60, 'acodec': 'none'}, + '313': {'ext': 'webm', 'height': 2160, 'vcodec': 'vp9', 'acodec': 'none'}, + '315': {'ext': 'webm', 'height': 2160, 'vcodec': 'vp9', 'fps': 60, 'acodec': 'none'}, + + # Dash webm audio + '171': {'ext': 'webm', 'acodec': 'vorbis', 'vcodec': 'none'}, + '172': {'ext': 'webm', 'acodec': 'vorbis', 'vcodec': 'none'}, + + # Dash webm audio with opus inside + '249': {'ext': 'webm', 'acodec': 'opus', 'vcodec': 'none'}, + '250': {'ext': 'webm', 'acodec': 'opus', 'vcodec': 'none'}, + '251': {'ext': 'webm', 'acodec': 'opus', 'vcodec': 'none'}, + + # av01 video only formats sometimes served with "unknown" codecs + '394': {'ext': 'mp4', 'height': 144, 'vcodec': 'av01.0.00M.08', 'acodec': 'none'}, + '395': {'ext': 'mp4', 'height': 240, 'vcodec': 'av01.0.00M.08', 'acodec': 'none'}, + '396': {'ext': 'mp4', 'height': 360, 'vcodec': 'av01.0.01M.08', 'acodec': 'none'}, + '397': {'ext': 'mp4', 'height': 480, 'vcodec': 'av01.0.04M.08', 'acodec': 'none'}, + '398': {'ext': 'mp4', 'height': 720, 'vcodec': 'av01.0.05M.08', 'acodec': 'none'}, + '399': {'ext': 'mp4', 'height': 1080, 'vcodec': 'av01.0.08M.08', 'acodec': 'none'}, + '400': {'ext': 'mp4', 'height': 1440, 'vcodec': 'av01.0.12M.08', 'acodec': 'none'}, + '401': {'ext': 'mp4', 'height': 2160, 'vcodec': 'av01.0.12M.08', 'acodec': 'none'}, + } + def _call_cdx_api(self, item_id, url, filters: list | None = None, collapse: list | None = None, query: dict | None = None, note=None, fatal=False): # CDX docs: https://github.com/internetarchive/wayback/blob/master/wayback-cdx-server/README.md query = { @@ -933,23 +1064,13 @@ class YoutubeWebArchiveIE(InfoExtractor): video_id, url_date, url_date_2 = self._match_valid_url(url).group('id', 'date', 'date2') url_date = url_date or url_date_2 - urlh = None - retry_manager = self.RetryManager(fatal=False) - for retry in retry_manager: - try: - urlh = self._request_webpage( - HEADRequest(f'https://web.archive.org/web/2oe_/http://wayback-fakeurl.archive.org/yt/{video_id}'), - video_id, note='Fetching archived video file url', expected_status=True) - except ExtractorError as e: - # HTTP Error 404 is expected if the video is not saved. - if isinstance(e.cause, HTTPError) and e.cause.status == 404: - self.raise_no_formats( - 'The requested video is not archived, indexed, or there is an issue with web.archive.org (try again later)', expected=True) - else: - retry.error = e + video_info = self._download_json( + 'https://web.archive.org/__wb/videoinfo', video_id, + query={'vtype': 'youtube', 'vid': video_id}) - if retry_manager.error: - self.raise_no_formats(retry_manager.error, expected=True, video_id=video_id) + if not traverse_obj(video_info, 'formats'): + self.raise_no_formats( + 'The requested video is not archived or indexed', expected=True) capture_dates = self._get_capture_dates(video_id, int_or_none(url_date)) self.write_debug('Captures to try: ' + join_nonempty(*capture_dates, delim=', ')) @@ -968,25 +1089,18 @@ class YoutubeWebArchiveIE(InfoExtractor): info['thumbnails'] = self._extract_thumbnails(video_id) - if urlh: - url = urllib.parse.unquote(urlh.url) - video_file_url_qs = parse_qs(url) - # Attempt to recover any ext & format info from playback url & response headers - fmt = {'url': url, 'filesize': int_or_none(urlh.headers.get('x-archive-orig-content-length'))} - itag = try_get(video_file_url_qs, lambda x: x['itag'][0]) - if itag and itag in YoutubeIE._formats: - fmt.update(YoutubeIE._formats[itag]) - fmt.update({'format_id': itag}) - else: - mime = try_get(video_file_url_qs, lambda x: x['mime'][0]) - ext = (mimetype2ext(mime) - or urlhandle_detect_ext(urlh) - or mimetype2ext(urlh.headers.get('x-archive-guessed-content-type'))) - fmt.update({'ext': ext}) - info['formats'] = [fmt] - if not info.get('duration'): - info['duration'] = str_to_int(try_get(video_file_url_qs, lambda x: x['dur'][0])) + formats = [] + for fmt in traverse_obj(video_info, ('formats', lambda _, v: url_or_none(v['url']))): + format_id = traverse_obj(fmt, ('url', {parse_qs}, 'itag', 0)) + formats.append({ + 'format_id': format_id, + **self._FORMATS.get(format_id, {}), + **traverse_obj(fmt, { + 'url': ('url', {lambda x: f'https://web.archive.org/web/2id_/{x}'}), + 'ext': ('ext', {str}), + 'filesize': ('url', {parse_qs}, 'clen', 0, {int_or_none}), + }), + }) + info['formats'] = formats - if not info.get('title'): - info['title'] = video_id return info diff --git a/yt-dlp/yt_dlp/extractor/googledrive.py b/yt-dlp/yt_dlp/extractor/googledrive.py index 0c84f0b241..c973f648b2 100644 --- a/yt-dlp/yt_dlp/extractor/googledrive.py +++ b/yt-dlp/yt_dlp/extractor/googledrive.py @@ -1,21 +1,19 @@ import re -import urllib.parse from .common import InfoExtractor -from .youtube import YoutubeIE from ..utils import ( - ExtractorError, - bug_reports_message, determine_ext, extract_attributes, get_element_by_class, get_element_html_by_id, int_or_none, - lowercase_escape, - parse_qs, - try_get, + mimetype2ext, + parse_duration, + str_or_none, update_url_query, + url_or_none, ) +from ..utils.traversal import traverse_obj, value class GoogleDriveIE(InfoExtractor): @@ -38,8 +36,8 @@ class GoogleDriveIE(InfoExtractor): 'id': '0ByeS4oOUV-49Zzh4R1J6R09zazQ', 'ext': 'mp4', 'title': 'Big Buck Bunny.mp4', - 'duration': 45, - 'thumbnail': 'https://drive.google.com/thumbnail?id=0ByeS4oOUV-49Zzh4R1J6R09zazQ', + 'duration': 45.069, + 'thumbnail': r're:https://lh3\.googleusercontent\.com/drive-storage/', }, }, { # has itag 50 which is not in YoutubeIE._formats (royalty Free music from 1922) @@ -49,8 +47,18 @@ class GoogleDriveIE(InfoExtractor): 'id': '1IP0o8dHcQrIHGgVyp0Ofvx2cGfLzyO1x', 'ext': 'mp3', 'title': 'My Buddy - Henry Burr - Gus Kahn - Walter Donaldson.mp3', - 'duration': 184, - 'thumbnail': 'https://drive.google.com/thumbnail?id=1IP0o8dHcQrIHGgVyp0Ofvx2cGfLzyO1x', + 'duration': 184.68, + }, + }, { + # Has subtitle track + 'url': 'https://drive.google.com/file/d/1RAGWRgzn85TXCaCk4gxnwF6TGUaZatzE/view', + 'md5': '05488c528da6ef737ec8c962bfa9724e', + 'info_dict': { + 'id': '1RAGWRgzn85TXCaCk4gxnwF6TGUaZatzE', + 'ext': 'mp4', + 'title': 'test.mp4', + 'duration': 9.999, + 'thumbnail': r're:https://lh3\.googleusercontent\.com/drive-storage/', }, }, { # video can't be watched anonymously due to view count limit reached, @@ -71,17 +79,6 @@ class GoogleDriveIE(InfoExtractor): 'url': 'https://drive.usercontent.google.com/download?id=0ByeS4oOUV-49Zzh4R1J6R09zazQ', 'only_matching': True, }] - _FORMATS_EXT = { - **{k: v['ext'] for k, v in YoutubeIE._formats.items() if v.get('ext')}, - '50': 'm4a', - } - _BASE_URL_CAPTIONS = 'https://drive.google.com/timedtext' - _CAPTIONS_ENTRY_TAG = { - 'subtitles': 'track', - 'automatic_captions': 'target', - } - _caption_formats_ext = [] - _captions_xml = None @classmethod def _extract_embed_urls(cls, url, webpage): @@ -91,129 +88,71 @@ class GoogleDriveIE(InfoExtractor): if mobj: yield 'https://drive.google.com/file/d/{}'.format(mobj.group('id')) - def _download_subtitles_xml(self, video_id, subtitles_id, hl): - if self._captions_xml: - return - self._captions_xml = self._download_xml( - self._BASE_URL_CAPTIONS, video_id, query={ - 'id': video_id, - 'vid': subtitles_id, - 'hl': hl, + @staticmethod + def _construct_subtitle_url(base_url, video_id, language, fmt): + return update_url_query( + base_url, { + 'hl': 'en-US', 'v': video_id, + 'type': 'track', + 'lang': language, + 'fmt': fmt, + }) + + def _get_subtitles(self, video_id, video_info): + subtitles = {} + timed_text_base_url = traverse_obj(video_info, ('timedTextDetails', 'timedTextBaseUrl', {url_or_none})) + if not timed_text_base_url: + return subtitles + subtitle_data = self._download_xml( + timed_text_base_url, video_id, 'Downloading subtitles XML', fatal=False, query={ + 'hl': 'en-US', 'type': 'list', - 'tlangs': '1', - 'fmts': '1', - 'vssids': '1', - }, note='Downloading subtitles XML', - errnote='Unable to download subtitles XML', fatal=False) - if self._captions_xml: - for f in self._captions_xml.findall('format'): - if f.attrib.get('fmt_code') and not f.attrib.get('default'): - self._caption_formats_ext.append(f.attrib['fmt_code']) - - def _get_captions_by_type(self, video_id, subtitles_id, caption_type, - origin_lang_code=None, origin_lang_name=None): - if not subtitles_id or not caption_type: - return - captions = {} - for caption_entry in self._captions_xml.findall( - self._CAPTIONS_ENTRY_TAG[caption_type]): - caption_lang_code = caption_entry.attrib.get('lang_code') - caption_name = caption_entry.attrib.get('name') or origin_lang_name - if not caption_lang_code or not caption_name: - self.report_warning(f'Missing necessary caption metadata. ' - f'Need lang_code and name attributes. ' - f'Found: {caption_entry.attrib}') - continue - caption_format_data = [] - for caption_format in self._caption_formats_ext: - query = { - 'vid': subtitles_id, - 'v': video_id, - 'fmt': caption_format, - 'lang': (caption_lang_code if origin_lang_code is None - else origin_lang_code), - 'type': 'track', - 'name': caption_name, - 'kind': '', - } - if origin_lang_code is not None: - query.update({'tlang': caption_lang_code}) - caption_format_data.append({ - 'url': update_url_query(self._BASE_URL_CAPTIONS, query), - 'ext': caption_format, - }) - captions[caption_lang_code] = caption_format_data - return captions - - def _get_subtitles(self, video_id, subtitles_id, hl): - if not subtitles_id or not hl: - return - self._download_subtitles_xml(video_id, subtitles_id, hl) - if not self._captions_xml: - return - return self._get_captions_by_type(video_id, subtitles_id, 'subtitles') - - def _get_automatic_captions(self, video_id, subtitles_id, hl): - if not subtitles_id or not hl: - return - self._download_subtitles_xml(video_id, subtitles_id, hl) - if not self._captions_xml: - return - track = next((t for t in self._captions_xml.findall('track') if t.attrib.get('cantran') == 'true'), None) - if track is None: - return - origin_lang_code = track.attrib.get('lang_code') - origin_lang_name = track.attrib.get('name') - if not origin_lang_code or not origin_lang_name: - return - return self._get_captions_by_type( - video_id, subtitles_id, 'automatic_captions', origin_lang_code, origin_lang_name) + 'tlangs': 1, + 'v': video_id, + 'vssids': 1, + }) + subtitle_formats = traverse_obj(subtitle_data, (lambda _, v: v.tag == 'format', {lambda x: x.get('fmt_code')}, {str})) + for track in traverse_obj(subtitle_data, (lambda _, v: v.tag == 'track' and v.get('lang_code'))): + language = track.get('lang_code') + subtitles.setdefault(language, []).extend([{ + 'url': self._construct_subtitle_url(timed_text_base_url, video_id, language, sub_fmt), + 'name': track.get('lang_original'), + 'ext': sub_fmt, + } for sub_fmt in subtitle_formats]) + return subtitles def _real_extract(self, url): video_id = self._match_id(url) - video_info = urllib.parse.parse_qs(self._download_webpage( - 'https://drive.google.com/get_video_info', - video_id, 'Downloading video webpage', query={'docid': video_id})) - - def get_value(key): - return try_get(video_info, lambda x: x[key][0]) - - reason = get_value('reason') - title = get_value('title') + video_info = self._download_json( + f'https://content-workspacevideo-pa.googleapis.com/v1/drive/media/{video_id}/playback', + video_id, 'Downloading video webpage', query={'key': 'AIzaSyDVQw45DwoYh632gvsP5vPDqEKvb-Ywnb8'}, + headers={'Referer': 'https://drive.google.com/'}) formats = [] - fmt_stream_map = (get_value('fmt_stream_map') or '').split(',') - fmt_list = (get_value('fmt_list') or '').split(',') - if fmt_stream_map and fmt_list: - resolutions = {} - for fmt in fmt_list: - mobj = re.search( - r'^(?P\d+)/(?P\d+)[xX](?P\d+)', fmt) - if mobj: - resolutions[mobj.group('format_id')] = ( - int(mobj.group('width')), int(mobj.group('height'))) + for fmt in traverse_obj(video_info, ( + 'mediaStreamingData', 'formatStreamingData', ('adaptiveTranscodes', 'progressiveTranscodes'), + lambda _, v: url_or_none(v['url']))): + formats.append({ + **traverse_obj(fmt, { + 'url': 'url', + 'format_id': ('itag', {int}, {str_or_none}), + }), + **traverse_obj(fmt, ('transcodeMetadata', { + 'ext': ('mimeType', {mimetype2ext}), + 'width': ('width', {int_or_none}), + 'height': ('height', {int_or_none}), + 'fps': ('videoFps', {int_or_none}), + 'filesize': ('contentLength', {int_or_none}), + 'vcodec': ((('videoCodecString', {str}), {value('none')}), any), + 'acodec': ((('audioCodecString', {str}), {value('none')}), any), + })), + 'downloader_options': { + 'http_chunk_size': 10 << 20, + }, + }) - for fmt_stream in fmt_stream_map: - fmt_stream_split = fmt_stream.split('|') - if len(fmt_stream_split) < 2: - continue - format_id, format_url = fmt_stream_split[:2] - ext = self._FORMATS_EXT.get(format_id) - if not ext: - self.report_warning(f'Unknown format {format_id}{bug_reports_message()}') - f = { - 'url': lowercase_escape(format_url), - 'format_id': format_id, - 'ext': ext, - } - resolution = resolutions.get(format_id) - if resolution: - f.update({ - 'width': resolution[0], - 'height': resolution[1], - }) - formats.append(f) + title = traverse_obj(video_info, ('mediaMetadata', 'title', {str})) source_url = update_url_query( 'https://drive.usercontent.google.com/download', { @@ -264,30 +203,20 @@ class GoogleDriveIE(InfoExtractor): or get_element_by_class('uc-error-caption', confirmation_webpage) or 'unable to extract confirmation code') - if not formats and reason: - if title: - self.raise_no_formats(reason, expected=True) - else: - raise ExtractorError(reason, expected=True) - - hl = get_value('hl') - subtitles_id = None - ttsurl = get_value('ttsurl') - if ttsurl: - # the subtitles ID is the vid param of the ttsurl query - subtitles_id = parse_qs(ttsurl).get('vid', [None])[-1] - - self.cookiejar.clear(domain='.google.com', path='/', name='NID') - return { 'id': video_id, 'title': title, - 'thumbnail': 'https://drive.google.com/thumbnail?id=' + video_id, - 'duration': int_or_none(get_value('length_seconds')), + **traverse_obj(video_info, { + 'duration': ('mediaMetadata', 'duration', {parse_duration}), + 'thumbnails': ('thumbnails', lambda _, v: url_or_none(v['url']), { + 'url': 'url', + 'ext': ('mimeType', {mimetype2ext}), + 'width': ('width', {int}), + 'height': ('height', {int}), + }), + }), 'formats': formats, - 'subtitles': self.extract_subtitles(video_id, subtitles_id, hl), - 'automatic_captions': self.extract_automatic_captions( - video_id, subtitles_id, hl), + 'subtitles': self.extract_subtitles(video_id, video_info), } diff --git a/yt-dlp/yt_dlp/extractor/youtube/_video.py b/yt-dlp/yt_dlp/extractor/youtube/_video.py index 1fc45dac6f..9d03254b85 100644 --- a/yt-dlp/yt_dlp/extractor/youtube/_video.py +++ b/yt-dlp/yt_dlp/extractor/youtube/_video.py @@ -147,115 +147,6 @@ class YoutubeIE(YoutubeBaseInfoExtractor): r'/(?P[a-zA-Z0-9_-]{8,})/player(?:_ias\.vflset(?:/[a-zA-Z]{2,3}_[a-zA-Z]{2,3})?|-plasma-ias-(?:phone|tablet)-[a-z]{2}_[A-Z]{2}\.vflset)/base\.js$', r'\b(?Pvfl[a-zA-Z0-9_-]+)\b.*?\.js$', ) - _formats = { # NB: Used in YoutubeWebArchiveIE and GoogleDriveIE - '5': {'ext': 'flv', 'width': 400, 'height': 240, 'acodec': 'mp3', 'abr': 64, 'vcodec': 'h263'}, - '6': {'ext': 'flv', 'width': 450, 'height': 270, 'acodec': 'mp3', 'abr': 64, 'vcodec': 'h263'}, - '13': {'ext': '3gp', 'acodec': 'aac', 'vcodec': 'mp4v'}, - '17': {'ext': '3gp', 'width': 176, 'height': 144, 'acodec': 'aac', 'abr': 24, 'vcodec': 'mp4v'}, - '18': {'ext': 'mp4', 'width': 640, 'height': 360, 'acodec': 'aac', 'abr': 96, 'vcodec': 'h264'}, - '22': {'ext': 'mp4', 'width': 1280, 'height': 720, 'acodec': 'aac', 'abr': 192, 'vcodec': 'h264'}, - '34': {'ext': 'flv', 'width': 640, 'height': 360, 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264'}, - '35': {'ext': 'flv', 'width': 854, 'height': 480, 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264'}, - # itag 36 videos are either 320x180 (BaW_jenozKc) or 320x240 (__2ABJjxzNo), abr varies as well - '36': {'ext': '3gp', 'width': 320, 'acodec': 'aac', 'vcodec': 'mp4v'}, - '37': {'ext': 'mp4', 'width': 1920, 'height': 1080, 'acodec': 'aac', 'abr': 192, 'vcodec': 'h264'}, - '38': {'ext': 'mp4', 'width': 4096, 'height': 3072, 'acodec': 'aac', 'abr': 192, 'vcodec': 'h264'}, - '43': {'ext': 'webm', 'width': 640, 'height': 360, 'acodec': 'vorbis', 'abr': 128, 'vcodec': 'vp8'}, - '44': {'ext': 'webm', 'width': 854, 'height': 480, 'acodec': 'vorbis', 'abr': 128, 'vcodec': 'vp8'}, - '45': {'ext': 'webm', 'width': 1280, 'height': 720, 'acodec': 'vorbis', 'abr': 192, 'vcodec': 'vp8'}, - '46': {'ext': 'webm', 'width': 1920, 'height': 1080, 'acodec': 'vorbis', 'abr': 192, 'vcodec': 'vp8'}, - '59': {'ext': 'mp4', 'width': 854, 'height': 480, 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264'}, - '78': {'ext': 'mp4', 'width': 854, 'height': 480, 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264'}, - - - # 3D videos - '82': {'ext': 'mp4', 'height': 360, 'format_note': '3D', 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264', 'preference': -20}, - '83': {'ext': 'mp4', 'height': 480, 'format_note': '3D', 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264', 'preference': -20}, - '84': {'ext': 'mp4', 'height': 720, 'format_note': '3D', 'acodec': 'aac', 'abr': 192, 'vcodec': 'h264', 'preference': -20}, - '85': {'ext': 'mp4', 'height': 1080, 'format_note': '3D', 'acodec': 'aac', 'abr': 192, 'vcodec': 'h264', 'preference': -20}, - '100': {'ext': 'webm', 'height': 360, 'format_note': '3D', 'acodec': 'vorbis', 'abr': 128, 'vcodec': 'vp8', 'preference': -20}, - '101': {'ext': 'webm', 'height': 480, 'format_note': '3D', 'acodec': 'vorbis', 'abr': 192, 'vcodec': 'vp8', 'preference': -20}, - '102': {'ext': 'webm', 'height': 720, 'format_note': '3D', 'acodec': 'vorbis', 'abr': 192, 'vcodec': 'vp8', 'preference': -20}, - - # Apple HTTP Live Streaming - '91': {'ext': 'mp4', 'height': 144, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 48, 'vcodec': 'h264', 'preference': -10}, - '92': {'ext': 'mp4', 'height': 240, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 48, 'vcodec': 'h264', 'preference': -10}, - '93': {'ext': 'mp4', 'height': 360, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264', 'preference': -10}, - '94': {'ext': 'mp4', 'height': 480, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 128, 'vcodec': 'h264', 'preference': -10}, - '95': {'ext': 'mp4', 'height': 720, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 256, 'vcodec': 'h264', 'preference': -10}, - '96': {'ext': 'mp4', 'height': 1080, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 256, 'vcodec': 'h264', 'preference': -10}, - '132': {'ext': 'mp4', 'height': 240, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 48, 'vcodec': 'h264', 'preference': -10}, - '151': {'ext': 'mp4', 'height': 72, 'format_note': 'HLS', 'acodec': 'aac', 'abr': 24, 'vcodec': 'h264', 'preference': -10}, - - # DASH mp4 video - '133': {'ext': 'mp4', 'height': 240, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '134': {'ext': 'mp4', 'height': 360, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '135': {'ext': 'mp4', 'height': 480, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '136': {'ext': 'mp4', 'height': 720, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '137': {'ext': 'mp4', 'height': 1080, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '138': {'ext': 'mp4', 'format_note': 'DASH video', 'vcodec': 'h264'}, # Height can vary (https://github.com/ytdl-org/youtube-dl/issues/4559) - '160': {'ext': 'mp4', 'height': 144, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '212': {'ext': 'mp4', 'height': 480, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '264': {'ext': 'mp4', 'height': 1440, 'format_note': 'DASH video', 'vcodec': 'h264'}, - '298': {'ext': 'mp4', 'height': 720, 'format_note': 'DASH video', 'vcodec': 'h264', 'fps': 60}, - '299': {'ext': 'mp4', 'height': 1080, 'format_note': 'DASH video', 'vcodec': 'h264', 'fps': 60}, - '266': {'ext': 'mp4', 'height': 2160, 'format_note': 'DASH video', 'vcodec': 'h264'}, - - # Dash mp4 audio - '139': {'ext': 'm4a', 'format_note': 'DASH audio', 'acodec': 'aac', 'abr': 48, 'container': 'm4a_dash'}, - '140': {'ext': 'm4a', 'format_note': 'DASH audio', 'acodec': 'aac', 'abr': 128, 'container': 'm4a_dash'}, - '141': {'ext': 'm4a', 'format_note': 'DASH audio', 'acodec': 'aac', 'abr': 256, 'container': 'm4a_dash'}, - '256': {'ext': 'm4a', 'format_note': 'DASH audio', 'acodec': 'aac', 'container': 'm4a_dash'}, - '258': {'ext': 'm4a', 'format_note': 'DASH audio', 'acodec': 'aac', 'container': 'm4a_dash'}, - '325': {'ext': 'm4a', 'format_note': 'DASH audio', 'acodec': 'dtse', 'container': 'm4a_dash'}, - '328': {'ext': 'm4a', 'format_note': 'DASH audio', 'acodec': 'ec-3', 'container': 'm4a_dash'}, - - # Dash webm - '167': {'ext': 'webm', 'height': 360, 'width': 640, 'format_note': 'DASH video', 'container': 'webm', 'vcodec': 'vp8'}, - '168': {'ext': 'webm', 'height': 480, 'width': 854, 'format_note': 'DASH video', 'container': 'webm', 'vcodec': 'vp8'}, - '169': {'ext': 'webm', 'height': 720, 'width': 1280, 'format_note': 'DASH video', 'container': 'webm', 'vcodec': 'vp8'}, - '170': {'ext': 'webm', 'height': 1080, 'width': 1920, 'format_note': 'DASH video', 'container': 'webm', 'vcodec': 'vp8'}, - '218': {'ext': 'webm', 'height': 480, 'width': 854, 'format_note': 'DASH video', 'container': 'webm', 'vcodec': 'vp8'}, - '219': {'ext': 'webm', 'height': 480, 'width': 854, 'format_note': 'DASH video', 'container': 'webm', 'vcodec': 'vp8'}, - '278': {'ext': 'webm', 'height': 144, 'format_note': 'DASH video', 'container': 'webm', 'vcodec': 'vp9'}, - '242': {'ext': 'webm', 'height': 240, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '243': {'ext': 'webm', 'height': 360, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '244': {'ext': 'webm', 'height': 480, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '245': {'ext': 'webm', 'height': 480, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '246': {'ext': 'webm', 'height': 480, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '247': {'ext': 'webm', 'height': 720, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '248': {'ext': 'webm', 'height': 1080, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '271': {'ext': 'webm', 'height': 1440, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - # itag 272 videos are either 3840x2160 (e.g. RtoitU2A-3E) or 7680x4320 (sLprVF6d7Ug) - '272': {'ext': 'webm', 'height': 2160, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '302': {'ext': 'webm', 'height': 720, 'format_note': 'DASH video', 'vcodec': 'vp9', 'fps': 60}, - '303': {'ext': 'webm', 'height': 1080, 'format_note': 'DASH video', 'vcodec': 'vp9', 'fps': 60}, - '308': {'ext': 'webm', 'height': 1440, 'format_note': 'DASH video', 'vcodec': 'vp9', 'fps': 60}, - '313': {'ext': 'webm', 'height': 2160, 'format_note': 'DASH video', 'vcodec': 'vp9'}, - '315': {'ext': 'webm', 'height': 2160, 'format_note': 'DASH video', 'vcodec': 'vp9', 'fps': 60}, - - # Dash webm audio - '171': {'ext': 'webm', 'acodec': 'vorbis', 'format_note': 'DASH audio', 'abr': 128}, - '172': {'ext': 'webm', 'acodec': 'vorbis', 'format_note': 'DASH audio', 'abr': 256}, - - # Dash webm audio with opus inside - '249': {'ext': 'webm', 'format_note': 'DASH audio', 'acodec': 'opus', 'abr': 50}, - '250': {'ext': 'webm', 'format_note': 'DASH audio', 'acodec': 'opus', 'abr': 70}, - '251': {'ext': 'webm', 'format_note': 'DASH audio', 'acodec': 'opus', 'abr': 160}, - - # RTMP (unnamed) - '_rtmp': {'protocol': 'rtmp'}, - - # av01 video only formats sometimes served with "unknown" codecs - '394': {'ext': 'mp4', 'height': 144, 'format_note': 'DASH video', 'vcodec': 'av01.0.00M.08'}, - '395': {'ext': 'mp4', 'height': 240, 'format_note': 'DASH video', 'vcodec': 'av01.0.00M.08'}, - '396': {'ext': 'mp4', 'height': 360, 'format_note': 'DASH video', 'vcodec': 'av01.0.01M.08'}, - '397': {'ext': 'mp4', 'height': 480, 'format_note': 'DASH video', 'vcodec': 'av01.0.04M.08'}, - '398': {'ext': 'mp4', 'height': 720, 'format_note': 'DASH video', 'vcodec': 'av01.0.05M.08'}, - '399': {'ext': 'mp4', 'height': 1080, 'format_note': 'DASH video', 'vcodec': 'av01.0.08M.08'}, - '400': {'ext': 'mp4', 'height': 1440, 'format_note': 'DASH video', 'vcodec': 'av01.0.12M.08'}, - '401': {'ext': 'mp4', 'height': 2160, 'format_note': 'DASH video', 'vcodec': 'av01.0.12M.08'}, - } _SUBTITLE_FORMATS = ('json3', 'srv1', 'srv2', 'srv3', 'ttml', 'srt', 'vtt') _DEFAULT_CLIENTS = ('android_sdkless', 'tv', 'web_safari', 'web') _DEFAULT_AUTHED_CLIENTS = ('tv', 'web_safari', 'web')