Update On Wed Nov 26 19:35:55 CET 2025

This commit is contained in:
github-action[bot]
2025-11-26 19:35:56 +01:00
parent ee7416bae7
commit 5f24d5979b
38 changed files with 505 additions and 261 deletions
+1
View File
@@ -1193,3 +1193,4 @@ Update On Sat Nov 22 19:36:29 CET 2025
Update On Sun Nov 23 19:36:55 CET 2025 Update On Sun Nov 23 19:36:55 CET 2025
Update On Mon Nov 24 19:40:17 CET 2025 Update On Mon Nov 24 19:40:17 CET 2025
Update On Tue Nov 25 19:40:43 CET 2025 Update On Tue Nov 25 19:40:43 CET 2025
Update On Wed Nov 26 19:35:47 CET 2025
+1 -1
View File
@@ -289,7 +289,7 @@ func (d *Decoder) decodeBool(name string, data any, val reflect.Value) (err erro
case isInt(kind) && d.option.WeaklyTypedInput: case isInt(kind) && d.option.WeaklyTypedInput:
val.SetBool(dataVal.Int() != 0) val.SetBool(dataVal.Int() != 0)
case isUint(kind) && d.option.WeaklyTypedInput: case isUint(kind) && d.option.WeaklyTypedInput:
val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) val.SetBool(dataVal.Uint() != 0)
default: default:
err = fmt.Errorf( err = fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s'", "'%s' expected type '%s', got unconvertible type '%s'",
+13 -12
View File
@@ -355,7 +355,7 @@ dependencies = [
"objc2-foundation 0.3.2", "objc2-foundation 0.3.2",
"parking_lot", "parking_lot",
"percent-encoding", "percent-encoding",
"windows-sys 0.52.0", "windows-sys 0.59.0",
"wl-clipboard-rs", "wl-clipboard-rs",
"x11rb", "x11rb",
] ]
@@ -2853,7 +2853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad"
dependencies = [ dependencies = [
"libc", "libc",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -5334,14 +5334,15 @@ dependencies = [
[[package]] [[package]]
name = "mlua" name = "mlua"
version = "0.11.4" version = "0.11.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9be1c2bfc684b8a228fbaebf954af7a47a98ec27721986654a4cc2c40a20cc7e" checksum = "935ac67539907efcd7198137eb7358e052555f77fe1b2916600a2249351f2b33"
dependencies = [ dependencies = [
"bstr", "bstr",
"either", "either",
"erased-serde", "erased-serde",
"futures-util", "futures-util",
"libc",
"mlua-sys", "mlua-sys",
"num-traits", "num-traits",
"parking_lot", "parking_lot",
@@ -5353,9 +5354,9 @@ dependencies = [
[[package]] [[package]]
name = "mlua-sys" name = "mlua-sys"
version = "0.8.3" version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d4dc9cfc5a7698899802e97480617d9726f7da78c910db989d4d0fd4991d900" checksum = "8c968af21bf6b19fc9ca8e7b85ee16f86e4c9e3d0591de101a5608086bda0ad8"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if",
@@ -6333,9 +6334,9 @@ checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
[[package]] [[package]]
name = "open" name = "open"
version = "5.3.2" version = "5.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2483562e62ea94312f3576a7aca397306df7990b8d89033e18766744377ef95" checksum = "43bb73a7fa3799b198970490a51174027ba0d4ec504b03cd08caf513d40024bc"
dependencies = [ dependencies = [
"dunce", "dunce",
"is-wsl", "is-wsl",
@@ -7383,7 +7384,7 @@ dependencies = [
"once_cell", "once_cell",
"socket2", "socket2",
"tracing", "tracing",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -7937,7 +7938,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys 0.4.15", "linux-raw-sys 0.4.15",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -7950,7 +7951,7 @@ dependencies = [
"errno", "errno",
"libc", "libc",
"linux-raw-sys 0.9.4", "linux-raw-sys 0.9.4",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
@@ -9606,7 +9607,7 @@ dependencies = [
"getrandom 0.3.3", "getrandom 0.3.3",
"once_cell", "once_cell",
"rustix 1.0.8", "rustix 1.0.8",
"windows-sys 0.52.0", "windows-sys 0.59.0",
] ]
[[package]] [[package]]
+84 -85
View File
@@ -82,7 +82,7 @@ importers:
version: 4.5.5(@vueuse/core@14.0.0(vue@3.5.25(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.25(typescript@5.9.3)) version: 4.5.5(@vueuse/core@14.0.0(vue@3.5.25(typescript@5.9.3)))(@vueuse/integrations@14.0.0(focus-trap@7.6.2)(jwt-decode@4.0.0)(vue@3.5.25(typescript@5.9.3)))(focus-trap@7.6.2)(vue@3.5.25(typescript@5.9.3))
vue-i18n: vue-i18n:
specifier: ^11.1.10 specifier: ^11.1.10
version: 11.2.1(vue@3.5.25(typescript@5.9.3)) version: 11.2.2(vue@3.5.25(typescript@5.9.3))
vue-lazyload: vue-lazyload:
specifier: ^3.0.0 specifier: ^3.0.0
version: 3.0.0 version: 3.0.0
@@ -98,7 +98,7 @@ importers:
devDependencies: devDependencies:
'@intlify/unplugin-vue-i18n': '@intlify/unplugin-vue-i18n':
specifier: ^11.0.1 specifier: ^11.0.1
version: 11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) version: 11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@tsconfig/node24': '@tsconfig/node24':
specifier: ^24.0.2 specifier: ^24.0.2
version: 24.0.3 version: 24.0.3
@@ -110,7 +110,7 @@ importers:
version: 24.10.1 version: 24.10.1
'@typescript-eslint/eslint-plugin': '@typescript-eslint/eslint-plugin':
specifier: ^8.37.0 specifier: ^8.37.0
version: 8.47.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3) version: 8.48.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)
'@vitejs/plugin-legacy': '@vitejs/plugin-legacy':
specifier: ^7.2.1 specifier: ^7.2.1
version: 7.2.1(terser@5.44.1)(vite@7.2.4(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0)) version: 7.2.1(terser@5.44.1)(vite@7.2.4(@types/node@24.10.1)(terser@5.44.1)(yaml@2.7.0))
@@ -122,7 +122,7 @@ importers:
version: 10.2.0(eslint@9.39.1)(prettier@3.6.2) version: 10.2.0(eslint@9.39.1)(prettier@3.6.2)
'@vue/eslint-config-typescript': '@vue/eslint-config-typescript':
specifier: ^14.6.0 specifier: ^14.6.0
version: 14.6.0(eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3) version: 14.6.0(eslint-plugin-vue@10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)
'@vue/tsconfig': '@vue/tsconfig':
specifier: ^0.8.1 specifier: ^0.8.1
version: 0.8.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3)) version: 0.8.1(typescript@5.9.3)(vue@3.5.25(typescript@5.9.3))
@@ -140,7 +140,7 @@ importers:
version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2) version: 5.5.4(eslint-config-prettier@10.1.8(eslint@9.39.1))(eslint@9.39.1)(prettier@3.6.2)
eslint-plugin-vue: eslint-plugin-vue:
specifier: ^10.5.1 specifier: ^10.5.1
version: 10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)) version: 10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
postcss: postcss:
specifier: ^8.5.6 specifier: ^8.5.6
version: 8.5.6 version: 8.5.6
@@ -887,20 +887,20 @@ packages:
vue-i18n: vue-i18n:
optional: true optional: true
'@intlify/core-base@11.2.1': '@intlify/core-base@11.2.2':
resolution: {integrity: sha512-2V1A4yaN9ElAnQ6ih3HHEc+jZ+sHV6BlQHjCsnIVlOotL5NCUgJElIxgUFiJs6zV4puoAq3hHuQIfWNp+J+8yQ==} resolution: {integrity: sha512-0mCTBOLKIqFUP3BzwuFW23hYEl9g/wby6uY//AC5hTgQfTsM2srCYF2/hYGp+a5DZ/HIFIgKkLJMzXTt30r0JQ==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
'@intlify/message-compiler@11.2.1': '@intlify/message-compiler@11.2.2':
resolution: {integrity: sha512-J2454D3Agg3Kvgaj14gxTleJU8/H06Sisz7C2BwiHF0/i5Soyfb5ySpwn8GCL6yscDbOGj6xM+lUe6gO6BFQyg==} resolution: {integrity: sha512-XS2p8Ff5JxWsKhgfld4/MRQzZRQ85drMMPhb7Co6Be4ZOgqJX1DzcZt0IFgGTycgqL8rkYNwgnD443Q+TapOoA==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
'@intlify/shared@11.1.12': '@intlify/shared@11.1.12':
resolution: {integrity: sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==} resolution: {integrity: sha512-Om86EjuQtA69hdNj3GQec9ZC0L0vPSAnXzB3gP/gyJ7+mA7t06d9aOAiqMZ+xEOsumGP4eEBlfl8zF2LOTzf2A==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
'@intlify/shared@11.2.1': '@intlify/shared@11.2.2':
resolution: {integrity: sha512-O67LZM4dbfr70WCsZLW+g+pIXdgQ66laLVd/FicW7iYgP/RuH0X1FDGSh+Hr9Gou/8TeldUE6KmTGdLwX2ufIA==} resolution: {integrity: sha512-OtCmyFpSXxNu/oET/aN6HtPCbZ01btXVd0f3w00YsHOb13Kverk1jzA2k47pAekM55qbUw421fvPF1yxZ+gicw==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
'@intlify/unplugin-vue-i18n@11.0.1': '@intlify/unplugin-vue-i18n@11.0.1':
@@ -1127,11 +1127,11 @@ packages:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0' typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/eslint-plugin@8.47.0': '@typescript-eslint/eslint-plugin@8.48.0':
resolution: {integrity: sha512-fe0rz9WJQ5t2iaLfdbDc9T80GJy0AeO453q8C3YCilnGozvOyCG5t+EZtg7j7D88+c3FipfP/x+wzGnh1xp8ZA==} resolution: {integrity: sha512-XxXP5tL1txl13YFtrECECQYeZjBZad4fyd3cFV4a19LkAY/bIp9fev3US4S5fDVV2JaYFiKAZ/GRTOLer+mbyQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
'@typescript-eslint/parser': ^8.47.0 '@typescript-eslint/parser': ^8.48.0
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
@@ -1154,8 +1154,8 @@ packages:
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/project-service@8.47.0': '@typescript-eslint/project-service@8.48.0':
resolution: {integrity: sha512-2X4BX8hUeB5JcA1TQJ7GjcgulXQ+5UkNb0DL8gHsHUHdFoiCTJoYLTpib3LtSDPZsRET5ygN4qqIWrHyYIKERA==} resolution: {integrity: sha512-Ne4CTZyRh1BecBf84siv42wv5vQvVmgtk8AuiEffKTUo3DrBaGYZueJSxxBZ8fjk/N3DrgChH4TOdIOwOwiqqw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
@@ -1168,8 +1168,8 @@ packages:
resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==} resolution: {integrity: sha512-tMDbLGXb1wC+McN1M6QeDx7P7c0UWO5z9CXqp7J8E+xGcJuUuevWKxuG8j41FoweS3+L41SkyKKkia16jpX7CA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/scope-manager@8.47.0': '@typescript-eslint/scope-manager@8.48.0':
resolution: {integrity: sha512-a0TTJk4HXMkfpFkL9/WaGTNuv7JWfFTQFJd6zS9dVAjKsojmv9HT55xzbEpnZoY+VUb+YXLMp+ihMLz/UlZfDg==} resolution: {integrity: sha512-uGSSsbrtJrLduti0Q1Q9+BF1/iFKaxGoQwjWOIVNJv0o6omrdyR8ct37m4xIl5Zzpkp69Kkmvom7QFTtue89YQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/tsconfig-utils@8.37.0': '@typescript-eslint/tsconfig-utils@8.37.0':
@@ -1184,8 +1184,8 @@ packages:
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/tsconfig-utils@8.47.0': '@typescript-eslint/tsconfig-utils@8.48.0':
resolution: {integrity: sha512-ybUAvjy4ZCL11uryalkKxuT3w3sXJAuWhOoGS3T/Wu+iUu1tGJmk5ytSY8gbdACNARmcYEB0COksD2j6hfGK2g==} resolution: {integrity: sha512-WNebjBdFdyu10sR1M4OXTt2OkMd5KWIL+LLfeH9KhgP+jzfDV/LI3eXzwJ1s9+Yc0Kzo2fQCdY/OpdusCMmh6w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
@@ -1197,8 +1197,8 @@ packages:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0' typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/type-utils@8.47.0': '@typescript-eslint/type-utils@8.48.0':
resolution: {integrity: sha512-QC9RiCmZ2HmIdCEvhd1aJELBlD93ErziOXXlHEZyuBo3tBiAZieya0HLIxp+DoDWlsQqDawyKuNEhORyku+P8A==} resolution: {integrity: sha512-zbeVaVqeXhhab6QNEKfK96Xyc7UQuoFWERhEnj3mLVnUWrQnv15cJNseUni7f3g557gm0e46LZ6IJ4NJVOgOpw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
@@ -1212,8 +1212,8 @@ packages:
resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==} resolution: {integrity: sha512-USjyxm3gQEePdUwJBFjjGNG18xY9A2grDVGuk7/9AkjIF1L+ZrVnwR5VAU5JXtUnBL/Nwt3H31KlRDaksnM7/w==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/types@8.47.0': '@typescript-eslint/types@8.48.0':
resolution: {integrity: sha512-nHAE6bMKsizhA2uuYZbEbmp5z2UpffNrPEqiKIeN7VsV6UY/roxanWfoRrf6x/k9+Obf+GQdkm0nPU+vnMXo9A==} resolution: {integrity: sha512-cQMcGQQH7kwKoVswD1xdOytxQR60MWKM1di26xSUtxehaDs/32Zpqsu5WJlXTtTTqyAVK8R7hvsUnIXRS+bjvA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/typescript-estree@8.37.0': '@typescript-eslint/typescript-estree@8.37.0':
@@ -1228,8 +1228,8 @@ packages:
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
'@typescript-eslint/typescript-estree@8.47.0': '@typescript-eslint/typescript-estree@8.48.0':
resolution: {integrity: sha512-k6ti9UepJf5NpzCjH31hQNLHQWupTRPhZ+KFF8WtTuTpy7uHPfeg2NM7cP27aCGajoEplxJDFVCEm9TGPYyiVg==} resolution: {integrity: sha512-ljHab1CSO4rGrQIAyizUS6UGHHCiAYhbfcIZ1zVJr5nMryxlXMVWS3duFPSKvSUbFPwkXMFk1k0EMIjub4sRRQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
typescript: '>=4.8.4 <6.0.0' typescript: '>=4.8.4 <6.0.0'
@@ -1241,8 +1241,8 @@ packages:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
typescript: '>=4.8.4 <5.9.0' typescript: '>=4.8.4 <5.9.0'
'@typescript-eslint/utils@8.47.0': '@typescript-eslint/utils@8.48.0':
resolution: {integrity: sha512-g7XrNf25iL4TJOiPqatNuaChyqt49a/onq5YsJ9+hXeugK+41LVg7AxikMfM02PC6jbNtZLCJj6AUcQXJS/jGQ==} resolution: {integrity: sha512-yTJO1XuGxCsSfIVt1+1UrLHtue8xz16V8apzPYI06W0HbEbEWHxHXgZaAgavIkoh+GeV6hKKd5jm0sS6OYxWXQ==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
eslint: ^8.57.0 || ^9.0.0 eslint: ^8.57.0 || ^9.0.0
@@ -1256,8 +1256,8 @@ packages:
resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==} resolution: {integrity: sha512-/++5CYLQqsO9HFGLI7APrxBJYo+5OCMpViuhV8q5/Qa3o5mMrF//eQHks+PXcsAVaLdn817fMuS7zqoXNNZGaw==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@typescript-eslint/visitor-keys@8.47.0': '@typescript-eslint/visitor-keys@8.48.0':
resolution: {integrity: sha512-SIV3/6eftCy1bNzCQoPmbWsRLujS8t5iDIZ4spZOBHqrM+yfX2ogg8Tt3PDTAVKw3sSCiUgg30uOAvK2r9zGjQ==} resolution: {integrity: sha512-T0XJMaRPOH3+LBbAfzR2jalckP1MSG/L9eUtY0DEzUyVaXJ/t6zN0nR7co5kz0Jko/nkSYCBRkz1djvjajVTTg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
'@videojs/http-streaming@3.17.2': '@videojs/http-streaming@3.17.2':
@@ -1668,8 +1668,8 @@ packages:
eslint-config-prettier: eslint-config-prettier:
optional: true optional: true
eslint-plugin-vue@10.6.0: eslint-plugin-vue@10.6.1:
resolution: {integrity: sha512-TsoFluWxOpsJlE/l2jJygLQLWBPJ3Qdkesv7tBIunICbTcG0dS1/NBw/Ol4tJw5kHWlAVds4lUmC29/vlPUcEQ==} resolution: {integrity: sha512-OMvDAFbewocYrJamF1EoSWoT4xa7/QRb/yYouEZMiroTE+WRmFUreR+kAFQHqM45W3kg5oljVfUYfH9HEwX1Bg==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
peerDependencies: peerDependencies:
'@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0 '@stylistic/eslint-plugin': ^2.0.0 || ^3.0.0 || ^4.0.0 || ^5.0.0
@@ -2496,8 +2496,8 @@ packages:
focus-trap: '>=7.2.0' focus-trap: '>=7.2.0'
vue: '>=3.2.0' vue: '>=3.2.0'
vue-i18n@11.2.1: vue-i18n@11.2.2:
resolution: {integrity: sha512-cc3Wx4eJZac9WMS8mxhfYiCipm9PBQ2Dz15piWYm7DwNcCehaKRgpolEdiqrjjT27T3Wijz3xJ7NeIc8ofIWAA==} resolution: {integrity: sha512-ULIKZyRluUPRCZmihVgUvpq8hJTtOqnbGZuv4Lz+byEKZq4mU0g92og414l6f/4ju+L5mORsiUuEPYrAuX2NJg==}
engines: {node: '>= 16'} engines: {node: '>= 16'}
peerDependencies: peerDependencies:
vue: ^3.0.0 vue: ^3.0.0
@@ -3359,9 +3359,9 @@ snapshots:
'@humanwhocodes/retry@0.4.3': {} '@humanwhocodes/retry@0.4.3': {}
'@intlify/bundle-utils@11.0.1(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))': '@intlify/bundle-utils@11.0.1(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))':
dependencies: dependencies:
'@intlify/message-compiler': 11.2.1 '@intlify/message-compiler': 11.2.2
'@intlify/shared': 11.1.12 '@intlify/shared': 11.1.12
acorn: 8.15.0 acorn: 8.15.0
esbuild: 0.25.12 esbuild: 0.25.12
@@ -3371,28 +3371,28 @@ snapshots:
source-map-js: 1.2.1 source-map-js: 1.2.1
yaml-eslint-parser: 1.2.3 yaml-eslint-parser: 1.2.3
optionalDependencies: optionalDependencies:
vue-i18n: 11.2.1(vue@3.5.25(typescript@5.9.3)) vue-i18n: 11.2.2(vue@3.5.25(typescript@5.9.3))
'@intlify/core-base@11.2.1': '@intlify/core-base@11.2.2':
dependencies: dependencies:
'@intlify/message-compiler': 11.2.1 '@intlify/message-compiler': 11.2.2
'@intlify/shared': 11.2.1 '@intlify/shared': 11.2.2
'@intlify/message-compiler@11.2.1': '@intlify/message-compiler@11.2.2':
dependencies: dependencies:
'@intlify/shared': 11.2.1 '@intlify/shared': 11.2.2
source-map-js: 1.2.1 source-map-js: 1.2.1
'@intlify/shared@11.1.12': {} '@intlify/shared@11.1.12': {}
'@intlify/shared@11.2.1': {} '@intlify/shared@11.2.2': {}
'@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))': '@intlify/unplugin-vue-i18n@11.0.1(@vue/compiler-dom@3.5.25)(eslint@9.39.1)(rollup@4.53.3)(typescript@5.9.3)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
'@intlify/bundle-utils': 11.0.1(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3))) '@intlify/bundle-utils': 11.0.1(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))
'@intlify/shared': 11.1.12 '@intlify/shared': 11.1.12
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3)) '@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))
'@rollup/pluginutils': 5.3.0(rollup@4.53.3) '@rollup/pluginutils': 5.3.0(rollup@4.53.3)
'@typescript-eslint/scope-manager': 8.46.4 '@typescript-eslint/scope-manager': 8.46.4
'@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.46.4(typescript@5.9.3)
@@ -3403,7 +3403,7 @@ snapshots:
unplugin: 2.3.10 unplugin: 2.3.10
vue: 3.5.25(typescript@5.9.3) vue: 3.5.25(typescript@5.9.3)
optionalDependencies: optionalDependencies:
vue-i18n: 11.2.1(vue@3.5.25(typescript@5.9.3)) vue-i18n: 11.2.2(vue@3.5.25(typescript@5.9.3))
transitivePeerDependencies: transitivePeerDependencies:
- '@vue/compiler-dom' - '@vue/compiler-dom'
- eslint - eslint
@@ -3411,14 +3411,14 @@ snapshots:
- supports-color - supports-color
- typescript - typescript
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))': '@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.12)(@vue/compiler-dom@3.5.25)(vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)))(vue@3.5.25(typescript@5.9.3))':
dependencies: dependencies:
'@babel/parser': 7.28.5 '@babel/parser': 7.28.5
optionalDependencies: optionalDependencies:
'@intlify/shared': 11.1.12 '@intlify/shared': 11.1.12
'@vue/compiler-dom': 3.5.25 '@vue/compiler-dom': 3.5.25
vue: 3.5.25(typescript@5.9.3) vue: 3.5.25(typescript@5.9.3)
vue-i18n: 11.2.1(vue@3.5.25(typescript@5.9.3)) vue-i18n: 11.2.2(vue@3.5.25(typescript@5.9.3))
'@jridgewell/gen-mapping@0.3.13': '@jridgewell/gen-mapping@0.3.13':
dependencies: dependencies:
@@ -3576,14 +3576,14 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/eslint-plugin@8.47.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)': '@typescript-eslint/eslint-plugin@8.48.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(typescript@5.9.3)':
dependencies: dependencies:
'@eslint-community/regexpp': 4.12.2 '@eslint-community/regexpp': 4.12.2
'@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3) '@typescript-eslint/parser': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/scope-manager': 8.47.0 '@typescript-eslint/scope-manager': 8.48.0
'@typescript-eslint/type-utils': 8.47.0(eslint@9.39.1)(typescript@5.9.3) '@typescript-eslint/type-utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/utils': 8.47.0(eslint@9.39.1)(typescript@5.9.3) '@typescript-eslint/utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3)
'@typescript-eslint/visitor-keys': 8.47.0 '@typescript-eslint/visitor-keys': 8.48.0
eslint: 9.39.1 eslint: 9.39.1
graphemer: 1.4.0 graphemer: 1.4.0
ignore: 7.0.5 ignore: 7.0.5
@@ -3623,10 +3623,10 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/project-service@8.47.0(typescript@5.9.3)': '@typescript-eslint/project-service@8.48.0(typescript@5.9.3)':
dependencies: dependencies:
'@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3) '@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3)
'@typescript-eslint/types': 8.47.0 '@typescript-eslint/types': 8.48.0
debug: 4.4.3 debug: 4.4.3
typescript: 5.9.3 typescript: 5.9.3
transitivePeerDependencies: transitivePeerDependencies:
@@ -3642,10 +3642,10 @@ snapshots:
'@typescript-eslint/types': 8.46.4 '@typescript-eslint/types': 8.46.4
'@typescript-eslint/visitor-keys': 8.46.4 '@typescript-eslint/visitor-keys': 8.46.4
'@typescript-eslint/scope-manager@8.47.0': '@typescript-eslint/scope-manager@8.48.0':
dependencies: dependencies:
'@typescript-eslint/types': 8.47.0 '@typescript-eslint/types': 8.48.0
'@typescript-eslint/visitor-keys': 8.47.0 '@typescript-eslint/visitor-keys': 8.48.0
'@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.9.3)': '@typescript-eslint/tsconfig-utils@8.37.0(typescript@5.9.3)':
dependencies: dependencies:
@@ -3655,7 +3655,7 @@ snapshots:
dependencies: dependencies:
typescript: 5.9.3 typescript: 5.9.3
'@typescript-eslint/tsconfig-utils@8.47.0(typescript@5.9.3)': '@typescript-eslint/tsconfig-utils@8.48.0(typescript@5.9.3)':
dependencies: dependencies:
typescript: 5.9.3 typescript: 5.9.3
@@ -3671,11 +3671,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/type-utils@8.47.0(eslint@9.39.1)(typescript@5.9.3)': '@typescript-eslint/type-utils@8.48.0(eslint@9.39.1)(typescript@5.9.3)':
dependencies: dependencies:
'@typescript-eslint/types': 8.47.0 '@typescript-eslint/types': 8.48.0
'@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3)
'@typescript-eslint/utils': 8.47.0(eslint@9.39.1)(typescript@5.9.3) '@typescript-eslint/utils': 8.48.0(eslint@9.39.1)(typescript@5.9.3)
debug: 4.4.3 debug: 4.4.3
eslint: 9.39.1 eslint: 9.39.1
ts-api-utils: 2.1.0(typescript@5.9.3) ts-api-utils: 2.1.0(typescript@5.9.3)
@@ -3687,7 +3687,7 @@ snapshots:
'@typescript-eslint/types@8.46.4': {} '@typescript-eslint/types@8.46.4': {}
'@typescript-eslint/types@8.47.0': {} '@typescript-eslint/types@8.48.0': {}
'@typescript-eslint/typescript-estree@8.37.0(typescript@5.9.3)': '@typescript-eslint/typescript-estree@8.37.0(typescript@5.9.3)':
dependencies: dependencies:
@@ -3721,17 +3721,16 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/typescript-estree@8.47.0(typescript@5.9.3)': '@typescript-eslint/typescript-estree@8.48.0(typescript@5.9.3)':
dependencies: dependencies:
'@typescript-eslint/project-service': 8.47.0(typescript@5.9.3) '@typescript-eslint/project-service': 8.48.0(typescript@5.9.3)
'@typescript-eslint/tsconfig-utils': 8.47.0(typescript@5.9.3) '@typescript-eslint/tsconfig-utils': 8.48.0(typescript@5.9.3)
'@typescript-eslint/types': 8.47.0 '@typescript-eslint/types': 8.48.0
'@typescript-eslint/visitor-keys': 8.47.0 '@typescript-eslint/visitor-keys': 8.48.0
debug: 4.4.3 debug: 4.4.3
fast-glob: 3.3.3
is-glob: 4.0.3
minimatch: 9.0.5 minimatch: 9.0.5
semver: 7.7.3 semver: 7.7.3
tinyglobby: 0.2.15
ts-api-utils: 2.1.0(typescript@5.9.3) ts-api-utils: 2.1.0(typescript@5.9.3)
typescript: 5.9.3 typescript: 5.9.3
transitivePeerDependencies: transitivePeerDependencies:
@@ -3748,12 +3747,12 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@typescript-eslint/utils@8.47.0(eslint@9.39.1)(typescript@5.9.3)': '@typescript-eslint/utils@8.48.0(eslint@9.39.1)(typescript@5.9.3)':
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
'@typescript-eslint/scope-manager': 8.47.0 '@typescript-eslint/scope-manager': 8.48.0
'@typescript-eslint/types': 8.47.0 '@typescript-eslint/types': 8.48.0
'@typescript-eslint/typescript-estree': 8.47.0(typescript@5.9.3) '@typescript-eslint/typescript-estree': 8.48.0(typescript@5.9.3)
eslint: 9.39.1 eslint: 9.39.1
typescript: 5.9.3 typescript: 5.9.3
transitivePeerDependencies: transitivePeerDependencies:
@@ -3769,9 +3768,9 @@ snapshots:
'@typescript-eslint/types': 8.46.4 '@typescript-eslint/types': 8.46.4
eslint-visitor-keys: 4.2.1 eslint-visitor-keys: 4.2.1
'@typescript-eslint/visitor-keys@8.47.0': '@typescript-eslint/visitor-keys@8.48.0':
dependencies: dependencies:
'@typescript-eslint/types': 8.47.0 '@typescript-eslint/types': 8.48.0
eslint-visitor-keys: 4.2.1 eslint-visitor-keys: 4.2.1
'@videojs/http-streaming@3.17.2(video.js@8.23.4)': '@videojs/http-streaming@3.17.2(video.js@8.23.4)':
@@ -3892,11 +3891,11 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- '@types/eslint' - '@types/eslint'
'@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)': '@vue/eslint-config-typescript@14.6.0(eslint-plugin-vue@10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)))(eslint@9.39.1)(typescript@5.9.3)':
dependencies: dependencies:
'@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3) '@typescript-eslint/utils': 8.37.0(eslint@9.39.1)(typescript@5.9.3)
eslint: 9.39.1 eslint: 9.39.1
eslint-plugin-vue: 10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)) eslint-plugin-vue: 10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1))
fast-glob: 3.3.3 fast-glob: 3.3.3
typescript-eslint: 8.37.0(eslint@9.39.1)(typescript@5.9.3) typescript-eslint: 8.37.0(eslint@9.39.1)(typescript@5.9.3)
vue-eslint-parser: 10.2.0(eslint@9.39.1) vue-eslint-parser: 10.2.0(eslint@9.39.1)
@@ -4229,7 +4228,7 @@ snapshots:
optionalDependencies: optionalDependencies:
eslint-config-prettier: 10.1.8(eslint@9.39.1) eslint-config-prettier: 10.1.8(eslint@9.39.1)
eslint-plugin-vue@10.6.0(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)): eslint-plugin-vue@10.6.1(@typescript-eslint/parser@8.37.0(eslint@9.39.1)(typescript@5.9.3))(eslint@9.39.1)(vue-eslint-parser@10.2.0(eslint@9.39.1)):
dependencies: dependencies:
'@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1) '@eslint-community/eslint-utils': 4.9.0(eslint@9.39.1)
eslint: 9.39.1 eslint: 9.39.1
@@ -5021,10 +5020,10 @@ snapshots:
focus-trap: 7.6.2 focus-trap: 7.6.2
vue: 3.5.25(typescript@5.9.3) vue: 3.5.25(typescript@5.9.3)
vue-i18n@11.2.1(vue@3.5.25(typescript@5.9.3)): vue-i18n@11.2.2(vue@3.5.25(typescript@5.9.3)):
dependencies: dependencies:
'@intlify/core-base': 11.2.1 '@intlify/core-base': 11.2.2
'@intlify/shared': 11.2.1 '@intlify/shared': 11.2.2
'@vue/devtools-api': 6.6.4 '@vue/devtools-api': 6.6.4
vue: 3.5.25(typescript@5.9.3) vue: 3.5.25(typescript@5.9.3)
+2 -2
View File
@@ -102,7 +102,7 @@
"username": "Korisničko ime", "username": "Korisničko ime",
"usernameTaken": "Korisničko ime zauzeto", "usernameTaken": "Korisničko ime zauzeto",
"wrongCredentials": "Neispravno korisničko ime/lozinka", "wrongCredentials": "Neispravno korisničko ime/lozinka",
"passwordTooShort": "Password must be at least {min} characters", "passwordTooShort": "Lozinka mora sadržavati minimalno {min} znakova",
"logout_reasons": { "logout_reasons": {
"inactivity": "Odjavljeni ste zbog neaktivnosti." "inactivity": "Odjavljeni ste zbog neaktivnosti."
} }
@@ -167,7 +167,7 @@
"allowNew": "Stvori nove datoteke i mape", "allowNew": "Stvori nove datoteke i mape",
"allowPublish": "Objavi nove objave i stranice", "allowPublish": "Objavi nove objave i stranice",
"allowSignup": "Dopusti registraciju korisnicima", "allowSignup": "Dopusti registraciju korisnicima",
"hideLoginButton": "Hide the login button from public pages", "hideLoginButton": "Sakrij tipku za prijavu s javnih stranica",
"avoidChanges": "(ostavite prazno kako biste izbjegli promjene)", "avoidChanges": "(ostavite prazno kako biste izbjegli promjene)",
"branding": "Brendiranje", "branding": "Brendiranje",
"brandingDirectoryPath": "Put brendiranja", "brandingDirectoryPath": "Put brendiranja",
@@ -90,7 +90,7 @@
// MAC1 ---SGMII---> QCA8337 SerDes // MAC1 ---SGMII---> QCA8337 SerDes
&dp2 { &dp2 {
status = "okay"; status = "okay";
nvmem-cells = <&macaddr_dp2>; nvmem-cells = <&macaddr_dp2 0>;
nvmem-cell-names = "mac-address"; nvmem-cell-names = "mac-address";
fixed-link { fixed-link {
@@ -230,11 +230,8 @@
compatible = "qcom,smem-part"; compatible = "qcom,smem-part";
partition-0-art { partition-0-art {
compatible = "fixed-partitions"; label = "0:art";
label = "0:ART";
read-only; read-only;
#address-cells = <1>;
#size-cells = <1>;
nvmem-layout { nvmem-layout {
compatible = "fixed-layout"; compatible = "fixed-layout";
@@ -244,7 +241,7 @@
macaddr_dp2: macaddr@0 { macaddr_dp2: macaddr@0 {
compatible = "mac-base"; compatible = "mac-base";
#nvmem-cell-cells = <1>; #nvmem-cell-cells = <1>;
reg = <0x0 0x6>; reg = <0x6 0x6>;
}; };
}; };
}; };
+16 -3
View File
@@ -683,7 +683,7 @@ func (m *Mux) maybePickExistingUnderlay() Underlay {
// cleanUnderlay removes closed underlays. // cleanUnderlay removes closed underlays.
// This method MUST be called only when holding the mu lock. // This method MUST be called only when holding the mu lock.
func (m *Mux) cleanUnderlay(alsoDisableIdleUnderlay bool) { func (m *Mux) cleanUnderlay(alsoDisableIdleOrOverloadUnderlay bool) {
remaining := make([]Underlay, 0) remaining := make([]Underlay, 0)
disable := 0 disable := 0
close := 0 close := 0
@@ -691,11 +691,24 @@ func (m *Mux) cleanUnderlay(alsoDisableIdleUnderlay bool) {
select { select {
case <-underlay.Done(): case <-underlay.Done():
default: default:
if alsoDisableIdleUnderlay && underlay.SessionCount() == 0 { if alsoDisableIdleOrOverloadUnderlay {
if underlay.Scheduler().TryDisable() { // Disable idle underlay.
if underlay.SessionCount() == 0 {
if underlay.Scheduler().TryDisableIdle() {
disable++ disable++
} }
} }
// Disable overloaded underlay.
// If multiplexFactor is 1, the limit is 1 GiB.
var trafficVolumeLimit int64 = 512 * 1024 * 1024 << m.multiplexFactor
if underlay.Scheduler().DisableTime().IsZero() && (underlay.InBytes() > trafficVolumeLimit || underlay.OutBytes() > trafficVolumeLimit) {
underlay.Scheduler().SetRemainingTime(0)
disable++
}
}
// Close idle underlay.
if underlay.SessionCount() == 0 && underlay.Scheduler().Idle() { if underlay.SessionCount() == 0 && underlay.Scheduler().Idle() {
underlay.Close() underlay.Close()
close++ close++
+11 -4
View File
@@ -57,6 +57,13 @@ func (c *ScheduleController) DecPending() {
c.lastScheduleTime = time.Now() c.lastScheduleTime = time.Now()
} }
// DisableTime returns the underlay disable time.
func (c *ScheduleController) DisableTime() time.Time {
c.mu.Lock()
defer c.mu.Unlock()
return c.disableTime
}
// IsDisabled returns true if scheduling new sessions to the underlay is disabled. // IsDisabled returns true if scheduling new sessions to the underlay is disabled.
func (c *ScheduleController) IsDisabled() bool { func (c *ScheduleController) IsDisabled() bool {
c.mu.Lock() c.mu.Lock()
@@ -71,8 +78,8 @@ func (c *ScheduleController) Idle() bool {
return !c.disableTime.IsZero() && time.Since(c.lastScheduleTime) > scheduleIdleTime && time.Since(c.disableTime) > scheduleIdleTime return !c.disableTime.IsZero() && time.Since(c.lastScheduleTime) > scheduleIdleTime && time.Since(c.disableTime) > scheduleIdleTime
} }
// TryDisable tries to disable scheduling new sessions. // TryDisableIdle tries to disable scheduling new sessions on idle underlay.
func (c *ScheduleController) TryDisable() (successful bool) { func (c *ScheduleController) TryDisableIdle() (ok bool) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
if !c.disableTime.IsZero() { if !c.disableTime.IsZero() {
@@ -88,12 +95,12 @@ func (c *ScheduleController) TryDisable() (successful bool) {
return true return true
} }
// SetRemainingTime disables the scheduler after the given duration. // SetRemainingTime unconditionally disables the scheduler after the given duration.
// Do nothing if the scheduler has already been disabled. // Do nothing if the scheduler has already been disabled.
func (c *ScheduleController) SetRemainingTime(d time.Duration) { func (c *ScheduleController) SetRemainingTime(d time.Duration) {
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
if d <= 0 || !c.disableTime.IsZero() { if d < 0 || !c.disableTime.IsZero() {
return return
} }
c.disableTime = time.Now().Add(d) c.disableTime = time.Now().Add(d)
+6
View File
@@ -72,6 +72,12 @@ type Underlay interface {
// Returns detailed information of all the sessions. // Returns detailed information of all the sessions.
SessionInfos() []*appctlpb.SessionInfo SessionInfos() []*appctlpb.SessionInfo
// Number of bytes received from the network.
InBytes() int64
// Number of bytes sent to the network.
OutBytes() int64
// Run event loop. // Run event loop.
// The underlay needs to be closed when this returns. // The underlay needs to be closed when this returns.
RunEventLoop(context.Context) error RunEventLoop(context.Context) error
+12
View File
@@ -21,6 +21,7 @@ import (
"io" "io"
"net" "net"
"sync" "sync"
"sync/atomic"
"time" "time"
"github.com/enfein/mieru/v3/pkg/appctl/appctlpb" "github.com/enfein/mieru/v3/pkg/appctl/appctlpb"
@@ -52,6 +53,9 @@ type baseUnderlay struct {
sendMutex sync.Mutex // protect writing data to the connection sendMutex sync.Mutex // protect writing data to the connection
closeMutex sync.Mutex // protect closing the connection closeMutex sync.Mutex // protect closing the connection
inBytes atomic.Int64
outBytes atomic.Int64
// ---- client fields ---- // ---- client fields ----
scheduler *ScheduleController scheduler *ScheduleController
} }
@@ -193,6 +197,14 @@ func (b *baseUnderlay) SessionInfos() []*appctlpb.SessionInfo {
return res return res
} }
func (b *baseUnderlay) InBytes() int64 {
return b.inBytes.Load()
}
func (b *baseUnderlay) OutBytes() int64 {
return b.outBytes.Load()
}
func (b *baseUnderlay) RunEventLoop(ctx context.Context) error { func (b *baseUnderlay) RunEventLoop(ctx context.Context) error {
return stderror.ErrUnsupported return stderror.ErrUnsupported
} }
+3
View File
@@ -356,6 +356,7 @@ func (u *PacketUnderlay) readOneSegment() error {
continue continue
} }
b = b[:n] b = b[:n]
u.inBytes.Add(int64(n))
if u.isClient { if u.isClient {
metrics.DownloadBytes.Add(int64(n)) metrics.DownloadBytes.Add(int64(n))
} else { } else {
@@ -692,6 +693,7 @@ func (u *PacketUnderlay) writeOneSegment(seg *segment, addr net.Addr) error {
if _, err := u.conn.WriteTo(dataToSend, addr); err != nil { if _, err := u.conn.WriteTo(dataToSend, addr); err != nil {
return fmt.Errorf("WriteTo() failed: %w", err) return fmt.Errorf("WriteTo() failed: %w", err)
} }
u.outBytes.Add(int64(len(dataToSend)))
if u.isClient { if u.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend))) metrics.UploadBytes.Add(int64(len(dataToSend)))
} else { } else {
@@ -731,6 +733,7 @@ func (u *PacketUnderlay) writeOneSegment(seg *segment, addr net.Addr) error {
if _, err := u.conn.WriteTo(dataToSend, addr); err != nil { if _, err := u.conn.WriteTo(dataToSend, addr); err != nil {
return fmt.Errorf("WriteTo() failed: %w", err) return fmt.Errorf("WriteTo() failed: %w", err)
} }
u.outBytes.Add(int64(len(dataToSend)))
if u.isClient { if u.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend))) metrics.UploadBytes.Add(int64(len(dataToSend)))
} else { } else {
+8
View File
@@ -305,6 +305,7 @@ func (t *StreamUnderlay) readOneSegment() (*segment, error) {
err = fmt.Errorf("metadata: read %d bytes from StreamUnderlay failed: %w", readLen, err) err = fmt.Errorf("metadata: read %d bytes from StreamUnderlay failed: %w", readLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR) return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
} }
t.inBytes.Add(int64(len(encryptedMeta)))
if t.isClient { if t.isClient {
metrics.DownloadBytes.Add(int64(len(encryptedMeta))) metrics.DownloadBytes.Add(int64(len(encryptedMeta)))
} else { } else {
@@ -398,6 +399,7 @@ func (t *StreamUnderlay) readSessionSegment(ss *sessionStruct) (*segment, error)
err = fmt.Errorf("payload: read %d bytes from StreamUnderlay failed: %w", ss.payloadLen+cipher.DefaultOverhead, err) err = fmt.Errorf("payload: read %d bytes from StreamUnderlay failed: %w", ss.payloadLen+cipher.DefaultOverhead, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR) return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
} }
t.inBytes.Add(int64(len(encryptedPayload)))
if t.isClient { if t.isClient {
metrics.DownloadBytes.Add(int64(len(encryptedPayload))) metrics.DownloadBytes.Add(int64(len(encryptedPayload)))
} else { } else {
@@ -428,6 +430,7 @@ func (t *StreamUnderlay) readSessionSegment(ss *sessionStruct) (*segment, error)
err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", ss.suffixLen, err) err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", ss.suffixLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR) return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
} }
t.inBytes.Add(int64(len(padding)))
if t.isClient { if t.isClient {
metrics.DownloadBytes.Add(int64(len(padding))) metrics.DownloadBytes.Add(int64(len(padding)))
} else { } else {
@@ -453,6 +456,7 @@ func (t *StreamUnderlay) readDataAckSegment(das *dataAckStruct) (*segment, error
err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", das.prefixLen, err) err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", das.prefixLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR) return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
} }
t.inBytes.Add(int64(len(padding1)))
if t.isClient { if t.isClient {
metrics.DownloadBytes.Add(int64(len(padding1))) metrics.DownloadBytes.Add(int64(len(padding1)))
} else { } else {
@@ -465,6 +469,7 @@ func (t *StreamUnderlay) readDataAckSegment(das *dataAckStruct) (*segment, error
err = fmt.Errorf("payload: read %d bytes from StreamUnderlay failed: %w", das.payloadLen+cipher.DefaultOverhead, err) err = fmt.Errorf("payload: read %d bytes from StreamUnderlay failed: %w", das.payloadLen+cipher.DefaultOverhead, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR) return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
} }
t.inBytes.Add(int64(len(encryptedPayload)))
if t.isClient { if t.isClient {
metrics.DownloadBytes.Add(int64(len(encryptedPayload))) metrics.DownloadBytes.Add(int64(len(encryptedPayload)))
} else { } else {
@@ -495,6 +500,7 @@ func (t *StreamUnderlay) readDataAckSegment(das *dataAckStruct) (*segment, error
err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", das.suffixLen, err) err = fmt.Errorf("padding: read %d bytes from StreamUnderlay failed: %w", das.suffixLen, err)
return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR) return nil, stderror.WrapErrorWithType(err, stderror.NETWORK_ERROR)
} }
t.inBytes.Add(int64(len(padding2)))
if t.isClient { if t.isClient {
metrics.DownloadBytes.Add(int64(len(padding2))) metrics.DownloadBytes.Add(int64(len(padding2)))
} else { } else {
@@ -549,6 +555,7 @@ func (t *StreamUnderlay) writeOneSegment(seg *segment) error {
if _, err := t.conn.Write(dataToSend); err != nil { if _, err := t.conn.Write(dataToSend); err != nil {
return fmt.Errorf("Write() failed: %w", err) return fmt.Errorf("Write() failed: %w", err)
} }
t.outBytes.Add(int64(len(dataToSend)))
if t.isClient { if t.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend))) metrics.UploadBytes.Add(int64(len(dataToSend)))
} else { } else {
@@ -590,6 +597,7 @@ func (t *StreamUnderlay) writeOneSegment(seg *segment) error {
if _, err := t.conn.Write(dataToSend); err != nil { if _, err := t.conn.Write(dataToSend); err != nil {
return fmt.Errorf("Write() failed: %w", err) return fmt.Errorf("Write() failed: %w", err)
} }
t.outBytes.Add(int64(len(dataToSend)))
if t.isClient { if t.isClient {
metrics.UploadBytes.Add(int64(len(dataToSend))) metrics.UploadBytes.Add(int64(len(dataToSend)))
} else { } else {
+1 -1
View File
@@ -289,7 +289,7 @@ func (d *Decoder) decodeBool(name string, data any, val reflect.Value) (err erro
case isInt(kind) && d.option.WeaklyTypedInput: case isInt(kind) && d.option.WeaklyTypedInput:
val.SetBool(dataVal.Int() != 0) val.SetBool(dataVal.Int() != 0)
case isUint(kind) && d.option.WeaklyTypedInput: case isUint(kind) && d.option.WeaklyTypedInput:
val.SetString(strconv.FormatUint(dataVal.Uint(), 10)) val.SetBool(dataVal.Uint() != 0)
default: default:
err = fmt.Errorf( err = fmt.Errorf(
"'%s' expected type '%s', got unconvertible type '%s'", "'%s' expected type '%s', got unconvertible type '%s'",
+2 -2
View File
@@ -8,12 +8,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=ddns-go PKG_NAME:=ddns-go
PKG_VERSION:=6.13.2 PKG_VERSION:=6.13.3
PKG_RELEASE:=1 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://codeload.github.com/jeessy2/ddns-go/tar.gz/v$(PKG_VERSION)? PKG_SOURCE_URL:=https://codeload.github.com/jeessy2/ddns-go/tar.gz/v$(PKG_VERSION)?
PKG_HASH:=a729096b6d0d769223a21dfd82040b264d6f672d6018d08157f400de321d381e PKG_HASH:=b2b6e48988abec12bba37ac9fb2f9a6777d28125c0ab2ac3be1d8659b8b7b9a5
PKG_LICENSE:=MIT PKG_LICENSE:=MIT
PKG_LICENSE_FILES:=LICENSE PKG_LICENSE_FILES:=LICENSE
File diff suppressed because one or more lines are too long
@@ -216,7 +216,7 @@ o.cfgvalue = function(t, n)
str = str ~= "" and "<br>" .. str or "" str = str ~= "" and "<br>" .. str or ""
local num = 0 local num = 0
m.uci:foreach(appname, "nodes", function(s) m.uci:foreach(appname, "nodes", function(s)
if s["group"] ~= "" and s["group"] == remark then if s["group"] and s["group"]:lower() == remark:lower() then
num = num + 1 num = num + 1
end end
end) end)
@@ -1,6 +1,7 @@
<% <%
local api = require "luci.passwall.api" local api = require "luci.passwall.api"
-%> -%>
<script src="<%=resource%>/view/<%=api.appname%>/Sortable.min.js"></script>
<style> <style>
table th, .table .th { table th, .table .th {
@@ -66,7 +67,34 @@ table td, .table .td {
margin-right: 0 !important; margin-right: 0 !important;
} }
.node-wrapper .drag-handle {
cursor: grab !important;
display: inline-flex;
align-items: center;
justify-content: center;
font-size: 18px;
padding: 0 !important;
line-height: inherit;
user-select: none;
height: 32px !important;
width: 32px;
min-width: 32px;
}
.sortable-chosen {
background-color: rgba(220, 235, 245, 0.4) !important;
opacity: 0.7;
}
.sortable-ghost {
background: #cce5ff !important;
height: 3px !important;
}
.dragging-row {
background-color: rgba(131, 191, 255, 0.7) !important;
box-shadow: 0 4px 6px rgba(0,0,0,0.1);
}
</style> </style>
<% if api.is_js_luci() then -%> <% if api.is_js_luci() then -%>
@@ -210,21 +238,6 @@ table td, .table .td {
document.getElementById("set_node_name").innerHTML = ""; document.getElementById("set_node_name").innerHTML = "";
} }
function row_swap(btn, up) {
const row = btn.closest("tr");
if (!row) return;
const parent = row.parentNode;
if (up) {
const prev = row.previousElementSibling;
if (prev && !prev.classList.contains("cbi-section-table-titles")) {
parent.insertBefore(row, prev);
}
} else {
const next = row.nextElementSibling;
if (next) parent.insertBefore(next, row);
}
}
function row_top(btn) { function row_top(btn) {
const row = btn.closest("tr"); const row = btn.closest("tr");
if (!row) return; if (!row) return;
@@ -548,6 +561,60 @@ table td, .table .td {
} }
} }
} }
//列表拖动重排
function initSortableForTable(table) {
if (!table) return null;
var root = table.querySelector('tbody') || table;
if (root._sortable_initialized) return root._sortable_instance;
root._sortable_initialized = true;
var opts = {
handle: ".drag-handle",
draggable: "tr.cbi-section-table-row",
animation: 150,
ghostClass: "dragging-row",
fallbackOnBody: true,
forceFallback: false,
swapThreshold: 0.65,
onEnd: function (evt) {
//var group = evt.to.id.replace("cbi-passwall-nodes-", "").replace("-table", "");
//save_current_page_order(group); // 自动提交保存
}
};
try {
var instance = Sortable.create(root, opts);
root._sortable_instance = instance;
return instance;
} catch (err) {
root._sortable_initialized = false;
console.error("Sortable init failed:", err);
return null;
}
}
function initAllSortable(group_nodes) {
if (typeof Sortable === 'undefined') {
var retries = 0;
var maxRetries = 25;
var t = setInterval(function () {
retries++;
if (typeof Sortable !== 'undefined') {
clearInterval(t);
for (var group in group_nodes) {
var table = document.getElementById("cbi-passwall-nodes-" + group + "-table");
initSortableForTable(table);
}
} else if (retries >= maxRetries) {
clearInterval(t);
}
}, 200);
} else {
for (var group in group_nodes) {
var table = document.getElementById("cbi-passwall-nodes-" + group + "-table");
initSortableForTable(table);
}
}
}
</script> </script>
<script type="text/template" id="nodes-table-template"> <script type="text/template" id="nodes-table-template">
@@ -584,10 +651,9 @@ table td, .table .td {
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:To Top%>" onclick="row_top(this)" title="<%:To Top%>"/> <input class="btn cbi-button cbi-button-edit" type="button" value="<%:To Top%>" onclick="row_top(this)" title="<%:To Top%>"/>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/> <input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/>
<input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/> <input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/>
<input class="btn cbi-button cbi-button-up" type="button" value="<%:Move up%>" onclick="return row_swap(this, true)" title="<%:Move up%>">
<input class="btn cbi-button cbi-button-down" type="button" value="<%:Move down%>" onclick="return row_swap(this, false)" title="<%:Move down%>">
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>"> <input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>">
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="del_node('{{id}}')" alt="<%:Delete%>" title="<%:Delete%>"> <input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="del_node('{{id}}')" alt="<%:Delete%>" title="<%:Delete%>">
<input class="cbi-button drag-handle center" type="button" value="☰" title="<%:Drag to reorder%>"/>
</div> </div>
</td> </td>
</tr> </tr>
@@ -749,6 +815,8 @@ table td, .table .td {
cbi_t_switch("passwall.nodes", default_group) cbi_t_switch("passwall.nodes", default_group)
} }
initAllSortable(group_nodes);
//clear expire data //clear expire data
if (localStorage && localStorage.length > 0) { if (localStorage && localStorage.length > 0) {
const now = Date.now(); const now = Date.now();
@@ -427,6 +427,9 @@ msgstr "保存当前顺序"
msgid "Saved current page order successfully." msgid "Saved current page order successfully."
msgstr "保存当前页面顺序成功。" msgstr "保存当前页面顺序成功。"
msgid "Drag to reorder"
msgstr "拖动以重排"
msgid "Type" msgid "Type"
msgstr "类型" msgstr "类型"
@@ -504,8 +504,8 @@ local function processData(szType, content, add_mode, group)
end end
result.obfs_param = base64Decode(params.obfsparam) result.obfs_param = base64Decode(params.obfsparam)
result.protocol_param = base64Decode(params.protoparam) result.protocol_param = base64Decode(params.protoparam)
local group = base64Decode(params.group) -- local ssr_group = base64Decode(params.group)
if group then result.group = group end -- if ssr_group then result.ssr_group = ssr_group end
result.remarks = base64Decode(params.remarks) result.remarks = base64Decode(params.remarks)
elseif szType == 'vmess' then elseif szType == 'vmess' then
local info = jsonParse(content) local info = jsonParse(content)
@@ -83,6 +83,7 @@ function index()
entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true
entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true
entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true
entry({"admin", "services", appname, "save_node_order"}, call("save_node_order")).leaf = true
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
@@ -591,13 +592,12 @@ function delete_select_nodes()
end end
end end
function get_node() function get_node()
local id = http.formvalue("id") local id = http.formvalue("id")
local result = {} local result = {}
local show_node_info = api.uci_get_type("global_other", "show_node_info", "0") local show_node_info = api.uci_get_type("global_other", "show_node_info", "0")
function add_is_ipv6_key(o) local function add_is_ipv6_key(o)
if o and o.address and show_node_info == "1" then if o and o.address and show_node_info == "1" then
local f = api.get_ipv6_full(o.address) local f = api.get_ipv6_full(o.address)
if f ~= "" then if f ~= "" then
@@ -611,14 +611,35 @@ function get_node()
result = uci:get_all(appname, id) result = uci:get_all(appname, id)
add_is_ipv6_key(result) add_is_ipv6_key(result)
else else
local default_nodes = {}
local other_nodes = {}
uci:foreach(appname, "nodes", function(t) uci:foreach(appname, "nodes", function(t)
add_is_ipv6_key(t) add_is_ipv6_key(t)
result[#result + 1] = t if not t.group or t.group == "" then
default_nodes[#default_nodes + 1] = t
else
other_nodes[#other_nodes + 1] = t
end
end) end)
for i = 1, #default_nodes do result[#result + 1] = default_nodes[i] end
for i = 1, #other_nodes do result[#result + 1] = other_nodes[i] end
end end
http_write_json(result) http_write_json(result)
end end
function save_node_order()
local ids = http.formvalue("ids") or ""
local new_order = {}
for id in ids:gmatch("([^,]+)") do
new_order[#new_order + 1] = id
end
for idx, name in ipairs(new_order) do
luci.sys.call(string.format("uci -q reorder %s.%s=%d", appname, name, idx - 1))
end
api.sh_uci_commit(appname)
http_write_json({ status = "ok" })
end
function update_rules() function update_rules()
local update = http.formvalue("update") local update = http.formvalue("update")
luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &") luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. update .. "' > /dev/null 2>&1 &")
@@ -210,19 +210,28 @@ table td, .table .td {
document.getElementById("set_node_name").innerHTML = ""; document.getElementById("set_node_name").innerHTML = "";
} }
function _cbi_row_top(id) { function row_swap(btn, up) {
//此函数已经损坏,等待修复或其他解决方案。 const row = btn.closest("tr");
var dom = document.getElementById("cbi-passwall-" + id); if (!row) return;
if (dom) { const parent = row.parentNode;
var trs = document.getElementById("cbi-passwall-nodes").getElementsByClassName("cbi-section-table-row");
if (trs && trs.length > 0) {
for (var i = 0; i < trs.length; i++) {
var up = dom.getElementsByClassName("cbi-button-up");
if (up) { if (up) {
cbi_row_swap(up[0], true, 'cbi.sts.passwall.nodes'); const prev = row.previousElementSibling;
} if (prev && !prev.classList.contains("cbi-section-table-titles")) {
parent.insertBefore(row, prev);
}
} else {
const next = row.nextElementSibling;
if (next) parent.insertBefore(next, row);
} }
} }
function row_top(btn) {
const row = btn.closest("tr");
if (!row) return;
const parent = row.parentNode;
let firstDataRow = parent.querySelector("tr:not(.cbi-section-table-titles)");
if (firstDataRow && firstDataRow !== row) {
parent.insertBefore(row, firstDataRow);
} }
} }
@@ -305,6 +314,39 @@ table td, .table .td {
return { address: address, port: port }; return { address: address, port: port };
} }
function save_current_page_order(group) {
var table = document.getElementById("cbi-passwall-nodes-" + group + "-table");
if (!table) {
alert("<%:No table!%>");
return;
}
var rows = table.querySelectorAll("tr.cbi-section-table-row");
if (!rows || rows.length === 0) {
alert("<%:No nodes!%>");
return;
}
var btn = document.getElementById("save_order_btn_" + group);
if (btn) btn.disabled = true;
var ids = [];
rows.forEach(function(row) {
var id = row.id.replace("cbi-passwall-", "");
ids.push(id);
});
XHR.get('<%=api.url("save_node_order")%>', {
group: group,
ids: ids.join(",")
},
function(x, result) {
if (btn) btn.disabled = false;
if (x && x.status === 200) {
alert("<%:Saved current page order successfully.%>");
} else {
alert("<%:Save failed!%>");
}
}
);
}
//获取当前使用的节点 //获取当前使用的节点
function get_now_use_node() { function get_now_use_node() {
XHR.get('<%=api.url("get_now_use_node")%>', null, XHR.get('<%=api.url("get_now_use_node")%>', null,
@@ -522,6 +564,7 @@ table td, .table .td {
</table> </table>
<div class="cbi-section-create cbi-tblsection-create"> <div class="cbi-section-create cbi-tblsection-create">
<input class="cbi-button cbi-button-add" type="button" value="<%:Add%>" onclick="to_add_node()"> <input class="cbi-button cbi-button-add" type="button" value="<%:Add%>" onclick="to_add_node()">
<input class="cbi-button cbi-button-apply" type="button" id="save_order_btn_{{group}}" value="<%:Save Order%>" onclick="save_current_page_order('{{group}}')">
</div> </div>
</fieldset> </fieldset>
</script> </script>
@@ -537,11 +580,12 @@ table td, .table .td {
<td class="td cbi-value-field">{{url_test}}</td> <td class="td cbi-value-field">{{url_test}}</td>
<td class="td cbi-section-table-cell nowrap cbi-section-actions"> <td class="td cbi-section-table-cell nowrap cbi-section-actions">
<div class="node-wrapper"> <div class="node-wrapper">
<!--It has been damaged and awaits repair or other solutions.-->
<!--<input class="btn cbi-button" type="button" value="<%:To Top%>" onclick="_cbi_row_top('{{id}}')"/>-->
<input class="cbi-input-checkbox nodes_select" type="checkbox" cbid="{{id}}" /> <input class="cbi-input-checkbox nodes_select" type="checkbox" cbid="{{id}}" />
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:To Top%>" onclick="row_top(this)" title="<%:To Top%>"/>
<input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/> <input class="btn cbi-button cbi-button-apply" type="button" value="<%:Use%>" id="apply_{{id}}" onclick="open_set_node_div('{{id}}')"/>
<input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/> <input class="btn cbi-button cbi-button-add" type="button" value="<%:Copy%>" onclick="copy_node('{{id}}')"/>
<input class="btn cbi-button cbi-button-up" type="button" value="<%:Move up%>" onclick="return row_swap(this, true)" title="<%:Move up%>">
<input class="btn cbi-button cbi-button-down" type="button" value="<%:Move down%>" onclick="return row_swap(this, false)" title="<%:Move down%>">
<input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>"> <input class="btn cbi-button cbi-button-edit" type="button" value="<%:Edit%>" onclick="location.href='<%=api.url("node_config")%>/{{id}}'" alt="<%:Edit%>" title="<%:Edit%>">
<input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="del_node('{{id}}')" alt="<%:Delete%>" title="<%:Delete%>"> <input class="btn cbi-button cbi-button-remove" type="button" value="<%:Delete%>" onclick="del_node('{{id}}')" alt="<%:Delete%>" title="<%:Delete%>">
</div> </div>
@@ -421,6 +421,12 @@ msgstr "节点备注"
msgid "Add Mode" msgid "Add Mode"
msgstr "添加方式" msgstr "添加方式"
msgid "Save Order"
msgstr "保存当前顺序"
msgid "Saved current page order successfully."
msgstr "保存当前页面顺序成功。"
msgid "Type" msgid "Type"
msgstr "类型" msgstr "类型"
@@ -760,13 +760,16 @@ local function processData(szType, content)
-- 未指定peersni)默认使用remote addr -- 未指定peersni)默认使用remote addr
result.tls_host = params.peer or params.sni result.tls_host = params.peer or params.sni
end end
if params.allowInsecure then params.allowinsecure = params.allowinsecure or params.insecure
if params.allowinsecure then
-- 处理 insecure 参数 -- 处理 insecure 参数
if params.allowinsecure == "1" or params.allowinsecure == "0" then if params.allowinsecure == "1" or params.allowinsecure == "0" then
result.insecure = params.allowInsecure result.insecure = params.allowinsecure
else else
result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0" result.insecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
end end
else
result.insecure = "0"
end end
if params.tfo then if params.tfo then
-- 处理 fast open 参数 -- 处理 fast open 参数
+2 -2
View File
@@ -21,13 +21,13 @@ define Download/geoip
HASH:=2445b44d9ae3ab9a867c9d1e0e244646c4c378622e14b9afaf3658ecf46a40b9 HASH:=2445b44d9ae3ab9a867c9d1e0e244646c4c378622e14b9afaf3658ecf46a40b9
endef endef
GEOSITE_VER:=20251125142217 GEOSITE_VER:=20251126114359
GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER)
define Download/geosite define Download/geosite
URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/
URL_FILE:=dlc.dat URL_FILE:=dlc.dat
FILE:=$(GEOSITE_FILE) FILE:=$(GEOSITE_FILE)
HASH:=ae6033c884713da8e98f2c1d8167141fbb47aadd297b3ba81450d87582827d5c HASH:=74559fa06bfb073ac5eaa8be34213ff66e6bcbab96512e94c6e6693ee083ac66
endef endef
GEOSITE_IRAN_VER:=202511240043 GEOSITE_IRAN_VER:=202511240043
+1 -1
View File
@@ -37,7 +37,7 @@ jobs:
fetch-depth: '0' fetch-depth: '0'
- name: Setup .NET - name: Setup .NET
uses: actions/setup-dotnet@v5.0.0 uses: actions/setup-dotnet@v5.0.1
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
fetch-depth: '0' fetch-depth: '0'
- name: Setup - name: Setup
uses: actions/setup-dotnet@v5.0.0 uses: actions/setup-dotnet@v5.0.1
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
+1 -1
View File
@@ -32,7 +32,7 @@ jobs:
fetch-depth: '0' fetch-depth: '0'
- name: Setup - name: Setup
uses: actions/setup-dotnet@v5.0.0 uses: actions/setup-dotnet@v5.0.1
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
+1 -1
View File
@@ -30,7 +30,7 @@ jobs:
uses: actions/checkout@v6.0.0 uses: actions/checkout@v6.0.0
- name: Setup - name: Setup
uses: actions/setup-dotnet@v5.0.0 uses: actions/setup-dotnet@v5.0.1
with: with:
dotnet-version: '8.0.x' dotnet-version: '8.0.x'
+21 -14
View File
@@ -118,22 +118,15 @@ public class BaseFmt
} }
if (item.Extra.IsNotEmpty()) if (item.Extra.IsNotEmpty())
{ {
var extra = item.Extra; var node = JsonUtils.ParseJson(item.Extra);
try var extra = node != null
{ ? JsonUtils.Serialize(node, new JsonSerializerOptions
var node = JsonNode.Parse(item.Extra);
if (node != null)
{
extra = node.ToJsonString(new JsonSerializerOptions
{ {
WriteIndented = false, WriteIndented = false,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
}); })
} : item.Extra;
}
catch
{
}
dicQuery.Add("extra", Utils.UrlEncode(extra)); dicQuery.Add("extra", Utils.UrlEncode(extra));
} }
break; break;
@@ -253,7 +246,21 @@ public class BaseFmt
item.RequestHost = GetQueryDecoded(query, "host"); item.RequestHost = GetQueryDecoded(query, "host");
item.Path = GetQueryDecoded(query, "path", "/"); item.Path = GetQueryDecoded(query, "path", "/");
item.HeaderType = GetQueryDecoded(query, "mode"); item.HeaderType = GetQueryDecoded(query, "mode");
item.Extra = GetQueryDecoded(query, "extra"); var extraDecoded = GetQueryDecoded(query, "extra");
if (extraDecoded.IsNotEmpty())
{
var node = JsonUtils.ParseJson(extraDecoded);
if (node != null)
{
extraDecoded = JsonUtils.Serialize(node, new JsonSerializerOptions
{
WriteIndented = true,
DefaultIgnoreCondition = JsonIgnoreCondition.Never,
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping
});
}
}
item.Extra = extraDecoded;
break; break;
case nameof(ETransport.http): case nameof(ETransport.http):
@@ -77,6 +77,7 @@ public class ProfilesViewModel : MyReactiveObject
public ReactiveCommand<Unit, Unit> AddSubCmd { get; } public ReactiveCommand<Unit, Unit> AddSubCmd { get; }
public ReactiveCommand<Unit, Unit> EditSubCmd { get; } public ReactiveCommand<Unit, Unit> EditSubCmd { get; }
public ReactiveCommand<Unit, Unit> DeleteSubCmd { get; }
#endregion Menu #endregion Menu
@@ -235,6 +236,10 @@ public class ProfilesViewModel : MyReactiveObject
{ {
await EditSubAsync(false); await EditSubAsync(false);
}); });
DeleteSubCmd = ReactiveCommand.CreateFromTask(async () =>
{
await DeleteSubAsync();
});
#endregion WhenAnyValue && ReactiveCommand #endregion WhenAnyValue && ReactiveCommand
@@ -884,5 +889,23 @@ public class ProfilesViewModel : MyReactiveObject
} }
} }
private async Task DeleteSubAsync()
{
var item = await AppManager.Instance.GetSubItem(_config.SubIndexId);
if (item is null)
{
return;
}
if (await _updateView?.Invoke(EViewAction.ShowYesNo, null) == false)
{
return;
}
await ConfigHandler.DeleteSubItem(_config, item.Id);
await RefreshSubscriptions();
await SubSelectedChangedAsync(true);
}
#endregion Subscription #endregion Subscription
} }
@@ -28,6 +28,14 @@
<WrapPanel /> <WrapPanel />
</ItemsPanelTemplate> </ItemsPanelTemplate>
</ListBox.ItemsPanel> </ListBox.ItemsPanel>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem x:Name="menuSubEdit" Header="{x:Static resx:ResUI.menuSubEdit}" />
<MenuItem x:Name="menuSubAdd" Header="{x:Static resx:ResUI.menuSubAdd}" />
<MenuItem x:Name="menuSubDelete" Header="{x:Static resx:ResUI.menuSubDelete}" />
</ContextMenu>
</ListBox.ContextMenu>
</ListBox> </ListBox>
<Button <Button
@@ -49,6 +49,9 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.ServerFilter, v => v.txtServerFilter.Text).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddSubCmd, v => v.btnAddSub).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.AddSubCmd, v => v.btnAddSub).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.EditSubCmd, v => v.btnEditSub).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.EditSubCmd, v => v.btnEditSub).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.EditSubCmd, v => v.menuSubEdit).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.AddSubCmd, v => v.menuSubAdd).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.DeleteSubCmd, v => v.menuSubDelete).DisposeWith(disposables);
//servers delete //servers delete
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.menuEditServer).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.menuEditServer).DisposeWith(disposables);
+3 -3
View File
@@ -43,19 +43,19 @@ jobs:
uses: actions/cache/restore@v4 uses: actions/cache/restore@v4
with: with:
path: ${{ github.workspace }}/libs path: ${{ github.workspace }}/libs
key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }} key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}-${{ hashFiles('compile-tun2socks.sh') }}--${{ hashFiles('compile-hevtun.sh') }}
- name: Build libtun2socks - name: Build libtun2socks
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true' if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
run: | run: |
bash compile-tun2socks.sh bash compile-tun2socks.sh && bash compile-hevtun.sh
- name: Save libtun2socks - name: Save libtun2socks
if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true' if: steps.cache-libtun2socks-restore.outputs.cache-hit != 'true'
uses: actions/cache/save@v4 uses: actions/cache/save@v4
with: with:
path: ${{ github.workspace }}/libs path: ${{ github.workspace }}/libs
key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }} key: libtun2socks-${{ runner.os }}-${{ env.NDK_HOME }}-${{ hashFiles('.git/modules/hev-socks5-tunnel/HEAD') }}-${{ hashFiles('.git/modules/badvpn/HEAD') }}-${{ hashFiles('.git/modules/libancillary/HEAD') }}-${{ hashFiles('compile-tun2socks.sh') }}--${{ hashFiles('compile-hevtun.sh') }}
- name: Copy libtun2socks - name: Copy libtun2socks
run: | run: |
@@ -72,7 +72,8 @@ class TProxyService(
appendLine(" udp: 'udp'") appendLine(" udp: 'udp'")
appendLine("misc:") appendLine("misc:")
appendLine(" read-write-timeout: ${MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) ?: AppConfig.HEVTUN_RW_TIMEOUT}") appendLine(" tcp-read-write-timeout: ${MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) ?: AppConfig.HEVTUN_RW_TIMEOUT}")
appendLine(" udp-read-write-timeout: ${MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_RW_TIMEOUT) ?: AppConfig.HEVTUN_RW_TIMEOUT}")
val hevTunLogLevel = MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_LOGLEVEL) ?: "none" val hevTunLogLevel = MmkvManager.decodeSettingsString(AppConfig.PREF_HEV_TUNNEL_LOGLEVEL) ?: "none"
if (hevTunLogLevel != "none") { if (hevTunLogLevel != "none") {
appendLine(" log-level: $hevTunLogLevel") appendLine(" log-level: $hevTunLogLevel")
+40
View File
@@ -0,0 +1,40 @@
#!/bin/bash
set -o errexit
set -o pipefail
set -o nounset
# Set magic variables for current file & dir
__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
__base="$(basename ${__file} .sh)"
if [[ ! -d $NDK_HOME ]]; then
echo "Android NDK: NDK_HOME not found. please set env \$NDK_HOME"
exit 1
fi
TMPDIR=$(mktemp -d)
clear_tmp () {
rm -rf $TMPDIR
}
trap 'echo -e "Aborted, error $? in command: $BASH_COMMAND"; trap ERR; clear_tmp; exit 1' ERR INT
#build hev-socks5-tunnel
mkdir -p "$TMPDIR/jni"
pushd "$TMPDIR"
echo 'include $(call all-subdir-makefiles)' > jni/Android.mk
ln -s "$__dir/hev-socks5-tunnel" jni/hev-socks5-tunnel
"$NDK_HOME/ndk-build" \
NDK_PROJECT_PATH=. \
APP_BUILD_SCRIPT=jni/Android.mk \
"APP_ABI=armeabi-v7a arm64-v8a x86 x86_64" \
APP_PLATFORM=android-21 \
NDK_LIBS_OUT="$TMPDIR/libs" \
NDK_OUT="$TMPDIR/obj" \
"APP_CFLAGS=-O3 -DPKGNAME=com/v2ray/ang/service" \
"APP_LDFLAGS=-Wl,--build-id=none -Wl,--hash-style=gnu" \
cp -r "$TMPDIR/libs/"* "$__dir/libs/"
popd
rm -rf $TMPDIR
-26
View File
@@ -30,29 +30,3 @@ $NDK_HOME/ndk-build \
cp -r $TMPDIR/libs $__dir/ cp -r $TMPDIR/libs $__dir/
popd popd
rm -rf $TMPDIR rm -rf $TMPDIR
#build hev-socks5-tunnel
HEVTUN_TMP=$(mktemp -d)
trap 'rm -rf "$HEVTUN_TMP"' EXIT
mkdir -p "$HEVTUN_TMP/jni"
pushd "$HEVTUN_TMP"
echo 'include $(call all-subdir-makefiles)' > jni/Android.mk
ln -s "$__dir/hev-socks5-tunnel" jni/hev-socks5-tunnel
"$NDK_HOME/ndk-build" \
NDK_PROJECT_PATH=. \
APP_BUILD_SCRIPT=jni/Android.mk \
"APP_ABI=armeabi-v7a arm64-v8a x86 x86_64" \
APP_PLATFORM=android-21 \
NDK_LIBS_OUT="$HEVTUN_TMP/libs" \
NDK_OUT="$HEVTUN_TMP/obj" \
"APP_CFLAGS=-O3 -DPKGNAME=com/v2ray/ang/service" \
"APP_LDFLAGS=-WI,--build-id=none -WI,--hash-style=gnu" \
cp -r "$HEVTUN_TMP/libs/"* "$__dir/libs/"
popd
rm -rf "$HEVTUN_TMP"
+41 -49
View File
@@ -2404,60 +2404,52 @@ class YoutubeDL(object):
return res return res
def _format_note(self, fdict): def _format_note(self, fdict):
res = ''
if fdict.get('ext') in ['f4f', 'f4m']: def simplified_codec(f, field):
res += '(unsupported) ' assert field in ('acodec', 'vcodec')
if fdict.get('language'): codec = f.get(field)
if res: return (
res += ' ' 'unknown' if not codec
res += '[%s] ' % fdict['language'] else '.'.join(codec.split('.')[:4]) if codec != 'none'
if fdict.get('format_note') is not None: else 'images' if field == 'vcodec' and f.get('acodec') == 'none'
res += fdict['format_note'] + ' ' else None if field == 'acodec' and f.get('vcodec') == 'none'
if fdict.get('tbr') is not None: else 'audio only' if field == 'vcodec'
res += '%4dk ' % fdict['tbr'] else 'video only')
res = join_nonempty(
fdict.get('ext') in ('f4f', 'f4m') and '(unsupported)',
fdict.get('language') and ('[%s]' % (fdict['language'],)),
fdict.get('format_note') is not None and fdict['format_note'],
fdict.get('tbr') is not None and ('%4dk' % fdict['tbr']),
delim=' ')
res = [res] if res else []
if fdict.get('container') is not None: if fdict.get('container') is not None:
if res: res.append('%s container' % (fdict['container'],))
res += ', ' if fdict.get('vcodec') not in (None, 'none'):
res += '%s container' % fdict['container'] codec = simplified_codec(fdict, 'vcodec')
if (fdict.get('vcodec') is not None if codec and fdict.get('vbr') is not None:
and fdict.get('vcodec') != 'none'): codec += '@'
if res:
res += ', '
res += fdict['vcodec']
if fdict.get('vbr') is not None:
res += '@'
elif fdict.get('vbr') is not None and fdict.get('abr') is not None: elif fdict.get('vbr') is not None and fdict.get('abr') is not None:
res += 'video@' codec = 'video@'
if fdict.get('vbr') is not None:
res += '%4dk' % fdict['vbr']
if fdict.get('fps') is not None:
if res:
res += ', '
res += '%sfps' % fdict['fps']
if fdict.get('acodec') is not None:
if res:
res += ', '
if fdict['acodec'] == 'none':
res += 'video only'
else: else:
res += '%-5s' % fdict['acodec'] codec = None
elif fdict.get('abr') is not None: codec = join_nonempty(codec, fdict.get('vbr') is not None and ('%4dk' % fdict['vbr']))
if res: if codec:
res += ', ' res.append(codec)
res += 'audio' if fdict.get('fps') is not None:
if fdict.get('abr') is not None: res.append('%sfps' % (fdict['fps'],))
res += '@%3dk' % fdict['abr'] codec = (
if fdict.get('asr') is not None: simplified_codec(fdict, 'acodec') if fdict.get('acodec') is not None
res += ' (%5dHz)' % fdict['asr'] else 'audio' if fdict.get('abr') is not None else None)
if codec:
res.append(join_nonempty(
'%-4s' % (codec + (('@%3dk' % fdict['abr']) if fdict.get('abr') else ''),),
fdict.get('asr') and '(%5dHz)' % fdict['asr'], delim=' '))
if fdict.get('filesize') is not None: if fdict.get('filesize') is not None:
if res: res.append(format_bytes(fdict['filesize']))
res += ', '
res += format_bytes(fdict['filesize'])
elif fdict.get('filesize_approx') is not None: elif fdict.get('filesize_approx') is not None:
if res: res.append('~' + format_bytes(fdict['filesize_approx']))
res += ', ' return ', '.join(res)
res += '~' + format_bytes(fdict['filesize_approx'])
return res
def list_formats(self, info_dict): def list_formats(self, info_dict):
formats = info_dict.get('formats', [info_dict]) formats = info_dict.get('formats', [info_dict])
+7 -5
View File
@@ -1669,10 +1669,12 @@ class YoutubeIE(YoutubeBaseInfoExtractor):
'_rtmp': {'protocol': 'rtmp'}, '_rtmp': {'protocol': 'rtmp'},
# av01 video only formats sometimes served with "unknown" codecs # av01 video only formats sometimes served with "unknown" codecs
'394': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'}, '394': {'acodec': 'none', 'vcodec': 'av01.0.00M.08'},
'395': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'}, '395': {'acodec': 'none', 'vcodec': 'av01.0.00M.08'},
'396': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'}, '396': {'acodec': 'none', 'vcodec': 'av01.0.01M.08'},
'397': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'}, '397': {'acodec': 'none', 'vcodec': 'av01.0.04M.08'},
'398': {'acodec': 'none', 'vcodec': 'av01.0.05M.08'},
'399': {'acodec': 'none', 'vcodec': 'av01.0.08M.08'},
} }
_PLAYER_JS_VARIANT_MAP = ( _PLAYER_JS_VARIANT_MAP = (
@@ -3811,7 +3813,7 @@ class YoutubeTabIE(YoutubeBaseInfoExtractor):
continuation = None continuation = None
for is_renderer in traverse_obj(slr_renderer, ( for is_renderer in traverse_obj(slr_renderer, (
'contents', Ellipsis, 'itemSectionRenderer', T(dict))): 'contents', Ellipsis, 'itemSectionRenderer', T(dict))):
for isr_content in traverse_obj(slr_renderer, ( for isr_content in traverse_obj(is_renderer, (
'contents', Ellipsis, T(dict))): 'contents', Ellipsis, T(dict))):
renderer = isr_content.get('playlistVideoListRenderer') renderer = isr_content.get('playlistVideoListRenderer')
if renderer: if renderer: