From b4025330d86da0428171ca8d0fc4b7299eb2c2e3 Mon Sep 17 00:00:00 2001 From: "github-action[bot]" Date: Sat, 20 Dec 2025 19:36:00 +0100 Subject: [PATCH] Update On Sat Dec 20 19:36:00 CET 2025 --- .github/update.log | 1 + clash-meta/.github/patch/go1.25.patch | 188 +++- clash-meta/.github/patch/go1.26.patch | 842 +++++++++++++++ clash-meta/.github/workflows/build.yml | 4 + clash-meta/.github/workflows/test.yml | 9 +- clash-nyanpasu/backend/Cargo.lock | 36 +- .../frontend/nyanpasu/messages/en.json | 9 +- .../frontend/nyanpasu/messages/ru.json | 9 +- .../frontend/nyanpasu/messages/zh-cn.json | 9 +- .../frontend/nyanpasu/messages/zh-tw.json | 9 +- clash-nyanpasu/frontend/nyanpasu/package.json | 5 +- .../nyanpasu/src/components/ui/input.tsx | 193 +++- .../nyanpasu/src/components/ui/select.tsx | 45 +- .../nyanpasu/src/components/ui/separator.tsx | 25 + .../settings/_modules/settings-card.tsx | 34 + .../settings/_modules/settings-navigate.tsx | 9 +- .../settings/clash-port/route.tsx | 11 - .../_modules/mixed-port-config.tsx | 135 +++ .../_modules/random-port-switch.tsx | 48 + .../settings/clash-settings/route.tsx | 9 + .../_modules/proxy-bypass-config.tsx | 113 +- .../_modules/proxy-guard-config.tsx | 113 +- .../_modules/experimental-switch.tsx | 8 +- .../frontend/nyanpasu/src/route-tree.gen.ts | 23 - clash-nyanpasu/manifest/version.json | 4 +- clash-nyanpasu/package.json | 4 +- clash-nyanpasu/pnpm-lock.yaml | 500 +++++++-- mihomo/.github/patch/go1.25.patch | 188 +++- mihomo/.github/patch/go1.26.patch | 842 +++++++++++++++ mihomo/.github/workflows/build.yml | 4 + mihomo/.github/workflows/test.yml | 9 +- openwrt-packages/ddns-go/Makefile | 4 +- .../model/cbi/passwall/client/other.lua | 20 +- .../luasrc/passwall/util_sing-box.lua | 10 +- sing-box/.github/CRONET_GO_VERSION | 2 +- sing-box/adapter/endpoint/manager.go | 22 +- sing-box/adapter/inbound/manager.go | 22 +- sing-box/adapter/lifecycle.go | 39 +- sing-box/adapter/outbound/manager.go | 37 +- sing-box/adapter/service/manager.go | 22 +- sing-box/box.go | 49 +- sing-box/docs/changelog.md | 4 + sing-box/go.mod | 48 +- sing-box/go.sum | 96 +- .../htdocs/luci-static/resources/fchomo.js | 2 + small/luci-app-fchomo/po/templates/fchomo.pot | 991 +++++++++--------- small/luci-app-fchomo/po/zh_Hans/fchomo.po | 991 +++++++++--------- small/luci-app-fchomo/po/zh_Hant/fchomo.po | 991 +++++++++--------- .../model/cbi/passwall/client/other.lua | 20 +- .../luasrc/passwall/util_sing-box.lua | 10 +- .../root/etc/init.d/shadowsocksr | 41 + .../luci-app-ssr-plus/root/usr/bin/ssr-rules | 81 +- small/v2ray-geodata/Makefile | 4 +- v2rayn/v2rayN/Directory.Build.props | 2 +- v2rayn/v2rayN/Directory.Packages.props | 6 +- .../ServiceLib/Services/UpdateService.cs | 7 - yt-dlp/.github/workflows/build.yml | 46 +- yt-dlp/.github/workflows/cache-warmer.yml | 6 +- yt-dlp/.github/workflows/challenge-tests.yml | 8 +- yt-dlp/.github/workflows/codeql.yml | 4 + yt-dlp/.github/workflows/core.yml | 7 +- yt-dlp/.github/workflows/download.yml | 12 +- yt-dlp/.github/workflows/issue-lockdown.yml | 5 +- yt-dlp/.github/workflows/quick-test.yml | 12 +- yt-dlp/.github/workflows/release-master.yml | 14 +- yt-dlp/.github/workflows/release-nightly.yml | 17 +- yt-dlp/.github/workflows/release.yml | 20 +- yt-dlp/.github/workflows/sanitize-comment.yml | 5 +- yt-dlp/.github/workflows/test-workflows.yml | 9 +- yt-dlp/yt_dlp/YoutubeDL.py | 4 + yt-dlp/yt_dlp/extractor/_extractors.py | 1 + yt-dlp/yt_dlp/extractor/bandcamp.py | 81 +- yt-dlp/yt_dlp/extractor/nebula.py | 53 + yt-dlp/yt_dlp/extractor/neteasemusic.py | 5 +- yt-dlp/yt_dlp/extractor/yahoo.py | 167 +-- 75 files changed, 5360 insertions(+), 2075 deletions(-) create mode 100644 clash-meta/.github/patch/go1.26.patch create mode 100644 clash-nyanpasu/frontend/nyanpasu/src/components/ui/separator.tsx delete mode 100644 clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-port/route.tsx create mode 100644 clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/mixed-port-config.tsx create mode 100644 clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/random-port-switch.tsx create mode 100644 mihomo/.github/patch/go1.26.patch diff --git a/.github/update.log b/.github/update.log index 8cde6690f3..152d46b0ae 100644 --- a/.github/update.log +++ b/.github/update.log @@ -1217,3 +1217,4 @@ Update On Tue Dec 16 19:42:39 CET 2025 Update On Wed Dec 17 19:43:54 CET 2025 Update On Thu Dec 18 19:42:36 CET 2025 Update On Fri Dec 19 19:41:31 CET 2025 +Update On Sat Dec 20 19:35:51 CET 2025 diff --git a/clash-meta/.github/patch/go1.25.patch b/clash-meta/.github/patch/go1.25.patch index 626779dbdd..a7f724ff46 100644 --- a/clash-meta/.github/patch/go1.25.patch +++ b/clash-meta/.github/patch/go1.25.patch @@ -1,4 +1,5 @@ -Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Subject: [PATCH] Fix os.RemoveAll not working on Windows7 +Revert "runtime: always use LoadLibraryEx to load system libraries" Revert "syscall: remove Windows 7 console handle workaround" Revert "net: remove sysSocket fallback for Windows 7" Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" @@ -655,3 +656,188 @@ diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go } else { h, e = loadlibrary(namep) } +Index: src/os/removeall_at.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go +--- a/src/os/removeall_at.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/removeall_at.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build unix || wasip1 || windows ++//go:build unix || wasip1 + + package os + +@@ -175,3 +175,25 @@ + } + return newDirFile(fd, name) + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ // Consistency with os.RemoveAll: Strip trailing /s from the name, ++ // so RemoveAll("not_a_directory/") succeeds. ++ for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { ++ name = name[:len(name)-1] ++ } ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { ++ return struct{}{}, removeAllFrom(parent, name) ++ }) ++ if IsNotExist(err) { ++ return nil ++ } ++ if err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return err ++} +Index: src/os/removeall_noat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_noat.go b/src/os/removeall_noat.go +--- a/src/os/removeall_noat.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/removeall_noat.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (js && wasm) || plan9 ++//go:build (js && wasm) || plan9 || windows + + package os + +@@ -140,3 +140,22 @@ + } + return err + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ if err := checkPathEscapesLstat(r, name); err != nil { ++ if err == syscall.ENOTDIR { ++ // Some intermediate path component is not a directory. ++ // RemoveAll treats this as success (since the target doesn't exist). ++ return nil ++ } ++ return &PathError{Op: "RemoveAll", Path: name, Err: err} ++ } ++ if err := RemoveAll(joinPath(r.root.name, name)); err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return nil ++} +Index: src/os/root_noopenat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_noopenat.go b/src/os/root_noopenat.go +--- a/src/os/root_noopenat.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/root_noopenat.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -11,7 +11,6 @@ + "internal/filepathlite" + "internal/stringslite" + "sync/atomic" +- "syscall" + "time" + ) + +@@ -185,25 +184,6 @@ + } + return nil + } +- +-func rootRemoveAll(r *Root, name string) error { +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- if err := checkPathEscapesLstat(r, name); err != nil { +- if err == syscall.ENOTDIR { +- // Some intermediate path component is not a directory. +- // RemoveAll treats this as success (since the target doesn't exist). +- return nil +- } +- return &PathError{Op: "RemoveAll", Path: name, Err: err} +- } +- if err := RemoveAll(joinPath(r.root.name, name)); err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return nil +-} + + func rootReadlink(r *Root, name string) (string, error) { + if err := checkPathEscapesLstat(r, name); err != nil { +Index: src/os/root_openat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_openat.go b/src/os/root_openat.go +--- a/src/os/root_openat.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/root_openat.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -194,28 +194,6 @@ + return nil + } + +-func rootRemoveAll(r *Root, name string) error { +- // Consistency with os.RemoveAll: Strip trailing /s from the name, +- // so RemoveAll("not_a_directory/") succeeds. +- for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { +- name = name[:len(name)-1] +- } +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { +- return struct{}{}, removeAllFrom(parent, name) +- }) +- if IsNotExist(err) { +- return nil +- } +- if err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return err +-} +- + func rootRename(r *Root, oldname, newname string) error { + _, err := doInRoot(r, oldname, nil, func(oldparent sysfdType, oldname string) (struct{}, error) { + _, err := doInRoot(r, newname, nil, func(newparent sysfdType, newname string) (struct{}, error) { +Index: src/os/root_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_windows.go b/src/os/root_windows.go +--- a/src/os/root_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/root_windows.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -402,3 +402,14 @@ + } + return fi.Mode(), nil + } ++ ++func checkPathEscapes(r *Root, name string) error { ++ if !filepathlite.IsLocal(name) { ++ return errPathEscapes ++ } ++ return nil ++} ++ ++func checkPathEscapesLstat(r *Root, name string) error { ++ return checkPathEscapes(r, name) ++} diff --git a/clash-meta/.github/patch/go1.26.patch b/clash-meta/.github/patch/go1.26.patch new file mode 100644 index 0000000000..29dab4d0a6 --- /dev/null +++ b/clash-meta/.github/patch/go1.26.patch @@ -0,0 +1,842 @@ +Subject: [PATCH] Fix os.RemoveAll not working on Windows7 +Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/internal/sysrand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go +--- a/src/crypto/internal/sysrand/rand_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/crypto/internal/sysrand/rand_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -7,5 +7,26 @@ + import "internal/syscall/windows" + + func read(b []byte) error { +- return windows.ProcessPrng(b) ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ return batched(windows.RtlGenRandom, 1<<31-1)(b) ++} ++ ++// batched returns a function that calls f to populate a []byte by chunking it ++// into subslices of, at most, readMax bytes. ++func batched(f func([]byte) error, readMax int) func([]byte) error { ++ return func(out []byte) error { ++ for len(out) > 0 { ++ read := len(out) ++ if read > readMax { ++ read = readMax ++ } ++ if err := f(out[:read]); err != nil { ++ return err ++ } ++ out = out[read:] ++ } ++ return nil ++ } + } +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/crypto/rand/rand.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -25,7 +25,7 @@ + // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. + // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). + // - On NetBSD, Reader uses the kern.arandom sysctl. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get. + // +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -421,7 +421,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -63,7 +62,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") +@@ -244,12 +243,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.SyscallN(procProcessPrng.Addr(), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf))) ++ r1, _, e1 := syscall.SyscallN(procSystemFunction036.Addr(), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/runtime/os_windows.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) +@@ -40,7 +40,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -74,7 +75,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -97,7 +97,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, ++ _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -126,8 +127,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -144,13 +160,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -242,9 +251,40 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 +- return stdcall(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } ++} ++ ++const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 ++ ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// ++//go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryExW)), 3, uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryW)), 1, uintptr(unsafe.Pointer(absoluteFilepath))) ++ } ++ KeepAlive(filename) ++ KeepAlive(absoluteFilepath) ++ if handle != 0 { ++ err = 0 ++ } ++ return + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -262,13 +302,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -297,7 +352,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -351,6 +406,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -417,7 +488,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -458,6 +530,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := windows.OSVERSIONINFOW{} ++ info.OSVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.MajorVersion ++ osVersionInfo.minorVersion = info.MinorVersion ++ osVersionInfo.buildNumber = info.BuildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(windows.AsmStdCallAddr()) + +@@ -470,8 +564,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + numCPUStartup = getCPUCount() + +@@ -487,7 +581,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/hook_windows.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/internal/socktest/main_test.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/internal/socktest/sys_windows.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/main_windows_test.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -12,6 +12,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -21,6 +22,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -30,6 +32,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/sock_windows.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/syscall/exec_windows.go (revision b4aece36e51ecce81c3ee9fe03e31db552e90018) +@@ -15,7 +15,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -304,6 +303,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -367,6 +369,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -375,7 +388,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -406,6 +427,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision b4aece36e51ecce81c3ee9fe03e31db552e90018) ++++ b/src/syscall/dll_windows.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) +@@ -119,14 +119,7 @@ + } + + //go:linkname loadsystemlibrary +-func loadsystemlibrary(filename *uint16) (uintptr, Errno) { +- const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 +- handle, _, err := SyscallN(uintptr(__LoadLibraryExW), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) +- if handle != 0 { +- err = 0 +- } +- return handle, err +-} ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + + //go:linkname getprocaddress + func getprocaddress(handle uintptr, procname *uint8) (uintptr, Errno) { +@@ -143,6 +136,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -159,7 +155,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } +Index: src/os/removeall_at.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go +--- a/src/os/removeall_at.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/removeall_at.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build unix || wasip1 || windows ++//go:build unix || wasip1 + + package os + +@@ -175,3 +175,25 @@ + } + return newDirFile(fd, name) + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ // Consistency with os.RemoveAll: Strip trailing /s from the name, ++ // so RemoveAll("not_a_directory/") succeeds. ++ for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { ++ name = name[:len(name)-1] ++ } ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { ++ return struct{}{}, removeAllFrom(parent, name) ++ }) ++ if IsNotExist(err) { ++ return nil ++ } ++ if err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return err ++} +Index: src/os/removeall_noat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_noat.go b/src/os/removeall_noat.go +--- a/src/os/removeall_noat.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/removeall_noat.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (js && wasm) || plan9 ++//go:build (js && wasm) || plan9 || windows + + package os + +@@ -140,3 +140,22 @@ + } + return err + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ if err := checkPathEscapesLstat(r, name); err != nil { ++ if err == syscall.ENOTDIR { ++ // Some intermediate path component is not a directory. ++ // RemoveAll treats this as success (since the target doesn't exist). ++ return nil ++ } ++ return &PathError{Op: "RemoveAll", Path: name, Err: err} ++ } ++ if err := RemoveAll(joinPath(r.root.name, name)); err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return nil ++} +Index: src/os/root_noopenat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_noopenat.go b/src/os/root_noopenat.go +--- a/src/os/root_noopenat.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/root_noopenat.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -11,7 +11,6 @@ + "internal/filepathlite" + "internal/stringslite" + "sync/atomic" +- "syscall" + "time" + ) + +@@ -185,25 +184,6 @@ + } + return nil + } +- +-func rootRemoveAll(r *Root, name string) error { +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- if err := checkPathEscapesLstat(r, name); err != nil { +- if err == syscall.ENOTDIR { +- // Some intermediate path component is not a directory. +- // RemoveAll treats this as success (since the target doesn't exist). +- return nil +- } +- return &PathError{Op: "RemoveAll", Path: name, Err: err} +- } +- if err := RemoveAll(joinPath(r.root.name, name)); err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return nil +-} + + func rootReadlink(r *Root, name string) (string, error) { + if err := checkPathEscapesLstat(r, name); err != nil { +Index: src/os/root_openat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_openat.go b/src/os/root_openat.go +--- a/src/os/root_openat.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/root_openat.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -196,28 +196,6 @@ + return nil + } + +-func rootRemoveAll(r *Root, name string) error { +- // Consistency with os.RemoveAll: Strip trailing /s from the name, +- // so RemoveAll("not_a_directory/") succeeds. +- for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { +- name = name[:len(name)-1] +- } +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { +- return struct{}{}, removeAllFrom(parent, name) +- }) +- if IsNotExist(err) { +- return nil +- } +- if err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return err +-} +- + func rootRename(r *Root, oldname, newname string) error { + _, err := doInRoot(r, oldname, nil, func(oldparent sysfdType, oldname string) (struct{}, error) { + _, err := doInRoot(r, newname, nil, func(newparent sysfdType, newname string) (struct{}, error) { +Index: src/os/root_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_windows.go b/src/os/root_windows.go +--- a/src/os/root_windows.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/root_windows.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -402,3 +402,14 @@ + } + return fi.Mode(), nil + } ++ ++func checkPathEscapes(r *Root, name string) error { ++ if !filepathlite.IsLocal(name) { ++ return errPathEscapes ++ } ++ return nil ++} ++ ++func checkPathEscapesLstat(r *Root, name string) error { ++ return checkPathEscapes(r, name) ++} diff --git a/clash-meta/.github/workflows/build.yml b/clash-meta/.github/workflows/build.yml index 9ba36ed8ae..3fe99a6b62 100644 --- a/clash-meta/.github/workflows/build.yml +++ b/clash-meta/.github/workflows/build.yml @@ -59,6 +59,8 @@ jobs: - { goos: linux, goarch: s390x, output: s390x, debian: s390x, rpm: s390x } - { goos: linux, goarch: ppc64le, output: ppc64le, debian: ppc64el, rpm: ppc64le } + # Go 1.25 with special patch can work on Windows 7 + # https://github.com/MetaCubeX/go/commits/release-branch.go1.25/ - { goos: windows, goarch: '386', output: '386' } - { goos: windows, goarch: amd64, goamd64: v1, output: amd64-compatible } # old style file name will be removed in next released - { goos: windows, goarch: amd64, goamd64: v3, output: amd64 } @@ -176,6 +178,8 @@ jobs: # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" + # sepical fix: + # - os.RemoveAll not working on Windows7 - name: Revert Golang1.25 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '' }} run: | diff --git a/clash-meta/.github/workflows/test.yml b/clash-meta/.github/workflows/test.yml index ddddb5eee5..af3ae18fe7 100644 --- a/clash-meta/.github/workflows/test.yml +++ b/clash-meta/.github/workflows/test.yml @@ -24,6 +24,7 @@ jobs: - 'ubuntu-24.04-arm' # arm64 linux - 'macos-15-intel' # amd64 macos go-version: + - '1.26.0-rc.1' - '1.25' - '1.24' - '1.23' @@ -49,11 +50,17 @@ jobs: go-version: ${{ matrix.go-version }} - name: Revert Golang commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version != '1.20' }} + if: ${{ runner.os == 'Windows' && matrix.go-version != '1.20' && matrix.go-version != '1.26.0-rc.1' }} run: | cd $(go env GOROOT) patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go${{matrix.go-version}}.patch + - name: Revert Golang commit for Windows7/8 + if: ${{ runner.os == 'Windows' && matrix.go-version == '1.26.0-rc.1' }} + run: | + cd $(go env GOROOT) + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.26.patch + - name: Remove inbound test for macOS if: ${{ runner.os == 'macOS' }} run: | diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index f3ac23b084..4ab30a4d56 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -355,7 +355,7 @@ dependencies = [ "objc2-foundation 0.3.2", "parking_lot", "percent-encoding", - "windows-sys 0.59.0", + "windows-sys 0.60.2", "wl-clipboard-rs", "x11rb", ] @@ -1333,9 +1333,9 @@ dependencies = [ [[package]] name = "camino" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276a59bf2b2c967788139340c9f0c5b12d7fd6630315c15c217e559de85d2609" +checksum = "e629a66d692cb9ff1a1c664e41771b3dcaf961985a9774c0eb0bd1b51cf60a48" dependencies = [ "serde_core", ] @@ -2344,7 +2344,7 @@ dependencies = [ "libc", "option-ext", "redox_users 0.5.2", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -2853,7 +2853,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "778e2ac28f6c47af28e4907f13ffd1e1ddbd400980a9abd7c8df189bf578a5ad" dependencies = [ "libc", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -5043,9 +5043,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "loom" @@ -7384,7 +7384,7 @@ dependencies = [ "once_cell", "socket2", "tracing", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -7716,9 +7716,9 @@ checksum = "19b30a45b0cd0bcca8037f3d0dc3421eaf95327a17cad11964fb8179b4fc4832" [[package]] name = "reqwest" -version = "0.12.24" +version = "0.12.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0946410b9f7b082a427e4ef5c8ff541a88b357bc6c637c40db3a68ac70a36f" +checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" dependencies = [ "base64 0.22.1", "bytes", @@ -7951,7 +7951,7 @@ dependencies = [ "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -9607,7 +9607,7 @@ dependencies = [ "getrandom 0.3.3", "once_cell", "rustix 1.0.8", - "windows-sys 0.59.0", + "windows-sys 0.60.2", ] [[package]] @@ -10079,9 +10079,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.6" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" dependencies = [ "bitflags 2.9.4", "bytes", @@ -10109,9 +10109,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -10145,9 +10145,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", diff --git a/clash-nyanpasu/frontend/nyanpasu/messages/en.json b/clash-nyanpasu/frontend/nyanpasu/messages/en.json index d97c5ba8bd..f21b8f795f 100644 --- a/clash-nyanpasu/frontend/nyanpasu/messages/en.json +++ b/clash-nyanpasu/frontend/nyanpasu/messages/en.json @@ -28,7 +28,14 @@ "settings_clash_settings_ipv6_label": "Enable IPv6", "settings_clash_settings_tun_stack_label": "TUN Stack", "settings_clash_settings_log_level_label": "Log Level", + "settings_clash_settings_mixed_port_label": "Mixed Port", + "settings_clash_settings_random_port_label": "Random Port", + "settings_clash_settings_random_port_enabled": "Random port enabled, after restart to take effect.", + "settings_clash_settings_random_port_disabled": "Random port disabled, after restart to take effect.", "unit_seconds": "s", "common_submit": "Submit", - "common_cancel": "Cancel" + "common_cancel": "Cancel", + "common_apply": "Apply", + "common_reset": "Reset", + "common_save": "Save" } diff --git a/clash-nyanpasu/frontend/nyanpasu/messages/ru.json b/clash-nyanpasu/frontend/nyanpasu/messages/ru.json index c756167bb6..49ffa40561 100644 --- a/clash-nyanpasu/frontend/nyanpasu/messages/ru.json +++ b/clash-nyanpasu/frontend/nyanpasu/messages/ru.json @@ -28,7 +28,14 @@ "settings_clash_settings_ipv6_label": "Включить IPv6", "settings_clash_settings_tun_stack_label": "TUN Stack", "settings_clash_settings_log_level_label": "Уровень журнала", + "settings_clash_settings_mixed_port_label": "Смешанный порт", + "settings_clash_settings_random_port_label": "Случайный порт", + "settings_clash_settings_random_port_enabled": "Случайный порт включен, после перезапуска для вступления в силу.", + "settings_clash_settings_random_port_disabled": "Случайный порт отключен, после перезапуска для вступления в силу.", "unit_seconds": "секунды", "common_submit": "Отправить", - "common_cancel": "Отменить" + "common_cancel": "Отменить", + "common_apply": "Применить", + "common_reset": "Сбросить", + "common_save": "Сохранить" } diff --git a/clash-nyanpasu/frontend/nyanpasu/messages/zh-cn.json b/clash-nyanpasu/frontend/nyanpasu/messages/zh-cn.json index b795099c0a..1d55c3f4ca 100644 --- a/clash-nyanpasu/frontend/nyanpasu/messages/zh-cn.json +++ b/clash-nyanpasu/frontend/nyanpasu/messages/zh-cn.json @@ -28,7 +28,14 @@ "settings_clash_settings_ipv6_label": "启用 IPv6", "settings_clash_settings_tun_stack_label": "TUN 堆栈", "settings_clash_settings_log_level_label": "日志级别", + "settings_clash_settings_mixed_port_label": "混合端口", + "settings_clash_settings_random_port_label": "随机端口", + "settings_clash_settings_random_port_enabled": "随机端口已启用,重启后生效。", + "settings_clash_settings_random_port_disabled": "随机端口已禁用,重启后生效。", "unit_seconds": "秒", "common_submit": "提交", - "common_cancel": "取消" + "common_cancel": "取消", + "common_apply": "应用", + "common_reset": "重置", + "common_save": "保存" } diff --git a/clash-nyanpasu/frontend/nyanpasu/messages/zh-tw.json b/clash-nyanpasu/frontend/nyanpasu/messages/zh-tw.json index 7e2b14594f..e2584419d5 100644 --- a/clash-nyanpasu/frontend/nyanpasu/messages/zh-tw.json +++ b/clash-nyanpasu/frontend/nyanpasu/messages/zh-tw.json @@ -28,7 +28,14 @@ "settings_clash_settings_ipv6_label": "啟用 IPv6", "settings_clash_settings_tun_stack_label": "TUN 堆棧", "settings_clash_settings_log_level_label": "日誌級別", + "settings_clash_settings_mixed_port_label": "混合端口", + "settings_clash_settings_random_port_label": "隨機端口", + "settings_clash_settings_random_port_enabled": "隨機端口已啟用,重啟後生效。", + "settings_clash_settings_random_port_disabled": "隨機端口已禁用,重啟後生效。", "unit_seconds": "秒", "common_submit": "提交", - "common_cancel": "取消" + "common_cancel": "取消", + "common_apply": "應用", + "common_reset": "重置", + "common_save": "保存" } diff --git a/clash-nyanpasu/frontend/nyanpasu/package.json b/clash-nyanpasu/frontend/nyanpasu/package.json index 1cc8f99ff6..7556ae0bf6 100644 --- a/clash-nyanpasu/frontend/nyanpasu/package.json +++ b/clash-nyanpasu/frontend/nyanpasu/package.json @@ -14,6 +14,7 @@ "@dnd-kit/sortable": "10.0.0", "@dnd-kit/utilities": "3.2.2", "@emotion/styled": "11.14.1", + "@hookform/resolvers": "^5.2.2", "@inlang/paraglide-js": "2.7.0", "@juggle/resize-observer": "3.4.0", "@material/material-color-utilities": "0.3.0", @@ -26,6 +27,7 @@ "@radix-ui/react-dropdown-menu": "2.1.16", "@radix-ui/react-scroll-area": "1.2.10", "@radix-ui/react-select": "2.2.6", + "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "1.2.4", "@radix-ui/react-switch": "1.2.6", "@radix-ui/react-use-controllable-state": "1.2.2", @@ -52,6 +54,7 @@ "react-dom": "19.2.0", "react-error-boundary": "6.0.0", "react-fast-marquee": "1.6.5", + "react-hook-form": "^7.69.0", "react-hook-form-mui": "8.2.0", "react-i18next": "15.7.4", "react-markdown": "10.1.0", @@ -66,7 +69,7 @@ "@csstools/normalize.css": "12.1.1", "@emotion/babel-plugin": "11.13.5", "@emotion/react": "11.14.0", - "@iconify/json": "2.2.419", + "@iconify/json": "2.2.420", "@monaco-editor/react": "4.7.0", "@tanstack/react-query": "5.90.11", "@tanstack/react-router": "1.134.15", diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/ui/input.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/ui/input.tsx index e82f2e5000..5307a4df06 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/ui/input.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/ui/input.tsx @@ -1,7 +1,16 @@ import { useCreation } from 'ahooks' import { cva, type VariantProps } from 'class-variance-authority' -import React, { useEffect } from 'react' +import { + ChangeEvent, + ComponentProps, + createContext, + isValidElement, + useContext, + useEffect, + useState, +} from 'react' import { cn } from '@nyanpasu/ui' +import { Slot } from '@radix-ui/react-slot' export const inputContainerVariants = cva( [ @@ -10,13 +19,13 @@ export const inputContainerVariants = cva( 'px-4 py-4 outline-hidden', // TODO: size variants, fix this 'flex items-center justify-between h-14', - 'dark:text-surface', + 'dark:text-on-surface', ], { variants: { variant: { - filled: ['rounded-t', 'bg-surface-variant dark:bg-on-surface-variant'], - // outlined use selectValuePlaceholderFieldsetVariants + filled: 'rounded-t bg-surface-variant/30 dark:bg-surface', + // outlined use inputLabelFieldsetVariants outlined: '', }, }, @@ -33,6 +42,7 @@ export const inputVariants = cva( 'peer', 'w-full border-none p-0', 'bg-transparent placeholder-transparent outline-hidden', + 'transition-[margin] duration-200', ], { variants: { @@ -54,7 +64,7 @@ export const inputVariants = cva( variant: 'filled', haveValue: true, haveLabel: true, - className: 'mt-3', + className: 'mt-3!', }, ], defaultVariants: { @@ -127,7 +137,7 @@ export const inputLineVariants = cva('', { variants: { variant: { filled: [ - 'absolute inset-x-0 bottom-0 w-full border-b border-on-primary-container', + 'absolute inset-x-0 bottom-0 w-full border-b border-b-outline-variant', 'transition-all duration-200', // pseudo elements be overlay parent element, will not affect the box size 'after:absolute after:inset-x-0 after:bottom-0 after:z-10', @@ -167,15 +177,15 @@ export const inputLabelFieldsetVariants = cva('pointer-events-none', { 'peer-not-focus:border', 'peer-focus:border-2', // different material web border color, i think this looks better - 'group-data-[state=closed]:border-primary-container', + 'group-data-[state=closed]:border-outline-variant', 'group-data-[state=open]:border-primary', 'peer-not-focus:border-primary-container', 'peer-focus:border-primary', // dark must be prefixed - 'dark:group-data-[state=closed]:border-primary-container', - 'dark:group-data-[state=open]:border-inverse-primary', - 'dark:peer-not-focus:border-primary-container', - 'dark:peer-focus:border-inverse-primary', + 'dark:group-data-[state=closed]:border-outline-variant', + 'dark:group-data-[state=open]:border-primary-container', + 'dark:peer-not-focus:border-outline-variant', + 'dark:peer-focus:border-primary-container', ], }, }, @@ -222,10 +232,10 @@ type InputContextType = { haveValue?: boolean } & InputContainerVariants -const InputContext = React.createContext(null) +const InputContext = createContext(null) const useInputContext = () => { - const context = React.useContext(InputContext) + const context = useContext(InputContext) if (!context) { throw new Error('InputContext is undefined') @@ -237,7 +247,7 @@ const useInputContext = () => { export const InputContainer = ({ className, ...props -}: React.ComponentProps<'div'>) => { +}: ComponentProps<'div'>) => { const { variant } = useInputContext() return ( @@ -253,10 +263,7 @@ export const InputContainer = ({ ) } -export const InputLine = ({ - className, - ...props -}: React.ComponentProps<'input'>) => { +export const InputLine = ({ className, ...props }: ComponentProps<'input'>) => { const { variant } = useInputContext() return ( @@ -272,11 +279,13 @@ export const InputLine = ({ ) } -export type InputProps = React.ComponentProps<'input'> & { +export type InputProps = ComponentProps<'input'> & { label?: string + asChild?: boolean } & InputContainerVariants export const Input = ({ + asChild, variant, className, label, @@ -284,14 +293,14 @@ export const Input = ({ onChange, ...props }: InputProps) => { - const [haveValue, setHaveValue] = React.useState(false) + const [haveValue, setHaveValue] = useState(false) const haveLabel = useCreation(() => { if (label) { return true } - if (React.isValidElement(children)) { + if (isValidElement(children)) { if (typeof children.type !== 'string') { if ('displayName' in children.type) { if (children.type.displayName === InputLabel.displayName) { @@ -312,14 +321,16 @@ export const Input = ({ } }, [props.value, props.defaultValue]) - const handleChange = (event: React.ChangeEvent) => { + const handleChange = (event: ChangeEvent) => { setHaveValue(event.target.value.length > 0) onChange?.(event) } useEffect(() => { - console.log('haveValue', haveValue) - }, [haveValue]) + setHaveValue(Boolean(props.value || props.defaultValue)) + }, [props.value, props.defaultValue]) + + const Comp = asChild ? Slot : 'input' return ( - ) => { +}: ComponentProps<'label'>) => { const { haveValue, variant } = useInputContext() return ( @@ -398,3 +409,133 @@ export const InputLabel = ({ } InputLabel.displayName = 'InputLabel' + +export type NumericInputProps = Omit< + ComponentProps<'input'>, + 'onChange' | 'value' | 'defaultValue' | 'type' +> & { + value?: number | null + defaultValue?: number | null + onChange?: (value: number | null) => void + label?: string + min?: number + max?: number + step?: number + decimalScale?: number + allowNegative?: boolean +} & InputContainerVariants + +export const NumericInput = ({ + label, + variant, + className, + onChange, + value, + defaultValue, + min, + max, + step = 1, + decimalScale, + allowNegative = true, + ...props +}: NumericInputProps) => { + const [inputValue, setInputValue] = useState(() => { + const initialValue = value ?? defaultValue + return initialValue != null ? String(initialValue) : '' + }) + + useEffect(() => { + if (value != null) { + setInputValue(String(value)) + } + }, [value]) + + const validateAndFormatValue = (numValue: number): number => { + let validated = numValue + + if (!allowNegative && validated < 0) { + validated = 0 + } + + if (min != null && validated < min) { + validated = min + } + + if (max != null && validated > max) { + validated = max + } + + if (decimalScale != null) { + validated = Number(validated.toFixed(decimalScale)) + } + + return validated + } + + const handleChange = (e: ChangeEvent) => { + const rawValue = e.target.value + + // Allow empty string + if (rawValue === '') { + setInputValue('') + onChange?.(null) + return + } + + // Allow minus sign for negative numbers + if (rawValue === '-' && allowNegative) { + setInputValue('-') + return + } + + // Allow decimal point + if (rawValue.endsWith('.') || rawValue.endsWith(',')) { + setInputValue(rawValue) + return + } + + const numValue = Number(rawValue) + + // Check if it's a valid number + if (!isNaN(numValue)) { + setInputValue(rawValue) + + // Only validate and callback when it's a complete number + if (!rawValue.endsWith('.') && !rawValue.endsWith(',')) { + const validated = validateAndFormatValue(numValue) + onChange?.(validated) + } + } + } + + const handleBlur = () => { + if (inputValue === '' || inputValue === '-') { + setInputValue('') + onChange?.(null) + return + } + + const numValue = Number(inputValue) + if (!isNaN(numValue)) { + const validated = validateAndFormatValue(numValue) + setInputValue(String(validated)) + onChange?.(validated) + } + } + + return ( + + ) +} + +NumericInput.displayName = 'NumericInput' diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/ui/select.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/ui/select.tsx index f74277ddc2..57568c8d80 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/components/ui/select.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/ui/select.tsx @@ -27,7 +27,7 @@ export const selectTriggerVariants = cva( { variants: { variant: { - filled: 'rounded-t bg-surface-variant dark:bg-on-surface-variant', + filled: 'rounded-t bg-surface-variant/30 dark:bg-surface', // outlined use selectValuePlaceholderFieldsetVariants outlined: '', }, @@ -72,29 +72,32 @@ export const selectLineVariants = cva('', { export type SelectLineVariants = VariantProps -export const selectValueVariants = cva('pointer-events-none', { - variants: { - variant: { - filled: '', - outlined: '', +export const selectValueVariants = cva( + 'pointer-events-none transition-[margin] duration-200', + { + variants: { + variant: { + filled: '', + outlined: '', + }, + haveValue: { + true: '', + false: '', + }, }, - haveValue: { - true: '', - false: '', - }, - }, - compoundVariants: [ - { + compoundVariants: [ + { + variant: 'filled', + haveValue: true, + className: 'mt-3!', + }, + ], + defaultVariants: { variant: 'filled', - haveValue: true, - className: 'mt-3', + haveValue: false, }, - ], - defaultVariants: { - variant: 'filled', - haveValue: false, }, -}) +) export type SelectValueVariants = VariantProps @@ -111,7 +114,7 @@ export const selectValuePlaceholderVariants = cva( variants: { variant: { filled: [ - 'group-data-[state=open]:top-2 group-data-[state=open]:dark:text-surface', + 'group-data-[state=open]:top-2', 'group-data-[state=open]:text-xs group-data-[state=open]:text-primary', ], outlined: [ diff --git a/clash-nyanpasu/frontend/nyanpasu/src/components/ui/separator.tsx b/clash-nyanpasu/frontend/nyanpasu/src/components/ui/separator.tsx new file mode 100644 index 0000000000..cbcdb38771 --- /dev/null +++ b/clash-nyanpasu/frontend/nyanpasu/src/components/ui/separator.tsx @@ -0,0 +1,25 @@ +import { ComponentProps } from 'react' +import { cn } from '@nyanpasu/ui' +import * as SeparatorPrimitive from '@radix-ui/react-separator' + +export function Separator({ + className, + orientation = 'horizontal', + decorative = true, + ...props +}: ComponentProps) { + return ( + + ) +} diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-card.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-card.tsx index a728b072b7..83d5e64395 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-card.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-card.tsx @@ -1,3 +1,4 @@ +import { motion } from 'framer-motion' import { ComponentProps } from 'react' import { cn } from '@nyanpasu/ui' @@ -23,3 +24,36 @@ export function SettingsCardContent({ }: ComponentProps<'div'>) { return
} + +export function SettingsCardAnimatedItem({ + className, + ...props +}: ComponentProps) { + return ( + + ) +} diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-navigate.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-navigate.tsx index c0ed50b0c3..d361f580ec 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-navigate.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/_modules/settings-navigate.tsx @@ -3,7 +3,6 @@ import DisplayExternalInput from '~icons/material-symbols/display-external-input import FrameBugOutlineRounded from '~icons/material-symbols/frame-bug-outline-rounded' import ListsRounded from '~icons/material-symbols/lists-rounded' import NetworkNode from '~icons/material-symbols/network-node' -import RoomServiceRounded from '~icons/material-symbols/room-service-rounded' import SettingsBoltRounded from '~icons/material-symbols/settings-b-roll-rounded' import SettingsEthernet from '~icons/material-symbols/settings-ethernet-rounded' import ShareWindows from '~icons/material-symbols/share-windows-rounded' @@ -45,12 +44,6 @@ const ROUTES = [ href: '/experimental/settings/clash-settings', icon: SettingsBoltRounded, }, - { - label: 'Clash Port', - description: 'Configure the clash port', - href: '/experimental/settings/clash-port', - icon: NetworkNode, - }, { label: 'Clash External Controll', description: 'Configure the clash external controll', @@ -85,7 +78,7 @@ const ROUTES = [ label: 'System Service', description: 'Configure the system service', href: '/experimental/settings/system-service', - icon: RoomServiceRounded, + icon: NetworkNode, }, { label: 'Nyanpasu Config', diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-port/route.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-port/route.tsx deleted file mode 100644 index 176be04da0..0000000000 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-port/route.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import { createFileRoute } from '@tanstack/react-router' - -export const Route = createFileRoute( - '/(experimental)/experimental/settings/clash-port', -)({ - component: RouteComponent, -}) - -function RouteComponent() { - return
Hello "/(experimental)/experimental/settings/about"!
-} diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/mixed-port-config.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/mixed-port-config.tsx new file mode 100644 index 0000000000..353d744111 --- /dev/null +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/mixed-port-config.tsx @@ -0,0 +1,135 @@ +import { AnimatePresence } from 'framer-motion' +import { useCallback, useEffect, useMemo } from 'react' +import { Controller, useForm } from 'react-hook-form' +import { z } from 'zod' +import { Button } from '@/components/ui/button' +import { NumericInput } from '@/components/ui/input' +import { m } from '@/paraglide/messages' +import { formatError } from '@/utils' +import { message } from '@/utils/notification' +import { zodResolver } from '@hookform/resolvers/zod' +import { useClashConfig, useSetting } from '@nyanpasu/interface' +import { + SettingsCard, + SettingsCardAnimatedItem, + SettingsCardContent, +} from '../../_modules/settings-card' + +const DEFAULT_MIXED_PORT = 7890 + +const formSchema = z.object({ + mixedPort: z.number().min(1).max(65535), +}) + +export default function MixedPortConfig() { + const mixedPort = useSetting('verge_mixed_port') + + const clashConfig = useClashConfig() + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + mixedPort: DEFAULT_MIXED_PORT, + }, + }) + + // get current mixed port from clash config or verge setting + const currentMixedPort = useMemo(() => { + return ( + clashConfig.query.data?.['mixed-port'] || + mixedPort.value || + DEFAULT_MIXED_PORT + ) + }, [clashConfig.query.data, mixedPort.value]) + + // sync current mixed port to form + useEffect(() => { + form.setValue('mixedPort', currentMixedPort) + }, [currentMixedPort, form]) + + const handleSubmit = form.handleSubmit(async (data) => { + try { + await clashConfig.upsert.mutateAsync({ + 'mixed-port': data.mixedPort, + }) + await mixedPort.upsert(data.mixedPort) + + form.reset({ + mixedPort: data.mixedPort, + }) + } catch (error) { + message(formatError(error), { + title: 'Error', + kind: 'error', + }) + } + }) + + const handleReset = useCallback(() => { + form.reset({ + mixedPort: currentMixedPort, + }) + }, [form, currentMixedPort]) + + return ( + + +
+ { + const handleChange = (value: number | null) => { + field.onChange(value) + } + + return ( + <> + + + + {fieldState.error && ( + + {fieldState.error.message} + + )} + + + ) + }} + /> + + + {form.formState.isDirty && ( + +
+ + + +
+
+ )} +
+ +
+
+ ) +} diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/random-port-switch.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/random-port-switch.tsx new file mode 100644 index 0000000000..da071a7c04 --- /dev/null +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/_modules/random-port-switch.tsx @@ -0,0 +1,48 @@ +import { Switch } from '@/components/ui/switch' +import { m } from '@/paraglide/messages' +import { formatError } from '@/utils' +import { message } from '@/utils/notification' +import { useSetting } from '@nyanpasu/interface' +import { SettingsCard, SettingsCardContent } from '../../_modules/settings-card' + +export default function RandomPortSwitch() { + const enableRandomPort = useSetting('enable_random_port') + + const handleRandomPort = async () => { + try { + await enableRandomPort.upsert(!enableRandomPort.value) + } catch (e) { + message(formatError(e), { + title: 'Error', + kind: 'error', + }) + } finally { + message( + enableRandomPort.value + ? m.settings_clash_settings_random_port_disabled() + : m.settings_clash_settings_random_port_enabled(), + { + title: 'Successful', + kind: 'info', + }, + ) + } + } + + return ( + + +
{m.settings_clash_settings_random_port_label()}
+ + +
+
+ ) +} diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/route.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/route.tsx index 6a9789595f..dee3a8e237 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/route.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/clash-settings/route.tsx @@ -1,3 +1,4 @@ +import { Separator } from '@/components/ui/separator' import { m } from '@/paraglide/messages' import { createFileRoute } from '@tanstack/react-router' import { @@ -7,6 +8,8 @@ import { import AllowLanSwitch from './_modules/allow-lan-switch' import IPv6Switch from './_modules/ipv6-switch' import LogLevelSelector from './_modules/log-level-selector' +import MixedPortConfig from './_modules/mixed-port-config' +import RandomPortSwitch from './_modules/random-port-switch' import TunStackSelector from './_modules/tun-stack-selector' export const Route = createFileRoute( @@ -28,6 +31,12 @@ function RouteComponent() { + + + + + + ) } diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-bypass-config.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-bypass-config.tsx index 024dc73b06..aa015c4b82 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-bypass-config.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-bypass-config.tsx @@ -1,17 +1,118 @@ +import { AnimatePresence } from 'framer-motion' +import { ChangeEvent, useCallback, useEffect } from 'react' +import { Controller, useForm } from 'react-hook-form' +import { z } from 'zod' +import { Button } from '@/components/ui/button' +import { Input } from '@/components/ui/input' import { m } from '@/paraglide/messages' -import { SettingsCard, SettingsCardContent } from '../../_modules/settings-card' +import { formatError } from '@/utils' +import { message } from '@/utils/notification' +import { zodResolver } from '@hookform/resolvers/zod' +import { useSetting } from '@nyanpasu/interface' +import { + SettingsCard, + SettingsCardAnimatedItem, + SettingsCardContent, +} from '../../_modules/settings-card' + +const DEFAULT_BYPASS = + 'localhost;127.;192.168.;10.;' + + '172.16.;172.17.;172.18.;172.19.;172.20.;172.21.;172.22.;172.23.;' + + '172.24.;172.25.;172.26.;172.27.;172.28.;172.29.;172.30.;172.31.*' + +const formSchema = z.object({ + systemProxyBypass: z.string().nullable().optional(), +}) export default function ProxyBypassConfig() { + const systemProxyBypass = useSetting('system_proxy_bypass') + + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + systemProxyBypass: systemProxyBypass.value, + }, + }) + + useEffect(() => { + form.setValue('systemProxyBypass', systemProxyBypass.value) + }, [systemProxyBypass.value, form]) + + const handleSubmit = form.handleSubmit(async (data) => { + try { + await systemProxyBypass.upsert(data.systemProxyBypass ?? DEFAULT_BYPASS) + + form.reset({ + systemProxyBypass: data.systemProxyBypass ?? DEFAULT_BYPASS, + }) + } catch (error) { + message(formatError(error), { + title: 'Error', + kind: 'error', + }) + } + }) + + const handleReset = useCallback(() => { + form.reset({ + systemProxyBypass: systemProxyBypass.value, + }) + }, [systemProxyBypass.value, form]) + return ( - {/* TODO: implement input component */} -
- {m.settings_system_proxy_proxy_bypass_label()} -
+
+ { + const handleChange = (event: ChangeEvent) => { + field.onChange(event.target.value) + } + + return ( + <> + + + {form.formState.errors.systemProxyBypass && ( + + {form.formState.errors.systemProxyBypass.message} + + )} + + ) + }} + /> + + + {form.formState.isDirty && ( + +
+ + + +
+
+ )} +
+
) diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-guard-config.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-guard-config.tsx index 6b73d408a1..70827978b3 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-guard-config.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/system-proxy/_modules/proxy-guard-config.tsx @@ -1,23 +1,122 @@ +import { AnimatePresence } from 'framer-motion' +import { isNumber } from 'lodash-es' +import { useCallback, useEffect } from 'react' +import { Controller, useForm } from 'react-hook-form' +import { z } from 'zod' +import { Button } from '@/components/ui/button' +import { NumericInput } from '@/components/ui/input' import { m } from '@/paraglide/messages' +import { formatError } from '@/utils' +import { message } from '@/utils/notification' +import { zodResolver } from '@hookform/resolvers/zod' import { useSetting } from '@nyanpasu/interface' -import { SettingsCard, SettingsCardContent } from '../../_modules/settings-card' +import { + SettingsCard, + SettingsCardAnimatedItem, + SettingsCardContent, +} from '../../_modules/settings-card' + +const formSchema = z.object({ + proxyGuardInterval: z.number().min(1), +}) export default function ProxyGuardConfig() { const proxyGuardInterval = useSetting('proxy_guard_interval') + const form = useForm>({ + resolver: zodResolver(formSchema), + defaultValues: { + proxyGuardInterval: proxyGuardInterval.value || 1, + }, + }) + + useEffect(() => { + if (isNumber(proxyGuardInterval.value)) { + form.setValue('proxyGuardInterval', proxyGuardInterval.value) + } + }, [proxyGuardInterval.value, form]) + + const handleSubmit = form.handleSubmit(async (data) => { + try { + await proxyGuardInterval.upsert(data.proxyGuardInterval) + + form.reset({ + proxyGuardInterval: data.proxyGuardInterval, + }) + } catch (error) { + message(formatError(error), { + title: 'Error', + kind: 'error', + }) + } + }) + + const handleReset = useCallback(() => { + form.reset({ + proxyGuardInterval: proxyGuardInterval.value || 1, + }) + }, [proxyGuardInterval.value, form]) + return ( - {m.settings_system_proxy_proxy_guard_interval_label()} - - {/* TODO: implement input component */} -
+ {/*
{proxyGuardInterval.value || 0} {m.unit_seconds()} -
+
*/} +
+ { + const handleChange = (value: number | null) => { + field.onChange(value) + } + + return ( + <> + + + + {form.formState.errors.proxyGuardInterval && ( + + {form.formState.errors.proxyGuardInterval.message} + + )} + + + ) + }} + /> + + + {form.formState.isDirty && ( + +
+ + + +
+
+ )} +
+
) diff --git a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/user-interface/_modules/experimental-switch.tsx b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/user-interface/_modules/experimental-switch.tsx index 792d40103d..21f0f3a9e9 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/user-interface/_modules/experimental-switch.tsx +++ b/clash-nyanpasu/frontend/nyanpasu/src/pages/(experimental)/experimental/settings/user-interface/_modules/experimental-switch.tsx @@ -1,13 +1,19 @@ +import { useSetAtom } from 'jotai' import { Button } from '@/components/ui/button' +import { memorizedRoutePathAtom } from '@/store' import { setEnabledExperimentalRouter } from '@/utils/experimental' import { useNavigate } from '@tanstack/react-router' import { SettingsCard, SettingsCardContent } from '../../_modules/settings-card' export default function ExperimentalSwitch() { const navigate = useNavigate() + + const setMemorizedNavigate = useSetAtom(memorizedRoutePathAtom) + const handleClick = () => { setEnabledExperimentalRouter(false) - navigate({ to: '/' }) + navigate({ to: '/dashboard' }) + setMemorizedNavigate('/dashboard') } return ( diff --git a/clash-nyanpasu/frontend/nyanpasu/src/route-tree.gen.ts b/clash-nyanpasu/frontend/nyanpasu/src/route-tree.gen.ts index 5c930b69dd..a26a8093cd 100644 --- a/clash-nyanpasu/frontend/nyanpasu/src/route-tree.gen.ts +++ b/clash-nyanpasu/frontend/nyanpasu/src/route-tree.gen.ts @@ -37,7 +37,6 @@ import { Route as experimentalExperimentalSettingsSystemBehaviorRouteRouteImport import { Route as experimentalExperimentalSettingsNyanpasuConfigRouteRouteImport } from './pages/(experimental)/experimental/settings/nyanpasu-config/route' import { Route as experimentalExperimentalSettingsDebugUtilsRouteRouteImport } from './pages/(experimental)/experimental/settings/debug-utils/route' import { Route as experimentalExperimentalSettingsClashSettingsRouteRouteImport } from './pages/(experimental)/experimental/settings/clash-settings/route' -import { Route as experimentalExperimentalSettingsClashPortRouteRouteImport } from './pages/(experimental)/experimental/settings/clash-port/route' import { Route as experimentalExperimentalSettingsClashFiledRouteRouteImport } from './pages/(experimental)/experimental/settings/clash-filed/route' import { Route as experimentalExperimentalSettingsClashExternalControllRouteRouteImport } from './pages/(experimental)/experimental/settings/clash-external-controll/route' import { Route as experimentalExperimentalSettingsClashCoreRouteRouteImport } from './pages/(experimental)/experimental/settings/clash-core/route' @@ -198,12 +197,6 @@ const experimentalExperimentalSettingsClashSettingsRouteRoute = path: '/clash-settings', getParentRoute: () => experimentalExperimentalSettingsRouteRoute, } as any) -const experimentalExperimentalSettingsClashPortRouteRoute = - experimentalExperimentalSettingsClashPortRouteRouteImport.update({ - id: '/clash-port', - path: '/clash-port', - getParentRoute: () => experimentalExperimentalSettingsRouteRoute, - } as any) const experimentalExperimentalSettingsClashFiledRouteRoute = experimentalExperimentalSettingsClashFiledRouteRouteImport.update({ id: '/clash-filed', @@ -251,7 +244,6 @@ export interface FileRoutesByFullPath { '/experimental/settings/clash-core': typeof experimentalExperimentalSettingsClashCoreRouteRoute '/experimental/settings/clash-external-controll': typeof experimentalExperimentalSettingsClashExternalControllRouteRoute '/experimental/settings/clash-filed': typeof experimentalExperimentalSettingsClashFiledRouteRoute - '/experimental/settings/clash-port': typeof experimentalExperimentalSettingsClashPortRouteRoute '/experimental/settings/clash-settings': typeof experimentalExperimentalSettingsClashSettingsRouteRoute '/experimental/settings/debug-utils': typeof experimentalExperimentalSettingsDebugUtilsRouteRoute '/experimental/settings/nyanpasu-config': typeof experimentalExperimentalSettingsNyanpasuConfigRouteRoute @@ -283,7 +275,6 @@ export interface FileRoutesByTo { '/experimental/settings/clash-core': typeof experimentalExperimentalSettingsClashCoreRouteRoute '/experimental/settings/clash-external-controll': typeof experimentalExperimentalSettingsClashExternalControllRouteRoute '/experimental/settings/clash-filed': typeof experimentalExperimentalSettingsClashFiledRouteRoute - '/experimental/settings/clash-port': typeof experimentalExperimentalSettingsClashPortRouteRoute '/experimental/settings/clash-settings': typeof experimentalExperimentalSettingsClashSettingsRouteRoute '/experimental/settings/debug-utils': typeof experimentalExperimentalSettingsDebugUtilsRouteRoute '/experimental/settings/nyanpasu-config': typeof experimentalExperimentalSettingsNyanpasuConfigRouteRoute @@ -319,7 +310,6 @@ export interface FileRoutesById { '/(experimental)/experimental/settings/clash-core': typeof experimentalExperimentalSettingsClashCoreRouteRoute '/(experimental)/experimental/settings/clash-external-controll': typeof experimentalExperimentalSettingsClashExternalControllRouteRoute '/(experimental)/experimental/settings/clash-filed': typeof experimentalExperimentalSettingsClashFiledRouteRoute - '/(experimental)/experimental/settings/clash-port': typeof experimentalExperimentalSettingsClashPortRouteRoute '/(experimental)/experimental/settings/clash-settings': typeof experimentalExperimentalSettingsClashSettingsRouteRoute '/(experimental)/experimental/settings/debug-utils': typeof experimentalExperimentalSettingsDebugUtilsRouteRoute '/(experimental)/experimental/settings/nyanpasu-config': typeof experimentalExperimentalSettingsNyanpasuConfigRouteRoute @@ -354,7 +344,6 @@ export interface FileRouteTypes { | '/experimental/settings/clash-core' | '/experimental/settings/clash-external-controll' | '/experimental/settings/clash-filed' - | '/experimental/settings/clash-port' | '/experimental/settings/clash-settings' | '/experimental/settings/debug-utils' | '/experimental/settings/nyanpasu-config' @@ -386,7 +375,6 @@ export interface FileRouteTypes { | '/experimental/settings/clash-core' | '/experimental/settings/clash-external-controll' | '/experimental/settings/clash-filed' - | '/experimental/settings/clash-port' | '/experimental/settings/clash-settings' | '/experimental/settings/debug-utils' | '/experimental/settings/nyanpasu-config' @@ -421,7 +409,6 @@ export interface FileRouteTypes { | '/(experimental)/experimental/settings/clash-core' | '/(experimental)/experimental/settings/clash-external-controll' | '/(experimental)/experimental/settings/clash-filed' - | '/(experimental)/experimental/settings/clash-port' | '/(experimental)/experimental/settings/clash-settings' | '/(experimental)/experimental/settings/debug-utils' | '/(experimental)/experimental/settings/nyanpasu-config' @@ -637,13 +624,6 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof experimentalExperimentalSettingsClashSettingsRouteRouteImport parentRoute: typeof experimentalExperimentalSettingsRouteRoute } - '/(experimental)/experimental/settings/clash-port': { - id: '/(experimental)/experimental/settings/clash-port' - path: '/clash-port' - fullPath: '/experimental/settings/clash-port' - preLoaderRoute: typeof experimentalExperimentalSettingsClashPortRouteRouteImport - parentRoute: typeof experimentalExperimentalSettingsRouteRoute - } '/(experimental)/experimental/settings/clash-filed': { id: '/(experimental)/experimental/settings/clash-filed' path: '/clash-filed' @@ -680,7 +660,6 @@ interface experimentalExperimentalSettingsRouteRouteChildren { experimentalExperimentalSettingsClashCoreRouteRoute: typeof experimentalExperimentalSettingsClashCoreRouteRoute experimentalExperimentalSettingsClashExternalControllRouteRoute: typeof experimentalExperimentalSettingsClashExternalControllRouteRoute experimentalExperimentalSettingsClashFiledRouteRoute: typeof experimentalExperimentalSettingsClashFiledRouteRoute - experimentalExperimentalSettingsClashPortRouteRoute: typeof experimentalExperimentalSettingsClashPortRouteRoute experimentalExperimentalSettingsClashSettingsRouteRoute: typeof experimentalExperimentalSettingsClashSettingsRouteRoute experimentalExperimentalSettingsDebugUtilsRouteRoute: typeof experimentalExperimentalSettingsDebugUtilsRouteRoute experimentalExperimentalSettingsNyanpasuConfigRouteRoute: typeof experimentalExperimentalSettingsNyanpasuConfigRouteRoute @@ -702,8 +681,6 @@ const experimentalExperimentalSettingsRouteRouteChildren: experimentalExperiment experimentalExperimentalSettingsClashExternalControllRouteRoute, experimentalExperimentalSettingsClashFiledRouteRoute: experimentalExperimentalSettingsClashFiledRouteRoute, - experimentalExperimentalSettingsClashPortRouteRoute: - experimentalExperimentalSettingsClashPortRouteRoute, experimentalExperimentalSettingsClashSettingsRouteRoute: experimentalExperimentalSettingsClashSettingsRouteRoute, experimentalExperimentalSettingsDebugUtilsRouteRoute: diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index d34d1057a9..5cf077e694 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.19.17", - "mihomo_alpha": "alpha-17966b5", + "mihomo_alpha": "alpha-87c3f70", "clash_rs": "v0.9.3", "clash_premium": "2023-09-05-gdcc8d87", "clash_rs_alpha": "0.9.3-alpha+sha.a6538ac" @@ -69,5 +69,5 @@ "linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf" } }, - "updated_at": "2025-12-18T22:21:30.469Z" + "updated_at": "2025-12-19T22:21:30.804Z" } diff --git a/clash-nyanpasu/package.json b/clash-nyanpasu/package.json index 125c058a2d..7ce0a1ec86 100644 --- a/clash-nyanpasu/package.json +++ b/clash-nyanpasu/package.json @@ -66,7 +66,7 @@ "@tauri-apps/cli": "2.8.4", "@types/fs-extra": "11.0.4", "@types/lodash-es": "4.17.12", - "@types/node": "24.10.1", + "@types/node": "24.10.4", "@typescript-eslint/eslint-plugin": "8.50.0", "@typescript-eslint/parser": "8.50.0", "autoprefixer": "10.4.23", @@ -105,7 +105,7 @@ "stylelint-order": "7.0.0", "stylelint-scss": "6.13.0", "tailwindcss": "4.1.17", - "tsx": "4.20.6", + "tsx": "4.21.0", "typescript": "5.9.3", "typescript-eslint": "8.50.0" }, diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index eebb4d699d..63a6237d85 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -24,7 +24,7 @@ importers: devDependencies: '@commitlint/cli': specifier: 20.2.0 - version: 20.2.0(@types/node@24.10.1)(typescript@5.9.3) + version: 20.2.0(@types/node@24.10.4)(typescript@5.9.3) '@commitlint/config-conventional': specifier: 20.2.0 version: 20.2.0 @@ -47,8 +47,8 @@ importers: specifier: 4.17.12 version: 4.17.12 '@types/node': - specifier: 24.10.1 - version: 24.10.1 + specifier: 24.10.4 + version: 24.10.4 '@typescript-eslint/eslint-plugin': specifier: 8.50.0 version: 8.50.0(@typescript-eslint/parser@8.50.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3))(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) @@ -105,7 +105,7 @@ importers: version: 16.5.0 knip: specifier: 5.68.0 - version: 5.68.0(@types/node@24.10.1)(typescript@5.9.3) + version: 5.68.0(@types/node@24.10.4)(typescript@5.9.3) lint-staged: specifier: 16.2.7 version: 16.2.7 @@ -164,8 +164,8 @@ importers: specifier: 4.1.17 version: 4.1.17 tsx: - specifier: 4.20.6 - version: 4.20.6 + specifier: 4.21.0 + version: 4.21.0 typescript: specifier: 5.9.3 version: 5.9.3 @@ -221,6 +221,9 @@ importers: '@emotion/styled': specifier: 11.14.1 version: 11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react@19.2.0) + '@hookform/resolvers': + specifier: ^5.2.2 + version: 5.2.2(react-hook-form@7.69.0(react@19.2.0)) '@inlang/paraglide-js': specifier: 2.7.0 version: 2.7.0(babel-plugin-macros@3.1.0) @@ -257,6 +260,9 @@ importers: '@radix-ui/react-select': specifier: 2.2.6 version: 2.2.6(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@radix-ui/react-separator': + specifier: ^1.1.8 + version: 1.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@radix-ui/react-slot': specifier: 1.2.4 version: 1.2.4(@types/react@19.2.7)(react@19.2.0) @@ -335,9 +341,12 @@ importers: react-fast-marquee: specifier: 1.6.5 version: 1.6.5(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react-hook-form: + specifier: ^7.69.0 + version: 7.69.0(react@19.2.0) react-hook-form-mui: specifier: 8.2.0 - version: 8.2.0(a94fb62675188bb2256f3adb84e9f008) + version: 8.2.0(ccfc370862f0ca346424eba435f9b21c) react-i18next: specifier: 15.7.4 version: 15.7.4(i18next@25.6.3(typescript@5.9.3))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(typescript@5.9.3) @@ -373,8 +382,8 @@ importers: specifier: 11.14.0 version: 11.14.0(@types/react@19.2.7)(react@19.2.0) '@iconify/json': - specifier: 2.2.419 - version: 2.2.419 + specifier: 2.2.420 + version: 2.2.420 '@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) @@ -386,10 +395,10 @@ importers: version: 1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@tanstack/react-router-devtools': specifier: 1.134.15 - version: 1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.15)(@types/node@24.10.1)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) + version: 1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.15)(@types/node@24.10.4)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.21.0)(yaml@2.8.1) '@tanstack/router-plugin': specifier: 1.134.15 - version: 1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) '@tauri-apps/plugin-clipboard-manager': specifier: 2.3.0 version: 2.3.0 @@ -425,13 +434,13 @@ importers: version: 13.15.10 '@vitejs/plugin-legacy': specifier: 7.2.1 - version: 7.2.1(terser@5.36.0)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 7.2.1(terser@5.36.0)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) '@vitejs/plugin-react': specifier: 5.1.1 - version: 5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.1(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) '@vitejs/plugin-react-swc': specifier: 4.2.2 - version: 4.2.2(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.2.2(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) change-case: specifier: 5.4.4 version: 5.4.4 @@ -470,19 +479,19 @@ importers: version: 13.15.26 vite: specifier: 7.2.4 - version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) vite-plugin-html: specifier: 3.2.2 - version: 3.2.2(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 3.2.2(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) vite-plugin-sass-dts: specifier: 1.3.34 - version: 1.3.34(postcss@8.5.6)(prettier@3.7.4)(sass-embedded@1.93.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 1.3.34(postcss@8.5.6)(prettier@3.7.4)(sass-embedded@1.93.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) vite-plugin-svgr: specifier: 4.5.0 - version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) zod: specifier: 4.1.13 version: 4.1.13 @@ -518,7 +527,7 @@ importers: version: 19.2.7 '@vitejs/plugin-react': specifier: 5.1.1 - version: 5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.1(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) ahooks: specifier: 3.9.6 version: 3.9.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) @@ -548,10 +557,10 @@ importers: version: 4.1.17 vite: specifier: 7.2.4 - version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + version: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) vite-tsconfig-paths: specifier: 5.1.4 - version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) devDependencies: '@emotion/react': specifier: 11.14.0 @@ -576,7 +585,7 @@ importers: version: 5.2.0(typescript@5.9.3) vite-plugin-dts: specifier: 4.5.4 - version: 4.5.4(@types/node@24.10.1)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)) + version: 4.5.4(@types/node@24.10.4)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)) scripts: dependencies: @@ -1617,150 +1626,306 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.27.2': + resolution: {integrity: sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.25.0': resolution: {integrity: sha512-grvv8WncGjDSyUBjN9yHXNt+cq0snxXbDxy5pJtzMKGmmpPxeAmAhWxXI+01lU5rwZomDgD3kJwulEnhTRUd6g==} engines: {node: '>=18'} cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.27.2': + resolution: {integrity: sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.25.0': resolution: {integrity: sha512-PTyWCYYiU0+1eJKmw21lWtC+d08JDZPQ5g+kFyxP0V+es6VPPSUhM6zk8iImp2jbV6GwjX4pap0JFbUQN65X1g==} engines: {node: '>=18'} cpu: [arm] os: [android] + '@esbuild/android-arm@0.27.2': + resolution: {integrity: sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.25.0': resolution: {integrity: sha512-m/ix7SfKG5buCnxasr52+LI78SQ+wgdENi9CqyCXwjVR2X4Jkz+BpC3le3AoBPYTC9NHklwngVXvbJ9/Akhrfg==} engines: {node: '>=18'} cpu: [x64] os: [android] + '@esbuild/android-x64@0.27.2': + resolution: {integrity: sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.25.0': resolution: {integrity: sha512-mVwdUb5SRkPayVadIOI78K7aAnPamoeFR2bT5nszFUZ9P8UpK4ratOdYbZZXYSqPKMHfS1wdHCJk1P1EZpRdvw==} engines: {node: '>=18'} cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.27.2': + resolution: {integrity: sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.25.0': resolution: {integrity: sha512-DgDaYsPWFTS4S3nWpFcMn/33ZZwAAeAFKNHNa1QN0rI4pUjgqf0f7ONmXf6d22tqTY+H9FNdgeaAa+YIFUn2Rg==} engines: {node: '>=18'} cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.27.2': + resolution: {integrity: sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.25.0': resolution: {integrity: sha512-VN4ocxy6dxefN1MepBx/iD1dH5K8qNtNe227I0mnTRjry8tj5MRk4zprLEdG8WPyAPb93/e4pSgi1SoHdgOa4w==} engines: {node: '>=18'} cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.27.2': + resolution: {integrity: sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.0': resolution: {integrity: sha512-mrSgt7lCh07FY+hDD1TxiTyIHyttn6vnjesnPoVDNmDfOmggTLXRv8Id5fNZey1gl/V2dyVK1VXXqVsQIiAk+A==} engines: {node: '>=18'} cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.27.2': + resolution: {integrity: sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.25.0': resolution: {integrity: sha512-9QAQjTWNDM/Vk2bgBl17yWuZxZNQIF0OUUuPZRKoDtqF2k4EtYbpyiG5/Dk7nqeK6kIJWPYldkOcBqjXjrUlmg==} engines: {node: '>=18'} cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.27.2': + resolution: {integrity: sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.25.0': resolution: {integrity: sha512-vkB3IYj2IDo3g9xX7HqhPYxVkNQe8qTK55fraQyTzTX/fxaDtXiEnavv9geOsonh2Fd2RMB+i5cbhu2zMNWJwg==} engines: {node: '>=18'} cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.27.2': + resolution: {integrity: sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.25.0': resolution: {integrity: sha512-43ET5bHbphBegyeqLb7I1eYn2P/JYGNmzzdidq/w0T8E2SsYL1U6un2NFROFRg1JZLTzdCoRomg8Rvf9M6W6Gg==} engines: {node: '>=18'} cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.27.2': + resolution: {integrity: sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.25.0': resolution: {integrity: sha512-fC95c/xyNFueMhClxJmeRIj2yrSMdDfmqJnyOY4ZqsALkDrrKJfIg5NTMSzVBr5YW1jf+l7/cndBfP3MSDpoHw==} engines: {node: '>=18'} cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.27.2': + resolution: {integrity: sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.25.0': resolution: {integrity: sha512-nkAMFju7KDW73T1DdH7glcyIptm95a7Le8irTQNO/qtkoyypZAnjchQgooFUDQhNAy4iu08N79W4T4pMBwhPwQ==} engines: {node: '>=18'} cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.27.2': + resolution: {integrity: sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.25.0': resolution: {integrity: sha512-NhyOejdhRGS8Iwv+KKR2zTq2PpysF9XqY+Zk77vQHqNbo/PwZCzB5/h7VGuREZm1fixhs4Q/qWRSi5zmAiO4Fw==} engines: {node: '>=18'} cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.27.2': + resolution: {integrity: sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.25.0': resolution: {integrity: sha512-5S/rbP5OY+GHLC5qXp1y/Mx//e92L1YDqkiBbO9TQOvuFXM+iDqUNG5XopAnXoRH3FjIUDkeGcY1cgNvnXp/kA==} engines: {node: '>=18'} cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.27.2': + resolution: {integrity: sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.25.0': resolution: {integrity: sha512-XM2BFsEBz0Fw37V0zU4CXfcfuACMrppsMFKdYY2WuTS3yi8O1nFOhil/xhKTmE1nPmVyvQJjJivgDT+xh8pXJA==} engines: {node: '>=18'} cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.27.2': + resolution: {integrity: sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.25.0': resolution: {integrity: sha512-9yl91rHw/cpwMCNytUDxwj2XjFpxML0y9HAOH9pNVQDpQrBxHy01Dx+vaMu0N1CKa/RzBD2hB4u//nfc+Sd3Cw==} engines: {node: '>=18'} cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.27.2': + resolution: {integrity: sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.0': resolution: {integrity: sha512-RuG4PSMPFfrkH6UwCAqBzauBWTygTvb1nxWasEJooGSJ/NwRw7b2HOwyRTQIU97Hq37l3npXoZGYMy3b3xYvPw==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@esbuild/netbsd-arm64@0.27.2': + resolution: {integrity: sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.0': resolution: {integrity: sha512-jl+qisSB5jk01N5f7sPCsBENCOlPiS/xptD5yxOx2oqQfyourJwIKLRA2yqWdifj3owQZCL2sn6o08dBzZGQzA==} engines: {node: '>=18'} cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.27.2': + resolution: {integrity: sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.0': resolution: {integrity: sha512-21sUNbq2r84YE+SJDfaQRvdgznTD8Xc0oc3p3iW/a1EVWeNj/SdUCbm5U0itZPQYRuRTW20fPMWMpcrciH2EJw==} engines: {node: '>=18'} cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.27.2': + resolution: {integrity: sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.0': resolution: {integrity: sha512-2gwwriSMPcCFRlPlKx3zLQhfN/2WjJ2NSlg5TKLQOJdV0mSxIcYNTMhk3H3ulL/cak+Xj0lY1Ym9ysDV1igceg==} engines: {node: '>=18'} cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.27.2': + resolution: {integrity: sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.27.2': + resolution: {integrity: sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.25.0': resolution: {integrity: sha512-bxI7ThgLzPrPz484/S9jLlvUAHYMzy6I0XiU1ZMeAEOBcS0VePBFxh1JjTQt3Xiat5b6Oh4x7UC7IwKQKIJRIg==} engines: {node: '>=18'} cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.27.2': + resolution: {integrity: sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.25.0': resolution: {integrity: sha512-ZUAc2YK6JW89xTbXvftxdnYy3m4iHIkDtK3CLce8wg8M2L+YZhIvO1DKpxrd0Yr59AeNNkTiic9YLf6FTtXWMw==} engines: {node: '>=18'} cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.27.2': + resolution: {integrity: sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.25.0': resolution: {integrity: sha512-eSNxISBu8XweVEWG31/JzjkIGbGIJN/TrRoiSVZwZ6pkC6VX4Im/WV2cz559/TXLcYbcrDN8JtKgd9DJVIo8GA==} engines: {node: '>=18'} cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.27.2': + resolution: {integrity: sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.25.0': resolution: {integrity: sha512-ZENoHJBxA20C2zFzh6AI4fT6RraMzjYw4xKWemRTRmRVtN9c5DcH9r/f2ihEkMjOW5eGgrwCslG/+Y/3bL+DHQ==} engines: {node: '>=18'} cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.27.2': + resolution: {integrity: sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.1': resolution: {integrity: sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1845,6 +2010,11 @@ packages: react: '>=18.0' react-dom: '>=18.0' + '@hookform/resolvers@5.2.2': + resolution: {integrity: sha512-A/IxlMLShx3KjV/HeTcTfaMxdwy690+L/ZADoeaTltLx+CVuzkeVIPuybK3jrRfw7YZnmdKsVVHAlEPIAEUNlA==} + peerDependencies: + react-hook-form: ^7.55.0 + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1886,8 +2056,8 @@ packages: prettier-plugin-ember-template-tag: optional: true - '@iconify/json@2.2.419': - resolution: {integrity: sha512-50GipvrxOs/b03MP0GxCTn65o4S/DDEXbf03oXbglp0m552TcT8yAidLl7kyQ1fiI+rx3LbvZ6hNSU3CrXZnIQ==} + '@iconify/json@2.2.420': + resolution: {integrity: sha512-3dgvkB8eiUA/PkGHaRB+x17MS1u22V2O1YtFpdpdFpbXp/fAdloOMbxeMXXgNlcGgjk7x4hUIeDunic/diHYqg==} '@iconify/types@2.0.0': resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} @@ -2920,6 +3090,19 @@ packages: '@types/react-dom': optional: true + '@radix-ui/react-separator@1.1.8': + resolution: {integrity: sha512-sDvqVY4itsKwwSMEe0jtKgfTh+72Sy3gPmQpjqcQneqQ4PFmr/1I0YA+2/puilhggCe2gJcx5EBAYFkWkdpa5g==} + peerDependencies: + '@types/react': '*' + '@types/react-dom': '*' + react: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + react-dom: ^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc + peerDependenciesMeta: + '@types/react': + optional: true + '@types/react-dom': + optional: true + '@radix-ui/react-slot@1.2.3': resolution: {integrity: sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==} peerDependencies: @@ -3217,6 +3400,9 @@ packages: resolution: {integrity: sha512-hI6twvUkzOmyGZhQMza1gpfqErZxXRw6JEsiVjUbo7tFanVD+8Oil0Ih3l2nGzHdxPI41zFmfUQG7GHqhciKZQ==} hasBin: true + '@standard-schema/utils@0.3.0': + resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==} + '@stylistic/eslint-plugin@2.11.0': resolution: {integrity: sha512-PNRHbydNG5EH8NK4c+izdJlxajIR6GxcUhzsYNRsn6Myep4dsZt0qFCz3rCPnkvgO5FYibDcMqgNHUT+zvjYZw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -3857,8 +4043,8 @@ packages: '@types/ms@0.7.34': resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} - '@types/node@24.10.1': - resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + '@types/node@24.10.4': + resolution: {integrity: sha512-vnDVpYPMzs4wunl27jHrfmwojOGKya0xyM3sH+UE5iv5uPS6vX7UIoh6m+vQc5LGBq52HBKPIn/zcSZVzeDEZg==} '@types/parse-json@4.0.2': resolution: {integrity: sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==} @@ -5411,6 +5597,11 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.27.2: + resolution: {integrity: sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -7442,9 +7633,9 @@ packages: '@mui/x-date-pickers': optional: true - react-hook-form@7.52.1: - resolution: {integrity: sha512-uNKIhaoICJ5KQALYZ4TOaOLElyM+xipord+Ha3crEFhTntdLvWZqVY49Wqd/0GiVCA/f9NjemLeiNPjG7Hpurg==} - engines: {node: '>=12.22.0'} + react-hook-form@7.69.0: + resolution: {integrity: sha512-yt6ZGME9f4F6WHwevrvpAjh42HMvocuSnSIHUGycBqXIJdhqGSPQzTpGF+1NLREk/58IdPxEMfPcFCjlMhclGw==} + engines: {node: '>=18.0.0'} peerDependencies: react: ^16.8.0 || ^17 || ^18 || ^19 @@ -8335,8 +8526,8 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - tsx@4.20.6: - resolution: {integrity: sha512-ytQKuwgmrrkDTFP4LjR0ToE2nqgy886GpvRSpU0JAnrdBYppuY5rLkRUYPU1yCryb24SsKBTL/hlDQAEFVwtZg==} + tsx@4.21.0: + resolution: {integrity: sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==} engines: {node: '>=18.0.0'} hasBin: true @@ -10020,11 +10211,11 @@ snapshots: hashery: 1.3.0 keyv: 5.5.5 - '@commitlint/cli@20.2.0(@types/node@24.10.1)(typescript@5.9.3)': + '@commitlint/cli@20.2.0(@types/node@24.10.4)(typescript@5.9.3)': dependencies: '@commitlint/format': 20.2.0 '@commitlint/lint': 20.2.0 - '@commitlint/load': 20.2.0(@types/node@24.10.1)(typescript@5.9.3) + '@commitlint/load': 20.2.0(@types/node@24.10.4)(typescript@5.9.3) '@commitlint/read': 20.2.0 '@commitlint/types': 20.2.0 tinyexec: 1.0.1 @@ -10071,7 +10262,7 @@ snapshots: '@commitlint/rules': 20.2.0 '@commitlint/types': 20.2.0 - '@commitlint/load@20.2.0(@types/node@24.10.1)(typescript@5.9.3)': + '@commitlint/load@20.2.0(@types/node@24.10.4)(typescript@5.9.3)': dependencies: '@commitlint/config-validator': 20.2.0 '@commitlint/execute-rule': 20.0.0 @@ -10079,7 +10270,7 @@ snapshots: '@commitlint/types': 20.2.0 chalk: 5.4.1 cosmiconfig: 9.0.0(typescript@5.9.3) - cosmiconfig-typescript-loader: 6.1.0(@types/node@24.10.1)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) + cosmiconfig-typescript-loader: 6.1.0(@types/node@24.10.4)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -10300,78 +10491,156 @@ snapshots: '@esbuild/aix-ppc64@0.25.0': optional: true + '@esbuild/aix-ppc64@0.27.2': + optional: true + '@esbuild/android-arm64@0.25.0': optional: true + '@esbuild/android-arm64@0.27.2': + optional: true + '@esbuild/android-arm@0.25.0': optional: true + '@esbuild/android-arm@0.27.2': + optional: true + '@esbuild/android-x64@0.25.0': optional: true + '@esbuild/android-x64@0.27.2': + optional: true + '@esbuild/darwin-arm64@0.25.0': optional: true + '@esbuild/darwin-arm64@0.27.2': + optional: true + '@esbuild/darwin-x64@0.25.0': optional: true + '@esbuild/darwin-x64@0.27.2': + optional: true + '@esbuild/freebsd-arm64@0.25.0': optional: true + '@esbuild/freebsd-arm64@0.27.2': + optional: true + '@esbuild/freebsd-x64@0.25.0': optional: true + '@esbuild/freebsd-x64@0.27.2': + optional: true + '@esbuild/linux-arm64@0.25.0': optional: true + '@esbuild/linux-arm64@0.27.2': + optional: true + '@esbuild/linux-arm@0.25.0': optional: true + '@esbuild/linux-arm@0.27.2': + optional: true + '@esbuild/linux-ia32@0.25.0': optional: true + '@esbuild/linux-ia32@0.27.2': + optional: true + '@esbuild/linux-loong64@0.25.0': optional: true + '@esbuild/linux-loong64@0.27.2': + optional: true + '@esbuild/linux-mips64el@0.25.0': optional: true + '@esbuild/linux-mips64el@0.27.2': + optional: true + '@esbuild/linux-ppc64@0.25.0': optional: true + '@esbuild/linux-ppc64@0.27.2': + optional: true + '@esbuild/linux-riscv64@0.25.0': optional: true + '@esbuild/linux-riscv64@0.27.2': + optional: true + '@esbuild/linux-s390x@0.25.0': optional: true + '@esbuild/linux-s390x@0.27.2': + optional: true + '@esbuild/linux-x64@0.25.0': optional: true + '@esbuild/linux-x64@0.27.2': + optional: true + '@esbuild/netbsd-arm64@0.25.0': optional: true + '@esbuild/netbsd-arm64@0.27.2': + optional: true + '@esbuild/netbsd-x64@0.25.0': optional: true + '@esbuild/netbsd-x64@0.27.2': + optional: true + '@esbuild/openbsd-arm64@0.25.0': optional: true + '@esbuild/openbsd-arm64@0.27.2': + optional: true + '@esbuild/openbsd-x64@0.25.0': optional: true + '@esbuild/openbsd-x64@0.27.2': + optional: true + + '@esbuild/openharmony-arm64@0.27.2': + optional: true + '@esbuild/sunos-x64@0.25.0': optional: true + '@esbuild/sunos-x64@0.27.2': + optional: true + '@esbuild/win32-arm64@0.25.0': optional: true + '@esbuild/win32-arm64@0.27.2': + optional: true + '@esbuild/win32-ia32@0.25.0': optional: true + '@esbuild/win32-ia32@0.27.2': + optional: true + '@esbuild/win32-x64@0.25.0': optional: true + '@esbuild/win32-x64@0.27.2': + optional: true + '@eslint-community/eslint-utils@4.4.1(eslint@9.39.2(jiti@2.6.1))': dependencies: eslint: 9.39.2(jiti@2.6.1) @@ -10462,6 +10731,11 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) + '@hookform/resolvers@5.2.2(react-hook-form@7.69.0(react@19.2.0))': + dependencies: + '@standard-schema/utils': 0.3.0 + react-hook-form: 7.69.0(react@19.2.0) + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -10492,7 +10766,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@iconify/json@2.2.419': + '@iconify/json@2.2.420': dependencies: '@iconify/types': 2.0.0 pathe: 2.0.3 @@ -10594,23 +10868,23 @@ snapshots: '@material/material-color-utilities@0.3.0': {} - '@microsoft/api-extractor-model@7.30.3(@types/node@24.10.1)': + '@microsoft/api-extractor-model@7.30.3(@types/node@24.10.4)': dependencies: '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.11.0(@types/node@24.10.1) + '@rushstack/node-core-library': 5.11.0(@types/node@24.10.4) transitivePeerDependencies: - '@types/node' - '@microsoft/api-extractor@7.51.0(@types/node@24.10.1)': + '@microsoft/api-extractor@7.51.0(@types/node@24.10.4)': dependencies: - '@microsoft/api-extractor-model': 7.30.3(@types/node@24.10.1) + '@microsoft/api-extractor-model': 7.30.3(@types/node@24.10.4) '@microsoft/tsdoc': 0.15.1 '@microsoft/tsdoc-config': 0.17.1 - '@rushstack/node-core-library': 5.11.0(@types/node@24.10.1) + '@rushstack/node-core-library': 5.11.0(@types/node@24.10.4) '@rushstack/rig-package': 0.5.3 - '@rushstack/terminal': 0.15.0(@types/node@24.10.1) - '@rushstack/ts-command-line': 4.23.5(@types/node@24.10.1) + '@rushstack/terminal': 0.15.0(@types/node@24.10.4) + '@rushstack/ts-command-line': 4.23.5(@types/node@24.10.4) lodash: 4.17.21 minimatch: 3.0.8 resolve: 1.22.8 @@ -11539,6 +11813,15 @@ snapshots: '@types/react': 19.2.7 '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@radix-ui/react-separator@1.1.8(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@radix-ui/react-primitive': 2.1.4(@types/react-dom@19.2.3(@types/react@19.2.7))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.7 + '@types/react-dom': 19.2.3(@types/react@19.2.7) + '@radix-ui/react-slot@1.2.3(@types/react@19.2.7)(react@19.2.0)': dependencies: '@radix-ui/react-compose-refs': 1.1.2(@types/react@19.2.7)(react@19.2.0) @@ -11718,7 +12001,7 @@ snapshots: '@rtsao/scc@1.1.0': {} - '@rushstack/node-core-library@5.11.0(@types/node@24.10.1)': + '@rushstack/node-core-library@5.11.0(@types/node@24.10.4)': dependencies: ajv: 8.13.0 ajv-draft-04: 1.0.0(ajv@8.13.0) @@ -11729,23 +12012,23 @@ snapshots: resolve: 1.22.8 semver: 7.5.4 optionalDependencies: - '@types/node': 24.10.1 + '@types/node': 24.10.4 '@rushstack/rig-package@0.5.3': dependencies: resolve: 1.22.8 strip-json-comments: 3.1.1 - '@rushstack/terminal@0.15.0(@types/node@24.10.1)': + '@rushstack/terminal@0.15.0(@types/node@24.10.4)': dependencies: - '@rushstack/node-core-library': 5.11.0(@types/node@24.10.1) + '@rushstack/node-core-library': 5.11.0(@types/node@24.10.4) supports-color: 8.1.1 optionalDependencies: - '@types/node': 24.10.1 + '@types/node': 24.10.4 - '@rushstack/ts-command-line@4.23.5(@types/node@24.10.1)': + '@rushstack/ts-command-line@4.23.5(@types/node@24.10.4)': dependencies: - '@rushstack/terminal': 0.15.0(@types/node@24.10.1) + '@rushstack/terminal': 0.15.0(@types/node@24.10.4) '@types/argparse': 1.0.38 argparse: 1.0.10 string-argv: 0.3.2 @@ -11791,6 +12074,8 @@ snapshots: '@sqlite.org/sqlite-wasm@3.48.0-build4': {} + '@standard-schema/utils@0.3.0': {} + '@stylistic/eslint-plugin@2.11.0(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3)': dependencies: '@typescript-eslint/utils': 8.46.2(eslint@9.39.2(jiti@2.6.1))(typescript@5.9.3) @@ -12007,13 +12292,13 @@ snapshots: '@tanstack/query-core': 5.90.11 react: 19.2.0 - '@tanstack/react-router-devtools@1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.15)(@types/node@24.10.1)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': + '@tanstack/react-router-devtools@1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@tanstack/router-core@1.134.15)(@types/node@24.10.4)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.21.0)(yaml@2.8.1)': dependencies: '@tanstack/react-router': 1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - '@tanstack/router-devtools-core': 1.134.15(@tanstack/router-core@1.134.15)(@types/node@24.10.1)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1) + '@tanstack/router-devtools-core': 1.134.15(@tanstack/router-core@1.134.15)(@types/node@24.10.4)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.21.0)(yaml@2.8.1) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - '@tanstack/router-core' - '@types/node' @@ -12071,14 +12356,14 @@ snapshots: tiny-invariant: 1.3.3 tiny-warning: 1.0.3 - '@tanstack/router-devtools-core@1.134.15(@tanstack/router-core@1.134.15)(@types/node@24.10.1)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.20.6)(yaml@2.8.1)': + '@tanstack/router-devtools-core@1.134.15(@tanstack/router-core@1.134.15)(@types/node@24.10.4)(csstype@3.2.3)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(solid-js@1.9.5)(stylus@0.62.0)(terser@5.36.0)(tiny-invariant@1.3.3)(tsx@4.21.0)(yaml@2.8.1)': dependencies: '@tanstack/router-core': 1.134.15 clsx: 2.1.1 goober: 2.1.16(csstype@3.2.3) solid-js: 1.9.5 tiny-invariant: 1.3.3 - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) optionalDependencies: csstype: 3.2.3 transitivePeerDependencies: @@ -12102,12 +12387,12 @@ snapshots: prettier: 3.7.4 recast: 0.23.11 source-map: 0.7.4 - tsx: 4.20.6 + tsx: 4.21.0 zod: 3.25.76 transitivePeerDependencies: - supports-color - '@tanstack/router-plugin@1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@tanstack/router-plugin@1.134.15(@tanstack/react-router@1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.4 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.28.4) @@ -12125,7 +12410,7 @@ snapshots: zod: 3.25.76 optionalDependencies: '@tanstack/react-router': 1.134.15(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -12267,7 +12552,7 @@ snapshots: '@types/adm-zip@0.5.7': dependencies: - '@types/node': 24.10.1 + '@types/node': 24.10.4 '@types/argparse@1.0.38': {} @@ -12296,7 +12581,7 @@ snapshots: '@types/conventional-commits-parser@5.0.0': dependencies: - '@types/node': 24.10.1 + '@types/node': 24.10.4 '@types/d3-array@3.2.1': {} @@ -12432,7 +12717,7 @@ snapshots: '@types/fs-extra@11.0.4': dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 24.10.1 + '@types/node': 24.10.4 '@types/geojson@7946.0.14': {} @@ -12450,7 +12735,7 @@ snapshots: '@types/jsonfile@6.1.4': dependencies: - '@types/node': 24.10.1 + '@types/node': 24.10.4 '@types/lodash-es@4.17.12': dependencies: @@ -12464,7 +12749,7 @@ snapshots: '@types/ms@0.7.34': {} - '@types/node@24.10.1': + '@types/node@24.10.4': dependencies: undici-types: 7.16.0 @@ -12923,7 +13208,7 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.10.1': optional: true - '@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-legacy@7.2.1(terser@5.36.0)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.0 '@babel/plugin-transform-dynamic-import': 7.27.1(@babel/core@7.28.0) @@ -12938,19 +13223,19 @@ snapshots: regenerator-runtime: 0.14.1 systemjs: 6.15.1 terser: 5.36.0 - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitejs/plugin-react-swc@4.2.2(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-react-swc@4.2.2(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: '@rolldown/pluginutils': 1.0.0-beta.47 '@swc/core': 1.13.5 - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - '@swc/helpers' - '@vitejs/plugin-react@5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1))': + '@vitejs/plugin-react@5.1.1(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -12958,7 +13243,7 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.47 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -13600,9 +13885,9 @@ snapshots: core-util-is@1.0.3: {} - cosmiconfig-typescript-loader@6.1.0(@types/node@24.10.1)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): + cosmiconfig-typescript-loader@6.1.0(@types/node@24.10.4)(cosmiconfig@9.0.0(typescript@5.9.3))(typescript@5.9.3): dependencies: - '@types/node': 24.10.1 + '@types/node': 24.10.4 cosmiconfig: 9.0.0(typescript@5.9.3) jiti: 2.6.1 typescript: 5.9.3 @@ -14340,6 +14625,35 @@ snapshots: '@esbuild/win32-ia32': 0.25.0 '@esbuild/win32-x64': 0.25.0 + esbuild@0.27.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.27.2 + '@esbuild/android-arm': 0.27.2 + '@esbuild/android-arm64': 0.27.2 + '@esbuild/android-x64': 0.27.2 + '@esbuild/darwin-arm64': 0.27.2 + '@esbuild/darwin-x64': 0.27.2 + '@esbuild/freebsd-arm64': 0.27.2 + '@esbuild/freebsd-x64': 0.27.2 + '@esbuild/linux-arm': 0.27.2 + '@esbuild/linux-arm64': 0.27.2 + '@esbuild/linux-ia32': 0.27.2 + '@esbuild/linux-loong64': 0.27.2 + '@esbuild/linux-mips64el': 0.27.2 + '@esbuild/linux-ppc64': 0.27.2 + '@esbuild/linux-riscv64': 0.27.2 + '@esbuild/linux-s390x': 0.27.2 + '@esbuild/linux-x64': 0.27.2 + '@esbuild/netbsd-arm64': 0.27.2 + '@esbuild/netbsd-x64': 0.27.2 + '@esbuild/openbsd-arm64': 0.27.2 + '@esbuild/openbsd-x64': 0.27.2 + '@esbuild/openharmony-arm64': 0.27.2 + '@esbuild/sunos-x64': 0.27.2 + '@esbuild/win32-arm64': 0.27.2 + '@esbuild/win32-ia32': 0.27.2 + '@esbuild/win32-x64': 0.27.2 + escalade@3.2.0: {} escape-string-regexp@4.0.0: {} @@ -15466,10 +15780,10 @@ snapshots: kind-of@6.0.3: {} - knip@5.68.0(@types/node@24.10.1)(typescript@5.9.3): + knip@5.68.0(@types/node@24.10.4)(typescript@5.9.3): dependencies: '@nodelib/fs.walk': 1.2.8 - '@types/node': 24.10.1 + '@types/node': 24.10.4 fast-glob: 3.3.3 formatly: 0.3.0 jiti: 2.6.1 @@ -16537,16 +16851,16 @@ snapshots: react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - react-hook-form-mui@8.2.0(a94fb62675188bb2256f3adb84e9f008): + react-hook-form-mui@8.2.0(ccfc370862f0ca346424eba435f9b21c): dependencies: '@mui/material': 7.3.5(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) react: 19.2.0 - react-hook-form: 7.52.1(react@19.2.0) + react-hook-form: 7.69.0(react@19.2.0) optionalDependencies: '@mui/icons-material': 7.3.5(@mui/material@7.3.5(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@types/react@19.2.7)(react@19.2.0) '@mui/x-date-pickers': 8.17.0(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react@19.2.0))(@mui/material@7.3.5(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react-dom@19.2.0(react@19.2.0))(react@19.2.0))(@mui/system@7.3.5(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@emotion/styled@11.14.1(@emotion/react@11.14.0(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(react@19.2.0))(@types/react@19.2.7)(dayjs@1.11.19)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) - react-hook-form@7.52.1(react@19.2.0): + react-hook-form@7.69.0(react@19.2.0): dependencies: react: 19.2.0 @@ -17555,9 +17869,9 @@ snapshots: tslib@2.8.1: {} - tsx@4.20.6: + tsx@4.21.0: dependencies: - esbuild: 0.25.0 + esbuild: 0.27.2 get-tsconfig: 4.10.1 optionalDependencies: fsevents: 2.3.3 @@ -17934,9 +18248,9 @@ snapshots: - rollup - supports-color - vite-plugin-dts@4.5.4(@types/node@24.10.1)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-dts@4.5.4(@types/node@24.10.4)(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: - '@microsoft/api-extractor': 7.51.0(@types/node@24.10.1) + '@microsoft/api-extractor': 7.51.0(@types/node@24.10.4) '@rollup/pluginutils': 5.1.4(rollup@4.46.2) '@volar/typescript': 2.4.11 '@vue/language-core': 2.2.0(typescript@5.9.3) @@ -17947,13 +18261,13 @@ snapshots: magic-string: 0.30.17 typescript: 5.9.3 optionalDependencies: - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite-plugin-html@3.2.2(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-html@3.2.2(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: '@rollup/pluginutils': 4.2.1 colorette: 2.0.20 @@ -17967,39 +18281,39 @@ snapshots: html-minifier-terser: 6.1.0 node-html-parser: 5.4.2 pathe: 0.2.0 - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) - vite-plugin-sass-dts@1.3.34(postcss@8.5.6)(prettier@3.7.4)(sass-embedded@1.93.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-sass-dts@1.3.34(postcss@8.5.6)(prettier@3.7.4)(sass-embedded@1.93.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: postcss: 8.5.6 postcss-js: 4.0.1(postcss@8.5.6) prettier: 3.7.4 sass-embedded: 1.93.3 - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) - vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-plugin-svgr@4.5.0(rollup@4.46.2)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: '@rollup/pluginutils': 5.2.0(rollup@4.46.2) '@svgr/core': 8.1.0(typescript@5.9.3) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0(typescript@5.9.3)) - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - rollup - supports-color - typescript - vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1)): dependencies: debug: 4.3.7 globrex: 0.1.2 tsconfck: 3.0.3(typescript@5.9.3) optionalDependencies: - vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1) + vite: 7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.20.6)(yaml@2.8.1): + vite@7.2.4(@types/node@24.10.4)(jiti@2.6.1)(less@4.2.0)(lightningcss@1.30.2)(sass-embedded@1.93.3)(sass@1.93.3)(stylus@0.62.0)(terser@5.36.0)(tsx@4.21.0)(yaml@2.8.1): dependencies: esbuild: 0.25.0 fdir: 6.5.0(picomatch@4.0.3) @@ -18008,7 +18322,7 @@ snapshots: rollup: 4.46.2 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.10.1 + '@types/node': 24.10.4 fsevents: 2.3.3 jiti: 2.6.1 less: 4.2.0 @@ -18017,7 +18331,7 @@ snapshots: sass-embedded: 1.93.3 stylus: 0.62.0 terser: 5.36.0 - tsx: 4.20.6 + tsx: 4.21.0 yaml: 2.8.1 void-elements@3.1.0: {} diff --git a/mihomo/.github/patch/go1.25.patch b/mihomo/.github/patch/go1.25.patch index 626779dbdd..a7f724ff46 100644 --- a/mihomo/.github/patch/go1.25.patch +++ b/mihomo/.github/patch/go1.25.patch @@ -1,4 +1,5 @@ -Subject: [PATCH] Revert "runtime: always use LoadLibraryEx to load system libraries" +Subject: [PATCH] Fix os.RemoveAll not working on Windows7 +Revert "runtime: always use LoadLibraryEx to load system libraries" Revert "syscall: remove Windows 7 console handle workaround" Revert "net: remove sysSocket fallback for Windows 7" Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" @@ -655,3 +656,188 @@ diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go } else { h, e = loadlibrary(namep) } +Index: src/os/removeall_at.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go +--- a/src/os/removeall_at.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/removeall_at.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build unix || wasip1 || windows ++//go:build unix || wasip1 + + package os + +@@ -175,3 +175,25 @@ + } + return newDirFile(fd, name) + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ // Consistency with os.RemoveAll: Strip trailing /s from the name, ++ // so RemoveAll("not_a_directory/") succeeds. ++ for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { ++ name = name[:len(name)-1] ++ } ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { ++ return struct{}{}, removeAllFrom(parent, name) ++ }) ++ if IsNotExist(err) { ++ return nil ++ } ++ if err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return err ++} +Index: src/os/removeall_noat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_noat.go b/src/os/removeall_noat.go +--- a/src/os/removeall_noat.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/removeall_noat.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (js && wasm) || plan9 ++//go:build (js && wasm) || plan9 || windows + + package os + +@@ -140,3 +140,22 @@ + } + return err + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ if err := checkPathEscapesLstat(r, name); err != nil { ++ if err == syscall.ENOTDIR { ++ // Some intermediate path component is not a directory. ++ // RemoveAll treats this as success (since the target doesn't exist). ++ return nil ++ } ++ return &PathError{Op: "RemoveAll", Path: name, Err: err} ++ } ++ if err := RemoveAll(joinPath(r.root.name, name)); err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return nil ++} +Index: src/os/root_noopenat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_noopenat.go b/src/os/root_noopenat.go +--- a/src/os/root_noopenat.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/root_noopenat.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -11,7 +11,6 @@ + "internal/filepathlite" + "internal/stringslite" + "sync/atomic" +- "syscall" + "time" + ) + +@@ -185,25 +184,6 @@ + } + return nil + } +- +-func rootRemoveAll(r *Root, name string) error { +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- if err := checkPathEscapesLstat(r, name); err != nil { +- if err == syscall.ENOTDIR { +- // Some intermediate path component is not a directory. +- // RemoveAll treats this as success (since the target doesn't exist). +- return nil +- } +- return &PathError{Op: "RemoveAll", Path: name, Err: err} +- } +- if err := RemoveAll(joinPath(r.root.name, name)); err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return nil +-} + + func rootReadlink(r *Root, name string) (string, error) { + if err := checkPathEscapesLstat(r, name); err != nil { +Index: src/os/root_openat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_openat.go b/src/os/root_openat.go +--- a/src/os/root_openat.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/root_openat.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -194,28 +194,6 @@ + return nil + } + +-func rootRemoveAll(r *Root, name string) error { +- // Consistency with os.RemoveAll: Strip trailing /s from the name, +- // so RemoveAll("not_a_directory/") succeeds. +- for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { +- name = name[:len(name)-1] +- } +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { +- return struct{}{}, removeAllFrom(parent, name) +- }) +- if IsNotExist(err) { +- return nil +- } +- if err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return err +-} +- + func rootRename(r *Root, oldname, newname string) error { + _, err := doInRoot(r, oldname, nil, func(oldparent sysfdType, oldname string) (struct{}, error) { + _, err := doInRoot(r, newname, nil, func(newparent sysfdType, newname string) (struct{}, error) { +Index: src/os/root_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_windows.go b/src/os/root_windows.go +--- a/src/os/root_windows.go (revision f56f1e23507e646c85243a71bde7b9629b2f970c) ++++ b/src/os/root_windows.go (revision 0a52622d2331ff975fb0442617ec19bc352bb2ed) +@@ -402,3 +402,14 @@ + } + return fi.Mode(), nil + } ++ ++func checkPathEscapes(r *Root, name string) error { ++ if !filepathlite.IsLocal(name) { ++ return errPathEscapes ++ } ++ return nil ++} ++ ++func checkPathEscapesLstat(r *Root, name string) error { ++ return checkPathEscapes(r, name) ++} diff --git a/mihomo/.github/patch/go1.26.patch b/mihomo/.github/patch/go1.26.patch new file mode 100644 index 0000000000..29dab4d0a6 --- /dev/null +++ b/mihomo/.github/patch/go1.26.patch @@ -0,0 +1,842 @@ +Subject: [PATCH] Fix os.RemoveAll not working on Windows7 +Revert "runtime: always use LoadLibraryEx to load system libraries" +Revert "syscall: remove Windows 7 console handle workaround" +Revert "net: remove sysSocket fallback for Windows 7" +Revert "crypto/rand,runtime: switch RtlGenRandom for ProcessPrng" +--- +Index: src/crypto/internal/sysrand/rand_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/internal/sysrand/rand_windows.go b/src/crypto/internal/sysrand/rand_windows.go +--- a/src/crypto/internal/sysrand/rand_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/crypto/internal/sysrand/rand_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -7,5 +7,26 @@ + import "internal/syscall/windows" + + func read(b []byte) error { +- return windows.ProcessPrng(b) ++ // RtlGenRandom only returns 1<<32-1 bytes at a time. We only read at ++ // most 1<<31-1 bytes at a time so that this works the same on 32-bit ++ // and 64-bit systems. ++ return batched(windows.RtlGenRandom, 1<<31-1)(b) ++} ++ ++// batched returns a function that calls f to populate a []byte by chunking it ++// into subslices of, at most, readMax bytes. ++func batched(f func([]byte) error, readMax int) func([]byte) error { ++ return func(out []byte) error { ++ for len(out) > 0 { ++ read := len(out) ++ if read > readMax { ++ read = readMax ++ } ++ if err := f(out[:read]); err != nil { ++ return err ++ } ++ out = out[read:] ++ } ++ return nil ++ } + } +Index: src/crypto/rand/rand.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/crypto/rand/rand.go b/src/crypto/rand/rand.go +--- a/src/crypto/rand/rand.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/crypto/rand/rand.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -25,7 +25,7 @@ + // - On legacy Linux (< 3.17), Reader opens /dev/urandom on first use. + // - On macOS, iOS, and OpenBSD Reader, uses arc4random_buf(3). + // - On NetBSD, Reader uses the kern.arandom sysctl. +-// - On Windows, Reader uses the ProcessPrng API. ++// - On Windows systems, Reader uses the RtlGenRandom API. + // - On js/wasm, Reader uses the Web Crypto API. + // - On wasip1/wasm, Reader uses random_get. + // +Index: src/internal/syscall/windows/syscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/syscall_windows.go b/src/internal/syscall/windows/syscall_windows.go +--- a/src/internal/syscall/windows/syscall_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/internal/syscall/windows/syscall_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -421,7 +421,7 @@ + //sys DestroyEnvironmentBlock(block *uint16) (err error) = userenv.DestroyEnvironmentBlock + //sys CreateEvent(eventAttrs *SecurityAttributes, manualReset uint32, initialState uint32, name *uint16) (handle syscall.Handle, err error) = kernel32.CreateEventW + +-//sys ProcessPrng(buf []byte) (err error) = bcryptprimitives.ProcessPrng ++//sys RtlGenRandom(buf []byte) (err error) = advapi32.SystemFunction036 + + type FILE_ID_BOTH_DIR_INFO struct { + NextEntryOffset uint32 +Index: src/internal/syscall/windows/zsyscall_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/internal/syscall/windows/zsyscall_windows.go b/src/internal/syscall/windows/zsyscall_windows.go +--- a/src/internal/syscall/windows/zsyscall_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/internal/syscall/windows/zsyscall_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) +@@ -38,7 +38,6 @@ + + var ( + modadvapi32 = syscall.NewLazyDLL(sysdll.Add("advapi32.dll")) +- modbcryptprimitives = syscall.NewLazyDLL(sysdll.Add("bcryptprimitives.dll")) + modiphlpapi = syscall.NewLazyDLL(sysdll.Add("iphlpapi.dll")) + modkernel32 = syscall.NewLazyDLL(sysdll.Add("kernel32.dll")) + modnetapi32 = syscall.NewLazyDLL(sysdll.Add("netapi32.dll")) +@@ -63,7 +62,7 @@ + procQueryServiceStatus = modadvapi32.NewProc("QueryServiceStatus") + procRevertToSelf = modadvapi32.NewProc("RevertToSelf") + procSetTokenInformation = modadvapi32.NewProc("SetTokenInformation") +- procProcessPrng = modbcryptprimitives.NewProc("ProcessPrng") ++ procSystemFunction036 = modadvapi32.NewProc("SystemFunction036") + procGetAdaptersAddresses = modiphlpapi.NewProc("GetAdaptersAddresses") + procCreateEventW = modkernel32.NewProc("CreateEventW") + procCreateIoCompletionPort = modkernel32.NewProc("CreateIoCompletionPort") +@@ -244,12 +243,12 @@ + return + } + +-func ProcessPrng(buf []byte) (err error) { ++func RtlGenRandom(buf []byte) (err error) { + var _p0 *byte + if len(buf) > 0 { + _p0 = &buf[0] + } +- r1, _, e1 := syscall.SyscallN(procProcessPrng.Addr(), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf))) ++ r1, _, e1 := syscall.SyscallN(procSystemFunction036.Addr(), uintptr(unsafe.Pointer(_p0)), uintptr(len(buf)), 0) + if r1 == 0 { + err = errnoErr(e1) + } +Index: src/runtime/os_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/runtime/os_windows.go b/src/runtime/os_windows.go +--- a/src/runtime/os_windows.go (revision c599a8f2385849a225d02843b3c6389dbfc5aa69) ++++ b/src/runtime/os_windows.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) +@@ -40,7 +40,8 @@ + //go:cgo_import_dynamic runtime._GetSystemInfo GetSystemInfo%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._GetThreadContext GetThreadContext%2 "kernel32.dll" + //go:cgo_import_dynamic runtime._SetThreadContext SetThreadContext%2 "kernel32.dll" +-//go:cgo_import_dynamic runtime._LoadLibraryExW LoadLibraryExW%3 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryW LoadLibraryW%1 "kernel32.dll" ++//go:cgo_import_dynamic runtime._LoadLibraryA LoadLibraryA%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._PostQueuedCompletionStatus PostQueuedCompletionStatus%4 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceCounter QueryPerformanceCounter%1 "kernel32.dll" + //go:cgo_import_dynamic runtime._QueryPerformanceFrequency QueryPerformanceFrequency%1 "kernel32.dll" +@@ -74,7 +75,6 @@ + // Following syscalls are available on every Windows PC. + // All these variables are set by the Windows executable + // loader before the Go program starts. +- _AddVectoredContinueHandler, + _AddVectoredExceptionHandler, + _CloseHandle, + _CreateEventA, +@@ -97,7 +97,8 @@ + _GetSystemInfo, + _GetThreadContext, + _SetThreadContext, +- _LoadLibraryExW, ++ _LoadLibraryW, ++ _LoadLibraryA, + _PostQueuedCompletionStatus, + _QueryPerformanceCounter, + _QueryPerformanceFrequency, +@@ -126,8 +127,23 @@ + _WriteFile, + _ stdFunction + +- // Use ProcessPrng to generate cryptographically random data. +- _ProcessPrng stdFunction ++ // Following syscalls are only available on some Windows PCs. ++ // We will load syscalls, if available, before using them. ++ _AddDllDirectory, ++ _AddVectoredContinueHandler, ++ _LoadLibraryExA, ++ _LoadLibraryExW, ++ _ stdFunction ++ ++ // Use RtlGenRandom to generate cryptographically random data. ++ // This approach has been recommended by Microsoft (see issue ++ // 15589 for details). ++ // The RtlGenRandom is not listed in advapi32.dll, instead ++ // RtlGenRandom function can be found by searching for SystemFunction036. ++ // Also some versions of Mingw cannot link to SystemFunction036 ++ // when building executable as Cgo. So load SystemFunction036 ++ // manually during runtime startup. ++ _RtlGenRandom stdFunction + + // Load ntdll.dll manually during startup, otherwise Mingw + // links wrong printf function to cgo executable (see issue +@@ -144,13 +160,6 @@ + _ stdFunction + ) + +-var ( +- bcryptprimitivesdll = [...]uint16{'b', 'c', 'r', 'y', 'p', 't', 'p', 'r', 'i', 'm', 'i', 't', 'i', 'v', 'e', 's', '.', 'd', 'l', 'l', 0} +- ntdlldll = [...]uint16{'n', 't', 'd', 'l', 'l', '.', 'd', 'l', 'l', 0} +- powrprofdll = [...]uint16{'p', 'o', 'w', 'r', 'p', 'r', 'o', 'f', '.', 'd', 'l', 'l', 0} +- winmmdll = [...]uint16{'w', 'i', 'n', 'm', 'm', '.', 'd', 'l', 'l', 0} +-) +- + // Function to be called by windows CreateThread + // to start new os thread. + func tstart_stdcall(newm *m) +@@ -242,9 +251,40 @@ + return unsafe.String(&sysDirectory[0], sysDirectoryLen) + } + +-func windowsLoadSystemLib(name []uint16) uintptr { +- const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 +- return stdcall(_LoadLibraryExW, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++//go:linkname syscall_getSystemDirectory syscall.getSystemDirectory ++func syscall_getSystemDirectory() string { ++ return unsafe.String(&sysDirectory[0], sysDirectoryLen) ++} ++ ++func windowsLoadSystemLib(name []byte) uintptr { ++ if useLoadLibraryEx { ++ return stdcall(_LoadLibraryExA, uintptr(unsafe.Pointer(&name[0])), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ absName := append(sysDirectory[:sysDirectoryLen], name...) ++ return stdcall(_LoadLibraryA, uintptr(unsafe.Pointer(&absName[0]))) ++ } ++} ++ ++const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 ++ ++// When available, this function will use LoadLibraryEx with the filename ++// parameter and the important SEARCH_SYSTEM32 argument. But on systems that ++// do not have that option, absoluteFilepath should contain a fallback ++// to the full path inside of system32 for use with vanilla LoadLibrary. ++// ++//go:linkname syscall_loadsystemlibrary syscall.loadsystemlibrary ++func syscall_loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle, err uintptr) { ++ if useLoadLibraryEx { ++ handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryExW)), 3, uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) ++ } else { ++ handle, _, err = syscall_syscalln(uintptr(unsafe.Pointer(_LoadLibraryW)), 1, uintptr(unsafe.Pointer(absoluteFilepath))) ++ } ++ KeepAlive(filename) ++ KeepAlive(absoluteFilepath) ++ if handle != 0 { ++ err = 0 ++ } ++ return + } + + //go:linkname windows_QueryPerformanceCounter internal/syscall/windows.QueryPerformanceCounter +@@ -262,13 +302,28 @@ + } + + func loadOptionalSyscalls() { +- bcryptPrimitives := windowsLoadSystemLib(bcryptprimitivesdll[:]) +- if bcryptPrimitives == 0 { +- throw("bcryptprimitives.dll not found") ++ var kernel32dll = []byte("kernel32.dll\000") ++ k32 := stdcall(_LoadLibraryA, uintptr(unsafe.Pointer(&kernel32dll[0]))) ++ if k32 == 0 { ++ throw("kernel32.dll not found") + } +- _ProcessPrng = windowsFindfunc(bcryptPrimitives, []byte("ProcessPrng\000")) ++ _AddDllDirectory = windowsFindfunc(k32, []byte("AddDllDirectory\000")) ++ _AddVectoredContinueHandler = windowsFindfunc(k32, []byte("AddVectoredContinueHandler\000")) ++ _LoadLibraryExA = windowsFindfunc(k32, []byte("LoadLibraryExA\000")) ++ _LoadLibraryExW = windowsFindfunc(k32, []byte("LoadLibraryExW\000")) ++ useLoadLibraryEx = (_LoadLibraryExW != nil && _LoadLibraryExA != nil && _AddDllDirectory != nil) ++ ++ initSysDirectory() + +- n32 := windowsLoadSystemLib(ntdlldll[:]) ++ var advapi32dll = []byte("advapi32.dll\000") ++ a32 := windowsLoadSystemLib(advapi32dll) ++ if a32 == 0 { ++ throw("advapi32.dll not found") ++ } ++ _RtlGenRandom = windowsFindfunc(a32, []byte("SystemFunction036\000")) ++ ++ var ntdll = []byte("ntdll.dll\000") ++ n32 := windowsLoadSystemLib(ntdll) + if n32 == 0 { + throw("ntdll.dll not found") + } +@@ -297,7 +352,7 @@ + context uintptr + } + +- powrprof := windowsLoadSystemLib(powrprofdll[:]) ++ powrprof := windowsLoadSystemLib([]byte("powrprof.dll\000")) + if powrprof == 0 { + return // Running on Windows 7, where we don't need it anyway. + } +@@ -351,6 +406,22 @@ + // in sys_windows_386.s and sys_windows_amd64.s: + func getlasterror() uint32 + ++// When loading DLLs, we prefer to use LoadLibraryEx with ++// LOAD_LIBRARY_SEARCH_* flags, if available. LoadLibraryEx is not ++// available on old Windows, though, and the LOAD_LIBRARY_SEARCH_* ++// flags are not available on some versions of Windows without a ++// security patch. ++// ++// https://msdn.microsoft.com/en-us/library/ms684179(v=vs.85).aspx says: ++// "Windows 7, Windows Server 2008 R2, Windows Vista, and Windows ++// Server 2008: The LOAD_LIBRARY_SEARCH_* flags are available on ++// systems that have KB2533623 installed. To determine whether the ++// flags are available, use GetProcAddress to get the address of the ++// AddDllDirectory, RemoveDllDirectory, or SetDefaultDllDirectories ++// function. If GetProcAddress succeeds, the LOAD_LIBRARY_SEARCH_* ++// flags can be used with LoadLibraryEx." ++var useLoadLibraryEx bool ++ + var timeBeginPeriodRetValue uint32 + + // osRelaxMinNS indicates that sysmon shouldn't osRelax if the next +@@ -417,7 +488,8 @@ + // Only load winmm.dll if we need it. + // This avoids a dependency on winmm.dll for Go programs + // that run on new Windows versions. +- m32 := windowsLoadSystemLib(winmmdll[:]) ++ var winmmdll = []byte("winmm.dll\000") ++ m32 := windowsLoadSystemLib(winmmdll) + if m32 == 0 { + print("runtime: LoadLibraryExW failed; errno=", getlasterror(), "\n") + throw("winmm.dll not found") +@@ -458,6 +530,28 @@ + canUseLongPaths = true + } + ++var osVersionInfo struct { ++ majorVersion uint32 ++ minorVersion uint32 ++ buildNumber uint32 ++} ++ ++func initOsVersionInfo() { ++ info := windows.OSVERSIONINFOW{} ++ info.OSVersionInfoSize = uint32(unsafe.Sizeof(info)) ++ stdcall(_RtlGetVersion, uintptr(unsafe.Pointer(&info))) ++ osVersionInfo.majorVersion = info.MajorVersion ++ osVersionInfo.minorVersion = info.MinorVersion ++ osVersionInfo.buildNumber = info.BuildNumber ++} ++ ++//go:linkname rtlGetNtVersionNumbers syscall.rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) { ++ *majorVersion = osVersionInfo.majorVersion ++ *minorVersion = osVersionInfo.minorVersion ++ *buildNumber = osVersionInfo.buildNumber ++} ++ + func osinit() { + asmstdcallAddr = unsafe.Pointer(windows.AsmStdCallAddr()) + +@@ -470,8 +564,8 @@ + initHighResTimer() + timeBeginPeriodRetValue = osRelax(false) + +- initSysDirectory() + initLongPathSupport() ++ initOsVersionInfo() + + numCPUStartup = getCPUCount() + +@@ -487,7 +581,7 @@ + //go:nosplit + func readRandom(r []byte) int { + n := 0 +- if stdcall(_ProcessPrng, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { ++ if stdcall(_RtlGenRandom, uintptr(unsafe.Pointer(&r[0])), uintptr(len(r)))&0xff != 0 { + n = len(r) + } + return n +Index: src/net/hook_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/hook_windows.go b/src/net/hook_windows.go +--- a/src/net/hook_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/hook_windows.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -13,6 +13,7 @@ + hostsFilePath = windows.GetSystemDirectory() + "/Drivers/etc/hosts" + + // Placeholders for socket system calls. ++ socketFunc func(int, int, int) (syscall.Handle, error) = syscall.Socket + wsaSocketFunc func(int32, int32, int32, *syscall.WSAProtocolInfo, uint32, uint32) (syscall.Handle, error) = windows.WSASocket + connectFunc func(syscall.Handle, syscall.Sockaddr) error = syscall.Connect + listenFunc func(syscall.Handle, int) error = syscall.Listen +Index: src/net/internal/socktest/main_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_test.go b/src/net/internal/socktest/main_test.go +--- a/src/net/internal/socktest/main_test.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/internal/socktest/main_test.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build !js && !plan9 && !wasip1 && !windows ++//go:build !js && !plan9 && !wasip1 + + package socktest_test + +Index: src/net/internal/socktest/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/main_windows_test.go b/src/net/internal/socktest/main_windows_test.go +new file mode 100644 +--- /dev/null (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) ++++ b/src/net/internal/socktest/main_windows_test.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -0,0 +1,22 @@ ++// Copyright 2015 The Go Authors. All rights reserved. ++// Use of this source code is governed by a BSD-style ++// license that can be found in the LICENSE file. ++ ++package socktest_test ++ ++import "syscall" ++ ++var ( ++ socketFunc func(int, int, int) (syscall.Handle, error) ++ closeFunc func(syscall.Handle) error ++) ++ ++func installTestHooks() { ++ socketFunc = sw.Socket ++ closeFunc = sw.Closesocket ++} ++ ++func uninstallTestHooks() { ++ socketFunc = syscall.Socket ++ closeFunc = syscall.Closesocket ++} +Index: src/net/internal/socktest/sys_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/internal/socktest/sys_windows.go b/src/net/internal/socktest/sys_windows.go +--- a/src/net/internal/socktest/sys_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/internal/socktest/sys_windows.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -9,6 +9,38 @@ + "syscall" + ) + ++// Socket wraps [syscall.Socket]. ++func (sw *Switch) Socket(family, sotype, proto int) (s syscall.Handle, err error) { ++ sw.once.Do(sw.init) ++ ++ so := &Status{Cookie: cookie(family, sotype, proto)} ++ sw.fmu.RLock() ++ f, _ := sw.fltab[FilterSocket] ++ sw.fmu.RUnlock() ++ ++ af, err := f.apply(so) ++ if err != nil { ++ return syscall.InvalidHandle, err ++ } ++ s, so.Err = syscall.Socket(family, sotype, proto) ++ if err = af.apply(so); err != nil { ++ if so.Err == nil { ++ syscall.Closesocket(s) ++ } ++ return syscall.InvalidHandle, err ++ } ++ ++ sw.smu.Lock() ++ defer sw.smu.Unlock() ++ if so.Err != nil { ++ sw.stats.getLocked(so.Cookie).OpenFailed++ ++ return syscall.InvalidHandle, so.Err ++ } ++ nso := sw.addLocked(s, family, sotype, proto) ++ sw.stats.getLocked(nso.Cookie).Opened++ ++ return s, nil ++} ++ + // WSASocket wraps [syscall.WSASocket]. + func (sw *Switch) WSASocket(family, sotype, proto int32, protinfo *syscall.WSAProtocolInfo, group uint32, flags uint32) (s syscall.Handle, err error) { + sw.once.Do(sw.init) +Index: src/net/main_windows_test.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/main_windows_test.go b/src/net/main_windows_test.go +--- a/src/net/main_windows_test.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/main_windows_test.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -12,6 +12,7 @@ + + var ( + // Placeholders for saving original socket system calls. ++ origSocket = socketFunc + origWSASocket = wsaSocketFunc + origClosesocket = poll.CloseFunc + origConnect = connectFunc +@@ -21,6 +22,7 @@ + ) + + func installTestHooks() { ++ socketFunc = sw.Socket + wsaSocketFunc = sw.WSASocket + poll.CloseFunc = sw.Closesocket + connectFunc = sw.Connect +@@ -30,6 +32,7 @@ + } + + func uninstallTestHooks() { ++ socketFunc = origSocket + wsaSocketFunc = origWSASocket + poll.CloseFunc = origClosesocket + connectFunc = origConnect +Index: src/net/sock_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/net/sock_windows.go b/src/net/sock_windows.go +--- a/src/net/sock_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/net/sock_windows.go (revision 44e76f7cf1bc6e04b5da724e0b2e48f393713506) +@@ -20,6 +20,21 @@ + func sysSocket(family, sotype, proto int) (syscall.Handle, error) { + s, err := wsaSocketFunc(int32(family), int32(sotype), int32(proto), + nil, 0, windows.WSA_FLAG_OVERLAPPED|windows.WSA_FLAG_NO_HANDLE_INHERIT) ++ if err == nil { ++ return s, nil ++ } ++ // WSA_FLAG_NO_HANDLE_INHERIT flag is not supported on some ++ // old versions of Windows, see ++ // https://msdn.microsoft.com/en-us/library/windows/desktop/ms742212(v=vs.85).aspx ++ // for details. Just use syscall.Socket, if windows.WSASocket failed. ++ ++ // See ../syscall/exec_unix.go for description of ForkLock. ++ syscall.ForkLock.RLock() ++ s, err = socketFunc(family, sotype, proto) ++ if err == nil { ++ syscall.CloseOnExec(s) ++ } ++ syscall.ForkLock.RUnlock() + if err != nil { + return syscall.InvalidHandle, os.NewSyscallError("socket", err) + } +Index: src/syscall/exec_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/exec_windows.go b/src/syscall/exec_windows.go +--- a/src/syscall/exec_windows.go (revision b0d48afabb9fd14976c27221cb525c5d2ebbfe79) ++++ b/src/syscall/exec_windows.go (revision b4aece36e51ecce81c3ee9fe03e31db552e90018) +@@ -15,7 +15,6 @@ + "unsafe" + ) + +-// ForkLock is not used on Windows. + var ForkLock sync.RWMutex + + // EscapeArg rewrites command line argument s as prescribed +@@ -304,6 +303,9 @@ + var zeroProcAttr ProcAttr + var zeroSysProcAttr SysProcAttr + ++//go:linkname rtlGetNtVersionNumbers ++func rtlGetNtVersionNumbers(majorVersion *uint32, minorVersion *uint32, buildNumber *uint32) ++ + func StartProcess(argv0 string, argv []string, attr *ProcAttr) (pid int, handle uintptr, err error) { + if len(argv0) == 0 { + return 0, 0, EWINDOWS +@@ -367,6 +369,17 @@ + } + } + ++ var maj, min, build uint32 ++ rtlGetNtVersionNumbers(&maj, &min, &build) ++ isWin7 := maj < 6 || (maj == 6 && min <= 1) ++ // NT kernel handles are divisible by 4, with the bottom 3 bits left as ++ // a tag. The fully set tag correlates with the types of handles we're ++ // concerned about here. Except, the kernel will interpret some ++ // special handle values, like -1, -2, and so forth, so kernelbase.dll ++ // checks to see that those bottom three bits are checked, but that top ++ // bit is not checked. ++ isLegacyWin7ConsoleHandle := func(handle Handle) bool { return isWin7 && handle&0x10000003 == 3 } ++ + p, _ := GetCurrentProcess() + parentProcess := p + if sys.ParentProcess != 0 { +@@ -375,7 +388,15 @@ + fd := make([]Handle, len(attr.Files)) + for i := range attr.Files { + if attr.Files[i] > 0 { +- err := DuplicateHandle(p, Handle(attr.Files[i]), parentProcess, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) ++ destinationProcessHandle := parentProcess ++ ++ // On Windows 7, console handles aren't real handles, and can only be duplicated ++ // into the current process, not a parent one, which amounts to the same thing. ++ if parentProcess != p && isLegacyWin7ConsoleHandle(Handle(attr.Files[i])) { ++ destinationProcessHandle = p ++ } ++ ++ err := DuplicateHandle(p, Handle(attr.Files[i]), destinationProcessHandle, &fd[i], 0, true, DUPLICATE_SAME_ACCESS) + if err != nil { + return 0, 0, err + } +@@ -406,6 +427,14 @@ + + fd = append(fd, sys.AdditionalInheritedHandles...) + ++ // On Windows 7, console handles aren't real handles, so don't pass them ++ // through to PROC_THREAD_ATTRIBUTE_HANDLE_LIST. ++ for i := range fd { ++ if isLegacyWin7ConsoleHandle(fd[i]) { ++ fd[i] = 0 ++ } ++ } ++ + // The presence of a NULL handle in the list is enough to cause PROC_THREAD_ATTRIBUTE_HANDLE_LIST + // to treat the entire list as empty, so remove NULL handles. + j := 0 +Index: src/syscall/dll_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/syscall/dll_windows.go b/src/syscall/dll_windows.go +--- a/src/syscall/dll_windows.go (revision b4aece36e51ecce81c3ee9fe03e31db552e90018) ++++ b/src/syscall/dll_windows.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) +@@ -119,14 +119,7 @@ + } + + //go:linkname loadsystemlibrary +-func loadsystemlibrary(filename *uint16) (uintptr, Errno) { +- const _LOAD_LIBRARY_SEARCH_SYSTEM32 = 0x00000800 +- handle, _, err := SyscallN(uintptr(__LoadLibraryExW), uintptr(unsafe.Pointer(filename)), 0, _LOAD_LIBRARY_SEARCH_SYSTEM32) +- if handle != 0 { +- err = 0 +- } +- return handle, err +-} ++func loadsystemlibrary(filename *uint16, absoluteFilepath *uint16) (handle uintptr, err Errno) + + //go:linkname getprocaddress + func getprocaddress(handle uintptr, procname *uint8) (uintptr, Errno) { +@@ -143,6 +136,9 @@ + Handle Handle + } + ++//go:linkname getSystemDirectory ++func getSystemDirectory() string // Implemented in runtime package. ++ + // LoadDLL loads the named DLL file into memory. + // + // If name is not an absolute path and is not a known system DLL used by +@@ -159,7 +155,11 @@ + var h uintptr + var e Errno + if sysdll.IsSystemDLL[name] { +- h, e = loadsystemlibrary(namep) ++ absoluteFilepathp, err := UTF16PtrFromString(getSystemDirectory() + name) ++ if err != nil { ++ return nil, err ++ } ++ h, e = loadsystemlibrary(namep, absoluteFilepathp) + } else { + h, e = loadlibrary(namep) + } +Index: src/os/removeall_at.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_at.go b/src/os/removeall_at.go +--- a/src/os/removeall_at.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/removeall_at.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build unix || wasip1 || windows ++//go:build unix || wasip1 + + package os + +@@ -175,3 +175,25 @@ + } + return newDirFile(fd, name) + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ // Consistency with os.RemoveAll: Strip trailing /s from the name, ++ // so RemoveAll("not_a_directory/") succeeds. ++ for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { ++ name = name[:len(name)-1] ++ } ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { ++ return struct{}{}, removeAllFrom(parent, name) ++ }) ++ if IsNotExist(err) { ++ return nil ++ } ++ if err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return err ++} +Index: src/os/removeall_noat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/removeall_noat.go b/src/os/removeall_noat.go +--- a/src/os/removeall_noat.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/removeall_noat.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -2,7 +2,7 @@ + // Use of this source code is governed by a BSD-style + // license that can be found in the LICENSE file. + +-//go:build (js && wasm) || plan9 ++//go:build (js && wasm) || plan9 || windows + + package os + +@@ -140,3 +140,22 @@ + } + return err + } ++ ++func rootRemoveAll(r *Root, name string) error { ++ if endsWithDot(name) { ++ // Consistency with os.RemoveAll: Return EINVAL when trying to remove . ++ return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} ++ } ++ if err := checkPathEscapesLstat(r, name); err != nil { ++ if err == syscall.ENOTDIR { ++ // Some intermediate path component is not a directory. ++ // RemoveAll treats this as success (since the target doesn't exist). ++ return nil ++ } ++ return &PathError{Op: "RemoveAll", Path: name, Err: err} ++ } ++ if err := RemoveAll(joinPath(r.root.name, name)); err != nil { ++ return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} ++ } ++ return nil ++} +Index: src/os/root_noopenat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_noopenat.go b/src/os/root_noopenat.go +--- a/src/os/root_noopenat.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/root_noopenat.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -11,7 +11,6 @@ + "internal/filepathlite" + "internal/stringslite" + "sync/atomic" +- "syscall" + "time" + ) + +@@ -185,25 +184,6 @@ + } + return nil + } +- +-func rootRemoveAll(r *Root, name string) error { +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- if err := checkPathEscapesLstat(r, name); err != nil { +- if err == syscall.ENOTDIR { +- // Some intermediate path component is not a directory. +- // RemoveAll treats this as success (since the target doesn't exist). +- return nil +- } +- return &PathError{Op: "RemoveAll", Path: name, Err: err} +- } +- if err := RemoveAll(joinPath(r.root.name, name)); err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return nil +-} + + func rootReadlink(r *Root, name string) (string, error) { + if err := checkPathEscapesLstat(r, name); err != nil { +Index: src/os/root_openat.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_openat.go b/src/os/root_openat.go +--- a/src/os/root_openat.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/root_openat.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -196,28 +196,6 @@ + return nil + } + +-func rootRemoveAll(r *Root, name string) error { +- // Consistency with os.RemoveAll: Strip trailing /s from the name, +- // so RemoveAll("not_a_directory/") succeeds. +- for len(name) > 0 && IsPathSeparator(name[len(name)-1]) { +- name = name[:len(name)-1] +- } +- if endsWithDot(name) { +- // Consistency with os.RemoveAll: Return EINVAL when trying to remove . +- return &PathError{Op: "RemoveAll", Path: name, Err: syscall.EINVAL} +- } +- _, err := doInRoot(r, name, nil, func(parent sysfdType, name string) (struct{}, error) { +- return struct{}{}, removeAllFrom(parent, name) +- }) +- if IsNotExist(err) { +- return nil +- } +- if err != nil { +- return &PathError{Op: "RemoveAll", Path: name, Err: underlyingError(err)} +- } +- return err +-} +- + func rootRename(r *Root, oldname, newname string) error { + _, err := doInRoot(r, oldname, nil, func(oldparent sysfdType, oldname string) (struct{}, error) { + _, err := doInRoot(r, newname, nil, func(newparent sysfdType, newname string) (struct{}, error) { +Index: src/os/root_windows.go +IDEA additional info: +Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP +<+>UTF-8 +=================================================================== +diff --git a/src/os/root_windows.go b/src/os/root_windows.go +--- a/src/os/root_windows.go (revision ea2726a6fa25fbfa1092e696e522eafca544d24c) ++++ b/src/os/root_windows.go (revision d47e0d22130d597dcf9daa6b41fd9501274f0cb2) +@@ -402,3 +402,14 @@ + } + return fi.Mode(), nil + } ++ ++func checkPathEscapes(r *Root, name string) error { ++ if !filepathlite.IsLocal(name) { ++ return errPathEscapes ++ } ++ return nil ++} ++ ++func checkPathEscapesLstat(r *Root, name string) error { ++ return checkPathEscapes(r, name) ++} diff --git a/mihomo/.github/workflows/build.yml b/mihomo/.github/workflows/build.yml index 9ba36ed8ae..3fe99a6b62 100644 --- a/mihomo/.github/workflows/build.yml +++ b/mihomo/.github/workflows/build.yml @@ -59,6 +59,8 @@ jobs: - { goos: linux, goarch: s390x, output: s390x, debian: s390x, rpm: s390x } - { goos: linux, goarch: ppc64le, output: ppc64le, debian: ppc64el, rpm: ppc64le } + # Go 1.25 with special patch can work on Windows 7 + # https://github.com/MetaCubeX/go/commits/release-branch.go1.25/ - { goos: windows, goarch: '386', output: '386' } - { goos: windows, goarch: amd64, goamd64: v1, output: amd64-compatible } # old style file name will be removed in next released - { goos: windows, goarch: amd64, goamd64: v3, output: amd64 } @@ -176,6 +178,8 @@ jobs: # 7c1157f9544922e96945196b47b95664b1e39108: "net: remove sysSocket fallback for Windows 7" # 48042aa09c2f878c4faa576948b07fe625c4707a: "syscall: remove Windows 7 console handle workaround" # a17d959debdb04cd550016a3501dd09d50cd62e7: "runtime: always use LoadLibraryEx to load system libraries" + # sepical fix: + # - os.RemoveAll not working on Windows7 - name: Revert Golang1.25 commit for Windows7/8 if: ${{ matrix.jobs.goos == 'windows' && matrix.jobs.goversion == '' }} run: | diff --git a/mihomo/.github/workflows/test.yml b/mihomo/.github/workflows/test.yml index ddddb5eee5..af3ae18fe7 100644 --- a/mihomo/.github/workflows/test.yml +++ b/mihomo/.github/workflows/test.yml @@ -24,6 +24,7 @@ jobs: - 'ubuntu-24.04-arm' # arm64 linux - 'macos-15-intel' # amd64 macos go-version: + - '1.26.0-rc.1' - '1.25' - '1.24' - '1.23' @@ -49,11 +50,17 @@ jobs: go-version: ${{ matrix.go-version }} - name: Revert Golang commit for Windows7/8 - if: ${{ runner.os == 'Windows' && matrix.go-version != '1.20' }} + if: ${{ runner.os == 'Windows' && matrix.go-version != '1.20' && matrix.go-version != '1.26.0-rc.1' }} run: | cd $(go env GOROOT) patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go${{matrix.go-version}}.patch + - name: Revert Golang commit for Windows7/8 + if: ${{ runner.os == 'Windows' && matrix.go-version == '1.26.0-rc.1' }} + run: | + cd $(go env GOROOT) + patch --verbose -p 1 < $GITHUB_WORKSPACE/.github/patch/go1.26.patch + - name: Remove inbound test for macOS if: ${{ runner.os == 'macOS' }} run: | diff --git a/openwrt-packages/ddns-go/Makefile b/openwrt-packages/ddns-go/Makefile index ede4a3e7d4..293ef21f72 100644 --- a/openwrt-packages/ddns-go/Makefile +++ b/openwrt-packages/ddns-go/Makefile @@ -8,12 +8,12 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ddns-go -PKG_VERSION:=6.14.0 +PKG_VERSION:=6.14.1 PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/jeessy2/ddns-go/tar.gz/v$(PKG_VERSION)? -PKG_HASH:=684244194035a75f2830c57c6e0e1f4c06a0ca55d2f707acf06eaf6e0162f372 +PKG_HASH:=6a38c08e8c2fb17243720a94b0c54b8636019e7a4f151de60271d4ce19a41f48 PKG_LICENSE:=MIT PKG_LICENSE_FILES:=LICENSE diff --git a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua index 3862bab83f..eba4bb6672 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua @@ -250,27 +250,17 @@ if has_xray then end if has_singbox then - local version = api.get_app_version("sing-box"):match("[^v]+") - local version_ge_1_12_0 = api.compare_versions(version, ">=", "1.12.0") - s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings")) s.anonymous = true s.addremove = false - o = s:option(Flag, "sniff_override_destination", translate("Override the connection destination address")) + o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"), + translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first.")) o.default = 0 - o.rmempty = false - o.description = translate("Override the connection destination address with the sniffed domain.
When enabled, traffic will match only by domain, ignoring IP rules.
If using shunt nodes, configure the domain shunt rules correctly.") - if version_ge_1_12_0 then - o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"), - translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first.")) - o.default = 0 - - o = s:option(Flag, "fragment", "TLS TCP " .. translate("Fragment"), - translate("Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed.")) - o.default = 0 - end + o = s:option(Flag, "fragment", "TLS TCP " .. translate("Fragment"), + translate("Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed.")) + o.default = 0 end return m diff --git a/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_sing-box.lua index b60dc9922a..22d8dcda05 100644 --- a/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_sing-box.lua +++ b/openwrt-passwall/luci-app-passwall/luasrc/passwall/util_sing-box.lua @@ -1006,8 +1006,7 @@ function gen_config(var) tag = "redirect_tcp", listen = "::", listen_port = tonumber(tcp_redir_port), - sniff = true, - sniff_override_destination = (singbox_settings.sniff_override_destination == "1") and true or false, + sniff = true } table.insert(inbounds, inbound) else @@ -1017,8 +1016,7 @@ function gen_config(var) network = "tcp", listen = "::", listen_port = tonumber(tcp_redir_port), - sniff = true, - sniff_override_destination = (singbox_settings.sniff_override_destination == "1") and true or false, + sniff = true } table.insert(inbounds, inbound) end @@ -1031,8 +1029,7 @@ function gen_config(var) network = "udp", listen = "::", listen_port = tonumber(udp_redir_port), - sniff = true, - sniff_override_destination = (singbox_settings.sniff_override_destination == "1") and true or false, + sniff = true } table.insert(inbounds, inbound) end @@ -1970,7 +1967,6 @@ function gen_config(var) action = "sniff" }) value.sniff = nil - value.sniff_override_destination = nil end if value.domain_strategy then table.insert(config.route.rules, 1, { diff --git a/sing-box/.github/CRONET_GO_VERSION b/sing-box/.github/CRONET_GO_VERSION index 73d4820b59..f887e9a2b0 100644 --- a/sing-box/.github/CRONET_GO_VERSION +++ b/sing-box/.github/CRONET_GO_VERSION @@ -1 +1 @@ -5e61220bb2d22453eb6d105077c88c8ab1e1c3b2 +6228b14f72eea9db301d1fbe771c7bdecadefb40 diff --git a/sing-box/adapter/endpoint/manager.go b/sing-box/adapter/endpoint/manager.go index 5a633beed3..8b7c287f3d 100644 --- a/sing-box/adapter/endpoint/manager.go +++ b/sing-box/adapter/endpoint/manager.go @@ -4,6 +4,7 @@ import ( "context" "os" "sync" + "time" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/common/taskmonitor" @@ -11,6 +12,7 @@ import ( "github.com/sagernet/sing-box/log" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" + F "github.com/sagernet/sing/common/format" ) var _ adapter.EndpointManager = (*Manager)(nil) @@ -46,10 +48,14 @@ func (m *Manager) Start(stage adapter.StartStage) error { return nil } for _, endpoint := range m.endpoints { + name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]" + m.logger.Trace(stage, " ", name) + startTime := time.Now() err := adapter.LegacyStart(endpoint, stage) if err != nil { - return E.Cause(err, stage, " endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } @@ -66,11 +72,15 @@ func (m *Manager) Close() error { monitor := taskmonitor.New(m.logger, C.StopTimeout) var err error for _, endpoint := range endpoints { - monitor.Start("close endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]") + name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]" + m.logger.Trace("close ", name) + startTime := time.Now() + monitor.Start("close ", name) err = E.Append(err, endpoint.Close(), func(err error) error { - return E.Cause(err, "close endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]") + return E.Cause(err, "close ", name) }) monitor.Finish() + m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } @@ -119,11 +129,15 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log. m.access.Lock() defer m.access.Unlock() if m.started { + name := "endpoint/" + endpoint.Type() + "[" + endpoint.Tag() + "]" for _, stage := range adapter.ListStartStages { + m.logger.Trace(stage, " ", name) + startTime := time.Now() err = adapter.LegacyStart(endpoint, stage) if err != nil { - return E.Cause(err, stage, " endpoint/", endpoint.Type(), "[", endpoint.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } } if existsEndpoint, loaded := m.endpointByTag[tag]; loaded { diff --git a/sing-box/adapter/inbound/manager.go b/sing-box/adapter/inbound/manager.go index 89e424ac9d..438c20f4ba 100644 --- a/sing-box/adapter/inbound/manager.go +++ b/sing-box/adapter/inbound/manager.go @@ -4,6 +4,7 @@ import ( "context" "os" "sync" + "time" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/common/taskmonitor" @@ -11,6 +12,7 @@ import ( "github.com/sagernet/sing-box/log" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" + F "github.com/sagernet/sing/common/format" ) var _ adapter.InboundManager = (*Manager)(nil) @@ -45,10 +47,14 @@ func (m *Manager) Start(stage adapter.StartStage) error { inbounds := m.inbounds m.access.Unlock() for _, inbound := range inbounds { + name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]" + m.logger.Trace(stage, " ", name) + startTime := time.Now() err := adapter.LegacyStart(inbound, stage) if err != nil { - return E.Cause(err, stage, " inbound/", inbound.Type(), "[", inbound.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } @@ -65,11 +71,15 @@ func (m *Manager) Close() error { monitor := taskmonitor.New(m.logger, C.StopTimeout) var err error for _, inbound := range inbounds { - monitor.Start("close inbound/", inbound.Type(), "[", inbound.Tag(), "]") + name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]" + m.logger.Trace("close ", name) + startTime := time.Now() + monitor.Start("close ", name) err = E.Append(err, inbound.Close(), func(err error) error { - return E.Cause(err, "close inbound/", inbound.Type(), "[", inbound.Tag(), "]") + return E.Cause(err, "close ", name) }) monitor.Finish() + m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } @@ -121,11 +131,15 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log. m.access.Lock() defer m.access.Unlock() if m.started { + name := "inbound/" + inbound.Type() + "[" + inbound.Tag() + "]" for _, stage := range adapter.ListStartStages { + m.logger.Trace(stage, " ", name) + startTime := time.Now() err = adapter.LegacyStart(inbound, stage) if err != nil { - return E.Cause(err, stage, " inbound/", inbound.Type(), "[", inbound.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } } if existsInbound, loaded := m.inboundByTag[tag]; loaded { diff --git a/sing-box/adapter/lifecycle.go b/sing-box/adapter/lifecycle.go index face00b76d..b969c98ac6 100644 --- a/sing-box/adapter/lifecycle.go +++ b/sing-box/adapter/lifecycle.go @@ -1,6 +1,14 @@ package adapter -import E "github.com/sagernet/sing/common/exceptions" +import ( + "reflect" + "strings" + "time" + + "github.com/sagernet/sing-box/log" + E "github.com/sagernet/sing/common/exceptions" + F "github.com/sagernet/sing/common/format" +) type SimpleLifecycle interface { Start() error @@ -48,22 +56,47 @@ type LifecycleService interface { Lifecycle } -func Start(stage StartStage, services ...Lifecycle) error { +func getServiceName(service any) string { + if named, ok := service.(interface { + Type() string + Tag() string + }); ok { + tag := named.Tag() + if tag != "" { + return named.Type() + "[" + tag + "]" + } + return named.Type() + } + t := reflect.TypeOf(service) + if t.Kind() == reflect.Ptr { + t = t.Elem() + } + return strings.ToLower(t.Name()) +} + +func Start(logger log.ContextLogger, stage StartStage, services ...Lifecycle) error { for _, service := range services { + name := getServiceName(service) + logger.Trace(stage, " ", name) + startTime := time.Now() err := service.Start(stage) if err != nil { return err } + logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } -func StartNamed(stage StartStage, services []LifecycleService) error { +func StartNamed(logger log.ContextLogger, stage StartStage, services []LifecycleService) error { for _, service := range services { + logger.Trace(stage, " ", service.Name()) + startTime := time.Now() err := service.Start(stage) if err != nil { return E.Cause(err, stage.String(), " ", service.Name()) } + logger.Trace(stage, " ", service.Name(), " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } diff --git a/sing-box/adapter/outbound/manager.go b/sing-box/adapter/outbound/manager.go index 0fdeb390c2..5c1b5d990c 100644 --- a/sing-box/adapter/outbound/manager.go +++ b/sing-box/adapter/outbound/manager.go @@ -6,6 +6,7 @@ import ( "os" "strings" "sync" + "time" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/common/taskmonitor" @@ -13,6 +14,7 @@ import ( "github.com/sagernet/sing-box/log" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" + F "github.com/sagernet/sing/common/format" "github.com/sagernet/sing/common/logger" ) @@ -81,10 +83,14 @@ func (m *Manager) Start(stage adapter.StartStage) error { outbounds := m.outbounds m.access.Unlock() for _, outbound := range outbounds { + name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]" + m.logger.Trace(stage, " ", name) + startTime := time.Now() err := adapter.LegacyStart(outbound, stage) if err != nil { - return E.Cause(err, stage, " outbound/", outbound.Type(), "[", outbound.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } } return nil @@ -109,22 +115,29 @@ func (m *Manager) startOutbounds(outbounds []adapter.Outbound) error { } started[outboundTag] = true canContinue = true + name := "outbound/" + outboundToStart.Type() + "[" + outboundTag + "]" if starter, isStarter := outboundToStart.(adapter.Lifecycle); isStarter { - monitor.Start("start outbound/", outboundToStart.Type(), "[", outboundTag, "]") + m.logger.Trace("start ", name) + startTime := time.Now() + monitor.Start("start ", name) err := starter.Start(adapter.StartStateStart) monitor.Finish() if err != nil { - return E.Cause(err, "start outbound/", outboundToStart.Type(), "[", outboundTag, "]") + return E.Cause(err, "start ", name) } + m.logger.Trace("start ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } else if starter, isStarter := outboundToStart.(interface { Start() error }); isStarter { - monitor.Start("start outbound/", outboundToStart.Type(), "[", outboundTag, "]") + m.logger.Trace("start ", name) + startTime := time.Now() + monitor.Start("start ", name) err := starter.Start() monitor.Finish() if err != nil { - return E.Cause(err, "start outbound/", outboundToStart.Type(), "[", outboundTag, "]") + return E.Cause(err, "start ", name) } + m.logger.Trace("start ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } } if len(started) == len(outbounds) { @@ -171,11 +184,15 @@ func (m *Manager) Close() error { var err error for _, outbound := range outbounds { if closer, isCloser := outbound.(io.Closer); isCloser { - monitor.Start("close outbound/", outbound.Type(), "[", outbound.Tag(), "]") + name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]" + m.logger.Trace("close ", name) + startTime := time.Now() + monitor.Start("close ", name) err = E.Append(err, closer.Close(), func(err error) error { - return E.Cause(err, "close outbound/", outbound.Type(), "[", outbound.Tag(), "]") + return E.Cause(err, "close ", name) }) monitor.Finish() + m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } } return nil @@ -256,11 +273,15 @@ func (m *Manager) Create(ctx context.Context, router adapter.Router, logger log. return err } if m.started { + name := "outbound/" + outbound.Type() + "[" + outbound.Tag() + "]" for _, stage := range adapter.ListStartStages { + m.logger.Trace(stage, " ", name) + startTime := time.Now() err = adapter.LegacyStart(outbound, stage) if err != nil { - return E.Cause(err, stage, " outbound/", outbound.Type(), "[", outbound.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } } m.access.Lock() diff --git a/sing-box/adapter/service/manager.go b/sing-box/adapter/service/manager.go index d58b1a7779..f17aa07eff 100644 --- a/sing-box/adapter/service/manager.go +++ b/sing-box/adapter/service/manager.go @@ -4,6 +4,7 @@ import ( "context" "os" "sync" + "time" "github.com/sagernet/sing-box/adapter" "github.com/sagernet/sing-box/common/taskmonitor" @@ -11,6 +12,7 @@ import ( "github.com/sagernet/sing-box/log" "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" + F "github.com/sagernet/sing/common/format" ) var _ adapter.ServiceManager = (*Manager)(nil) @@ -43,10 +45,14 @@ func (m *Manager) Start(stage adapter.StartStage) error { services := m.services m.access.Unlock() for _, service := range services { + name := "service/" + service.Type() + "[" + service.Tag() + "]" + m.logger.Trace(stage, " ", name) + startTime := time.Now() err := adapter.LegacyStart(service, stage) if err != nil { - return E.Cause(err, stage, " service/", service.Type(), "[", service.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } @@ -63,11 +69,15 @@ func (m *Manager) Close() error { monitor := taskmonitor.New(m.logger, C.StopTimeout) var err error for _, service := range services { - monitor.Start("close service/", service.Type(), "[", service.Tag(), "]") + name := "service/" + service.Type() + "[" + service.Tag() + "]" + m.logger.Trace("close ", name) + startTime := time.Now() + monitor.Start("close ", name) err = E.Append(err, service.Close(), func(err error) error { - return E.Cause(err, "close service/", service.Type(), "[", service.Tag(), "]") + return E.Cause(err, "close ", name) }) monitor.Finish() + m.logger.Trace("close ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } return nil } @@ -116,11 +126,15 @@ func (m *Manager) Create(ctx context.Context, logger log.ContextLogger, tag stri m.access.Lock() defer m.access.Unlock() if m.started { + name := "service/" + service.Type() + "[" + service.Tag() + "]" for _, stage := range adapter.ListStartStages { + m.logger.Trace(stage, " ", name) + startTime := time.Now() err = adapter.LegacyStart(service, stage) if err != nil { - return E.Cause(err, stage, " service/", service.Type(), "[", service.Tag(), "]") + return E.Cause(err, stage, " ", name) } + m.logger.Trace(stage, " ", name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } } if existsService, loaded := m.serviceByTag[tag]; loaded { diff --git a/sing-box/box.go b/sing-box/box.go index 1c168820cb..7885b0d412 100644 --- a/sing-box/box.go +++ b/sing-box/box.go @@ -443,15 +443,15 @@ func (s *Box) preStart() error { if err != nil { return E.Cause(err, "start logger") } - err = adapter.StartNamed(adapter.StartStateInitialize, s.internalService) // cache-file clash-api v2ray-api + err = adapter.StartNamed(s.logger, adapter.StartStateInitialize, s.internalService) // cache-file clash-api v2ray-api if err != nil { return err } - err = adapter.Start(adapter.StartStateInitialize, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service) + err = adapter.Start(s.logger, adapter.StartStateInitialize, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service) if err != nil { return err } - err = adapter.Start(adapter.StartStateStart, s.outbound, s.dnsTransport, s.dnsRouter, s.network, s.connection, s.router) + err = adapter.Start(s.logger, adapter.StartStateStart, s.outbound, s.dnsTransport, s.dnsRouter, s.network, s.connection, s.router) if err != nil { return err } @@ -463,27 +463,27 @@ func (s *Box) start() error { if err != nil { return err } - err = adapter.StartNamed(adapter.StartStateStart, s.internalService) + err = adapter.StartNamed(s.logger, adapter.StartStateStart, s.internalService) if err != nil { return err } - err = adapter.Start(adapter.StartStateStart, s.inbound, s.endpoint, s.service) + err = adapter.Start(s.logger, adapter.StartStateStart, s.inbound, s.endpoint, s.service) if err != nil { return err } - err = adapter.Start(adapter.StartStatePostStart, s.outbound, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.inbound, s.endpoint, s.service) + err = adapter.Start(s.logger, adapter.StartStatePostStart, s.outbound, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.inbound, s.endpoint, s.service) if err != nil { return err } - err = adapter.StartNamed(adapter.StartStatePostStart, s.internalService) + err = adapter.StartNamed(s.logger, adapter.StartStatePostStart, s.internalService) if err != nil { return err } - err = adapter.Start(adapter.StartStateStarted, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service) + err = adapter.Start(s.logger, adapter.StartStateStarted, s.network, s.dnsTransport, s.dnsRouter, s.connection, s.router, s.outbound, s.inbound, s.endpoint, s.service) if err != nil { return err } - err = adapter.StartNamed(adapter.StartStateStarted, s.internalService) + err = adapter.StartNamed(s.logger, adapter.StartStateStarted, s.internalService) if err != nil { return err } @@ -497,17 +497,42 @@ func (s *Box) Close() error { default: close(s.done) } - err := common.Close( - s.service, s.endpoint, s.inbound, s.outbound, s.router, s.connection, s.dnsRouter, s.dnsTransport, s.network, - ) + var err error + for _, closeItem := range []struct { + name string + service adapter.Lifecycle + }{ + {"service", s.service}, + {"endpoint", s.endpoint}, + {"inbound", s.inbound}, + {"outbound", s.outbound}, + {"router", s.router}, + {"connection", s.connection}, + {"dns-router", s.dnsRouter}, + {"dns-transport", s.dnsTransport}, + {"network", s.network}, + } { + s.logger.Trace("close ", closeItem.name) + startTime := time.Now() + err = E.Append(err, closeItem.service.Close(), func(err error) error { + return E.Cause(err, "close ", closeItem.name) + }) + s.logger.Trace("close ", closeItem.name, " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") + } for _, lifecycleService := range s.internalService { + s.logger.Trace("close ", lifecycleService.Name()) + startTime := time.Now() err = E.Append(err, lifecycleService.Close(), func(err error) error { return E.Cause(err, "close ", lifecycleService.Name()) }) + s.logger.Trace("close ", lifecycleService.Name(), " completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") } + s.logger.Trace("close logger") + startTime := time.Now() err = E.Append(err, s.logFactory.Close(), func(err error) error { return E.Cause(err, "close logger") }) + s.logger.Trace("close logger completed (", F.Seconds(time.Since(startTime).Seconds()), "s)") return err } diff --git a/sing-box/docs/changelog.md b/sing-box/docs/changelog.md index 77c787ec82..16944571e7 100644 --- a/sing-box/docs/changelog.md +++ b/sing-box/docs/changelog.md @@ -2,6 +2,10 @@ icon: material/alert-decagram --- +#### 1.13.0-alpha.33 + +* Fixes and improvements + #### 1.13.0-alpha.32 * Remove `certificate_public_key_sha256` option for NaiveProxy outbound **1** diff --git a/sing-box/go.mod b/sing-box/go.mod index 1c2fe80ad9..b7d83f57f4 100644 --- a/sing-box/go.mod +++ b/sing-box/go.mod @@ -26,8 +26,8 @@ require ( github.com/sagernet/asc-go v0.0.0-20241217030726-d563060fe4e1 github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a github.com/sagernet/cors v1.2.1 - github.com/sagernet/cronet-go v0.0.0-20251219080614-460b6a5fb79d - github.com/sagernet/cronet-go/all v0.0.0-20251219080614-460b6a5fb79d + github.com/sagernet/cronet-go v0.0.0-20251220122645-b05b5c41614a + github.com/sagernet/cronet-go/all v0.0.0-20251220122645-b05b5c41614a github.com/sagernet/fswatch v0.1.1 github.com/sagernet/gomobile v0.1.10 github.com/sagernet/gvisor v0.0.0-20250811.0-sing-box-mod.1 @@ -108,28 +108,28 @@ require ( github.com/prometheus-community/pro-bing v0.4.0 // indirect github.com/quic-go/qpack v0.6.0 // indirect github.com/safchain/ethtool v0.3.0 // indirect - github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251219080137-fbc9bf07b76b // indirect - github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251219080137-fbc9bf07b76b // indirect + github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251220122226-25b6d00c5b7e // indirect + github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251220122226-25b6d00c5b7e // indirect github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a // indirect github.com/sagernet/nftables v0.3.0-beta.4 // indirect github.com/spf13/pflag v1.0.6 // indirect diff --git a/sing-box/go.sum b/sing-box/go.sum index 725da22ec8..f823efef3d 100644 --- a/sing-box/go.sum +++ b/sing-box/go.sum @@ -154,54 +154,54 @@ github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkk github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM= github.com/sagernet/cors v1.2.1 h1:Cv5Z8y9YSD6Gm+qSpNrL3LO4lD3eQVvbFYJSG7JCMHQ= github.com/sagernet/cors v1.2.1/go.mod h1:O64VyOjjhrkLmQIjF4KGRrJO/5dVXFdpEmCW/eISRAI= -github.com/sagernet/cronet-go v0.0.0-20251219080614-460b6a5fb79d h1:Wfs4UEnHE3d0hHHG1NedCCwU2lUVlsgKblBGuOps8k4= -github.com/sagernet/cronet-go v0.0.0-20251219080614-460b6a5fb79d/go.mod h1:hwFHBEjjthyEquDULbr4c4ucMedp8Drb6Jvm2kt/0Bw= -github.com/sagernet/cronet-go/all v0.0.0-20251219080614-460b6a5fb79d h1:DZy1I3zKP5bRaFGDYStZWAXrtlxn3W4ONbFUD027sw8= -github.com/sagernet/cronet-go/all v0.0.0-20251219080614-460b6a5fb79d/go.mod h1:eKeQLIddaQGZD2/jc0t+AdTnHve3Yo+uMujwgNOCfz0= -github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251219080137-fbc9bf07b76b h1:+WRqXRiHEom7+lZUEA4qPVfNQB7Rx4++6JEN8cd5CgQ= -github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw= -github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251219080137-fbc9bf07b76b h1:ofD/ZwijuG5ccz0afLcvbfssIG+q/Bp8A2sziYYlJ28= -github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM= -github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251219080137-fbc9bf07b76b h1:m3Hv8Hs6x6JdFNe93nzh1XhdZ7DmkfOKheloDmQmGQo= -github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc= -github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251219080137-fbc9bf07b76b h1:gA8bzjowa5Lmih+hBjjh6xsjghmGTIojKNtPzVDG93A= -github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ= -github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251219080137-fbc9bf07b76b h1:0ASeUCDj66dAHaCU/HkgbuSm/1co+yHbrq13BokW/us= -github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs= -github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251219080137-fbc9bf07b76b h1:NsbDT3L2pLS0Qsh0MPEn+IPkL33XoL7eFs56EA0jBeo= -github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0= -github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20251219080137-fbc9bf07b76b h1:hIMIG2AuF3n9yelPvfUB3jyW2vWJnPiJfhE3hGUGJDk= -github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0= -github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251219080137-fbc9bf07b76b h1:/l1dS38ijnn0IHtAdFH3Y8cahAGw6ii0TYow0jUNBGM= -github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4= -github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20251219080137-fbc9bf07b76b h1:m29qbSNfdNuTYEgTkph9TQUIyu7wIrY3PAvbgl23OjA= -github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo= -github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251219080137-fbc9bf07b76b h1:mmOPED30mKTr0DucTYQeJBHtjAgvBO7huwdG3gL6Gyw= -github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ= -github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251219080137-fbc9bf07b76b h1:y7V2c5QwMY07ME/M+cI/W1ZNw2QFT2oMw99GaPtK0MY= -github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU= -github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251219080137-fbc9bf07b76b h1:txNHLfT1miemCZgCrtrA+eTbGfsfN46wHIpOShALNzI= -github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI= -github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251219080137-fbc9bf07b76b h1:FVPZ3TKAoIeM1hTCqUn0D7gHx6rDkKqhx+E8yaYNbXI= -github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ= -github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251219080137-fbc9bf07b76b h1:4ei7Sz97XCFXh+FUi2cKGHrhqD0A8lxdjZxST7NzDrQ= -github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0= -github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251219080137-fbc9bf07b76b h1:W0SrTDGPaKfcgjiZDkYeWqpICeVkwydaa228znP4q2c= -github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s= -github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251219080137-fbc9bf07b76b h1:WD7V83I/FDatR0zXq6gSxh8gGZCD+fUZjLb1f+OVuF0= -github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ= -github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251219080137-fbc9bf07b76b h1:M1V7j6Bke+v9aXeEK/NcWqoPwl84h97fmL3XSJJmNJw= -github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow= -github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20251219080137-fbc9bf07b76b h1:DmLB0sgGw7vNao08a7NJ0xMJbZpeL49rAphknfRRs5I= -github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4= -github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20251219080137-fbc9bf07b76b h1:j8tKUY2VVnK/RxIvX75G/nLGu53to6LaDRH/NTzyLDw= -github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc= -github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20251219080137-fbc9bf07b76b h1:+1hjEBE2hUGUxDKtNg+gBYYCHXPQao273PjimC67v38= -github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc= -github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251219080137-fbc9bf07b76b h1:22Jx/y6cz2lVeUwbN/lmNOUjhEWYpohGEYpW/zdDcBk= -github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8= -github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251219080137-fbc9bf07b76b h1:7juUKsCbreYSP8gALPf45kut0zdSpZXrk2TLIwQ2zOo= -github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251219080137-fbc9bf07b76b/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw= +github.com/sagernet/cronet-go v0.0.0-20251220122645-b05b5c41614a h1:EdIrRa0yH3ZaLOfX95RYYiN0etpX3b9+jcsW/D8jCyQ= +github.com/sagernet/cronet-go v0.0.0-20251220122645-b05b5c41614a/go.mod h1:hwFHBEjjthyEquDULbr4c4ucMedp8Drb6Jvm2kt/0Bw= +github.com/sagernet/cronet-go/all v0.0.0-20251220122645-b05b5c41614a h1:GU/oBPVjyrCVb2l0SI5qtF6aUlLsnE4u4ehXbS/NF+0= +github.com/sagernet/cronet-go/all v0.0.0-20251220122645-b05b5c41614a/go.mod h1:4MT0juyKK0lIVwa6+6xLbRMFJBUIqRZOx70iMvq5vf0= +github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251220122226-25b6d00c5b7e h1:EAcY0ZK8DWTNUdVCKdBQfXRsfGsohsh2ae9jIjlri2o= +github.com/sagernet/cronet-go/lib/android_386 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:XXDwdjX/T8xftoeJxQmbBoYXZp8MAPFR2CwbFuTpEtw= +github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251220122226-25b6d00c5b7e h1:9luoNSy9Ej8rC/nZejzrP0uxX+BxiNxjLJ7XPYlApQg= +github.com/sagernet/cronet-go/lib/android_amd64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:iNiUGoLtnr8/JTuVNj7XJbmpOAp2C6+B81KDrPxwaZM= +github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251220122226-25b6d00c5b7e h1:CSWZTuMlkO/98RSQpqC1EHtc9eSBzVmvMdPTnaFSDCM= +github.com/sagernet/cronet-go/lib/android_arm v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:19ILNUOGIzRdOqa2mq+iY0JoHxuieB7/lnjYeaA2vEc= +github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251220122226-25b6d00c5b7e h1:vkf3GDA11NtGm6XQHyP4tgWK3GD426ObmshdKdxGMhA= +github.com/sagernet/cronet-go/lib/android_arm64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:JxzGyQf94Cr6sBShKqODGDyRUlESfJK/Njcz9Lz6qMQ= +github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251220122226-25b6d00c5b7e h1:pNyNjDC5XPC6+2yNqiDA8QL8IYSsBJpaSLwPi/jY4JQ= +github.com/sagernet/cronet-go/lib/darwin_amd64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:KN+9T9TBycGOLzmKU4QdcHAJEj6Nlx48ifnlTvvHMvs= +github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251220122226-25b6d00c5b7e h1:2yDmTzppvxWuwxo4oDjxRzjlXBzZ6O3OCPWYeQcJRrw= +github.com/sagernet/cronet-go/lib/darwin_arm64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:kojvtUc29KKnk8hs2QIANynVR59921SnGWA9kXohHc0= +github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20251220122226-25b6d00c5b7e h1:+lyrRlxlKBYT/3LcYMaFHilUnRlKn3OQrImlWCey+qM= +github.com/sagernet/cronet-go/lib/ios_amd64_simulator v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:hkQzRE5GDbaH1/ioqYh0Taho4L6i0yLRCVEZ5xHz5M0= +github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251220122226-25b6d00c5b7e h1:dBeeUaCPG0Y26FfCPO1o3v72yw2pSjqopryAW0uV354= +github.com/sagernet/cronet-go/lib/ios_arm64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:tzVJFTOm66UxLxy6K0ZN5Ic2PC79e+sKKnt+V9puEa4= +github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20251220122226-25b6d00c5b7e h1:JkGEqkfeglehN9tu+a0gHTq9Dmm+pY2wtjY+NiUdjgw= +github.com/sagernet/cronet-go/lib/ios_arm64_simulator v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:M/pN6m3j0HFU6/y83n0HU6GLYys3tYdr/xTE8hVEGMo= +github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251220122226-25b6d00c5b7e h1:rd/AbuuEMCHcA6ib5JBkQmWvonnoGwVc0/P0sHcWfAQ= +github.com/sagernet/cronet-go/lib/linux_386 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:cGh5hO6eljCo6KMQ/Cel8Xgq4+etL0awZLRBDVG1EZQ= +github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251220122226-25b6d00c5b7e h1:4XcwU6KOCkVOAr2EKKY8geYm7ctKCLlb1SsmFWMMUzE= +github.com/sagernet/cronet-go/lib/linux_386_musl v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:JFE0/cxaKkx0wqPMZU7MgaplQlU0zudv82dROJjClKU= +github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251220122226-25b6d00c5b7e h1:fYDhPtxvMtZxBUM0k6GcaxbynLxMG2iTmQL3XcLtjS8= +github.com/sagernet/cronet-go/lib/linux_amd64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:vU8VftFeSt7fURCa3JXD6+k6ss1YAX+idQjPvHmJ2tI= +github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251220122226-25b6d00c5b7e h1:F5Vzd50H/AaoSHvt81yXZeUwDRKTcFjO/+KVW6VqbUs= +github.com/sagernet/cronet-go/lib/linux_amd64_musl v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:vCe4OUuL+XOUge9v3MyTD45BnuAXiH+DkjN9quDXJzQ= +github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251220122226-25b6d00c5b7e h1:Ok/Eh8ajcvxlu7FAWk+lHAPLcSRDKrKkgq30o6gCR6M= +github.com/sagernet/cronet-go/lib/linux_arm v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:w9amBWrvjtohQzBGCKJ7LCh22LhTIJs4sE7cYaKQzM0= +github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251220122226-25b6d00c5b7e h1:JoohVAfcwE9HjpwAaTULtEOFZ1Mz0Zz5K4pOcrRjqwo= +github.com/sagernet/cronet-go/lib/linux_arm64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:TqlsFtcYS/etTeck46kHBeT8Le0Igw1Q/AV88UnMS3s= +github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251220122226-25b6d00c5b7e h1:ULxfoxcNRA96QDDRLmObH4adbeUGtudH/2HlL4TgaNY= +github.com/sagernet/cronet-go/lib/linux_arm64_musl v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:B6Qd0vys8sv9OKVRN6J9RqDzYRGE938Fb2zrYdBDyTQ= +github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251220122226-25b6d00c5b7e h1:NnhScXJyx4Fg+pV/WtkC1mD6+VR7D/Q+PMU4xGRvdRQ= +github.com/sagernet/cronet-go/lib/linux_arm_musl v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:3tXMMFY7AHugOVBZ5Al7cL7JKsnFOe5bMVr0hZPk3ow= +github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20251220122226-25b6d00c5b7e h1:INcIfjzUl0qgtZkt8OcVV537GoApcBsdegDl8yNJEdQ= +github.com/sagernet/cronet-go/lib/tvos_amd64_simulator v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:aaX0YGl8nhGmfRWI8bc3BtDjY8Vzx6O0cS/e1uqxDq4= +github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20251220122226-25b6d00c5b7e h1:jrialJ4U7BW9xyGI/JdUiigZ9hgyF1EayFKCH4pZxdw= +github.com/sagernet/cronet-go/lib/tvos_arm64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:EdzMKA96xITc42QEI+ct4SwqX8Dn3ltKK8wzdkLWpSc= +github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20251220122226-25b6d00c5b7e h1:XefHhnALVHU4ZgICNq6ZJl78bWDQO4nHwoWn+Ar7e0g= +github.com/sagernet/cronet-go/lib/tvos_arm64_simulator v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:qix4kv1TTAJ5tY4lJ9vjhe9EY4mM+B7H5giOhbxDVcc= +github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251220122226-25b6d00c5b7e h1:djShWO5vN0CamyboNDyNRDxL0/9oMtKjCDesqolIAsg= +github.com/sagernet/cronet-go/lib/windows_amd64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:lm9w/oCCRyBiUa3G8lDQTT8x/ONUvgVR2iV9fVzUZB8= +github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251220122226-25b6d00c5b7e h1:AgKqyS5zfRgDc8uprxUh+XCwwzJCj31KAFPjzyLRWs0= +github.com/sagernet/cronet-go/lib/windows_arm64 v0.0.0-20251220122226-25b6d00c5b7e/go.mod h1:n34YyLgapgjWdKa0IoeczjAFCwD3/dxbsH5sucKw0bw= github.com/sagernet/fswatch v0.1.1 h1:YqID+93B7VRfqIH3PArW/XpJv5H4OLEVWDfProGoRQs= github.com/sagernet/fswatch v0.1.1/go.mod h1:nz85laH0mkQqJfaOrqPpkwtU1znMFNVTpT/5oRsVz/o= github.com/sagernet/gomobile v0.1.10 h1:ElqZ0OVDvyQlU91MU0C9cfU0FrILBbc65+NOKzZ1t0c= diff --git a/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js b/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js index a97a381b67..dde9b4a6bf 100644 --- a/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js +++ b/small/luci-app-fchomo/htdocs/luci-static/resources/fchomo.js @@ -382,6 +382,8 @@ const CBIGridSection = form.GridSection.extend({ let el = form.GridSection.prototype.renderSectionAdd.call(this, extra_class), nameEl = el.querySelector('.cbi-section-create-name'); + nameEl.placeholder = _('Specify a ID'); + ui.addValidator(nameEl, 'uciname', true, (v) => { let button = el.querySelector('.cbi-section-create > .cbi-button-add'); diff --git a/small/luci-app-fchomo/po/templates/fchomo.pot b/small/luci-app-fchomo/po/templates/fchomo.pot index e33d962e69..e952d8c16d 100644 --- a/small/luci-app-fchomo/po/templates/fchomo.pot +++ b/small/luci-app-fchomo/po/templates/fchomo.pot @@ -5,21 +5,21 @@ msgstr "Content-Type: text/plain; charset=UTF-8" msgid "%s log" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:558 -#: htdocs/luci-static/resources/fchomo.js:561 +#: htdocs/luci-static/resources/fchomo.js:560 +#: htdocs/luci-static/resources/fchomo.js:563 #: htdocs/luci-static/resources/view/fchomo/client.js:293 msgid "(Imported)" msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:549 #: htdocs/luci-static/resources/view/fchomo/global.js:555 -#: htdocs/luci-static/resources/view/fchomo/node.js:911 -#: htdocs/luci-static/resources/view/fchomo/node.js:917 -#: htdocs/luci-static/resources/view/fchomo/node.js:925 -#: htdocs/luci-static/resources/view/fchomo/node.js:931 -#: htdocs/luci-static/resources/view/fchomo/server.js:808 -#: htdocs/luci-static/resources/view/fchomo/server.js:816 -#: htdocs/luci-static/resources/view/fchomo/server.js:825 +#: htdocs/luci-static/resources/view/fchomo/node.js:912 +#: htdocs/luci-static/resources/view/fchomo/node.js:918 +#: htdocs/luci-static/resources/view/fchomo/node.js:926 +#: htdocs/luci-static/resources/view/fchomo/node.js:932 +#: htdocs/luci-static/resources/view/fchomo/server.js:820 +#: htdocs/luci-static/resources/view/fchomo/server.js:828 +#: htdocs/luci-static/resources/view/fchomo/server.js:837 msgid "(mTLS)" msgstr "" @@ -30,10 +30,10 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1153 #: htdocs/luci-static/resources/view/fchomo/client.js:1612 #: htdocs/luci-static/resources/view/fchomo/client.js:1613 -#: htdocs/luci-static/resources/view/fchomo/node.js:1608 -#: htdocs/luci-static/resources/view/fchomo/node.js:1614 -#: htdocs/luci-static/resources/view/fchomo/node.js:1628 -#: htdocs/luci-static/resources/view/fchomo/node.js:1634 +#: htdocs/luci-static/resources/view/fchomo/node.js:1609 +#: htdocs/luci-static/resources/view/fchomo/node.js:1615 +#: htdocs/luci-static/resources/view/fchomo/node.js:1629 +#: htdocs/luci-static/resources/view/fchomo/node.js:1635 msgid "-- Please choose --" msgstr "" @@ -66,11 +66,11 @@ msgstr "" msgid "0 or 1 only." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:918 -#: htdocs/luci-static/resources/view/fchomo/node.js:932 -#: htdocs/luci-static/resources/view/fchomo/server.js:786 -#: htdocs/luci-static/resources/view/fchomo/server.js:801 -#: htdocs/luci-static/resources/view/fchomo/server.js:826 +#: htdocs/luci-static/resources/view/fchomo/node.js:919 +#: htdocs/luci-static/resources/view/fchomo/node.js:933 +#: htdocs/luci-static/resources/view/fchomo/server.js:798 +#: htdocs/luci-static/resources/view/fchomo/server.js:813 +#: htdocs/luci-static/resources/view/fchomo/server.js:838 msgid "Save your configuration before uploading files!" msgstr "" @@ -139,11 +139,11 @@ msgstr "" msgid "Add a Node" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1198 +#: htdocs/luci-static/resources/view/fchomo/node.js:1199 msgid "Add a provider" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1584 +#: htdocs/luci-static/resources/view/fchomo/node.js:1585 msgid "Add a proxy chain" msgstr "" @@ -167,11 +167,11 @@ msgstr "" msgid "Add a sub rule" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1409 +#: htdocs/luci-static/resources/view/fchomo/node.js:1410 msgid "Add prefix" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1413 +#: htdocs/luci-static/resources/view/fchomo/node.js:1414 msgid "Add suffix" msgstr "" @@ -206,7 +206,7 @@ msgid "" "network from a public website, it must be enabled." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:651 +#: htdocs/luci-static/resources/view/fchomo/node.js:652 msgid "Allowed IPs" msgstr "" @@ -218,8 +218,8 @@ msgstr "" msgid "Already in updating." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:580 -#: htdocs/luci-static/resources/view/fchomo/server.js:488 +#: htdocs/luci-static/resources/view/fchomo/node.js:581 +#: htdocs/luci-static/resources/view/fchomo/server.js:500 msgid "Alter ID" msgstr "" @@ -241,11 +241,11 @@ msgstr "" msgid "As the TOP upstream of dnsmasq." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:438 +#: htdocs/luci-static/resources/view/fchomo/server.js:450 msgid "Auth timeout" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:602 +#: htdocs/luci-static/resources/view/fchomo/node.js:603 msgid "Authenticated length" msgstr "" @@ -287,13 +287,13 @@ msgid "Binary mrs" msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:740 -#: htdocs/luci-static/resources/view/fchomo/node.js:1168 -#: htdocs/luci-static/resources/view/fchomo/node.js:1482 +#: htdocs/luci-static/resources/view/fchomo/node.js:1169 +#: htdocs/luci-static/resources/view/fchomo/node.js:1483 msgid "Bind interface" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1169 -#: htdocs/luci-static/resources/view/fchomo/node.js:1483 +#: htdocs/luci-static/resources/view/fchomo/node.js:1170 +#: htdocs/luci-static/resources/view/fchomo/node.js:1484 msgid "Bind outbound interface.
" msgstr "" @@ -338,21 +338,21 @@ msgstr "" msgid "CORS allowed origins, * will be used if empty." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:674 +#: htdocs/luci-static/resources/fchomo.js:676 msgid "Cancel" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:890 +#: htdocs/luci-static/resources/view/fchomo/node.js:891 msgid "Cert fingerprint" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:891 +#: htdocs/luci-static/resources/view/fchomo/node.js:892 msgid "" "Certificate fingerprint. Used to implement SSL Pinning and prevent MitM." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:911 -#: htdocs/luci-static/resources/view/fchomo/server.js:778 +#: htdocs/luci-static/resources/view/fchomo/node.js:912 +#: htdocs/luci-static/resources/view/fchomo/server.js:790 msgid "Certificate path" msgstr "" @@ -383,7 +383,7 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:326 #: htdocs/luci-static/resources/view/fchomo/node.js:379 -#: htdocs/luci-static/resources/view/fchomo/node.js:586 +#: htdocs/luci-static/resources/view/fchomo/node.js:587 #: htdocs/luci-static/resources/view/fchomo/server.js:269 #: htdocs/luci-static/resources/view/fchomo/server.js:356 msgid "Chipher" @@ -405,24 +405,24 @@ msgid "" msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:556 -#: htdocs/luci-static/resources/view/fchomo/node.js:788 -#: htdocs/luci-static/resources/view/fchomo/node.js:912 -#: htdocs/luci-static/resources/view/fchomo/node.js:926 -#: htdocs/luci-static/resources/view/fchomo/server.js:607 -#: htdocs/luci-static/resources/view/fchomo/server.js:817 +#: htdocs/luci-static/resources/view/fchomo/node.js:789 +#: htdocs/luci-static/resources/view/fchomo/node.js:913 +#: htdocs/luci-static/resources/view/fchomo/node.js:927 +#: htdocs/luci-static/resources/view/fchomo/server.js:619 +#: htdocs/luci-static/resources/view/fchomo/server.js:829 #: root/usr/share/luci/menu.d/luci-app-fchomo.json:22 msgid "Client" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:816 +#: htdocs/luci-static/resources/view/fchomo/server.js:828 msgid "Client Auth Certificate path" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:808 +#: htdocs/luci-static/resources/view/fchomo/server.js:820 msgid "Client Auth type" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:952 +#: htdocs/luci-static/resources/view/fchomo/node.js:953 msgid "Client fingerprint" msgstr "" @@ -443,16 +443,16 @@ msgstr "" msgid "Common ports (bypass P2P traffic)" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1245 +#: htdocs/luci-static/resources/fchomo.js:1275 msgid "Complete" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1429 +#: htdocs/luci-static/resources/view/fchomo/node.js:1430 msgid "Configuration Items" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:460 -#: htdocs/luci-static/resources/view/fchomo/server.js:416 +#: htdocs/luci-static/resources/view/fchomo/node.js:461 +#: htdocs/luci-static/resources/view/fchomo/server.js:428 msgid "Congestion controller" msgstr "" @@ -460,19 +460,19 @@ msgstr "" msgid "Connection check" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:543 +#: htdocs/luci-static/resources/fchomo.js:545 msgid "Content copied to clipboard!" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:608 -#: htdocs/luci-static/resources/view/fchomo/node.js:1339 -#: htdocs/luci-static/resources/view/fchomo/node.js:1365 +#: htdocs/luci-static/resources/view/fchomo/node.js:1340 +#: htdocs/luci-static/resources/view/fchomo/node.js:1366 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:324 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:350 msgid "Content will not be verified, Please make sure you enter it correctly." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1338 +#: htdocs/luci-static/resources/view/fchomo/node.js:1339 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:323 msgid "Contents" msgstr "" @@ -481,7 +481,7 @@ msgstr "" msgid "Contents have been saved." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:545 +#: htdocs/luci-static/resources/fchomo.js:547 msgid "Copy" msgstr "" @@ -497,7 +497,7 @@ msgstr "" msgid "Custom Direct List" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1400 +#: htdocs/luci-static/resources/view/fchomo/node.js:1401 msgid "Custom HTTP header." msgstr "" @@ -531,7 +531,7 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1303 #: htdocs/luci-static/resources/view/fchomo/client.js:1312 #: htdocs/luci-static/resources/view/fchomo/client.js:1625 -#: htdocs/luci-static/resources/view/fchomo/node.js:675 +#: htdocs/luci-static/resources/view/fchomo/node.js:676 msgid "DNS server" msgstr "" @@ -559,15 +559,15 @@ msgstr "" msgid "Default DNS server" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:652 +#: htdocs/luci-static/resources/view/fchomo/node.js:653 msgid "Destination addresses allowed to be forwarded via Wireguard." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1607 +#: htdocs/luci-static/resources/view/fchomo/node.js:1608 msgid "Destination provider" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1613 +#: htdocs/luci-static/resources/view/fchomo/node.js:1614 msgid "Destination proxy node" msgstr "" @@ -575,8 +575,8 @@ msgstr "" msgid "Dial fields" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1620 -#: htdocs/luci-static/resources/view/fchomo/node.js:1640 +#: htdocs/luci-static/resources/view/fchomo/node.js:1621 +#: htdocs/luci-static/resources/view/fchomo/node.js:1641 msgid "Different chain head/tail" msgstr "" @@ -614,7 +614,7 @@ msgstr "" msgid "Disable ICMP Forwarding" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:839 +#: htdocs/luci-static/resources/view/fchomo/node.js:840 msgid "Disable SNI" msgstr "" @@ -648,29 +648,29 @@ msgstr "" msgid "Domain" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:840 +#: htdocs/luci-static/resources/view/fchomo/node.js:841 msgid "Donot send server name in ClientHello." msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1450 -#: htdocs/luci-static/resources/view/fchomo/node.js:904 -#: htdocs/luci-static/resources/view/fchomo/node.js:1469 +#: htdocs/luci-static/resources/view/fchomo/node.js:905 +#: htdocs/luci-static/resources/view/fchomo/node.js:1470 msgid "Donot verifying server certificate." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1147 +#: htdocs/luci-static/resources/view/fchomo/node.js:1148 msgid "Download bandwidth" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1148 +#: htdocs/luci-static/resources/view/fchomo/node.js:1149 msgid "Download bandwidth in Mbps." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1130 +#: htdocs/luci-static/resources/fchomo.js:1154 msgid "Download failed: %s" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1128 +#: htdocs/luci-static/resources/fchomo.js:1152 msgid "Download successful." msgstr "" @@ -678,12 +678,12 @@ msgstr "" msgid "Dual stack" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:945 -#: htdocs/luci-static/resources/view/fchomo/server.js:874 +#: htdocs/luci-static/resources/view/fchomo/node.js:946 +#: htdocs/luci-static/resources/view/fchomo/server.js:886 msgid "ECH config" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:833 +#: htdocs/luci-static/resources/view/fchomo/server.js:845 msgid "ECH key" msgstr "" @@ -699,11 +699,11 @@ msgstr "" msgid "ETag support" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1060 +#: htdocs/luci-static/resources/view/fchomo/node.js:1061 msgid "Early Data first packet length limit." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1066 +#: htdocs/luci-static/resources/view/fchomo/node.js:1067 msgid "Early Data header name" msgstr "" @@ -715,7 +715,7 @@ msgstr "" msgid "Edit ruleset" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1336 +#: htdocs/luci-static/resources/view/fchomo/node.js:1337 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:321 msgid "Editer" msgstr "" @@ -733,23 +733,23 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:401 #: htdocs/luci-static/resources/view/fchomo/global.js:686 #: htdocs/luci-static/resources/view/fchomo/node.js:234 -#: htdocs/luci-static/resources/view/fchomo/node.js:1309 -#: htdocs/luci-static/resources/view/fchomo/node.js:1505 -#: htdocs/luci-static/resources/view/fchomo/node.js:1594 +#: htdocs/luci-static/resources/view/fchomo/node.js:1310 +#: htdocs/luci-static/resources/view/fchomo/node.js:1506 +#: htdocs/luci-static/resources/view/fchomo/node.js:1595 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:249 #: htdocs/luci-static/resources/view/fchomo/server.js:157 #: htdocs/luci-static/resources/view/fchomo/server.js:184 msgid "Enable" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:495 +#: htdocs/luci-static/resources/view/fchomo/node.js:496 msgid "" "Enable 0-RTT QUIC connection handshake on the client side. This is not " "impacting much on the performance, as the protocol is fully multiplexed.
Disabling this is highly recommended, as it is vulnerable to replay attacks." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:494 +#: htdocs/luci-static/resources/view/fchomo/node.js:495 msgid "Enable 0-RTT handshake" msgstr "" @@ -759,37 +759,37 @@ msgid "" "conversion for outbound connections" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:939 +#: htdocs/luci-static/resources/view/fchomo/node.js:940 msgid "Enable ECH" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1135 +#: htdocs/luci-static/resources/view/fchomo/node.js:1136 msgid "Enable TCP Brutal" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1136 +#: htdocs/luci-static/resources/view/fchomo/node.js:1137 msgid "Enable TCP Brutal congestion control algorithm" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1124 +#: htdocs/luci-static/resources/view/fchomo/node.js:1125 msgid "Enable multiplexing only for TCP." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:424 -#: htdocs/luci-static/resources/view/fchomo/server.js:402 +#: htdocs/luci-static/resources/view/fchomo/node.js:425 +#: htdocs/luci-static/resources/view/fchomo/server.js:414 msgid "Enable obfuscate for downlink" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1118 +#: htdocs/luci-static/resources/view/fchomo/node.js:1119 msgid "Enable padding" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1129 +#: htdocs/luci-static/resources/view/fchomo/node.js:1130 msgid "Enable statistic" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:740 -#: htdocs/luci-static/resources/view/fchomo/node.js:1451 +#: htdocs/luci-static/resources/view/fchomo/node.js:741 +#: htdocs/luci-static/resources/view/fchomo/node.js:1452 msgid "" "Enable the SUoT protocol, requires server support. Conflict with Multiplex." msgstr "" @@ -801,7 +801,7 @@ msgid "" "connections, losing the ability to masquerade with HTTP/3." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:570 +#: htdocs/luci-static/resources/view/fchomo/server.js:582 msgid "Encryption method" msgstr "" @@ -824,7 +824,7 @@ msgid "" "if empty." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1563 +#: htdocs/luci-static/resources/view/fchomo/node.js:1564 msgid "Exclude matched node types." msgstr "" @@ -835,7 +835,7 @@ msgid "" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1049 -#: htdocs/luci-static/resources/view/fchomo/node.js:1556 +#: htdocs/luci-static/resources/view/fchomo/node.js:1557 msgid "Exclude nodes that meet keywords or regexps." msgstr "" @@ -844,59 +844,61 @@ msgid "Expand/Collapse result" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1009 -#: htdocs/luci-static/resources/view/fchomo/node.js:1541 +#: htdocs/luci-static/resources/view/fchomo/node.js:1542 msgid "Expected HTTP code. 204 will be used if empty." msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1011 -#: htdocs/luci-static/resources/view/fchomo/node.js:1543 +#: htdocs/luci-static/resources/view/fchomo/node.js:1544 msgid "Expected status" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:393 -#: htdocs/luci-static/resources/fchomo.js:396 -#: htdocs/luci-static/resources/fchomo.js:399 -#: htdocs/luci-static/resources/fchomo.js:1262 -#: htdocs/luci-static/resources/fchomo.js:1270 -#: htdocs/luci-static/resources/fchomo.js:1278 -#: htdocs/luci-static/resources/fchomo.js:1301 -#: htdocs/luci-static/resources/fchomo.js:1304 -#: htdocs/luci-static/resources/fchomo.js:1311 -#: htdocs/luci-static/resources/fchomo.js:1327 -#: htdocs/luci-static/resources/fchomo.js:1336 -#: htdocs/luci-static/resources/fchomo.js:1348 -#: htdocs/luci-static/resources/fchomo.js:1351 -#: htdocs/luci-static/resources/fchomo.js:1361 -#: htdocs/luci-static/resources/fchomo.js:1373 -#: htdocs/luci-static/resources/fchomo.js:1376 -#: htdocs/luci-static/resources/fchomo.js:1386 -#: htdocs/luci-static/resources/fchomo.js:1396 -#: htdocs/luci-static/resources/fchomo.js:1431 -#: htdocs/luci-static/resources/fchomo.js:1433 -#: htdocs/luci-static/resources/fchomo.js:1443 -#: htdocs/luci-static/resources/fchomo.js:1452 +#: htdocs/luci-static/resources/fchomo.js:395 +#: htdocs/luci-static/resources/fchomo.js:398 +#: htdocs/luci-static/resources/fchomo.js:401 +#: htdocs/luci-static/resources/fchomo.js:1292 +#: htdocs/luci-static/resources/fchomo.js:1300 +#: htdocs/luci-static/resources/fchomo.js:1308 +#: htdocs/luci-static/resources/fchomo.js:1331 +#: htdocs/luci-static/resources/fchomo.js:1334 +#: htdocs/luci-static/resources/fchomo.js:1341 +#: htdocs/luci-static/resources/fchomo.js:1357 +#: htdocs/luci-static/resources/fchomo.js:1366 +#: htdocs/luci-static/resources/fchomo.js:1378 +#: htdocs/luci-static/resources/fchomo.js:1381 +#: htdocs/luci-static/resources/fchomo.js:1391 +#: htdocs/luci-static/resources/fchomo.js:1403 +#: htdocs/luci-static/resources/fchomo.js:1406 +#: htdocs/luci-static/resources/fchomo.js:1416 +#: htdocs/luci-static/resources/fchomo.js:1426 +#: htdocs/luci-static/resources/fchomo.js:1461 +#: htdocs/luci-static/resources/fchomo.js:1463 +#: htdocs/luci-static/resources/fchomo.js:1476 +#: htdocs/luci-static/resources/fchomo.js:1482 +#: htdocs/luci-static/resources/fchomo.js:1489 +#: htdocs/luci-static/resources/fchomo.js:1498 #: htdocs/luci-static/resources/view/fchomo/client.js:68 #: htdocs/luci-static/resources/view/fchomo/client.js:906 #: htdocs/luci-static/resources/view/fchomo/client.js:1381 #: htdocs/luci-static/resources/view/fchomo/global.js:886 #: htdocs/luci-static/resources/view/fchomo/node.js:388 -#: htdocs/luci-static/resources/view/fchomo/node.js:811 -#: htdocs/luci-static/resources/view/fchomo/node.js:896 -#: htdocs/luci-static/resources/view/fchomo/node.js:1620 -#: htdocs/luci-static/resources/view/fchomo/node.js:1640 +#: htdocs/luci-static/resources/view/fchomo/node.js:812 +#: htdocs/luci-static/resources/view/fchomo/node.js:897 +#: htdocs/luci-static/resources/view/fchomo/node.js:1621 +#: htdocs/luci-static/resources/view/fchomo/node.js:1641 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:276 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:290 #: htdocs/luci-static/resources/view/fchomo/server.js:365 -#: htdocs/luci-static/resources/view/fchomo/server.js:599 -#: htdocs/luci-static/resources/view/fchomo/server.js:630 -#: htdocs/luci-static/resources/view/fchomo/server.js:731 +#: htdocs/luci-static/resources/view/fchomo/server.js:611 +#: htdocs/luci-static/resources/view/fchomo/server.js:642 +#: htdocs/luci-static/resources/view/fchomo/server.js:743 msgid "Expecting: %s" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1001 -#: htdocs/luci-static/resources/view/fchomo/node.js:1008 -#: htdocs/luci-static/resources/view/fchomo/server.js:941 -#: htdocs/luci-static/resources/view/fchomo/server.js:948 +#: htdocs/luci-static/resources/view/fchomo/node.js:1002 +#: htdocs/luci-static/resources/view/fchomo/node.js:1009 +#: htdocs/luci-static/resources/view/fchomo/server.js:953 +#: htdocs/luci-static/resources/view/fchomo/server.js:960 msgid "Expecting: only support %s." msgstr "" @@ -915,19 +917,19 @@ msgstr "" msgid "Factor" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1203 +#: htdocs/luci-static/resources/fchomo.js:1233 msgid "Failed to execute \"/etc/init.d/fchomo %s %s\" reason: %s" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1162 +#: htdocs/luci-static/resources/fchomo.js:1186 msgid "Failed to generate %s, error: %s." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1552 +#: htdocs/luci-static/resources/fchomo.js:1598 msgid "Failed to upload %s, error: %s." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1571 +#: htdocs/luci-static/resources/fchomo.js:1617 msgid "Failed to upload, error: %s." msgstr "" @@ -945,7 +947,7 @@ msgid "Fallback filter" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1044 -#: htdocs/luci-static/resources/view/fchomo/node.js:1550 +#: htdocs/luci-static/resources/view/fchomo/node.js:1551 msgid "Filter nodes that meet keywords or regexps." msgstr "" @@ -965,8 +967,8 @@ msgstr "" msgid "Firewall" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:572 -#: htdocs/luci-static/resources/view/fchomo/server.js:480 +#: htdocs/luci-static/resources/view/fchomo/node.js:573 +#: htdocs/luci-static/resources/view/fchomo/server.js:492 msgid "Flow" msgstr "" @@ -977,14 +979,14 @@ msgid "" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1010 -#: htdocs/luci-static/resources/view/fchomo/node.js:1419 -#: htdocs/luci-static/resources/view/fchomo/node.js:1542 +#: htdocs/luci-static/resources/view/fchomo/node.js:1420 +#: htdocs/luci-static/resources/view/fchomo/node.js:1543 msgid "" "For format see %s." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:670 +#: htdocs/luci-static/resources/view/fchomo/node.js:671 msgid "Force DNS remote resolution." msgstr "" @@ -1003,7 +1005,7 @@ msgstr "" msgid "FullCombo Shark!" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1027 +#: htdocs/luci-static/resources/view/fchomo/node.js:1028 msgid "GET" msgstr "" @@ -1017,7 +1019,7 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:897 #: htdocs/luci-static/resources/view/fchomo/node.js:222 -#: htdocs/luci-static/resources/view/fchomo/node.js:1299 +#: htdocs/luci-static/resources/view/fchomo/node.js:1300 #: htdocs/luci-static/resources/view/fchomo/server.js:171 msgid "General fields" msgstr "" @@ -1026,14 +1028,16 @@ msgstr "" msgid "General settings" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:494 #: htdocs/luci-static/resources/fchomo.js:496 -#: htdocs/luci-static/resources/fchomo.js:510 +#: htdocs/luci-static/resources/fchomo.js:498 #: htdocs/luci-static/resources/fchomo.js:512 +#: htdocs/luci-static/resources/fchomo.js:514 #: htdocs/luci-static/resources/view/fchomo/global.js:593 #: htdocs/luci-static/resources/view/fchomo/server.js:343 -#: htdocs/luci-static/resources/view/fchomo/server.js:703 -#: htdocs/luci-static/resources/view/fchomo/server.js:866 +#: htdocs/luci-static/resources/view/fchomo/server.js:384 +#: htdocs/luci-static/resources/view/fchomo/server.js:386 +#: htdocs/luci-static/resources/view/fchomo/server.js:715 +#: htdocs/luci-static/resources/view/fchomo/server.js:878 msgid "Generate" msgstr "" @@ -1080,7 +1084,7 @@ msgstr "" msgid "Global client fingerprint" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:596 +#: htdocs/luci-static/resources/view/fchomo/node.js:597 msgid "Global padding" msgstr "" @@ -1102,24 +1106,24 @@ msgstr "" #: htdocs/luci-static/resources/fchomo.js:126 #: htdocs/luci-static/resources/fchomo.js:158 -#: htdocs/luci-static/resources/view/fchomo/node.js:693 -#: htdocs/luci-static/resources/view/fchomo/node.js:990 -#: htdocs/luci-static/resources/view/fchomo/node.js:1001 -#: htdocs/luci-static/resources/view/fchomo/server.js:941 +#: htdocs/luci-static/resources/view/fchomo/node.js:694 +#: htdocs/luci-static/resources/view/fchomo/node.js:991 +#: htdocs/luci-static/resources/view/fchomo/node.js:1002 +#: htdocs/luci-static/resources/view/fchomo/server.js:953 msgid "HTTP" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:267 -#: htdocs/luci-static/resources/view/fchomo/node.js:1049 -#: htdocs/luci-static/resources/view/fchomo/node.js:1399 +#: htdocs/luci-static/resources/view/fchomo/node.js:1050 +#: htdocs/luci-static/resources/view/fchomo/node.js:1400 msgid "HTTP header" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:419 +#: htdocs/luci-static/resources/view/fchomo/node.js:420 msgid "HTTP mask" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1026 +#: htdocs/luci-static/resources/view/fchomo/node.js:1027 msgid "HTTP request method" msgstr "" @@ -1133,9 +1137,9 @@ msgid "" "returned if empty." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:991 -#: htdocs/luci-static/resources/view/fchomo/node.js:1002 -#: htdocs/luci-static/resources/view/fchomo/server.js:942 +#: htdocs/luci-static/resources/view/fchomo/node.js:992 +#: htdocs/luci-static/resources/view/fchomo/node.js:1003 +#: htdocs/luci-static/resources/view/fchomo/server.js:954 msgid "HTTPUpgrade" msgstr "" @@ -1147,40 +1151,40 @@ msgstr "" msgid "Handshake mode" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:503 +#: htdocs/luci-static/resources/view/fchomo/server.js:515 msgid "Handshake target that supports TLS 1.3" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:396 +#: htdocs/luci-static/resources/view/fchomo/server.js:408 msgid "Handshake timeout" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:979 -#: htdocs/luci-static/resources/view/fchomo/node.js:1510 +#: htdocs/luci-static/resources/view/fchomo/node.js:1511 msgid "Health check URL" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1008 -#: htdocs/luci-static/resources/view/fchomo/node.js:1540 +#: htdocs/luci-static/resources/view/fchomo/node.js:1541 msgid "Health check expected status" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:988 -#: htdocs/luci-static/resources/view/fchomo/node.js:1520 +#: htdocs/luci-static/resources/view/fchomo/node.js:1521 msgid "Health check interval" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:995 -#: htdocs/luci-static/resources/view/fchomo/node.js:1527 +#: htdocs/luci-static/resources/view/fchomo/node.js:1528 msgid "Health check timeout" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:899 -#: htdocs/luci-static/resources/view/fchomo/node.js:1301 +#: htdocs/luci-static/resources/view/fchomo/node.js:1302 msgid "Health fields" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:501 +#: htdocs/luci-static/resources/view/fchomo/node.js:502 msgid "Heartbeat interval" msgstr "" @@ -1188,7 +1192,7 @@ msgstr "" msgid "Hidden" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:699 +#: htdocs/luci-static/resources/view/fchomo/node.js:700 msgid "Host that supports TLS 1.3" msgstr "" @@ -1219,12 +1223,12 @@ msgstr "" msgid "IP CIDR" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:454 +#: htdocs/luci-static/resources/view/fchomo/node.js:455 msgid "IP override" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1180 -#: htdocs/luci-static/resources/view/fchomo/node.js:1496 +#: htdocs/luci-static/resources/view/fchomo/node.js:1181 +#: htdocs/luci-static/resources/view/fchomo/node.js:1497 msgid "IP version" msgstr "" @@ -1245,19 +1249,19 @@ msgstr "" msgid "Icon" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:545 +#: htdocs/luci-static/resources/view/fchomo/node.js:546 msgid "Idle session check interval" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:552 +#: htdocs/luci-static/resources/view/fchomo/node.js:553 msgid "Idle session timeout" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:431 +#: htdocs/luci-static/resources/view/fchomo/server.js:443 msgid "Idle timeout" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1304 +#: htdocs/luci-static/resources/fchomo.js:1334 msgid "If All ports is selected, uncheck others" msgstr "" @@ -1269,7 +1273,7 @@ msgstr "" msgid "Ignore client bandwidth" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:679 +#: htdocs/luci-static/resources/fchomo.js:681 msgid "Import" msgstr "" @@ -1283,8 +1287,8 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1355 #: htdocs/luci-static/resources/view/fchomo/client.js:1552 #: htdocs/luci-static/resources/view/fchomo/client.js:1573 -#: htdocs/luci-static/resources/view/fchomo/node.js:1205 -#: htdocs/luci-static/resources/view/fchomo/node.js:1287 +#: htdocs/luci-static/resources/view/fchomo/node.js:1206 +#: htdocs/luci-static/resources/view/fchomo/node.js:1288 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:142 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:226 msgid "Import mihomo config" @@ -1298,33 +1302,33 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:280 #: htdocs/luci-static/resources/view/fchomo/node.js:286 -#: htdocs/luci-static/resources/view/fchomo/node.js:1457 -#: htdocs/luci-static/resources/view/fchomo/node.js:1463 +#: htdocs/luci-static/resources/view/fchomo/node.js:1458 +#: htdocs/luci-static/resources/view/fchomo/node.js:1464 #: htdocs/luci-static/resources/view/fchomo/server.js:231 #: htdocs/luci-static/resources/view/fchomo/server.js:237 msgid "In Mbps." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1377 +#: htdocs/luci-static/resources/view/fchomo/node.js:1378 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:362 msgid "In bytes. %s will be used if empty." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:502 -#: htdocs/luci-static/resources/view/fchomo/node.js:509 +#: htdocs/luci-static/resources/view/fchomo/node.js:503 +#: htdocs/luci-static/resources/view/fchomo/node.js:510 msgid "In millisecond." msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:996 #: htdocs/luci-static/resources/view/fchomo/client.js:1025 -#: htdocs/luci-static/resources/view/fchomo/node.js:1528 +#: htdocs/luci-static/resources/view/fchomo/node.js:1529 msgid "In millisecond. %s will be used if empty." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:546 -#: htdocs/luci-static/resources/view/fchomo/node.js:553 -#: htdocs/luci-static/resources/view/fchomo/server.js:432 -#: htdocs/luci-static/resources/view/fchomo/server.js:439 +#: htdocs/luci-static/resources/view/fchomo/node.js:547 +#: htdocs/luci-static/resources/view/fchomo/node.js:554 +#: htdocs/luci-static/resources/view/fchomo/server.js:444 +#: htdocs/luci-static/resources/view/fchomo/server.js:451 msgid "In seconds." msgstr "" @@ -1332,14 +1336,14 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:425 #: htdocs/luci-static/resources/view/fchomo/global.js:430 #: htdocs/luci-static/resources/view/fchomo/global.js:515 -#: htdocs/luci-static/resources/view/fchomo/node.js:1383 -#: htdocs/luci-static/resources/view/fchomo/node.js:1521 +#: htdocs/luci-static/resources/view/fchomo/node.js:1384 +#: htdocs/luci-static/resources/view/fchomo/node.js:1522 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:368 msgid "In seconds. %s will be used if empty." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:800 -#: htdocs/luci-static/resources/view/fchomo/server.js:619 +#: htdocs/luci-static/resources/view/fchomo/node.js:801 +#: htdocs/luci-static/resources/view/fchomo/server.js:631 msgid "" "In the order of one Padding-Length and one Padding-" "Interval, infinite concatenation." @@ -1377,7 +1381,7 @@ msgstr "" msgid "Info" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1316 +#: htdocs/luci-static/resources/view/fchomo/node.js:1317 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:264 msgid "Inline" msgstr "" @@ -1395,12 +1399,12 @@ msgstr "" msgid "Key" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:925 -#: htdocs/luci-static/resources/view/fchomo/server.js:793 +#: htdocs/luci-static/resources/view/fchomo/node.js:926 +#: htdocs/luci-static/resources/view/fchomo/server.js:805 msgid "Key path" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:638 +#: htdocs/luci-static/resources/view/fchomo/server.js:650 msgid "Keypairs" msgstr "" @@ -1410,19 +1414,19 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1361 #: htdocs/luci-static/resources/view/fchomo/client.js:1579 #: htdocs/luci-static/resources/view/fchomo/node.js:229 -#: htdocs/luci-static/resources/view/fchomo/node.js:1304 -#: htdocs/luci-static/resources/view/fchomo/node.js:1589 +#: htdocs/luci-static/resources/view/fchomo/node.js:1305 +#: htdocs/luci-static/resources/view/fchomo/node.js:1590 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:244 #: htdocs/luci-static/resources/view/fchomo/server.js:179 msgid "Label" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1002 -#: htdocs/luci-static/resources/view/fchomo/node.js:1534 +#: htdocs/luci-static/resources/view/fchomo/node.js:1535 msgid "Lazy" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:489 +#: htdocs/luci-static/resources/view/fchomo/server.js:501 msgid "" "Legacy protocol support (VMess MD5 Authentication) is provided for " "compatibility purposes only, use of alterId > 1 is not recommended." @@ -1432,8 +1436,8 @@ msgstr "" msgid "Less compatibility and sometimes better performance." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:852 -#: htdocs/luci-static/resources/view/fchomo/server.js:774 +#: htdocs/luci-static/resources/view/fchomo/node.js:853 +#: htdocs/luci-static/resources/view/fchomo/server.js:786 msgid "List of supported application level protocols, in order of preference." msgstr "" @@ -1462,16 +1466,16 @@ msgstr "" msgid "Load balance" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1314 +#: htdocs/luci-static/resources/view/fchomo/node.js:1315 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:262 msgid "Local" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:623 +#: htdocs/luci-static/resources/view/fchomo/node.js:624 msgid "Local IPv6 address" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:616 +#: htdocs/luci-static/resources/view/fchomo/node.js:617 msgid "Local address" msgstr "" @@ -1491,12 +1495,12 @@ msgstr "" msgid "Log level" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:393 +#: htdocs/luci-static/resources/fchomo.js:395 msgid "Lowercase only" msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:502 -#: htdocs/luci-static/resources/view/fchomo/node.js:663 +#: htdocs/luci-static/resources/view/fchomo/node.js:664 msgid "MTU" msgstr "" @@ -1532,12 +1536,12 @@ msgstr "" msgid "Match rule set." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1059 +#: htdocs/luci-static/resources/view/fchomo/node.js:1060 msgid "Max Early Data" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:488 -#: htdocs/luci-static/resources/view/fchomo/server.js:425 +#: htdocs/luci-static/resources/view/fchomo/node.js:489 +#: htdocs/luci-static/resources/view/fchomo/server.js:437 msgid "Max UDP relay packet size" msgstr "" @@ -1550,7 +1554,7 @@ msgstr "" msgid "Max download speed" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:515 +#: htdocs/luci-static/resources/view/fchomo/node.js:516 msgid "Max open streams" msgstr "" @@ -1559,23 +1563,23 @@ msgstr "" msgid "Max upload speed" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1096 -#: htdocs/luci-static/resources/view/fchomo/node.js:1112 +#: htdocs/luci-static/resources/view/fchomo/node.js:1097 +#: htdocs/luci-static/resources/view/fchomo/node.js:1113 msgid "Maximum connections" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1110 +#: htdocs/luci-static/resources/view/fchomo/node.js:1111 msgid "" "Maximum multiplexed streams in a connection before opening a new connection." "
Conflict with %s and %s." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:412 -#: htdocs/luci-static/resources/view/fchomo/server.js:389 +#: htdocs/luci-static/resources/view/fchomo/node.js:413 +#: htdocs/luci-static/resources/view/fchomo/server.js:401 msgid "Maximum padding" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1109 +#: htdocs/luci-static/resources/view/fchomo/node.js:1110 msgid "Maximum streams" msgstr "" @@ -1596,22 +1600,22 @@ msgstr "" msgid "Mihomo server" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:559 +#: htdocs/luci-static/resources/view/fchomo/node.js:560 msgid "Min of idle sessions to keep" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1103 +#: htdocs/luci-static/resources/view/fchomo/node.js:1104 msgid "" "Minimum multiplexed streams in a connection before opening a new connection." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:405 -#: htdocs/luci-static/resources/view/fchomo/server.js:382 +#: htdocs/luci-static/resources/view/fchomo/node.js:406 +#: htdocs/luci-static/resources/view/fchomo/server.js:394 msgid "Minimum padding" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1102 -#: htdocs/luci-static/resources/view/fchomo/node.js:1112 +#: htdocs/luci-static/resources/view/fchomo/node.js:1103 +#: htdocs/luci-static/resources/view/fchomo/node.js:1113 msgid "Minimum streams" msgstr "" @@ -1628,7 +1632,7 @@ msgstr "" msgid "Mixed port" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1082 +#: htdocs/luci-static/resources/view/fchomo/node.js:1083 msgid "Multiplex" msgstr "" @@ -1646,7 +1650,7 @@ msgstr "" msgid "NOT" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1389 +#: htdocs/luci-static/resources/view/fchomo/node.js:1390 msgid "Name of the Proxy group to download provider." msgstr "" @@ -1654,7 +1658,7 @@ msgstr "" msgid "Name of the Proxy group to download rule set." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:472 +#: htdocs/luci-static/resources/view/fchomo/node.js:473 msgid "Native UDP" msgstr "" @@ -1671,11 +1675,11 @@ msgid "No add'l params" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1003 -#: htdocs/luci-static/resources/view/fchomo/node.js:1535 +#: htdocs/luci-static/resources/view/fchomo/node.js:1536 msgid "No testing is performed when this provider node is not in use." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:640 +#: htdocs/luci-static/resources/fchomo.js:642 msgid "No valid %s found." msgstr "" @@ -1690,17 +1694,17 @@ msgid "Node" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1048 -#: htdocs/luci-static/resources/view/fchomo/node.js:1555 +#: htdocs/luci-static/resources/view/fchomo/node.js:1556 msgid "Node exclude filter" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1053 -#: htdocs/luci-static/resources/view/fchomo/node.js:1562 +#: htdocs/luci-static/resources/view/fchomo/node.js:1563 msgid "Node exclude type" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1043 -#: htdocs/luci-static/resources/view/fchomo/node.js:1549 +#: htdocs/luci-static/resources/view/fchomo/node.js:1550 msgid "Node filter" msgstr "" @@ -1716,11 +1720,11 @@ msgstr "" msgid "Not Installed" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1088 +#: htdocs/luci-static/resources/fchomo.js:1112 msgid "Not Running" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:692 +#: htdocs/luci-static/resources/view/fchomo/node.js:693 msgid "Obfs Mode" msgstr "" @@ -1754,7 +1758,7 @@ msgstr "" msgid "Only process traffic from specific interfaces. Leave empty for all." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1082 +#: htdocs/luci-static/resources/fchomo.js:1106 msgid "Open Dashboard" msgstr "" @@ -1768,11 +1772,11 @@ msgid "Override destination" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:898 -#: htdocs/luci-static/resources/view/fchomo/node.js:1300 +#: htdocs/luci-static/resources/view/fchomo/node.js:1301 msgid "Override fields" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:455 +#: htdocs/luci-static/resources/view/fchomo/node.js:456 msgid "Override the IP address of the server that DNS response." msgstr "" @@ -1792,43 +1796,43 @@ msgstr "" msgid "Overview" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1028 +#: htdocs/luci-static/resources/view/fchomo/node.js:1029 msgid "POST" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1029 +#: htdocs/luci-static/resources/view/fchomo/node.js:1030 msgid "PUT" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:608 +#: htdocs/luci-static/resources/view/fchomo/node.js:609 msgid "Packet encoding" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:469 +#: htdocs/luci-static/resources/view/fchomo/server.js:481 msgid "Padding scheme" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:798 -#: htdocs/luci-static/resources/view/fchomo/server.js:617 +#: htdocs/luci-static/resources/view/fchomo/node.js:799 +#: htdocs/luci-static/resources/view/fchomo/server.js:629 msgid "Paddings" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:261 #: htdocs/luci-static/resources/view/fchomo/node.js:334 -#: htdocs/luci-static/resources/view/fchomo/node.js:707 +#: htdocs/luci-static/resources/view/fchomo/node.js:708 #: htdocs/luci-static/resources/view/fchomo/server.js:221 #: htdocs/luci-static/resources/view/fchomo/server.js:277 -#: htdocs/luci-static/resources/view/fchomo/server.js:510 +#: htdocs/luci-static/resources/view/fchomo/server.js:522 msgid "Password" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1364 +#: htdocs/luci-static/resources/view/fchomo/node.js:1365 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:349 -#: htdocs/luci-static/resources/view/fchomo/server.js:557 +#: htdocs/luci-static/resources/view/fchomo/server.js:569 msgid "Payload" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:637 +#: htdocs/luci-static/resources/view/fchomo/node.js:638 msgid "Peer pubkic key" msgstr "" @@ -1855,8 +1859,8 @@ msgid "" "standards." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1337 -#: htdocs/luci-static/resources/view/fchomo/node.js:1363 +#: htdocs/luci-static/resources/view/fchomo/node.js:1338 +#: htdocs/luci-static/resources/view/fchomo/node.js:1364 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:322 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:348 msgid "" @@ -1869,25 +1873,25 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1195 #: htdocs/luci-static/resources/view/fchomo/client.js:1320 #: htdocs/luci-static/resources/view/fchomo/client.js:1553 -#: htdocs/luci-static/resources/view/fchomo/node.js:1206 +#: htdocs/luci-static/resources/view/fchomo/node.js:1207 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:143 msgid "Please type %s fields of mihomo config.
" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:681 -#: htdocs/luci-static/resources/view/fchomo/server.js:496 +#: htdocs/luci-static/resources/view/fchomo/node.js:682 +#: htdocs/luci-static/resources/view/fchomo/server.js:508 msgid "Plugin" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:692 -#: htdocs/luci-static/resources/view/fchomo/node.js:699 -#: htdocs/luci-static/resources/view/fchomo/node.js:707 -#: htdocs/luci-static/resources/view/fchomo/node.js:713 -#: htdocs/luci-static/resources/view/fchomo/node.js:721 -#: htdocs/luci-static/resources/view/fchomo/node.js:727 -#: htdocs/luci-static/resources/view/fchomo/server.js:503 -#: htdocs/luci-static/resources/view/fchomo/server.js:510 -#: htdocs/luci-static/resources/view/fchomo/server.js:516 +#: htdocs/luci-static/resources/view/fchomo/node.js:693 +#: htdocs/luci-static/resources/view/fchomo/node.js:700 +#: htdocs/luci-static/resources/view/fchomo/node.js:708 +#: htdocs/luci-static/resources/view/fchomo/node.js:714 +#: htdocs/luci-static/resources/view/fchomo/node.js:722 +#: htdocs/luci-static/resources/view/fchomo/node.js:728 +#: htdocs/luci-static/resources/view/fchomo/server.js:515 +#: htdocs/luci-static/resources/view/fchomo/server.js:522 +#: htdocs/luci-static/resources/view/fchomo/server.js:528 msgid "Plugin:" msgstr "" @@ -1895,7 +1899,7 @@ msgstr "" msgid "Port" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1313 +#: htdocs/luci-static/resources/fchomo.js:1343 msgid "Port %s alrealy exists!" msgstr "" @@ -1912,8 +1916,8 @@ msgstr "" msgid "Ports pool" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:432 -#: htdocs/luci-static/resources/view/fchomo/node.js:644 +#: htdocs/luci-static/resources/view/fchomo/node.js:433 +#: htdocs/luci-static/resources/view/fchomo/node.js:645 msgid "Pre-shared key" msgstr "" @@ -1932,10 +1936,10 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:742 #: htdocs/luci-static/resources/view/fchomo/global.js:759 -#: htdocs/luci-static/resources/view/fchomo/node.js:1170 -#: htdocs/luci-static/resources/view/fchomo/node.js:1176 -#: htdocs/luci-static/resources/view/fchomo/node.js:1484 -#: htdocs/luci-static/resources/view/fchomo/node.js:1491 +#: htdocs/luci-static/resources/view/fchomo/node.js:1171 +#: htdocs/luci-static/resources/view/fchomo/node.js:1177 +#: htdocs/luci-static/resources/view/fchomo/node.js:1485 +#: htdocs/luci-static/resources/view/fchomo/node.js:1492 msgid "Priority: Proxy Node > Global." msgstr "" @@ -1947,7 +1951,7 @@ msgstr "" msgid "Priv-key passphrase" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:629 +#: htdocs/luci-static/resources/view/fchomo/node.js:630 msgid "Private key" msgstr "" @@ -1956,28 +1960,28 @@ msgid "Process matching mode" msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:690 -#: htdocs/luci-static/resources/view/fchomo/node.js:1088 +#: htdocs/luci-static/resources/view/fchomo/node.js:1089 msgid "Protocol" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:603 +#: htdocs/luci-static/resources/view/fchomo/node.js:604 msgid "Protocol parameter. Enable length block encryption." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:597 +#: htdocs/luci-static/resources/view/fchomo/node.js:598 msgid "" "Protocol parameter. Will waste traffic randomly if enabled (enabled by " "default in v2ray and cannot be disabled)." msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:943 -#: htdocs/luci-static/resources/view/fchomo/node.js:1189 -#: htdocs/luci-static/resources/view/fchomo/node.js:1198 -#: htdocs/luci-static/resources/view/fchomo/node.js:1600 +#: htdocs/luci-static/resources/view/fchomo/node.js:1190 +#: htdocs/luci-static/resources/view/fchomo/node.js:1199 +#: htdocs/luci-static/resources/view/fchomo/node.js:1601 msgid "Provider" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1370 +#: htdocs/luci-static/resources/view/fchomo/node.js:1371 msgid "Provider URL" msgstr "" @@ -2000,18 +2004,18 @@ msgid "Proxy MAC-s" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:208 -#: htdocs/luci-static/resources/view/fchomo/node.js:1599 +#: htdocs/luci-static/resources/view/fchomo/node.js:1600 msgid "Proxy Node" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1575 -#: htdocs/luci-static/resources/view/fchomo/node.js:1584 +#: htdocs/luci-static/resources/view/fchomo/node.js:1576 +#: htdocs/luci-static/resources/view/fchomo/node.js:1585 msgid "Proxy chain" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:723 #: htdocs/luci-static/resources/view/fchomo/client.js:1416 -#: htdocs/luci-static/resources/view/fchomo/node.js:1388 +#: htdocs/luci-static/resources/view/fchomo/node.js:1389 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:373 msgid "Proxy group" msgstr "" @@ -2028,12 +2032,12 @@ msgstr "" msgid "Proxy routerself" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:473 +#: htdocs/luci-static/resources/view/fchomo/node.js:474 msgid "QUIC" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:461 -#: htdocs/luci-static/resources/view/fchomo/server.js:417 +#: htdocs/luci-static/resources/view/fchomo/node.js:462 +#: htdocs/luci-static/resources/view/fchomo/server.js:429 msgid "QUIC congestion controller." msgstr "" @@ -2042,40 +2046,40 @@ msgstr "" msgid "Quick Reload" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:961 -#: htdocs/luci-static/resources/view/fchomo/server.js:881 +#: htdocs/luci-static/resources/view/fchomo/node.js:962 +#: htdocs/luci-static/resources/view/fchomo/server.js:893 msgid "REALITY" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:976 +#: htdocs/luci-static/resources/view/fchomo/node.js:977 msgid "REALITY X25519MLKEM768 PQC support" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:918 +#: htdocs/luci-static/resources/view/fchomo/server.js:930 msgid "REALITY certificate issued to" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:886 +#: htdocs/luci-static/resources/view/fchomo/server.js:898 msgid "REALITY handshake server" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:893 +#: htdocs/luci-static/resources/view/fchomo/server.js:905 msgid "REALITY private key" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:966 -#: htdocs/luci-static/resources/view/fchomo/server.js:908 +#: htdocs/luci-static/resources/view/fchomo/node.js:967 +#: htdocs/luci-static/resources/view/fchomo/server.js:920 msgid "REALITY public key" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:971 -#: htdocs/luci-static/resources/view/fchomo/server.js:912 +#: htdocs/luci-static/resources/view/fchomo/node.js:972 +#: htdocs/luci-static/resources/view/fchomo/server.js:924 msgid "REALITY short ID" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:788 -#: htdocs/luci-static/resources/view/fchomo/server.js:588 -#: htdocs/luci-static/resources/view/fchomo/server.js:607 +#: htdocs/luci-static/resources/view/fchomo/node.js:789 +#: htdocs/luci-static/resources/view/fchomo/server.js:600 +#: htdocs/luci-static/resources/view/fchomo/server.js:619 msgid "RTT" msgstr "" @@ -2111,7 +2115,7 @@ msgstr "" msgid "Refresh every %s seconds." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1075 +#: htdocs/luci-static/resources/fchomo.js:1099 #: htdocs/luci-static/resources/view/fchomo/client.js:815 #: htdocs/luci-static/resources/view/fchomo/global.js:193 #: htdocs/luci-static/resources/view/fchomo/server.js:153 @@ -2122,32 +2126,32 @@ msgstr "" msgid "Reload All" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1315 +#: htdocs/luci-static/resources/view/fchomo/node.js:1316 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:263 msgid "Remote" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:669 +#: htdocs/luci-static/resources/view/fchomo/node.js:670 msgid "Remote DNS resolve" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1234 +#: htdocs/luci-static/resources/fchomo.js:1264 msgid "Remove" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1239 -#: htdocs/luci-static/resources/view/fchomo/node.js:1291 -#: htdocs/luci-static/resources/view/fchomo/node.js:1293 +#: htdocs/luci-static/resources/fchomo.js:1269 +#: htdocs/luci-static/resources/view/fchomo/node.js:1292 +#: htdocs/luci-static/resources/view/fchomo/node.js:1294 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:236 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:238 msgid "Remove idles" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1417 +#: htdocs/luci-static/resources/view/fchomo/node.js:1418 msgid "Replace name" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1418 +#: htdocs/luci-static/resources/view/fchomo/node.js:1419 msgid "Replace node name." msgstr "" @@ -2155,13 +2159,13 @@ msgstr "" msgid "Request" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1035 -#: htdocs/luci-static/resources/view/fchomo/node.js:1042 -#: htdocs/luci-static/resources/view/fchomo/server.js:960 +#: htdocs/luci-static/resources/view/fchomo/node.js:1036 +#: htdocs/luci-static/resources/view/fchomo/node.js:1043 +#: htdocs/luci-static/resources/view/fchomo/server.js:972 msgid "Request path" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:508 +#: htdocs/luci-static/resources/view/fchomo/node.js:509 msgid "Request timeout" msgstr "" @@ -2174,11 +2178,11 @@ msgid "Require any" msgstr "" #: htdocs/luci-static/resources/fchomo.js:347 -#: htdocs/luci-static/resources/view/fchomo/node.js:977 +#: htdocs/luci-static/resources/view/fchomo/node.js:978 msgid "Requires server support." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:658 +#: htdocs/luci-static/resources/view/fchomo/node.js:659 msgid "Reserved field bytes" msgstr "" @@ -2186,7 +2190,7 @@ msgstr "" msgid "Resources management" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:727 +#: htdocs/luci-static/resources/view/fchomo/node.js:728 msgid "Restls script" msgstr "" @@ -2213,8 +2217,8 @@ msgstr "" msgid "Routing GFW" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1175 -#: htdocs/luci-static/resources/view/fchomo/node.js:1490 +#: htdocs/luci-static/resources/view/fchomo/node.js:1176 +#: htdocs/luci-static/resources/view/fchomo/node.js:1491 msgid "Routing mark" msgstr "" @@ -2274,7 +2278,7 @@ msgstr "" msgid "Ruleset-URI-Scheme" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1088 +#: htdocs/luci-static/resources/fchomo.js:1112 msgid "Running" msgstr "" @@ -2302,7 +2306,7 @@ msgstr "" msgid "SUB-RULE" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:745 +#: htdocs/luci-static/resources/view/fchomo/node.js:746 msgid "SUoT version" msgstr "" @@ -2341,9 +2345,9 @@ msgid "Send random ticket of 300s-600s duration for client 0-RTT reuse." msgstr "" #: htdocs/luci-static/resources/view/fchomo/server.js:166 -#: htdocs/luci-static/resources/view/fchomo/server.js:588 -#: htdocs/luci-static/resources/view/fchomo/server.js:779 -#: htdocs/luci-static/resources/view/fchomo/server.js:794 +#: htdocs/luci-static/resources/view/fchomo/server.js:600 +#: htdocs/luci-static/resources/view/fchomo/server.js:791 +#: htdocs/luci-static/resources/view/fchomo/server.js:806 #: root/usr/share/luci/menu.d/luci-app-fchomo.json:54 msgid "Server" msgstr "" @@ -2352,7 +2356,7 @@ msgstr "" msgid "Server address" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1020 +#: htdocs/luci-static/resources/view/fchomo/node.js:1021 msgid "Server hostname" msgstr "" @@ -2369,22 +2373,22 @@ msgstr "" msgid "Shadowsocks" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:527 -#: htdocs/luci-static/resources/view/fchomo/server.js:451 +#: htdocs/luci-static/resources/view/fchomo/node.js:528 +#: htdocs/luci-static/resources/view/fchomo/server.js:463 msgid "Shadowsocks chipher" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:522 -#: htdocs/luci-static/resources/view/fchomo/server.js:446 +#: htdocs/luci-static/resources/view/fchomo/node.js:523 +#: htdocs/luci-static/resources/view/fchomo/server.js:458 msgid "Shadowsocks encrypt" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:535 -#: htdocs/luci-static/resources/view/fchomo/server.js:459 +#: htdocs/luci-static/resources/view/fchomo/node.js:536 +#: htdocs/luci-static/resources/view/fchomo/server.js:471 msgid "Shadowsocks password" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1130 +#: htdocs/luci-static/resources/view/fchomo/node.js:1131 msgid "Show connections in the dashboard for breaking connections easier." msgstr "" @@ -2396,14 +2400,14 @@ msgstr "" msgid "Simple round-robin all nodes" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1376 +#: htdocs/luci-static/resources/view/fchomo/node.js:1377 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:361 msgid "Size limit" msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1449 -#: htdocs/luci-static/resources/view/fchomo/node.js:903 -#: htdocs/luci-static/resources/view/fchomo/node.js:1468 +#: htdocs/luci-static/resources/view/fchomo/node.js:904 +#: htdocs/luci-static/resources/view/fchomo/node.js:1469 msgid "Skip cert verify" msgstr "" @@ -2435,6 +2439,10 @@ msgstr "" msgid "Sniffer settings" msgstr "" +#: htdocs/luci-static/resources/fchomo.js:385 +msgid "Specify a ID" +msgstr "" + #: htdocs/luci-static/resources/view/fchomo/global.js:823 #: htdocs/luci-static/resources/view/fchomo/global.js:832 msgid "" @@ -2468,7 +2476,7 @@ msgstr "" msgid "Sub rule group" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:643 +#: htdocs/luci-static/resources/fchomo.js:645 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:207 msgid "Successfully imported %s %s of total %s." msgstr "" @@ -2477,7 +2485,7 @@ msgstr "" msgid "Successfully updated." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1568 +#: htdocs/luci-static/resources/fchomo.js:1614 msgid "Successfully uploaded." msgstr "" @@ -2523,7 +2531,7 @@ msgstr "" msgid "TCP concurrency" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1123 +#: htdocs/luci-static/resources/view/fchomo/node.js:1124 msgid "TCP only" msgstr "" @@ -2546,24 +2554,24 @@ msgstr "" msgid "TCP/UDP" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1154 -#: htdocs/luci-static/resources/view/fchomo/node.js:1435 +#: htdocs/luci-static/resources/view/fchomo/node.js:1155 +#: htdocs/luci-static/resources/view/fchomo/node.js:1436 msgid "TFO" msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:529 -#: htdocs/luci-static/resources/view/fchomo/node.js:694 -#: htdocs/luci-static/resources/view/fchomo/node.js:820 -#: htdocs/luci-static/resources/view/fchomo/server.js:742 +#: htdocs/luci-static/resources/view/fchomo/node.js:695 +#: htdocs/luci-static/resources/view/fchomo/node.js:821 +#: htdocs/luci-static/resources/view/fchomo/server.js:754 msgid "TLS" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:851 -#: htdocs/luci-static/resources/view/fchomo/server.js:773 +#: htdocs/luci-static/resources/view/fchomo/node.js:852 +#: htdocs/luci-static/resources/view/fchomo/server.js:785 msgid "TLS ALPN" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:845 +#: htdocs/luci-static/resources/view/fchomo/node.js:846 msgid "TLS SNI" msgstr "" @@ -2586,24 +2594,24 @@ msgid "" "Tell the client to use the BBR flow control algorithm instead of Hysteria CC." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:617 -#: htdocs/luci-static/resources/view/fchomo/node.js:624 +#: htdocs/luci-static/resources/view/fchomo/node.js:618 +#: htdocs/luci-static/resources/view/fchomo/node.js:625 msgid "The %s address used by local machine in the Wireguard network." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:926 -#: htdocs/luci-static/resources/view/fchomo/server.js:794 +#: htdocs/luci-static/resources/view/fchomo/node.js:927 +#: htdocs/luci-static/resources/view/fchomo/server.js:806 msgid "The %s private key, in PEM format." msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:556 -#: htdocs/luci-static/resources/view/fchomo/node.js:912 -#: htdocs/luci-static/resources/view/fchomo/server.js:779 -#: htdocs/luci-static/resources/view/fchomo/server.js:817 +#: htdocs/luci-static/resources/view/fchomo/node.js:913 +#: htdocs/luci-static/resources/view/fchomo/server.js:791 +#: htdocs/luci-static/resources/view/fchomo/server.js:829 msgid "The %s public key, in PEM format." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:946 +#: htdocs/luci-static/resources/view/fchomo/node.js:947 msgid "" "The ECH parameter of the HTTPS record for the domain. Leave empty to resolve " "via DNS." @@ -2621,8 +2629,8 @@ msgstr "" msgid "The default value is 2:00 every day." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:801 -#: htdocs/luci-static/resources/view/fchomo/server.js:620 +#: htdocs/luci-static/resources/view/fchomo/node.js:802 +#: htdocs/luci-static/resources/view/fchomo/server.js:632 msgid "" "The first padding must have a probability of 100% and at least 35 bytes." msgstr "" @@ -2637,25 +2645,25 @@ msgstr "" msgid "The matching %s will be deemed as poisoned." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:799 -#: htdocs/luci-static/resources/view/fchomo/server.js:618 +#: htdocs/luci-static/resources/view/fchomo/node.js:800 +#: htdocs/luci-static/resources/view/fchomo/server.js:630 msgid "The server and client can set different padding parameters." msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:600 -#: htdocs/luci-static/resources/view/fchomo/server.js:875 +#: htdocs/luci-static/resources/view/fchomo/server.js:887 msgid "This ECH parameter needs to be added to the HTTPS record of the domain." msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1452 -#: htdocs/luci-static/resources/view/fchomo/node.js:906 -#: htdocs/luci-static/resources/view/fchomo/node.js:1471 +#: htdocs/luci-static/resources/view/fchomo/node.js:907 +#: htdocs/luci-static/resources/view/fchomo/node.js:1472 msgid "" "This is DANGEROUS, your traffic is almost like " "PLAIN TEXT! Use at your own risk!" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:478 +#: htdocs/luci-static/resources/view/fchomo/node.js:479 msgid "" "This is the TUIC port of the SUoT protocol, designed to provide a QUIC " "stream based UDP relay mode that TUIC does not provide." @@ -2684,18 +2692,18 @@ msgstr "" msgid "Tproxy port" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1627 +#: htdocs/luci-static/resources/view/fchomo/node.js:1628 msgid "Transit proxy group" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1633 +#: htdocs/luci-static/resources/view/fchomo/node.js:1634 msgid "Transit proxy node" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:349 -#: htdocs/luci-static/resources/view/fchomo/node.js:983 +#: htdocs/luci-static/resources/view/fchomo/node.js:984 #: htdocs/luci-static/resources/view/fchomo/server.js:287 -#: htdocs/luci-static/resources/view/fchomo/server.js:926 +#: htdocs/luci-static/resources/view/fchomo/server.js:938 msgid "Transport" msgstr "" @@ -2704,8 +2712,8 @@ msgstr "" msgid "Transport fields" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:988 -#: htdocs/luci-static/resources/view/fchomo/server.js:931 +#: htdocs/luci-static/resources/view/fchomo/node.js:989 +#: htdocs/luci-static/resources/view/fchomo/server.js:943 msgid "Transport type" msgstr "" @@ -2740,8 +2748,8 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:916 #: htdocs/luci-static/resources/view/fchomo/client.js:1594 #: htdocs/luci-static/resources/view/fchomo/node.js:238 -#: htdocs/luci-static/resources/view/fchomo/node.js:1313 -#: htdocs/luci-static/resources/view/fchomo/node.js:1598 +#: htdocs/luci-static/resources/view/fchomo/node.js:1314 +#: htdocs/luci-static/resources/view/fchomo/node.js:1599 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:261 #: htdocs/luci-static/resources/view/fchomo/server.js:193 msgid "Type" @@ -2754,9 +2762,9 @@ msgstr "" #: htdocs/luci-static/resources/fchomo.js:172 #: htdocs/luci-static/resources/view/fchomo/client.js:526 #: htdocs/luci-static/resources/view/fchomo/client.js:616 -#: htdocs/luci-static/resources/view/fchomo/node.js:734 -#: htdocs/luci-static/resources/view/fchomo/node.js:1445 -#: htdocs/luci-static/resources/view/fchomo/server.js:525 +#: htdocs/luci-static/resources/view/fchomo/node.js:735 +#: htdocs/luci-static/resources/view/fchomo/node.js:1446 +#: htdocs/luci-static/resources/view/fchomo/server.js:537 msgid "UDP" msgstr "" @@ -2764,19 +2772,19 @@ msgstr "" msgid "UDP NAT expiration time" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:477 +#: htdocs/luci-static/resources/view/fchomo/node.js:478 msgid "UDP over stream" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:483 +#: htdocs/luci-static/resources/view/fchomo/node.js:484 msgid "UDP over stream version" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:470 +#: htdocs/luci-static/resources/view/fchomo/node.js:471 msgid "UDP packet relay mode." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:469 +#: htdocs/luci-static/resources/view/fchomo/node.js:470 msgid "UDP relay mode" msgstr "" @@ -2784,15 +2792,15 @@ msgstr "" msgid "URL test" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:448 -#: htdocs/luci-static/resources/view/fchomo/node.js:566 +#: htdocs/luci-static/resources/view/fchomo/node.js:449 +#: htdocs/luci-static/resources/view/fchomo/node.js:567 #: htdocs/luci-static/resources/view/fchomo/server.js:297 -#: htdocs/luci-static/resources/view/fchomo/server.js:410 -#: htdocs/luci-static/resources/view/fchomo/server.js:474 +#: htdocs/luci-static/resources/view/fchomo/server.js:422 +#: htdocs/luci-static/resources/view/fchomo/server.js:486 msgid "UUID" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1133 +#: htdocs/luci-static/resources/fchomo.js:1157 msgid "Unable to download unsupported type: %s" msgstr "" @@ -2817,8 +2825,8 @@ msgstr "" msgid "Unknown error: %s" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:739 -#: htdocs/luci-static/resources/view/fchomo/node.js:1450 +#: htdocs/luci-static/resources/view/fchomo/node.js:740 +#: htdocs/luci-static/resources/view/fchomo/node.js:1451 msgid "UoT" msgstr "" @@ -2826,29 +2834,29 @@ msgstr "" msgid "Update failed." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1382 +#: htdocs/luci-static/resources/view/fchomo/node.js:1383 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:367 msgid "Update interval" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:426 -#: htdocs/luci-static/resources/view/fchomo/server.js:404 +#: htdocs/luci-static/resources/view/fchomo/node.js:427 +#: htdocs/luci-static/resources/view/fchomo/server.js:416 msgid "" "Uplink keeps the Sudoku protocol, and downlink characteristics are " "consistent with uplink characteristics." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1141 +#: htdocs/luci-static/resources/view/fchomo/node.js:1142 msgid "Upload bandwidth" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1142 +#: htdocs/luci-static/resources/view/fchomo/node.js:1143 msgid "Upload bandwidth in Mbps." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:917 -#: htdocs/luci-static/resources/view/fchomo/server.js:785 -#: htdocs/luci-static/resources/view/fchomo/server.js:825 +#: htdocs/luci-static/resources/view/fchomo/node.js:918 +#: htdocs/luci-static/resources/view/fchomo/server.js:797 +#: htdocs/luci-static/resources/view/fchomo/server.js:837 msgid "Upload certificate" msgstr "" @@ -2856,17 +2864,17 @@ msgstr "" msgid "Upload initial package" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:931 -#: htdocs/luci-static/resources/view/fchomo/server.js:800 +#: htdocs/luci-static/resources/view/fchomo/node.js:932 +#: htdocs/luci-static/resources/view/fchomo/server.js:812 msgid "Upload key" msgstr "" #: htdocs/luci-static/resources/view/fchomo/global.js:306 -#: htdocs/luci-static/resources/view/fchomo/node.js:920 -#: htdocs/luci-static/resources/view/fchomo/node.js:934 -#: htdocs/luci-static/resources/view/fchomo/server.js:788 -#: htdocs/luci-static/resources/view/fchomo/server.js:803 -#: htdocs/luci-static/resources/view/fchomo/server.js:828 +#: htdocs/luci-static/resources/view/fchomo/node.js:921 +#: htdocs/luci-static/resources/view/fchomo/node.js:935 +#: htdocs/luci-static/resources/view/fchomo/server.js:800 +#: htdocs/luci-static/resources/view/fchomo/server.js:815 +#: htdocs/luci-static/resources/view/fchomo/server.js:840 msgid "Upload..." msgstr "" @@ -2890,7 +2898,7 @@ msgstr "" msgid "Used to resolve the domain of the Proxy node." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:846 +#: htdocs/luci-static/resources/view/fchomo/node.js:847 msgid "Used to verify the hostname on the returned certificates." msgstr "" @@ -2907,11 +2915,11 @@ msgstr "" msgid "Users filter mode" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1071 +#: htdocs/luci-static/resources/view/fchomo/node.js:1072 msgid "V2ray HTTPUpgrade" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1076 +#: htdocs/luci-static/resources/view/fchomo/node.js:1077 msgid "V2ray HTTPUpgrade fast open" msgstr "" @@ -2925,8 +2933,8 @@ msgstr "" msgid "VMess" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1319 -#: htdocs/luci-static/resources/view/fchomo/node.js:1604 +#: htdocs/luci-static/resources/view/fchomo/node.js:1320 +#: htdocs/luci-static/resources/view/fchomo/node.js:1605 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:304 msgid "Value" msgstr "" @@ -2935,13 +2943,13 @@ msgstr "" msgid "Verify if given" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:439 -#: htdocs/luci-static/resources/view/fchomo/node.js:713 -#: htdocs/luci-static/resources/view/fchomo/server.js:516 +#: htdocs/luci-static/resources/view/fchomo/node.js:440 +#: htdocs/luci-static/resources/view/fchomo/node.js:714 +#: htdocs/luci-static/resources/view/fchomo/server.js:528 msgid "Version" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:721 +#: htdocs/luci-static/resources/view/fchomo/node.js:722 msgid "Version hint" msgstr "" @@ -2958,17 +2966,17 @@ msgstr "" msgid "Warning" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:993 -#: htdocs/luci-static/resources/view/fchomo/node.js:1004 -#: htdocs/luci-static/resources/view/fchomo/node.js:1009 -#: htdocs/luci-static/resources/view/fchomo/server.js:933 -#: htdocs/luci-static/resources/view/fchomo/server.js:944 -#: htdocs/luci-static/resources/view/fchomo/server.js:949 +#: htdocs/luci-static/resources/view/fchomo/node.js:994 +#: htdocs/luci-static/resources/view/fchomo/node.js:1005 +#: htdocs/luci-static/resources/view/fchomo/node.js:1010 +#: htdocs/luci-static/resources/view/fchomo/server.js:945 +#: htdocs/luci-static/resources/view/fchomo/server.js:956 +#: htdocs/luci-static/resources/view/fchomo/server.js:961 msgid "WebSocket" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:425 -#: htdocs/luci-static/resources/view/fchomo/server.js:403 +#: htdocs/luci-static/resources/view/fchomo/node.js:426 +#: htdocs/luci-static/resources/view/fchomo/server.js:415 msgid "" "When disabled, downlink ciphertext is split into 6-bit segments, reusing the " "original padding pool and obfuscate type to reduce downlink overhead." @@ -2986,23 +2994,23 @@ msgstr "" msgid "WireGuard" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:638 +#: htdocs/luci-static/resources/view/fchomo/node.js:639 msgid "WireGuard peer public key." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:645 +#: htdocs/luci-static/resources/view/fchomo/node.js:646 msgid "WireGuard pre-shared key." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:630 +#: htdocs/luci-static/resources/view/fchomo/node.js:631 msgid "WireGuard requires base64-encoded private keys." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:579 +#: htdocs/luci-static/resources/view/fchomo/server.js:591 msgid "XOR mode" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:611 +#: htdocs/luci-static/resources/view/fchomo/node.js:612 msgid "Xudp (Xray-core)" msgstr "" @@ -3014,14 +3022,14 @@ msgstr "" msgid "YouTube" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1550 +#: htdocs/luci-static/resources/fchomo.js:1596 msgid "Your %s was successfully uploaded. Size: %sB." msgstr "" #: htdocs/luci-static/resources/fchomo.js:289 #: htdocs/luci-static/resources/fchomo.js:302 #: htdocs/luci-static/resources/fchomo.js:307 -#: htdocs/luci-static/resources/view/fchomo/node.js:591 +#: htdocs/luci-static/resources/view/fchomo/node.js:592 msgid "aes-128-gcm" msgstr "" @@ -3034,18 +3042,18 @@ msgstr "" msgid "aes-256-gcm" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:588 +#: htdocs/luci-static/resources/view/fchomo/node.js:589 msgid "auto" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:465 -#: htdocs/luci-static/resources/view/fchomo/server.js:421 +#: htdocs/luci-static/resources/view/fchomo/node.js:466 +#: htdocs/luci-static/resources/view/fchomo/server.js:433 msgid "bbr" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:922 -#: htdocs/luci-static/resources/view/fchomo/server.js:790 -#: htdocs/luci-static/resources/view/fchomo/server.js:830 +#: htdocs/luci-static/resources/view/fchomo/node.js:923 +#: htdocs/luci-static/resources/view/fchomo/server.js:802 +#: htdocs/luci-static/resources/view/fchomo/server.js:842 msgid "certificate" msgstr "" @@ -3055,17 +3063,17 @@ msgstr "" msgid "chacha20-ietf-poly1305" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:592 +#: htdocs/luci-static/resources/view/fchomo/node.js:593 msgid "chacha20-poly1305" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:463 -#: htdocs/luci-static/resources/view/fchomo/server.js:419 +#: htdocs/luci-static/resources/view/fchomo/node.js:464 +#: htdocs/luci-static/resources/view/fchomo/server.js:431 msgid "cubic" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:531 -#: htdocs/luci-static/resources/view/fchomo/server.js:562 +#: htdocs/luci-static/resources/view/fchomo/server.js:543 +#: htdocs/luci-static/resources/view/fchomo/server.js:574 msgid "decryption" msgstr "" @@ -3073,27 +3081,27 @@ msgstr "" msgid "dnsmasq selects upstream on its own. (may affect CDN accuracy)" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1462 +#: htdocs/luci-static/resources/view/fchomo/node.js:1463 msgid "down" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:753 -#: htdocs/luci-static/resources/view/fchomo/node.js:776 -#: htdocs/luci-static/resources/view/fchomo/server.js:566 +#: htdocs/luci-static/resources/view/fchomo/node.js:754 +#: htdocs/luci-static/resources/view/fchomo/node.js:777 +#: htdocs/luci-static/resources/view/fchomo/server.js:578 msgid "encryption" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:992 -#: htdocs/luci-static/resources/view/fchomo/node.js:1003 -#: htdocs/luci-static/resources/view/fchomo/node.js:1008 -#: htdocs/luci-static/resources/view/fchomo/server.js:932 -#: htdocs/luci-static/resources/view/fchomo/server.js:943 -#: htdocs/luci-static/resources/view/fchomo/server.js:948 +#: htdocs/luci-static/resources/view/fchomo/node.js:993 +#: htdocs/luci-static/resources/view/fchomo/node.js:1004 +#: htdocs/luci-static/resources/view/fchomo/node.js:1009 +#: htdocs/luci-static/resources/view/fchomo/server.js:944 +#: htdocs/luci-static/resources/view/fchomo/server.js:955 +#: htdocs/luci-static/resources/view/fchomo/server.js:960 msgid "gRPC" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1055 -#: htdocs/luci-static/resources/view/fchomo/server.js:967 +#: htdocs/luci-static/resources/view/fchomo/node.js:1056 +#: htdocs/luci-static/resources/view/fchomo/server.js:979 msgid "gRPC service name" msgstr "" @@ -3101,11 +3109,11 @@ msgstr "" msgid "gVisor" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1092 +#: htdocs/luci-static/resources/view/fchomo/node.js:1093 msgid "h2mux" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:731 +#: htdocs/luci-static/resources/view/fchomo/server.js:743 msgid "least one keypair required" msgstr "" @@ -3118,7 +3126,7 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1216 #: htdocs/luci-static/resources/view/fchomo/client.js:1353 #: htdocs/luci-static/resources/view/fchomo/client.js:1571 -#: htdocs/luci-static/resources/view/fchomo/node.js:1285 +#: htdocs/luci-static/resources/view/fchomo/node.js:1286 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:224 msgid "mihomo config" msgstr "" @@ -3127,13 +3135,13 @@ msgstr "" msgid "mlkem768x25519plus" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1158 -#: htdocs/luci-static/resources/view/fchomo/node.js:1440 +#: htdocs/luci-static/resources/view/fchomo/node.js:1159 +#: htdocs/luci-static/resources/view/fchomo/node.js:1441 msgid "mpTCP" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:464 -#: htdocs/luci-static/resources/view/fchomo/server.js:420 +#: htdocs/luci-static/resources/view/fchomo/node.js:465 +#: htdocs/luci-static/resources/view/fchomo/server.js:432 msgid "new_reno" msgstr "" @@ -3141,21 +3149,21 @@ msgstr "" msgid "no-resolve" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1301 -#: htdocs/luci-static/resources/fchomo.js:1396 -#: htdocs/luci-static/resources/fchomo.js:1431 -#: htdocs/luci-static/resources/fchomo.js:1443 +#: htdocs/luci-static/resources/fchomo.js:1331 +#: htdocs/luci-static/resources/fchomo.js:1426 +#: htdocs/luci-static/resources/fchomo.js:1461 +#: htdocs/luci-static/resources/fchomo.js:1489 msgid "non-empty value" msgstr "" #: htdocs/luci-static/resources/fchomo.js:287 #: htdocs/luci-static/resources/fchomo.js:301 #: htdocs/luci-static/resources/fchomo.js:313 -#: htdocs/luci-static/resources/view/fchomo/node.js:589 -#: htdocs/luci-static/resources/view/fchomo/node.js:609 -#: htdocs/luci-static/resources/view/fchomo/node.js:682 +#: htdocs/luci-static/resources/view/fchomo/node.js:590 +#: htdocs/luci-static/resources/view/fchomo/node.js:610 +#: htdocs/luci-static/resources/view/fchomo/node.js:683 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:300 -#: htdocs/luci-static/resources/view/fchomo/server.js:497 +#: htdocs/luci-static/resources/view/fchomo/server.js:509 msgid "none" msgstr "" @@ -3171,20 +3179,20 @@ msgstr "" msgid "null" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:683 +#: htdocs/luci-static/resources/view/fchomo/node.js:684 msgid "obfs-simple" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1420 +#: htdocs/luci-static/resources/view/fchomo/node.js:1421 msgid "override.proxy-name" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:610 +#: htdocs/luci-static/resources/view/fchomo/node.js:611 msgid "packet addr (v2ray-core v5+)" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:936 -#: htdocs/luci-static/resources/view/fchomo/server.js:805 +#: htdocs/luci-static/resources/view/fchomo/node.js:937 +#: htdocs/luci-static/resources/view/fchomo/server.js:817 msgid "private key" msgstr "" @@ -3197,7 +3205,7 @@ msgstr "" msgid "requires front-end adaptation using the API." msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:687 +#: htdocs/luci-static/resources/view/fchomo/node.js:688 msgid "restls" msgstr "" @@ -3205,12 +3213,12 @@ msgstr "" msgid "rule-set" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:686 -#: htdocs/luci-static/resources/view/fchomo/server.js:498 +#: htdocs/luci-static/resources/view/fchomo/node.js:687 +#: htdocs/luci-static/resources/view/fchomo/server.js:510 msgid "shadow-tls" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1090 +#: htdocs/luci-static/resources/view/fchomo/node.js:1091 msgid "smux" msgstr "" @@ -3226,70 +3234,75 @@ msgstr "" msgid "unchecked" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:396 +#: htdocs/luci-static/resources/fchomo.js:398 msgid "unique UCI identifier" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:399 +#: htdocs/luci-static/resources/fchomo.js:401 msgid "unique identifier" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1452 +#: htdocs/luci-static/resources/fchomo.js:1498 msgid "unique value" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1456 +#: htdocs/luci-static/resources/view/fchomo/node.js:1457 msgid "up" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:440 -#: htdocs/luci-static/resources/view/fchomo/node.js:484 -#: htdocs/luci-static/resources/view/fchomo/node.js:714 -#: htdocs/luci-static/resources/view/fchomo/node.js:746 -#: htdocs/luci-static/resources/view/fchomo/server.js:517 -msgid "v1" -msgstr "" - #: htdocs/luci-static/resources/view/fchomo/node.js:441 +#: htdocs/luci-static/resources/view/fchomo/node.js:485 #: htdocs/luci-static/resources/view/fchomo/node.js:715 #: htdocs/luci-static/resources/view/fchomo/node.js:747 -#: htdocs/luci-static/resources/view/fchomo/server.js:518 -msgid "v2" +#: htdocs/luci-static/resources/view/fchomo/server.js:529 +msgid "v1" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:442 #: htdocs/luci-static/resources/view/fchomo/node.js:716 -#: htdocs/luci-static/resources/view/fchomo/server.js:519 +#: htdocs/luci-static/resources/view/fchomo/node.js:748 +#: htdocs/luci-static/resources/view/fchomo/server.js:530 +msgid "v2" +msgstr "" + +#: htdocs/luci-static/resources/view/fchomo/node.js:443 +#: htdocs/luci-static/resources/view/fchomo/node.js:717 +#: htdocs/luci-static/resources/view/fchomo/server.js:531 msgid "v3" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1348 -#: htdocs/luci-static/resources/fchomo.js:1351 +#: htdocs/luci-static/resources/fchomo.js:1378 +#: htdocs/luci-static/resources/fchomo.js:1381 msgid "valid JSON format" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:896 +#: htdocs/luci-static/resources/view/fchomo/node.js:897 msgid "valid SHA256 string with %d characters" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1373 -#: htdocs/luci-static/resources/fchomo.js:1376 +#: htdocs/luci-static/resources/fchomo.js:1403 +#: htdocs/luci-static/resources/fchomo.js:1406 msgid "valid URL" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1386 +#: htdocs/luci-static/resources/fchomo.js:1416 msgid "valid base64 key with %d characters" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1433 +#: htdocs/luci-static/resources/fchomo.js:1476 +#: htdocs/luci-static/resources/fchomo.js:1482 +msgid "valid format: 2x, 2p, 4v" +msgstr "" + +#: htdocs/luci-static/resources/fchomo.js:1463 msgid "valid key length with %d characters" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1311 +#: htdocs/luci-static/resources/fchomo.js:1341 msgid "valid port value" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1361 +#: htdocs/luci-static/resources/fchomo.js:1391 msgid "valid uuid" msgstr "" @@ -3309,7 +3322,7 @@ msgstr "" msgid "yacd-meta" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1091 +#: htdocs/luci-static/resources/view/fchomo/node.js:1092 msgid "yamux" msgstr "" @@ -3317,10 +3330,10 @@ msgstr "" msgid "zashboard" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:590 +#: htdocs/luci-static/resources/view/fchomo/node.js:591 msgid "zero" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1135 +#: htdocs/luci-static/resources/fchomo.js:1159 msgid "🡇" msgstr "" diff --git a/small/luci-app-fchomo/po/zh_Hans/fchomo.po b/small/luci-app-fchomo/po/zh_Hans/fchomo.po index 04a154e198..4dc1426e48 100644 --- a/small/luci-app-fchomo/po/zh_Hans/fchomo.po +++ b/small/luci-app-fchomo/po/zh_Hans/fchomo.po @@ -12,21 +12,21 @@ msgstr "" msgid "%s log" msgstr "%s 日志" -#: htdocs/luci-static/resources/fchomo.js:558 -#: htdocs/luci-static/resources/fchomo.js:561 +#: htdocs/luci-static/resources/fchomo.js:560 +#: htdocs/luci-static/resources/fchomo.js:563 #: htdocs/luci-static/resources/view/fchomo/client.js:293 msgid "(Imported)" msgstr "(已导入)" #: htdocs/luci-static/resources/view/fchomo/global.js:549 #: htdocs/luci-static/resources/view/fchomo/global.js:555 -#: htdocs/luci-static/resources/view/fchomo/node.js:911 -#: htdocs/luci-static/resources/view/fchomo/node.js:917 -#: htdocs/luci-static/resources/view/fchomo/node.js:925 -#: htdocs/luci-static/resources/view/fchomo/node.js:931 -#: htdocs/luci-static/resources/view/fchomo/server.js:808 -#: htdocs/luci-static/resources/view/fchomo/server.js:816 -#: htdocs/luci-static/resources/view/fchomo/server.js:825 +#: htdocs/luci-static/resources/view/fchomo/node.js:912 +#: htdocs/luci-static/resources/view/fchomo/node.js:918 +#: htdocs/luci-static/resources/view/fchomo/node.js:926 +#: htdocs/luci-static/resources/view/fchomo/node.js:932 +#: htdocs/luci-static/resources/view/fchomo/server.js:820 +#: htdocs/luci-static/resources/view/fchomo/server.js:828 +#: htdocs/luci-static/resources/view/fchomo/server.js:837 msgid "(mTLS)" msgstr "" @@ -37,10 +37,10 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1153 #: htdocs/luci-static/resources/view/fchomo/client.js:1612 #: htdocs/luci-static/resources/view/fchomo/client.js:1613 -#: htdocs/luci-static/resources/view/fchomo/node.js:1608 -#: htdocs/luci-static/resources/view/fchomo/node.js:1614 -#: htdocs/luci-static/resources/view/fchomo/node.js:1628 -#: htdocs/luci-static/resources/view/fchomo/node.js:1634 +#: htdocs/luci-static/resources/view/fchomo/node.js:1609 +#: htdocs/luci-static/resources/view/fchomo/node.js:1615 +#: htdocs/luci-static/resources/view/fchomo/node.js:1629 +#: htdocs/luci-static/resources/view/fchomo/node.js:1635 msgid "-- Please choose --" msgstr "-- 请选择 --" @@ -73,11 +73,11 @@ msgstr "" msgid "0 or 1 only." msgstr "仅限 01。" -#: htdocs/luci-static/resources/view/fchomo/node.js:918 -#: htdocs/luci-static/resources/view/fchomo/node.js:932 -#: htdocs/luci-static/resources/view/fchomo/server.js:786 -#: htdocs/luci-static/resources/view/fchomo/server.js:801 -#: htdocs/luci-static/resources/view/fchomo/server.js:826 +#: htdocs/luci-static/resources/view/fchomo/node.js:919 +#: htdocs/luci-static/resources/view/fchomo/node.js:933 +#: htdocs/luci-static/resources/view/fchomo/server.js:798 +#: htdocs/luci-static/resources/view/fchomo/server.js:813 +#: htdocs/luci-static/resources/view/fchomo/server.js:838 msgid "Save your configuration before uploading files!" msgstr "上传文件前请先保存配置!" @@ -146,11 +146,11 @@ msgstr "新增 DNS 服务器" msgid "Add a Node" msgstr "新增 节点" -#: htdocs/luci-static/resources/view/fchomo/node.js:1198 +#: htdocs/luci-static/resources/view/fchomo/node.js:1199 msgid "Add a provider" msgstr "新增 供应商" -#: htdocs/luci-static/resources/view/fchomo/node.js:1584 +#: htdocs/luci-static/resources/view/fchomo/node.js:1585 msgid "Add a proxy chain" msgstr "新增 代理链" @@ -174,11 +174,11 @@ msgstr "新增 服务器" msgid "Add a sub rule" msgstr "新增 子规则" -#: htdocs/luci-static/resources/view/fchomo/node.js:1409 +#: htdocs/luci-static/resources/view/fchomo/node.js:1410 msgid "Add prefix" msgstr "添加前缀" -#: htdocs/luci-static/resources/view/fchomo/node.js:1413 +#: htdocs/luci-static/resources/view/fchomo/node.js:1414 msgid "Add suffix" msgstr "添加后缀" @@ -215,7 +215,7 @@ msgid "" msgstr "" "允许从私有网络访问。
要从公共网站访问私有网络上的 API,则必须启用。" -#: htdocs/luci-static/resources/view/fchomo/node.js:651 +#: htdocs/luci-static/resources/view/fchomo/node.js:652 msgid "Allowed IPs" msgstr "允许的 IP" @@ -227,8 +227,8 @@ msgstr "已是最新版本。" msgid "Already in updating." msgstr "已在更新中。" -#: htdocs/luci-static/resources/view/fchomo/node.js:580 -#: htdocs/luci-static/resources/view/fchomo/server.js:488 +#: htdocs/luci-static/resources/view/fchomo/node.js:581 +#: htdocs/luci-static/resources/view/fchomo/server.js:500 msgid "Alter ID" msgstr "额外 ID" @@ -250,11 +250,11 @@ msgstr "作为 dnsmasq 的最优先上游" msgid "As the TOP upstream of dnsmasq." msgstr "作为 dnsmasq 的最优先上游。" -#: htdocs/luci-static/resources/view/fchomo/server.js:438 +#: htdocs/luci-static/resources/view/fchomo/server.js:450 msgid "Auth timeout" msgstr "认证超时" -#: htdocs/luci-static/resources/view/fchomo/node.js:602 +#: htdocs/luci-static/resources/view/fchomo/node.js:603 msgid "Authenticated length" msgstr "认证长度" @@ -296,13 +296,13 @@ msgid "Binary mrs" msgstr "二进制 mrs" #: htdocs/luci-static/resources/view/fchomo/global.js:740 -#: htdocs/luci-static/resources/view/fchomo/node.js:1168 -#: htdocs/luci-static/resources/view/fchomo/node.js:1482 +#: htdocs/luci-static/resources/view/fchomo/node.js:1169 +#: htdocs/luci-static/resources/view/fchomo/node.js:1483 msgid "Bind interface" msgstr "绑定接口" -#: htdocs/luci-static/resources/view/fchomo/node.js:1169 -#: htdocs/luci-static/resources/view/fchomo/node.js:1483 +#: htdocs/luci-static/resources/view/fchomo/node.js:1170 +#: htdocs/luci-static/resources/view/fchomo/node.js:1484 msgid "Bind outbound interface.
" msgstr "绑定出站接口。
" @@ -347,21 +347,21 @@ msgstr "CORS 允许私有网络" msgid "CORS allowed origins, * will be used if empty." msgstr "CORS 允许的来源,留空则使用 *。" -#: htdocs/luci-static/resources/fchomo.js:674 +#: htdocs/luci-static/resources/fchomo.js:676 msgid "Cancel" msgstr "取消" -#: htdocs/luci-static/resources/view/fchomo/node.js:890 +#: htdocs/luci-static/resources/view/fchomo/node.js:891 msgid "Cert fingerprint" msgstr "证书指纹" -#: htdocs/luci-static/resources/view/fchomo/node.js:891 +#: htdocs/luci-static/resources/view/fchomo/node.js:892 msgid "" "Certificate fingerprint. Used to implement SSL Pinning and prevent MitM." msgstr "证书指纹。用于实现 SSL证书固定 并防止 MitM。" -#: htdocs/luci-static/resources/view/fchomo/node.js:911 -#: htdocs/luci-static/resources/view/fchomo/server.js:778 +#: htdocs/luci-static/resources/view/fchomo/node.js:912 +#: htdocs/luci-static/resources/view/fchomo/server.js:790 msgid "Certificate path" msgstr "证书路径" @@ -392,7 +392,7 @@ msgstr "大陆域名列表版本" #: htdocs/luci-static/resources/view/fchomo/node.js:326 #: htdocs/luci-static/resources/view/fchomo/node.js:379 -#: htdocs/luci-static/resources/view/fchomo/node.js:586 +#: htdocs/luci-static/resources/view/fchomo/node.js:587 #: htdocs/luci-static/resources/view/fchomo/server.js:269 #: htdocs/luci-static/resources/view/fchomo/server.js:356 msgid "Chipher" @@ -416,24 +416,24 @@ msgstr "" "最新的初始包。" #: htdocs/luci-static/resources/view/fchomo/global.js:556 -#: htdocs/luci-static/resources/view/fchomo/node.js:788 -#: htdocs/luci-static/resources/view/fchomo/node.js:912 -#: htdocs/luci-static/resources/view/fchomo/node.js:926 -#: htdocs/luci-static/resources/view/fchomo/server.js:607 -#: htdocs/luci-static/resources/view/fchomo/server.js:817 +#: htdocs/luci-static/resources/view/fchomo/node.js:789 +#: htdocs/luci-static/resources/view/fchomo/node.js:913 +#: htdocs/luci-static/resources/view/fchomo/node.js:927 +#: htdocs/luci-static/resources/view/fchomo/server.js:619 +#: htdocs/luci-static/resources/view/fchomo/server.js:829 #: root/usr/share/luci/menu.d/luci-app-fchomo.json:22 msgid "Client" msgstr "客户端" -#: htdocs/luci-static/resources/view/fchomo/server.js:816 +#: htdocs/luci-static/resources/view/fchomo/server.js:828 msgid "Client Auth Certificate path" msgstr "客户端认证证书路径" -#: htdocs/luci-static/resources/view/fchomo/server.js:808 +#: htdocs/luci-static/resources/view/fchomo/server.js:820 msgid "Client Auth type" msgstr "客户端认证类型" -#: htdocs/luci-static/resources/view/fchomo/node.js:952 +#: htdocs/luci-static/resources/view/fchomo/node.js:953 msgid "Client fingerprint" msgstr "客户端指纹" @@ -454,16 +454,16 @@ msgstr "收集数据中..." msgid "Common ports (bypass P2P traffic)" msgstr "常用端口(绕过 P2P 流量)" -#: htdocs/luci-static/resources/fchomo.js:1245 +#: htdocs/luci-static/resources/fchomo.js:1275 msgid "Complete" msgstr "完成" -#: htdocs/luci-static/resources/view/fchomo/node.js:1429 +#: htdocs/luci-static/resources/view/fchomo/node.js:1430 msgid "Configuration Items" msgstr "配置项" -#: htdocs/luci-static/resources/view/fchomo/node.js:460 -#: htdocs/luci-static/resources/view/fchomo/server.js:416 +#: htdocs/luci-static/resources/view/fchomo/node.js:461 +#: htdocs/luci-static/resources/view/fchomo/server.js:428 msgid "Congestion controller" msgstr "拥塞控制器" @@ -471,19 +471,19 @@ msgstr "拥塞控制器" msgid "Connection check" msgstr "连接检查" -#: htdocs/luci-static/resources/fchomo.js:543 +#: htdocs/luci-static/resources/fchomo.js:545 msgid "Content copied to clipboard!" msgstr "内容已复制到剪贴板!" #: htdocs/luci-static/resources/view/fchomo/client.js:608 -#: htdocs/luci-static/resources/view/fchomo/node.js:1339 -#: htdocs/luci-static/resources/view/fchomo/node.js:1365 +#: htdocs/luci-static/resources/view/fchomo/node.js:1340 +#: htdocs/luci-static/resources/view/fchomo/node.js:1366 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:324 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:350 msgid "Content will not be verified, Please make sure you enter it correctly." msgstr "内容将不会被验证,请确保输入正确。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1338 +#: htdocs/luci-static/resources/view/fchomo/node.js:1339 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:323 msgid "Contents" msgstr "内容" @@ -492,7 +492,7 @@ msgstr "内容" msgid "Contents have been saved." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:545 +#: htdocs/luci-static/resources/fchomo.js:547 msgid "Copy" msgstr "复制" @@ -508,7 +508,7 @@ msgstr "Cron 表达式" msgid "Custom Direct List" msgstr "自定义直连列表" -#: htdocs/luci-static/resources/view/fchomo/node.js:1400 +#: htdocs/luci-static/resources/view/fchomo/node.js:1401 msgid "Custom HTTP header." msgstr "自定义 HTTP header。" @@ -542,7 +542,7 @@ msgstr " DNS 端口" #: htdocs/luci-static/resources/view/fchomo/client.js:1303 #: htdocs/luci-static/resources/view/fchomo/client.js:1312 #: htdocs/luci-static/resources/view/fchomo/client.js:1625 -#: htdocs/luci-static/resources/view/fchomo/node.js:675 +#: htdocs/luci-static/resources/view/fchomo/node.js:676 msgid "DNS server" msgstr "DNS 服务器" @@ -570,15 +570,15 @@ msgstr "默认 DNS(由 WAN 下发)" msgid "Default DNS server" msgstr "默认 DNS 服务器" -#: htdocs/luci-static/resources/view/fchomo/node.js:652 +#: htdocs/luci-static/resources/view/fchomo/node.js:653 msgid "Destination addresses allowed to be forwarded via Wireguard." msgstr "允许通过 WireGuard 转发的目的地址" -#: htdocs/luci-static/resources/view/fchomo/node.js:1607 +#: htdocs/luci-static/resources/view/fchomo/node.js:1608 msgid "Destination provider" msgstr "落地供应商" -#: htdocs/luci-static/resources/view/fchomo/node.js:1613 +#: htdocs/luci-static/resources/view/fchomo/node.js:1614 msgid "Destination proxy node" msgstr "落地代理节点" @@ -586,8 +586,8 @@ msgstr "落地代理节点" msgid "Dial fields" msgstr "拨号字段" -#: htdocs/luci-static/resources/view/fchomo/node.js:1620 -#: htdocs/luci-static/resources/view/fchomo/node.js:1640 +#: htdocs/luci-static/resources/view/fchomo/node.js:1621 +#: htdocs/luci-static/resources/view/fchomo/node.js:1641 msgid "Different chain head/tail" msgstr "不同的链头/链尾" @@ -625,7 +625,7 @@ msgstr "禁用 quic-go 的 通用分段卸载(GSO)" msgid "Disable ICMP Forwarding" msgstr "禁用 ICMP 转发" -#: htdocs/luci-static/resources/view/fchomo/node.js:839 +#: htdocs/luci-static/resources/view/fchomo/node.js:840 msgid "Disable SNI" msgstr "禁用 SNI" @@ -661,29 +661,29 @@ msgstr "" msgid "Domain" msgstr "域名" -#: htdocs/luci-static/resources/view/fchomo/node.js:840 +#: htdocs/luci-static/resources/view/fchomo/node.js:841 msgid "Donot send server name in ClientHello." msgstr "不要在 ClientHello 中发送服务器名称。" #: htdocs/luci-static/resources/view/fchomo/client.js:1450 -#: htdocs/luci-static/resources/view/fchomo/node.js:904 -#: htdocs/luci-static/resources/view/fchomo/node.js:1469 +#: htdocs/luci-static/resources/view/fchomo/node.js:905 +#: htdocs/luci-static/resources/view/fchomo/node.js:1470 msgid "Donot verifying server certificate." msgstr "不验证服务器证书。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1147 +#: htdocs/luci-static/resources/view/fchomo/node.js:1148 msgid "Download bandwidth" msgstr "下载带宽" -#: htdocs/luci-static/resources/view/fchomo/node.js:1148 +#: htdocs/luci-static/resources/view/fchomo/node.js:1149 msgid "Download bandwidth in Mbps." msgstr "下载带宽(单位:Mbps)。" -#: htdocs/luci-static/resources/fchomo.js:1130 +#: htdocs/luci-static/resources/fchomo.js:1154 msgid "Download failed: %s" msgstr "下载失败: %s" -#: htdocs/luci-static/resources/fchomo.js:1128 +#: htdocs/luci-static/resources/fchomo.js:1152 msgid "Download successful." msgstr "下载成功。" @@ -691,12 +691,12 @@ msgstr "下载成功。" msgid "Dual stack" msgstr "双栈" -#: htdocs/luci-static/resources/view/fchomo/node.js:945 -#: htdocs/luci-static/resources/view/fchomo/server.js:874 +#: htdocs/luci-static/resources/view/fchomo/node.js:946 +#: htdocs/luci-static/resources/view/fchomo/server.js:886 msgid "ECH config" msgstr "ECH 配置" -#: htdocs/luci-static/resources/view/fchomo/server.js:833 +#: htdocs/luci-static/resources/view/fchomo/server.js:845 msgid "ECH key" msgstr "ECH 密钥" @@ -712,11 +712,11 @@ msgstr "" msgid "ETag support" msgstr "ETag 支持" -#: htdocs/luci-static/resources/view/fchomo/node.js:1060 +#: htdocs/luci-static/resources/view/fchomo/node.js:1061 msgid "Early Data first packet length limit." msgstr "前置数据长度阈值" -#: htdocs/luci-static/resources/view/fchomo/node.js:1066 +#: htdocs/luci-static/resources/view/fchomo/node.js:1067 msgid "Early Data header name" msgstr "前置数据标头" @@ -728,7 +728,7 @@ msgstr "编辑节点" msgid "Edit ruleset" msgstr "编辑规则集" -#: htdocs/luci-static/resources/view/fchomo/node.js:1336 +#: htdocs/luci-static/resources/view/fchomo/node.js:1337 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:321 msgid "Editer" msgstr "编辑器" @@ -746,16 +746,16 @@ msgstr "消除加密头特征" #: htdocs/luci-static/resources/view/fchomo/global.js:401 #: htdocs/luci-static/resources/view/fchomo/global.js:686 #: htdocs/luci-static/resources/view/fchomo/node.js:234 -#: htdocs/luci-static/resources/view/fchomo/node.js:1309 -#: htdocs/luci-static/resources/view/fchomo/node.js:1505 -#: htdocs/luci-static/resources/view/fchomo/node.js:1594 +#: htdocs/luci-static/resources/view/fchomo/node.js:1310 +#: htdocs/luci-static/resources/view/fchomo/node.js:1506 +#: htdocs/luci-static/resources/view/fchomo/node.js:1595 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:249 #: htdocs/luci-static/resources/view/fchomo/server.js:157 #: htdocs/luci-static/resources/view/fchomo/server.js:184 msgid "Enable" msgstr "启用" -#: htdocs/luci-static/resources/view/fchomo/node.js:495 +#: htdocs/luci-static/resources/view/fchomo/node.js:496 msgid "" "Enable 0-RTT QUIC connection handshake on the client side. This is not " "impacting much on the performance, as the protocol is fully multiplexed.
强烈建议禁用此功能,因为它容易受到重放攻击。" -#: htdocs/luci-static/resources/view/fchomo/node.js:494 +#: htdocs/luci-static/resources/view/fchomo/node.js:495 msgid "Enable 0-RTT handshake" msgstr "启用 0-RTT 握手" @@ -776,37 +776,37 @@ msgstr "" "为出站连接启用 IP4P 转换" -#: htdocs/luci-static/resources/view/fchomo/node.js:939 +#: htdocs/luci-static/resources/view/fchomo/node.js:940 msgid "Enable ECH" msgstr "启用 ECH" -#: htdocs/luci-static/resources/view/fchomo/node.js:1135 +#: htdocs/luci-static/resources/view/fchomo/node.js:1136 msgid "Enable TCP Brutal" msgstr "启用 TCP Brutal" -#: htdocs/luci-static/resources/view/fchomo/node.js:1136 +#: htdocs/luci-static/resources/view/fchomo/node.js:1137 msgid "Enable TCP Brutal congestion control algorithm" msgstr "启用 TCP Brutal 拥塞控制算法。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1124 +#: htdocs/luci-static/resources/view/fchomo/node.js:1125 msgid "Enable multiplexing only for TCP." msgstr "仅为 TCP 启用多路复用。" -#: htdocs/luci-static/resources/view/fchomo/node.js:424 -#: htdocs/luci-static/resources/view/fchomo/server.js:402 +#: htdocs/luci-static/resources/view/fchomo/node.js:425 +#: htdocs/luci-static/resources/view/fchomo/server.js:414 msgid "Enable obfuscate for downlink" msgstr "启用下行链路混淆" -#: htdocs/luci-static/resources/view/fchomo/node.js:1118 +#: htdocs/luci-static/resources/view/fchomo/node.js:1119 msgid "Enable padding" msgstr "启用填充" -#: htdocs/luci-static/resources/view/fchomo/node.js:1129 +#: htdocs/luci-static/resources/view/fchomo/node.js:1130 msgid "Enable statistic" msgstr "启用统计" -#: htdocs/luci-static/resources/view/fchomo/node.js:740 -#: htdocs/luci-static/resources/view/fchomo/node.js:1451 +#: htdocs/luci-static/resources/view/fchomo/node.js:741 +#: htdocs/luci-static/resources/view/fchomo/node.js:1452 msgid "" "Enable the SUoT protocol, requires server support. Conflict with Multiplex." msgstr "启用 SUoT 协议,需要服务端支持。与多路复用冲突。" @@ -818,7 +818,7 @@ msgid "" "connections, losing the ability to masquerade with HTTP/3." msgstr "启用混淆将使服务器与标准的 QUIC 连接不兼容,失去 HTTP/3 伪装的能力。" -#: htdocs/luci-static/resources/view/fchomo/server.js:570 +#: htdocs/luci-static/resources/view/fchomo/server.js:582 msgid "Encryption method" msgstr "加密方法" @@ -841,7 +841,7 @@ msgid "" "if empty." msgstr "超过此限制将会触发强制健康检查。留空则使用 5。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1563 +#: htdocs/luci-static/resources/view/fchomo/node.js:1564 msgid "Exclude matched node types." msgstr "排除匹配的节点类型。" @@ -854,7 +854,7 @@ msgstr "" "rel=\"noreferrer noopener\">此处。" #: htdocs/luci-static/resources/view/fchomo/client.js:1049 -#: htdocs/luci-static/resources/view/fchomo/node.js:1556 +#: htdocs/luci-static/resources/view/fchomo/node.js:1557 msgid "Exclude nodes that meet keywords or regexps." msgstr "排除匹配关键词或表达式的节点。" @@ -863,59 +863,61 @@ msgid "Expand/Collapse result" msgstr "展开/收起 结果" #: htdocs/luci-static/resources/view/fchomo/client.js:1009 -#: htdocs/luci-static/resources/view/fchomo/node.js:1541 +#: htdocs/luci-static/resources/view/fchomo/node.js:1542 msgid "Expected HTTP code. 204 will be used if empty." msgstr "预期的 HTTP code。留空则使用 204。" #: htdocs/luci-static/resources/view/fchomo/client.js:1011 -#: htdocs/luci-static/resources/view/fchomo/node.js:1543 +#: htdocs/luci-static/resources/view/fchomo/node.js:1544 msgid "Expected status" msgstr "预期状态" -#: htdocs/luci-static/resources/fchomo.js:393 -#: htdocs/luci-static/resources/fchomo.js:396 -#: htdocs/luci-static/resources/fchomo.js:399 -#: htdocs/luci-static/resources/fchomo.js:1262 -#: htdocs/luci-static/resources/fchomo.js:1270 -#: htdocs/luci-static/resources/fchomo.js:1278 -#: htdocs/luci-static/resources/fchomo.js:1301 -#: htdocs/luci-static/resources/fchomo.js:1304 -#: htdocs/luci-static/resources/fchomo.js:1311 -#: htdocs/luci-static/resources/fchomo.js:1327 -#: htdocs/luci-static/resources/fchomo.js:1336 -#: htdocs/luci-static/resources/fchomo.js:1348 -#: htdocs/luci-static/resources/fchomo.js:1351 -#: htdocs/luci-static/resources/fchomo.js:1361 -#: htdocs/luci-static/resources/fchomo.js:1373 -#: htdocs/luci-static/resources/fchomo.js:1376 -#: htdocs/luci-static/resources/fchomo.js:1386 -#: htdocs/luci-static/resources/fchomo.js:1396 -#: htdocs/luci-static/resources/fchomo.js:1431 -#: htdocs/luci-static/resources/fchomo.js:1433 -#: htdocs/luci-static/resources/fchomo.js:1443 -#: htdocs/luci-static/resources/fchomo.js:1452 +#: htdocs/luci-static/resources/fchomo.js:395 +#: htdocs/luci-static/resources/fchomo.js:398 +#: htdocs/luci-static/resources/fchomo.js:401 +#: htdocs/luci-static/resources/fchomo.js:1292 +#: htdocs/luci-static/resources/fchomo.js:1300 +#: htdocs/luci-static/resources/fchomo.js:1308 +#: htdocs/luci-static/resources/fchomo.js:1331 +#: htdocs/luci-static/resources/fchomo.js:1334 +#: htdocs/luci-static/resources/fchomo.js:1341 +#: htdocs/luci-static/resources/fchomo.js:1357 +#: htdocs/luci-static/resources/fchomo.js:1366 +#: htdocs/luci-static/resources/fchomo.js:1378 +#: htdocs/luci-static/resources/fchomo.js:1381 +#: htdocs/luci-static/resources/fchomo.js:1391 +#: htdocs/luci-static/resources/fchomo.js:1403 +#: htdocs/luci-static/resources/fchomo.js:1406 +#: htdocs/luci-static/resources/fchomo.js:1416 +#: htdocs/luci-static/resources/fchomo.js:1426 +#: htdocs/luci-static/resources/fchomo.js:1461 +#: htdocs/luci-static/resources/fchomo.js:1463 +#: htdocs/luci-static/resources/fchomo.js:1476 +#: htdocs/luci-static/resources/fchomo.js:1482 +#: htdocs/luci-static/resources/fchomo.js:1489 +#: htdocs/luci-static/resources/fchomo.js:1498 #: htdocs/luci-static/resources/view/fchomo/client.js:68 #: htdocs/luci-static/resources/view/fchomo/client.js:906 #: htdocs/luci-static/resources/view/fchomo/client.js:1381 #: htdocs/luci-static/resources/view/fchomo/global.js:886 #: htdocs/luci-static/resources/view/fchomo/node.js:388 -#: htdocs/luci-static/resources/view/fchomo/node.js:811 -#: htdocs/luci-static/resources/view/fchomo/node.js:896 -#: htdocs/luci-static/resources/view/fchomo/node.js:1620 -#: htdocs/luci-static/resources/view/fchomo/node.js:1640 +#: htdocs/luci-static/resources/view/fchomo/node.js:812 +#: htdocs/luci-static/resources/view/fchomo/node.js:897 +#: htdocs/luci-static/resources/view/fchomo/node.js:1621 +#: htdocs/luci-static/resources/view/fchomo/node.js:1641 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:276 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:290 #: htdocs/luci-static/resources/view/fchomo/server.js:365 -#: htdocs/luci-static/resources/view/fchomo/server.js:599 -#: htdocs/luci-static/resources/view/fchomo/server.js:630 -#: htdocs/luci-static/resources/view/fchomo/server.js:731 +#: htdocs/luci-static/resources/view/fchomo/server.js:611 +#: htdocs/luci-static/resources/view/fchomo/server.js:642 +#: htdocs/luci-static/resources/view/fchomo/server.js:743 msgid "Expecting: %s" msgstr "请输入:%s" -#: htdocs/luci-static/resources/view/fchomo/node.js:1001 -#: htdocs/luci-static/resources/view/fchomo/node.js:1008 -#: htdocs/luci-static/resources/view/fchomo/server.js:941 -#: htdocs/luci-static/resources/view/fchomo/server.js:948 +#: htdocs/luci-static/resources/view/fchomo/node.js:1002 +#: htdocs/luci-static/resources/view/fchomo/node.js:1009 +#: htdocs/luci-static/resources/view/fchomo/server.js:953 +#: htdocs/luci-static/resources/view/fchomo/server.js:960 msgid "Expecting: only support %s." msgstr "请输入:仅支援 %s." @@ -934,19 +936,19 @@ msgstr "实验性" msgid "Factor" msgstr "条件" -#: htdocs/luci-static/resources/fchomo.js:1203 +#: htdocs/luci-static/resources/fchomo.js:1233 msgid "Failed to execute \"/etc/init.d/fchomo %s %s\" reason: %s" msgstr "无法执行 \"/etc/init.d/fchomo %s %s\" 原因: %s" -#: htdocs/luci-static/resources/fchomo.js:1162 +#: htdocs/luci-static/resources/fchomo.js:1186 msgid "Failed to generate %s, error: %s." msgstr "生成 %s 失败,错误:%s。" -#: htdocs/luci-static/resources/fchomo.js:1552 +#: htdocs/luci-static/resources/fchomo.js:1598 msgid "Failed to upload %s, error: %s." msgstr "上传 %s 失败,错误:%s。" -#: htdocs/luci-static/resources/fchomo.js:1571 +#: htdocs/luci-static/resources/fchomo.js:1617 msgid "Failed to upload, error: %s." msgstr "上传失败,错误:%s。" @@ -964,7 +966,7 @@ msgid "Fallback filter" msgstr "後備过滤器" #: htdocs/luci-static/resources/view/fchomo/client.js:1044 -#: htdocs/luci-static/resources/view/fchomo/node.js:1550 +#: htdocs/luci-static/resources/view/fchomo/node.js:1551 msgid "Filter nodes that meet keywords or regexps." msgstr "过滤匹配关键字或表达式的节点。" @@ -984,8 +986,8 @@ msgstr "兜底 DNS 服务器 (用于已被投毒污染的域名)" msgid "Firewall" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:572 -#: htdocs/luci-static/resources/view/fchomo/server.js:480 +#: htdocs/luci-static/resources/view/fchomo/node.js:573 +#: htdocs/luci-static/resources/view/fchomo/server.js:492 msgid "Flow" msgstr "流控" @@ -998,8 +1000,8 @@ msgstr "" "noopener\">%s." #: htdocs/luci-static/resources/view/fchomo/client.js:1010 -#: htdocs/luci-static/resources/view/fchomo/node.js:1419 -#: htdocs/luci-static/resources/view/fchomo/node.js:1542 +#: htdocs/luci-static/resources/view/fchomo/node.js:1420 +#: htdocs/luci-static/resources/view/fchomo/node.js:1543 msgid "" "For format see %s." @@ -1007,7 +1009,7 @@ msgstr "" "格式请参阅 %s." -#: htdocs/luci-static/resources/view/fchomo/node.js:670 +#: htdocs/luci-static/resources/view/fchomo/node.js:671 msgid "Force DNS remote resolution." msgstr "强制 DNS 远程解析。" @@ -1026,7 +1028,7 @@ msgstr "格式" msgid "FullCombo Shark!" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1027 +#: htdocs/luci-static/resources/view/fchomo/node.js:1028 msgid "GET" msgstr "" @@ -1040,7 +1042,7 @@ msgstr "常规" #: htdocs/luci-static/resources/view/fchomo/client.js:897 #: htdocs/luci-static/resources/view/fchomo/node.js:222 -#: htdocs/luci-static/resources/view/fchomo/node.js:1299 +#: htdocs/luci-static/resources/view/fchomo/node.js:1300 #: htdocs/luci-static/resources/view/fchomo/server.js:171 msgid "General fields" msgstr "常规字段" @@ -1049,14 +1051,16 @@ msgstr "常规字段" msgid "General settings" msgstr "常规设置" -#: htdocs/luci-static/resources/fchomo.js:494 #: htdocs/luci-static/resources/fchomo.js:496 -#: htdocs/luci-static/resources/fchomo.js:510 +#: htdocs/luci-static/resources/fchomo.js:498 #: htdocs/luci-static/resources/fchomo.js:512 +#: htdocs/luci-static/resources/fchomo.js:514 #: htdocs/luci-static/resources/view/fchomo/global.js:593 #: htdocs/luci-static/resources/view/fchomo/server.js:343 -#: htdocs/luci-static/resources/view/fchomo/server.js:703 -#: htdocs/luci-static/resources/view/fchomo/server.js:866 +#: htdocs/luci-static/resources/view/fchomo/server.js:384 +#: htdocs/luci-static/resources/view/fchomo/server.js:386 +#: htdocs/luci-static/resources/view/fchomo/server.js:715 +#: htdocs/luci-static/resources/view/fchomo/server.js:878 msgid "Generate" msgstr "生成" @@ -1103,7 +1107,7 @@ msgstr "全局认证" msgid "Global client fingerprint" msgstr "全局客户端指纹" -#: htdocs/luci-static/resources/view/fchomo/node.js:596 +#: htdocs/luci-static/resources/view/fchomo/node.js:597 msgid "Global padding" msgstr "全局填充" @@ -1125,24 +1129,24 @@ msgstr "组" #: htdocs/luci-static/resources/fchomo.js:126 #: htdocs/luci-static/resources/fchomo.js:158 -#: htdocs/luci-static/resources/view/fchomo/node.js:693 -#: htdocs/luci-static/resources/view/fchomo/node.js:990 -#: htdocs/luci-static/resources/view/fchomo/node.js:1001 -#: htdocs/luci-static/resources/view/fchomo/server.js:941 +#: htdocs/luci-static/resources/view/fchomo/node.js:694 +#: htdocs/luci-static/resources/view/fchomo/node.js:991 +#: htdocs/luci-static/resources/view/fchomo/node.js:1002 +#: htdocs/luci-static/resources/view/fchomo/server.js:953 msgid "HTTP" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:267 -#: htdocs/luci-static/resources/view/fchomo/node.js:1049 -#: htdocs/luci-static/resources/view/fchomo/node.js:1399 +#: htdocs/luci-static/resources/view/fchomo/node.js:1050 +#: htdocs/luci-static/resources/view/fchomo/node.js:1400 msgid "HTTP header" msgstr "HTTP header" -#: htdocs/luci-static/resources/view/fchomo/node.js:419 +#: htdocs/luci-static/resources/view/fchomo/node.js:420 msgid "HTTP mask" msgstr "HTTP 掩码" -#: htdocs/luci-static/resources/view/fchomo/node.js:1026 +#: htdocs/luci-static/resources/view/fchomo/node.js:1027 msgid "HTTP request method" msgstr "HTTP 请求方法" @@ -1156,9 +1160,9 @@ msgid "" "returned if empty." msgstr "身份验证失败时的 HTTP3 服务器响应。默认返回 404 页面。" -#: htdocs/luci-static/resources/view/fchomo/node.js:991 -#: htdocs/luci-static/resources/view/fchomo/node.js:1002 -#: htdocs/luci-static/resources/view/fchomo/server.js:942 +#: htdocs/luci-static/resources/view/fchomo/node.js:992 +#: htdocs/luci-static/resources/view/fchomo/node.js:1003 +#: htdocs/luci-static/resources/view/fchomo/server.js:954 msgid "HTTPUpgrade" msgstr "" @@ -1170,40 +1174,40 @@ msgstr "处理域名" msgid "Handshake mode" msgstr "握手模式" -#: htdocs/luci-static/resources/view/fchomo/server.js:503 +#: htdocs/luci-static/resources/view/fchomo/server.js:515 msgid "Handshake target that supports TLS 1.3" msgstr "握手目标 (支援 TLS 1.3)" -#: htdocs/luci-static/resources/view/fchomo/server.js:396 +#: htdocs/luci-static/resources/view/fchomo/server.js:408 msgid "Handshake timeout" msgstr "握手超时" #: htdocs/luci-static/resources/view/fchomo/client.js:979 -#: htdocs/luci-static/resources/view/fchomo/node.js:1510 +#: htdocs/luci-static/resources/view/fchomo/node.js:1511 msgid "Health check URL" msgstr "健康检查 URL" #: htdocs/luci-static/resources/view/fchomo/client.js:1008 -#: htdocs/luci-static/resources/view/fchomo/node.js:1540 +#: htdocs/luci-static/resources/view/fchomo/node.js:1541 msgid "Health check expected status" msgstr "健康检查预期状态" #: htdocs/luci-static/resources/view/fchomo/client.js:988 -#: htdocs/luci-static/resources/view/fchomo/node.js:1520 +#: htdocs/luci-static/resources/view/fchomo/node.js:1521 msgid "Health check interval" msgstr "健康检查间隔" #: htdocs/luci-static/resources/view/fchomo/client.js:995 -#: htdocs/luci-static/resources/view/fchomo/node.js:1527 +#: htdocs/luci-static/resources/view/fchomo/node.js:1528 msgid "Health check timeout" msgstr "健康检查超时" #: htdocs/luci-static/resources/view/fchomo/client.js:899 -#: htdocs/luci-static/resources/view/fchomo/node.js:1301 +#: htdocs/luci-static/resources/view/fchomo/node.js:1302 msgid "Health fields" msgstr "健康字段" -#: htdocs/luci-static/resources/view/fchomo/node.js:501 +#: htdocs/luci-static/resources/view/fchomo/node.js:502 msgid "Heartbeat interval" msgstr "心跳间隔" @@ -1211,7 +1215,7 @@ msgstr "心跳间隔" msgid "Hidden" msgstr "隐藏" -#: htdocs/luci-static/resources/view/fchomo/node.js:699 +#: htdocs/luci-static/resources/view/fchomo/node.js:700 msgid "Host that supports TLS 1.3" msgstr "主机名称 (支援 TLS 1.3)" @@ -1242,12 +1246,12 @@ msgstr "" msgid "IP CIDR" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:454 +#: htdocs/luci-static/resources/view/fchomo/node.js:455 msgid "IP override" msgstr "IP 覆写" -#: htdocs/luci-static/resources/view/fchomo/node.js:1180 -#: htdocs/luci-static/resources/view/fchomo/node.js:1496 +#: htdocs/luci-static/resources/view/fchomo/node.js:1181 +#: htdocs/luci-static/resources/view/fchomo/node.js:1497 msgid "IP version" msgstr "IP 版本" @@ -1268,19 +1272,19 @@ msgstr "IPv6 支持" msgid "Icon" msgstr "图标" -#: htdocs/luci-static/resources/view/fchomo/node.js:545 +#: htdocs/luci-static/resources/view/fchomo/node.js:546 msgid "Idle session check interval" msgstr "闲置会话检查间隔" -#: htdocs/luci-static/resources/view/fchomo/node.js:552 +#: htdocs/luci-static/resources/view/fchomo/node.js:553 msgid "Idle session timeout" msgstr "闲置会话超时" -#: htdocs/luci-static/resources/view/fchomo/server.js:431 +#: htdocs/luci-static/resources/view/fchomo/server.js:443 msgid "Idle timeout" msgstr "闲置超时" -#: htdocs/luci-static/resources/fchomo.js:1304 +#: htdocs/luci-static/resources/fchomo.js:1334 msgid "If All ports is selected, uncheck others" msgstr "如果选择了“所有端口”,则取消选中“其他”" @@ -1292,7 +1296,7 @@ msgstr "如果选择了“阻止”,则取消选中“其他”" msgid "Ignore client bandwidth" msgstr "忽略客户端带宽" -#: htdocs/luci-static/resources/fchomo.js:679 +#: htdocs/luci-static/resources/fchomo.js:681 msgid "Import" msgstr "导入" @@ -1306,8 +1310,8 @@ msgstr "导入" #: htdocs/luci-static/resources/view/fchomo/client.js:1355 #: htdocs/luci-static/resources/view/fchomo/client.js:1552 #: htdocs/luci-static/resources/view/fchomo/client.js:1573 -#: htdocs/luci-static/resources/view/fchomo/node.js:1205 -#: htdocs/luci-static/resources/view/fchomo/node.js:1287 +#: htdocs/luci-static/resources/view/fchomo/node.js:1206 +#: htdocs/luci-static/resources/view/fchomo/node.js:1288 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:142 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:226 msgid "Import mihomo config" @@ -1321,33 +1325,33 @@ msgstr "导入规则集链接" #: htdocs/luci-static/resources/view/fchomo/node.js:280 #: htdocs/luci-static/resources/view/fchomo/node.js:286 -#: htdocs/luci-static/resources/view/fchomo/node.js:1457 -#: htdocs/luci-static/resources/view/fchomo/node.js:1463 +#: htdocs/luci-static/resources/view/fchomo/node.js:1458 +#: htdocs/luci-static/resources/view/fchomo/node.js:1464 #: htdocs/luci-static/resources/view/fchomo/server.js:231 #: htdocs/luci-static/resources/view/fchomo/server.js:237 msgid "In Mbps." msgstr "单位为 Mbps。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1377 +#: htdocs/luci-static/resources/view/fchomo/node.js:1378 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:362 msgid "In bytes. %s will be used if empty." msgstr "单位为字节。留空则使用 %s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:502 -#: htdocs/luci-static/resources/view/fchomo/node.js:509 +#: htdocs/luci-static/resources/view/fchomo/node.js:503 +#: htdocs/luci-static/resources/view/fchomo/node.js:510 msgid "In millisecond." msgstr "单位为毫秒。" #: htdocs/luci-static/resources/view/fchomo/client.js:996 #: htdocs/luci-static/resources/view/fchomo/client.js:1025 -#: htdocs/luci-static/resources/view/fchomo/node.js:1528 +#: htdocs/luci-static/resources/view/fchomo/node.js:1529 msgid "In millisecond. %s will be used if empty." msgstr "单位为毫秒。留空则使用 %s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:546 -#: htdocs/luci-static/resources/view/fchomo/node.js:553 -#: htdocs/luci-static/resources/view/fchomo/server.js:432 -#: htdocs/luci-static/resources/view/fchomo/server.js:439 +#: htdocs/luci-static/resources/view/fchomo/node.js:547 +#: htdocs/luci-static/resources/view/fchomo/node.js:554 +#: htdocs/luci-static/resources/view/fchomo/server.js:444 +#: htdocs/luci-static/resources/view/fchomo/server.js:451 msgid "In seconds." msgstr "单位为秒。" @@ -1355,14 +1359,14 @@ msgstr "单位为秒。" #: htdocs/luci-static/resources/view/fchomo/global.js:425 #: htdocs/luci-static/resources/view/fchomo/global.js:430 #: htdocs/luci-static/resources/view/fchomo/global.js:515 -#: htdocs/luci-static/resources/view/fchomo/node.js:1383 -#: htdocs/luci-static/resources/view/fchomo/node.js:1521 +#: htdocs/luci-static/resources/view/fchomo/node.js:1384 +#: htdocs/luci-static/resources/view/fchomo/node.js:1522 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:368 msgid "In seconds. %s will be used if empty." msgstr "单位为秒。留空则使用 %s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:800 -#: htdocs/luci-static/resources/view/fchomo/server.js:619 +#: htdocs/luci-static/resources/view/fchomo/node.js:801 +#: htdocs/luci-static/resources/view/fchomo/server.js:631 msgid "" "In the order of one Padding-Length and one Padding-" "Interval, infinite concatenation." @@ -1402,7 +1406,7 @@ msgstr "引入所有代理节点。" msgid "Info" msgstr "信息" -#: htdocs/luci-static/resources/view/fchomo/node.js:1316 +#: htdocs/luci-static/resources/view/fchomo/node.js:1317 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:264 msgid "Inline" msgstr "内嵌" @@ -1420,12 +1424,12 @@ msgstr "保持缺省" msgid "Key" msgstr "密钥" -#: htdocs/luci-static/resources/view/fchomo/node.js:925 -#: htdocs/luci-static/resources/view/fchomo/server.js:793 +#: htdocs/luci-static/resources/view/fchomo/node.js:926 +#: htdocs/luci-static/resources/view/fchomo/server.js:805 msgid "Key path" msgstr "证书路径" -#: htdocs/luci-static/resources/view/fchomo/server.js:638 +#: htdocs/luci-static/resources/view/fchomo/server.js:650 msgid "Keypairs" msgstr "密钥对" @@ -1435,19 +1439,19 @@ msgstr "密钥对" #: htdocs/luci-static/resources/view/fchomo/client.js:1361 #: htdocs/luci-static/resources/view/fchomo/client.js:1579 #: htdocs/luci-static/resources/view/fchomo/node.js:229 -#: htdocs/luci-static/resources/view/fchomo/node.js:1304 -#: htdocs/luci-static/resources/view/fchomo/node.js:1589 +#: htdocs/luci-static/resources/view/fchomo/node.js:1305 +#: htdocs/luci-static/resources/view/fchomo/node.js:1590 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:244 #: htdocs/luci-static/resources/view/fchomo/server.js:179 msgid "Label" msgstr "标签" #: htdocs/luci-static/resources/view/fchomo/client.js:1002 -#: htdocs/luci-static/resources/view/fchomo/node.js:1534 +#: htdocs/luci-static/resources/view/fchomo/node.js:1535 msgid "Lazy" msgstr "懒惰状态" -#: htdocs/luci-static/resources/view/fchomo/server.js:489 +#: htdocs/luci-static/resources/view/fchomo/server.js:501 msgid "" "Legacy protocol support (VMess MD5 Authentication) is provided for " "compatibility purposes only, use of alterId > 1 is not recommended." @@ -1459,8 +1463,8 @@ msgstr "" msgid "Less compatibility and sometimes better performance." msgstr "有时性能更好。" -#: htdocs/luci-static/resources/view/fchomo/node.js:852 -#: htdocs/luci-static/resources/view/fchomo/server.js:774 +#: htdocs/luci-static/resources/view/fchomo/node.js:853 +#: htdocs/luci-static/resources/view/fchomo/server.js:786 msgid "List of supported application level protocols, in order of preference." msgstr "支持的应用层协议协商列表,按顺序排列。" @@ -1489,16 +1493,16 @@ msgstr "监听端口" msgid "Load balance" msgstr "负载均衡" -#: htdocs/luci-static/resources/view/fchomo/node.js:1314 +#: htdocs/luci-static/resources/view/fchomo/node.js:1315 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:262 msgid "Local" msgstr "本地" -#: htdocs/luci-static/resources/view/fchomo/node.js:623 +#: htdocs/luci-static/resources/view/fchomo/node.js:624 msgid "Local IPv6 address" msgstr "本地 IPv6 地址" -#: htdocs/luci-static/resources/view/fchomo/node.js:616 +#: htdocs/luci-static/resources/view/fchomo/node.js:617 msgid "Local address" msgstr "本地地址" @@ -1518,12 +1522,12 @@ msgstr "日志为空。" msgid "Log level" msgstr "日志等级" -#: htdocs/luci-static/resources/fchomo.js:393 +#: htdocs/luci-static/resources/fchomo.js:395 msgid "Lowercase only" msgstr "仅限小写" #: htdocs/luci-static/resources/view/fchomo/global.js:502 -#: htdocs/luci-static/resources/view/fchomo/node.js:663 +#: htdocs/luci-static/resources/view/fchomo/node.js:664 msgid "MTU" msgstr "" @@ -1559,12 +1563,12 @@ msgstr "匹配响应通过 ipcidr
" msgid "Match rule set." msgstr "匹配规则集。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1059 +#: htdocs/luci-static/resources/view/fchomo/node.js:1060 msgid "Max Early Data" msgstr "前置数据最大值" -#: htdocs/luci-static/resources/view/fchomo/node.js:488 -#: htdocs/luci-static/resources/view/fchomo/server.js:425 +#: htdocs/luci-static/resources/view/fchomo/node.js:489 +#: htdocs/luci-static/resources/view/fchomo/server.js:437 msgid "Max UDP relay packet size" msgstr "UDP 中继数据包最大尺寸" @@ -1577,7 +1581,7 @@ msgstr "最大失败次数" msgid "Max download speed" msgstr "最大下载速度" -#: htdocs/luci-static/resources/view/fchomo/node.js:515 +#: htdocs/luci-static/resources/view/fchomo/node.js:516 msgid "Max open streams" msgstr "限制打开流的数量" @@ -1586,12 +1590,12 @@ msgstr "限制打开流的数量" msgid "Max upload speed" msgstr "最大上传速度" -#: htdocs/luci-static/resources/view/fchomo/node.js:1096 -#: htdocs/luci-static/resources/view/fchomo/node.js:1112 +#: htdocs/luci-static/resources/view/fchomo/node.js:1097 +#: htdocs/luci-static/resources/view/fchomo/node.js:1113 msgid "Maximum connections" msgstr "最大连接数" -#: htdocs/luci-static/resources/view/fchomo/node.js:1110 +#: htdocs/luci-static/resources/view/fchomo/node.js:1111 msgid "" "Maximum multiplexed streams in a connection before opening a new connection." "
Conflict with %s and %s." @@ -1599,12 +1603,12 @@ msgstr "" "在打开新连接之前,连接中的最大多路复用流数量。
%s 和 " "%s 冲突。" -#: htdocs/luci-static/resources/view/fchomo/node.js:412 -#: htdocs/luci-static/resources/view/fchomo/server.js:389 +#: htdocs/luci-static/resources/view/fchomo/node.js:413 +#: htdocs/luci-static/resources/view/fchomo/server.js:401 msgid "Maximum padding" msgstr "最大填充" -#: htdocs/luci-static/resources/view/fchomo/node.js:1109 +#: htdocs/luci-static/resources/view/fchomo/node.js:1110 msgid "Maximum streams" msgstr "最大流数量" @@ -1625,22 +1629,22 @@ msgstr "Mihomo 客户端" msgid "Mihomo server" msgstr "Mihomo 服务端" -#: htdocs/luci-static/resources/view/fchomo/node.js:559 +#: htdocs/luci-static/resources/view/fchomo/node.js:560 msgid "Min of idle sessions to keep" msgstr "要保留的最少闲置会话数" -#: htdocs/luci-static/resources/view/fchomo/node.js:1103 +#: htdocs/luci-static/resources/view/fchomo/node.js:1104 msgid "" "Minimum multiplexed streams in a connection before opening a new connection." msgstr "在打开新连接之前,连接中的最小多路复用流数量。" -#: htdocs/luci-static/resources/view/fchomo/node.js:405 -#: htdocs/luci-static/resources/view/fchomo/server.js:382 +#: htdocs/luci-static/resources/view/fchomo/node.js:406 +#: htdocs/luci-static/resources/view/fchomo/server.js:394 msgid "Minimum padding" msgstr "最小填充" -#: htdocs/luci-static/resources/view/fchomo/node.js:1102 -#: htdocs/luci-static/resources/view/fchomo/node.js:1112 +#: htdocs/luci-static/resources/view/fchomo/node.js:1103 +#: htdocs/luci-static/resources/view/fchomo/node.js:1113 msgid "Minimum streams" msgstr "最小流数量" @@ -1657,7 +1661,7 @@ msgstr "混合 系统 TCP 栈和 gVisor UDP 栈。" msgid "Mixed port" msgstr "混合端口" -#: htdocs/luci-static/resources/view/fchomo/node.js:1082 +#: htdocs/luci-static/resources/view/fchomo/node.js:1083 msgid "Multiplex" msgstr "多路复用" @@ -1675,7 +1679,7 @@ msgstr "多路复用" msgid "NOT" msgstr "NOT" -#: htdocs/luci-static/resources/view/fchomo/node.js:1389 +#: htdocs/luci-static/resources/view/fchomo/node.js:1390 msgid "Name of the Proxy group to download provider." msgstr "用于下载供应商订阅的代理组名称。" @@ -1683,7 +1687,7 @@ msgstr "用于下载供应商订阅的代理组名称。" msgid "Name of the Proxy group to download rule set." msgstr "用于下载规则集订阅的代理组名称。" -#: htdocs/luci-static/resources/view/fchomo/node.js:472 +#: htdocs/luci-static/resources/view/fchomo/node.js:473 msgid "Native UDP" msgstr "原生 UDP" @@ -1700,11 +1704,11 @@ msgid "No add'l params" msgstr "无附加参数" #: htdocs/luci-static/resources/view/fchomo/client.js:1003 -#: htdocs/luci-static/resources/view/fchomo/node.js:1535 +#: htdocs/luci-static/resources/view/fchomo/node.js:1536 msgid "No testing is performed when this provider node is not in use." msgstr "当此供应商的节点未使用时,不执行任何测试。" -#: htdocs/luci-static/resources/fchomo.js:640 +#: htdocs/luci-static/resources/fchomo.js:642 msgid "No valid %s found." msgstr "未找到有效的%s。" @@ -1719,17 +1723,17 @@ msgid "Node" msgstr "节点" #: htdocs/luci-static/resources/view/fchomo/client.js:1048 -#: htdocs/luci-static/resources/view/fchomo/node.js:1555 +#: htdocs/luci-static/resources/view/fchomo/node.js:1556 msgid "Node exclude filter" msgstr "排除节点" #: htdocs/luci-static/resources/view/fchomo/client.js:1053 -#: htdocs/luci-static/resources/view/fchomo/node.js:1562 +#: htdocs/luci-static/resources/view/fchomo/node.js:1563 msgid "Node exclude type" msgstr "排除节点类型" #: htdocs/luci-static/resources/view/fchomo/client.js:1043 -#: htdocs/luci-static/resources/view/fchomo/node.js:1549 +#: htdocs/luci-static/resources/view/fchomo/node.js:1550 msgid "Node filter" msgstr "过滤节点" @@ -1745,11 +1749,11 @@ msgstr "无" msgid "Not Installed" msgstr "未安装" -#: htdocs/luci-static/resources/fchomo.js:1088 +#: htdocs/luci-static/resources/fchomo.js:1112 msgid "Not Running" msgstr "未在运行" -#: htdocs/luci-static/resources/view/fchomo/node.js:692 +#: htdocs/luci-static/resources/view/fchomo/node.js:693 msgid "Obfs Mode" msgstr "Obfs 模式" @@ -1783,7 +1787,7 @@ msgstr "0-63 范围内的一个或多个数字,以逗号分隔" msgid "Only process traffic from specific interfaces. Leave empty for all." msgstr "只处理来自指定接口的流量。留空表示全部。" -#: htdocs/luci-static/resources/fchomo.js:1082 +#: htdocs/luci-static/resources/fchomo.js:1106 msgid "Open Dashboard" msgstr "打开面板" @@ -1797,11 +1801,11 @@ msgid "Override destination" msgstr "覆盖目标地址" #: htdocs/luci-static/resources/view/fchomo/client.js:898 -#: htdocs/luci-static/resources/view/fchomo/node.js:1300 +#: htdocs/luci-static/resources/view/fchomo/node.js:1301 msgid "Override fields" msgstr "覆盖字段" -#: htdocs/luci-static/resources/view/fchomo/node.js:455 +#: htdocs/luci-static/resources/view/fchomo/node.js:456 msgid "Override the IP address of the server that DNS response." msgstr "覆盖 DNS 回应的服务器的 IP 地址。" @@ -1821,43 +1825,43 @@ msgstr "覆盖原始请求中已有的 ECS。" msgid "Overview" msgstr "概览" -#: htdocs/luci-static/resources/view/fchomo/node.js:1028 +#: htdocs/luci-static/resources/view/fchomo/node.js:1029 msgid "POST" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1029 +#: htdocs/luci-static/resources/view/fchomo/node.js:1030 msgid "PUT" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:608 +#: htdocs/luci-static/resources/view/fchomo/node.js:609 msgid "Packet encoding" msgstr "数据包编码" -#: htdocs/luci-static/resources/view/fchomo/server.js:469 +#: htdocs/luci-static/resources/view/fchomo/server.js:481 msgid "Padding scheme" msgstr "填充方案" -#: htdocs/luci-static/resources/view/fchomo/node.js:798 -#: htdocs/luci-static/resources/view/fchomo/server.js:617 +#: htdocs/luci-static/resources/view/fchomo/node.js:799 +#: htdocs/luci-static/resources/view/fchomo/server.js:629 msgid "Paddings" msgstr "填充 (Paddings)" #: htdocs/luci-static/resources/view/fchomo/node.js:261 #: htdocs/luci-static/resources/view/fchomo/node.js:334 -#: htdocs/luci-static/resources/view/fchomo/node.js:707 +#: htdocs/luci-static/resources/view/fchomo/node.js:708 #: htdocs/luci-static/resources/view/fchomo/server.js:221 #: htdocs/luci-static/resources/view/fchomo/server.js:277 -#: htdocs/luci-static/resources/view/fchomo/server.js:510 +#: htdocs/luci-static/resources/view/fchomo/server.js:522 msgid "Password" msgstr "密码" -#: htdocs/luci-static/resources/view/fchomo/node.js:1364 +#: htdocs/luci-static/resources/view/fchomo/node.js:1365 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:349 -#: htdocs/luci-static/resources/view/fchomo/server.js:557 +#: htdocs/luci-static/resources/view/fchomo/server.js:569 msgid "Payload" msgstr "Payload" -#: htdocs/luci-static/resources/view/fchomo/node.js:637 +#: htdocs/luci-static/resources/view/fchomo/node.js:638 msgid "Peer pubkic key" msgstr "对端公钥" @@ -1886,8 +1890,8 @@ msgid "" "standards." msgstr "链接格式标准请参考
%s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1337 -#: htdocs/luci-static/resources/view/fchomo/node.js:1363 +#: htdocs/luci-static/resources/view/fchomo/node.js:1338 +#: htdocs/luci-static/resources/view/fchomo/node.js:1364 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:322 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:348 msgid "" @@ -1901,25 +1905,25 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1195 #: htdocs/luci-static/resources/view/fchomo/client.js:1320 #: htdocs/luci-static/resources/view/fchomo/client.js:1553 -#: htdocs/luci-static/resources/view/fchomo/node.js:1206 +#: htdocs/luci-static/resources/view/fchomo/node.js:1207 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:143 msgid "Please type %s fields of mihomo config.
" msgstr "请输入 mihomo 配置的 %s 字段。
" -#: htdocs/luci-static/resources/view/fchomo/node.js:681 -#: htdocs/luci-static/resources/view/fchomo/server.js:496 +#: htdocs/luci-static/resources/view/fchomo/node.js:682 +#: htdocs/luci-static/resources/view/fchomo/server.js:508 msgid "Plugin" msgstr "插件" -#: htdocs/luci-static/resources/view/fchomo/node.js:692 -#: htdocs/luci-static/resources/view/fchomo/node.js:699 -#: htdocs/luci-static/resources/view/fchomo/node.js:707 -#: htdocs/luci-static/resources/view/fchomo/node.js:713 -#: htdocs/luci-static/resources/view/fchomo/node.js:721 -#: htdocs/luci-static/resources/view/fchomo/node.js:727 -#: htdocs/luci-static/resources/view/fchomo/server.js:503 -#: htdocs/luci-static/resources/view/fchomo/server.js:510 -#: htdocs/luci-static/resources/view/fchomo/server.js:516 +#: htdocs/luci-static/resources/view/fchomo/node.js:693 +#: htdocs/luci-static/resources/view/fchomo/node.js:700 +#: htdocs/luci-static/resources/view/fchomo/node.js:708 +#: htdocs/luci-static/resources/view/fchomo/node.js:714 +#: htdocs/luci-static/resources/view/fchomo/node.js:722 +#: htdocs/luci-static/resources/view/fchomo/node.js:728 +#: htdocs/luci-static/resources/view/fchomo/server.js:515 +#: htdocs/luci-static/resources/view/fchomo/server.js:522 +#: htdocs/luci-static/resources/view/fchomo/server.js:528 msgid "Plugin:" msgstr "插件:" @@ -1927,7 +1931,7 @@ msgstr "插件:" msgid "Port" msgstr "端口" -#: htdocs/luci-static/resources/fchomo.js:1313 +#: htdocs/luci-static/resources/fchomo.js:1343 msgid "Port %s alrealy exists!" msgstr "端口 %s 已存在!" @@ -1944,8 +1948,8 @@ msgstr "端口" msgid "Ports pool" msgstr "端口池" -#: htdocs/luci-static/resources/view/fchomo/node.js:432 -#: htdocs/luci-static/resources/view/fchomo/node.js:644 +#: htdocs/luci-static/resources/view/fchomo/node.js:433 +#: htdocs/luci-static/resources/view/fchomo/node.js:645 msgid "Pre-shared key" msgstr "预共享密钥" @@ -1964,10 +1968,10 @@ msgstr "防止某些情况下的 ICMP 环回问题。Ping 不会显示实际延 #: htdocs/luci-static/resources/view/fchomo/global.js:742 #: htdocs/luci-static/resources/view/fchomo/global.js:759 -#: htdocs/luci-static/resources/view/fchomo/node.js:1170 -#: htdocs/luci-static/resources/view/fchomo/node.js:1176 -#: htdocs/luci-static/resources/view/fchomo/node.js:1484 -#: htdocs/luci-static/resources/view/fchomo/node.js:1491 +#: htdocs/luci-static/resources/view/fchomo/node.js:1171 +#: htdocs/luci-static/resources/view/fchomo/node.js:1177 +#: htdocs/luci-static/resources/view/fchomo/node.js:1485 +#: htdocs/luci-static/resources/view/fchomo/node.js:1492 msgid "Priority: Proxy Node > Global." msgstr "优先级: 代理节点 > 全局。" @@ -1979,7 +1983,7 @@ msgstr "密钥" msgid "Priv-key passphrase" msgstr "密钥密码" -#: htdocs/luci-static/resources/view/fchomo/node.js:629 +#: htdocs/luci-static/resources/view/fchomo/node.js:630 msgid "Private key" msgstr "私钥" @@ -1988,28 +1992,28 @@ msgid "Process matching mode" msgstr "进程匹配模式" #: htdocs/luci-static/resources/view/fchomo/global.js:690 -#: htdocs/luci-static/resources/view/fchomo/node.js:1088 +#: htdocs/luci-static/resources/view/fchomo/node.js:1089 msgid "Protocol" msgstr "协议" -#: htdocs/luci-static/resources/view/fchomo/node.js:603 +#: htdocs/luci-static/resources/view/fchomo/node.js:604 msgid "Protocol parameter. Enable length block encryption." msgstr "协议参数。启用长度块加密。" -#: htdocs/luci-static/resources/view/fchomo/node.js:597 +#: htdocs/luci-static/resources/view/fchomo/node.js:598 msgid "" "Protocol parameter. Will waste traffic randomly if enabled (enabled by " "default in v2ray and cannot be disabled)." msgstr "协议参数。 如启用会随机浪费流量(在 v2ray 中默认启用并且无法禁用)。" #: htdocs/luci-static/resources/view/fchomo/client.js:943 -#: htdocs/luci-static/resources/view/fchomo/node.js:1189 -#: htdocs/luci-static/resources/view/fchomo/node.js:1198 -#: htdocs/luci-static/resources/view/fchomo/node.js:1600 +#: htdocs/luci-static/resources/view/fchomo/node.js:1190 +#: htdocs/luci-static/resources/view/fchomo/node.js:1199 +#: htdocs/luci-static/resources/view/fchomo/node.js:1601 msgid "Provider" msgstr "供应商" -#: htdocs/luci-static/resources/view/fchomo/node.js:1370 +#: htdocs/luci-static/resources/view/fchomo/node.js:1371 msgid "Provider URL" msgstr "供应商订阅 URL" @@ -2032,18 +2036,18 @@ msgid "Proxy MAC-s" msgstr "代理 MAC 地址" #: htdocs/luci-static/resources/view/fchomo/node.js:208 -#: htdocs/luci-static/resources/view/fchomo/node.js:1599 +#: htdocs/luci-static/resources/view/fchomo/node.js:1600 msgid "Proxy Node" msgstr "代理节点" -#: htdocs/luci-static/resources/view/fchomo/node.js:1575 -#: htdocs/luci-static/resources/view/fchomo/node.js:1584 +#: htdocs/luci-static/resources/view/fchomo/node.js:1576 +#: htdocs/luci-static/resources/view/fchomo/node.js:1585 msgid "Proxy chain" msgstr "代理链" #: htdocs/luci-static/resources/view/fchomo/client.js:723 #: htdocs/luci-static/resources/view/fchomo/client.js:1416 -#: htdocs/luci-static/resources/view/fchomo/node.js:1388 +#: htdocs/luci-static/resources/view/fchomo/node.js:1389 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:373 msgid "Proxy group" msgstr "代理组" @@ -2060,12 +2064,12 @@ msgstr "代理模式" msgid "Proxy routerself" msgstr "代理路由器自身" -#: htdocs/luci-static/resources/view/fchomo/node.js:473 +#: htdocs/luci-static/resources/view/fchomo/node.js:474 msgid "QUIC" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:461 -#: htdocs/luci-static/resources/view/fchomo/server.js:417 +#: htdocs/luci-static/resources/view/fchomo/node.js:462 +#: htdocs/luci-static/resources/view/fchomo/server.js:429 msgid "QUIC congestion controller." msgstr "QUIC 拥塞控制器。" @@ -2074,40 +2078,40 @@ msgstr "QUIC 拥塞控制器。" msgid "Quick Reload" msgstr "快速重载" -#: htdocs/luci-static/resources/view/fchomo/node.js:961 -#: htdocs/luci-static/resources/view/fchomo/server.js:881 +#: htdocs/luci-static/resources/view/fchomo/node.js:962 +#: htdocs/luci-static/resources/view/fchomo/server.js:893 msgid "REALITY" msgstr "REALITY" -#: htdocs/luci-static/resources/view/fchomo/node.js:976 +#: htdocs/luci-static/resources/view/fchomo/node.js:977 msgid "REALITY X25519MLKEM768 PQC support" msgstr "REALITY X25519MLKEM768 后量子加密支持" -#: htdocs/luci-static/resources/view/fchomo/server.js:918 +#: htdocs/luci-static/resources/view/fchomo/server.js:930 msgid "REALITY certificate issued to" msgstr "REALITY 证书颁发给" -#: htdocs/luci-static/resources/view/fchomo/server.js:886 +#: htdocs/luci-static/resources/view/fchomo/server.js:898 msgid "REALITY handshake server" msgstr "REALITY 握手服务器" -#: htdocs/luci-static/resources/view/fchomo/server.js:893 +#: htdocs/luci-static/resources/view/fchomo/server.js:905 msgid "REALITY private key" msgstr "REALITY 私钥" -#: htdocs/luci-static/resources/view/fchomo/node.js:966 -#: htdocs/luci-static/resources/view/fchomo/server.js:908 +#: htdocs/luci-static/resources/view/fchomo/node.js:967 +#: htdocs/luci-static/resources/view/fchomo/server.js:920 msgid "REALITY public key" msgstr "REALITY 公钥" -#: htdocs/luci-static/resources/view/fchomo/node.js:971 -#: htdocs/luci-static/resources/view/fchomo/server.js:912 +#: htdocs/luci-static/resources/view/fchomo/node.js:972 +#: htdocs/luci-static/resources/view/fchomo/server.js:924 msgid "REALITY short ID" msgstr "REALITY 标识符" -#: htdocs/luci-static/resources/view/fchomo/node.js:788 -#: htdocs/luci-static/resources/view/fchomo/server.js:588 -#: htdocs/luci-static/resources/view/fchomo/server.js:607 +#: htdocs/luci-static/resources/view/fchomo/node.js:789 +#: htdocs/luci-static/resources/view/fchomo/server.js:600 +#: htdocs/luci-static/resources/view/fchomo/server.js:619 msgid "RTT" msgstr "" @@ -2143,7 +2147,7 @@ msgstr "Redirect TCP + Tun UDP" msgid "Refresh every %s seconds." msgstr "每 %s 秒刷新。" -#: htdocs/luci-static/resources/fchomo.js:1075 +#: htdocs/luci-static/resources/fchomo.js:1099 #: htdocs/luci-static/resources/view/fchomo/client.js:815 #: htdocs/luci-static/resources/view/fchomo/global.js:193 #: htdocs/luci-static/resources/view/fchomo/server.js:153 @@ -2154,32 +2158,32 @@ msgstr "重载" msgid "Reload All" msgstr "重载所有" -#: htdocs/luci-static/resources/view/fchomo/node.js:1315 +#: htdocs/luci-static/resources/view/fchomo/node.js:1316 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:263 msgid "Remote" msgstr "远程" -#: htdocs/luci-static/resources/view/fchomo/node.js:669 +#: htdocs/luci-static/resources/view/fchomo/node.js:670 msgid "Remote DNS resolve" msgstr "远程 DNS 解析" -#: htdocs/luci-static/resources/fchomo.js:1234 +#: htdocs/luci-static/resources/fchomo.js:1264 msgid "Remove" msgstr "移除" -#: htdocs/luci-static/resources/fchomo.js:1239 -#: htdocs/luci-static/resources/view/fchomo/node.js:1291 -#: htdocs/luci-static/resources/view/fchomo/node.js:1293 +#: htdocs/luci-static/resources/fchomo.js:1269 +#: htdocs/luci-static/resources/view/fchomo/node.js:1292 +#: htdocs/luci-static/resources/view/fchomo/node.js:1294 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:236 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:238 msgid "Remove idles" msgstr "移除闲置" -#: htdocs/luci-static/resources/view/fchomo/node.js:1417 +#: htdocs/luci-static/resources/view/fchomo/node.js:1418 msgid "Replace name" msgstr "名称替换" -#: htdocs/luci-static/resources/view/fchomo/node.js:1418 +#: htdocs/luci-static/resources/view/fchomo/node.js:1419 msgid "Replace node name." msgstr "替换节点名称" @@ -2187,13 +2191,13 @@ msgstr "替换节点名称" msgid "Request" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1035 -#: htdocs/luci-static/resources/view/fchomo/node.js:1042 -#: htdocs/luci-static/resources/view/fchomo/server.js:960 +#: htdocs/luci-static/resources/view/fchomo/node.js:1036 +#: htdocs/luci-static/resources/view/fchomo/node.js:1043 +#: htdocs/luci-static/resources/view/fchomo/server.js:972 msgid "Request path" msgstr "请求路径" -#: htdocs/luci-static/resources/view/fchomo/node.js:508 +#: htdocs/luci-static/resources/view/fchomo/node.js:509 msgid "Request timeout" msgstr "请求超时" @@ -2206,11 +2210,11 @@ msgid "Require any" msgstr "" #: htdocs/luci-static/resources/fchomo.js:347 -#: htdocs/luci-static/resources/view/fchomo/node.js:977 +#: htdocs/luci-static/resources/view/fchomo/node.js:978 msgid "Requires server support." msgstr "需要服务器支持。" -#: htdocs/luci-static/resources/view/fchomo/node.js:658 +#: htdocs/luci-static/resources/view/fchomo/node.js:659 msgid "Reserved field bytes" msgstr "保留字段字节" @@ -2218,7 +2222,7 @@ msgstr "保留字段字节" msgid "Resources management" msgstr "资源管理" -#: htdocs/luci-static/resources/view/fchomo/node.js:727 +#: htdocs/luci-static/resources/view/fchomo/node.js:728 msgid "Restls script" msgstr "Restls 剧本" @@ -2245,8 +2249,8 @@ msgstr "路由 DSCP" msgid "Routing GFW" msgstr "路由 GFW 流量" -#: htdocs/luci-static/resources/view/fchomo/node.js:1175 -#: htdocs/luci-static/resources/view/fchomo/node.js:1490 +#: htdocs/luci-static/resources/view/fchomo/node.js:1176 +#: htdocs/luci-static/resources/view/fchomo/node.js:1491 msgid "Routing mark" msgstr "路由标记" @@ -2306,7 +2310,7 @@ msgstr "规则集" msgid "Ruleset-URI-Scheme" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1088 +#: htdocs/luci-static/resources/fchomo.js:1112 msgid "Running" msgstr "正在运行" @@ -2334,7 +2338,7 @@ msgstr "STUN 端口" msgid "SUB-RULE" msgstr "SUB-RULE" -#: htdocs/luci-static/resources/view/fchomo/node.js:745 +#: htdocs/luci-static/resources/view/fchomo/node.js:746 msgid "SUoT version" msgstr "SUoT 版本" @@ -2373,9 +2377,9 @@ msgid "Send random ticket of 300s-600s duration for client 0-RTT reuse." msgstr "发送 300-600 秒的随机票证,以供客户端 0-RTT 重用。" #: htdocs/luci-static/resources/view/fchomo/server.js:166 -#: htdocs/luci-static/resources/view/fchomo/server.js:588 -#: htdocs/luci-static/resources/view/fchomo/server.js:779 -#: htdocs/luci-static/resources/view/fchomo/server.js:794 +#: htdocs/luci-static/resources/view/fchomo/server.js:600 +#: htdocs/luci-static/resources/view/fchomo/server.js:791 +#: htdocs/luci-static/resources/view/fchomo/server.js:806 #: root/usr/share/luci/menu.d/luci-app-fchomo.json:54 msgid "Server" msgstr "服务端" @@ -2384,7 +2388,7 @@ msgstr "服务端" msgid "Server address" msgstr "服务器地址" -#: htdocs/luci-static/resources/view/fchomo/node.js:1020 +#: htdocs/luci-static/resources/view/fchomo/node.js:1021 msgid "Server hostname" msgstr "服务器主机名称" @@ -2401,22 +2405,22 @@ msgstr "服务状态" msgid "Shadowsocks" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:527 -#: htdocs/luci-static/resources/view/fchomo/server.js:451 +#: htdocs/luci-static/resources/view/fchomo/node.js:528 +#: htdocs/luci-static/resources/view/fchomo/server.js:463 msgid "Shadowsocks chipher" msgstr "Shadowsocks 加密方法" -#: htdocs/luci-static/resources/view/fchomo/node.js:522 -#: htdocs/luci-static/resources/view/fchomo/server.js:446 +#: htdocs/luci-static/resources/view/fchomo/node.js:523 +#: htdocs/luci-static/resources/view/fchomo/server.js:458 msgid "Shadowsocks encrypt" msgstr "Shadowsocks 加密" -#: htdocs/luci-static/resources/view/fchomo/node.js:535 -#: htdocs/luci-static/resources/view/fchomo/server.js:459 +#: htdocs/luci-static/resources/view/fchomo/node.js:536 +#: htdocs/luci-static/resources/view/fchomo/server.js:471 msgid "Shadowsocks password" msgstr "Shadowsocks 密码" -#: htdocs/luci-static/resources/view/fchomo/node.js:1130 +#: htdocs/luci-static/resources/view/fchomo/node.js:1131 msgid "Show connections in the dashboard for breaking connections easier." msgstr "在面板中显示连接以便于打断连接。" @@ -2428,14 +2432,14 @@ msgstr "静音" msgid "Simple round-robin all nodes" msgstr "简单轮替所有节点" -#: htdocs/luci-static/resources/view/fchomo/node.js:1376 +#: htdocs/luci-static/resources/view/fchomo/node.js:1377 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:361 msgid "Size limit" msgstr "大小限制" #: htdocs/luci-static/resources/view/fchomo/client.js:1449 -#: htdocs/luci-static/resources/view/fchomo/node.js:903 -#: htdocs/luci-static/resources/view/fchomo/node.js:1468 +#: htdocs/luci-static/resources/view/fchomo/node.js:904 +#: htdocs/luci-static/resources/view/fchomo/node.js:1469 msgid "Skip cert verify" msgstr "跳过证书验证" @@ -2467,6 +2471,10 @@ msgstr "嗅探器" msgid "Sniffer settings" msgstr "嗅探器设置" +#: htdocs/luci-static/resources/fchomo.js:385 +msgid "Specify a ID" +msgstr "指定一个ID" + #: htdocs/luci-static/resources/view/fchomo/global.js:823 #: htdocs/luci-static/resources/view/fchomo/global.js:832 msgid "" @@ -2500,7 +2508,7 @@ msgstr "子规则" msgid "Sub rule group" msgstr "子规则组" -#: htdocs/luci-static/resources/fchomo.js:643 +#: htdocs/luci-static/resources/fchomo.js:645 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:207 msgid "Successfully imported %s %s of total %s." msgstr "已成功导入 %s 个%s (共 %s 个)。" @@ -2509,7 +2517,7 @@ msgstr "已成功导入 %s 个%s (共 %s 个)。" msgid "Successfully updated." msgstr "更新成功。" -#: htdocs/luci-static/resources/fchomo.js:1568 +#: htdocs/luci-static/resources/fchomo.js:1614 msgid "Successfully uploaded." msgstr "已成功上传。" @@ -2557,7 +2565,7 @@ msgstr "TCP" msgid "TCP concurrency" msgstr "TCP 并发" -#: htdocs/luci-static/resources/view/fchomo/node.js:1123 +#: htdocs/luci-static/resources/view/fchomo/node.js:1124 msgid "TCP only" msgstr "仅 TCP" @@ -2580,24 +2588,24 @@ msgstr "TCP-Keep-Alive 间隔" msgid "TCP/UDP" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1154 -#: htdocs/luci-static/resources/view/fchomo/node.js:1435 +#: htdocs/luci-static/resources/view/fchomo/node.js:1155 +#: htdocs/luci-static/resources/view/fchomo/node.js:1436 msgid "TFO" msgstr "TCP 快速打开 (TFO)" #: htdocs/luci-static/resources/view/fchomo/global.js:529 -#: htdocs/luci-static/resources/view/fchomo/node.js:694 -#: htdocs/luci-static/resources/view/fchomo/node.js:820 -#: htdocs/luci-static/resources/view/fchomo/server.js:742 +#: htdocs/luci-static/resources/view/fchomo/node.js:695 +#: htdocs/luci-static/resources/view/fchomo/node.js:821 +#: htdocs/luci-static/resources/view/fchomo/server.js:754 msgid "TLS" msgstr "TLS" -#: htdocs/luci-static/resources/view/fchomo/node.js:851 -#: htdocs/luci-static/resources/view/fchomo/server.js:773 +#: htdocs/luci-static/resources/view/fchomo/node.js:852 +#: htdocs/luci-static/resources/view/fchomo/server.js:785 msgid "TLS ALPN" msgstr "TLS ALPN" -#: htdocs/luci-static/resources/view/fchomo/node.js:845 +#: htdocs/luci-static/resources/view/fchomo/node.js:846 msgid "TLS SNI" msgstr "" @@ -2620,24 +2628,24 @@ msgid "" "Tell the client to use the BBR flow control algorithm instead of Hysteria CC." msgstr "让客户端使用 BBR 流控算法。" -#: htdocs/luci-static/resources/view/fchomo/node.js:617 -#: htdocs/luci-static/resources/view/fchomo/node.js:624 +#: htdocs/luci-static/resources/view/fchomo/node.js:618 +#: htdocs/luci-static/resources/view/fchomo/node.js:625 msgid "The %s address used by local machine in the Wireguard network." msgstr "WireGuard 网络中使用的本机 %s 地址。" -#: htdocs/luci-static/resources/view/fchomo/node.js:926 -#: htdocs/luci-static/resources/view/fchomo/server.js:794 +#: htdocs/luci-static/resources/view/fchomo/node.js:927 +#: htdocs/luci-static/resources/view/fchomo/server.js:806 msgid "The %s private key, in PEM format." msgstr "%s私钥,需要 PEM 格式。" #: htdocs/luci-static/resources/view/fchomo/global.js:556 -#: htdocs/luci-static/resources/view/fchomo/node.js:912 -#: htdocs/luci-static/resources/view/fchomo/server.js:779 -#: htdocs/luci-static/resources/view/fchomo/server.js:817 +#: htdocs/luci-static/resources/view/fchomo/node.js:913 +#: htdocs/luci-static/resources/view/fchomo/server.js:791 +#: htdocs/luci-static/resources/view/fchomo/server.js:829 msgid "The %s public key, in PEM format." msgstr "%s公钥,需要 PEM 格式。" -#: htdocs/luci-static/resources/view/fchomo/node.js:946 +#: htdocs/luci-static/resources/view/fchomo/node.js:947 msgid "" "The ECH parameter of the HTTPS record for the domain. Leave empty to resolve " "via DNS." @@ -2655,8 +2663,8 @@ msgstr "Sudoku 生成的 ED25519 主公钥 或 UUID。" msgid "The default value is 2:00 every day." msgstr "默认值为每天 2:00。" -#: htdocs/luci-static/resources/view/fchomo/node.js:801 -#: htdocs/luci-static/resources/view/fchomo/server.js:620 +#: htdocs/luci-static/resources/view/fchomo/node.js:802 +#: htdocs/luci-static/resources/view/fchomo/server.js:632 msgid "" "The first padding must have a probability of 100% and at least 35 bytes." msgstr "首个填充必须为 100% 的概率并且至少 35 字节。" @@ -2671,26 +2679,26 @@ msgstr "匹配 %s 的将被视为未被投毒污染。" msgid "The matching %s will be deemed as poisoned." msgstr "匹配 %s 的将被视为已被投毒污染。" -#: htdocs/luci-static/resources/view/fchomo/node.js:799 -#: htdocs/luci-static/resources/view/fchomo/server.js:618 +#: htdocs/luci-static/resources/view/fchomo/node.js:800 +#: htdocs/luci-static/resources/view/fchomo/server.js:630 msgid "The server and client can set different padding parameters." msgstr "服务器和客户端可以设置不同的填充参数。" #: htdocs/luci-static/resources/view/fchomo/global.js:600 -#: htdocs/luci-static/resources/view/fchomo/server.js:875 +#: htdocs/luci-static/resources/view/fchomo/server.js:887 msgid "This ECH parameter needs to be added to the HTTPS record of the domain." msgstr "此 ECH 参数需要添加到域名的 HTTPS 记录中。" #: htdocs/luci-static/resources/view/fchomo/client.js:1452 -#: htdocs/luci-static/resources/view/fchomo/node.js:906 -#: htdocs/luci-static/resources/view/fchomo/node.js:1471 +#: htdocs/luci-static/resources/view/fchomo/node.js:907 +#: htdocs/luci-static/resources/view/fchomo/node.js:1472 msgid "" "This is DANGEROUS, your traffic is almost like " "PLAIN TEXT! Use at your own risk!" msgstr "" "这是危险行为,您的流量将几乎等同于明文!使用风险自负!" -#: htdocs/luci-static/resources/view/fchomo/node.js:478 +#: htdocs/luci-static/resources/view/fchomo/node.js:479 msgid "" "This is the TUIC port of the SUoT protocol, designed to provide a QUIC " "stream based UDP relay mode that TUIC does not provide." @@ -2722,18 +2730,18 @@ msgstr "Tproxy Fwmark/fwmask" msgid "Tproxy port" msgstr "Tproxy 端口" -#: htdocs/luci-static/resources/view/fchomo/node.js:1627 +#: htdocs/luci-static/resources/view/fchomo/node.js:1628 msgid "Transit proxy group" msgstr "中转代理组" -#: htdocs/luci-static/resources/view/fchomo/node.js:1633 +#: htdocs/luci-static/resources/view/fchomo/node.js:1634 msgid "Transit proxy node" msgstr "中转代理节点" #: htdocs/luci-static/resources/view/fchomo/node.js:349 -#: htdocs/luci-static/resources/view/fchomo/node.js:983 +#: htdocs/luci-static/resources/view/fchomo/node.js:984 #: htdocs/luci-static/resources/view/fchomo/server.js:287 -#: htdocs/luci-static/resources/view/fchomo/server.js:926 +#: htdocs/luci-static/resources/view/fchomo/server.js:938 msgid "Transport" msgstr "传输层" @@ -2742,8 +2750,8 @@ msgstr "传输层" msgid "Transport fields" msgstr "传输层字段" -#: htdocs/luci-static/resources/view/fchomo/node.js:988 -#: htdocs/luci-static/resources/view/fchomo/server.js:931 +#: htdocs/luci-static/resources/view/fchomo/node.js:989 +#: htdocs/luci-static/resources/view/fchomo/server.js:943 msgid "Transport type" msgstr "传输层类型" @@ -2778,8 +2786,8 @@ msgstr "Tun 堆栈" #: htdocs/luci-static/resources/view/fchomo/client.js:916 #: htdocs/luci-static/resources/view/fchomo/client.js:1594 #: htdocs/luci-static/resources/view/fchomo/node.js:238 -#: htdocs/luci-static/resources/view/fchomo/node.js:1313 -#: htdocs/luci-static/resources/view/fchomo/node.js:1598 +#: htdocs/luci-static/resources/view/fchomo/node.js:1314 +#: htdocs/luci-static/resources/view/fchomo/node.js:1599 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:261 #: htdocs/luci-static/resources/view/fchomo/server.js:193 msgid "Type" @@ -2792,9 +2800,9 @@ msgstr "类型" #: htdocs/luci-static/resources/fchomo.js:172 #: htdocs/luci-static/resources/view/fchomo/client.js:526 #: htdocs/luci-static/resources/view/fchomo/client.js:616 -#: htdocs/luci-static/resources/view/fchomo/node.js:734 -#: htdocs/luci-static/resources/view/fchomo/node.js:1445 -#: htdocs/luci-static/resources/view/fchomo/server.js:525 +#: htdocs/luci-static/resources/view/fchomo/node.js:735 +#: htdocs/luci-static/resources/view/fchomo/node.js:1446 +#: htdocs/luci-static/resources/view/fchomo/server.js:537 msgid "UDP" msgstr "UDP" @@ -2802,19 +2810,19 @@ msgstr "UDP" msgid "UDP NAT expiration time" msgstr "UDP NAT 过期时间" -#: htdocs/luci-static/resources/view/fchomo/node.js:477 +#: htdocs/luci-static/resources/view/fchomo/node.js:478 msgid "UDP over stream" msgstr "UDP over stream" -#: htdocs/luci-static/resources/view/fchomo/node.js:483 +#: htdocs/luci-static/resources/view/fchomo/node.js:484 msgid "UDP over stream version" msgstr "UDP over stream 版本" -#: htdocs/luci-static/resources/view/fchomo/node.js:470 +#: htdocs/luci-static/resources/view/fchomo/node.js:471 msgid "UDP packet relay mode." msgstr "UDP 包中继模式。" -#: htdocs/luci-static/resources/view/fchomo/node.js:469 +#: htdocs/luci-static/resources/view/fchomo/node.js:470 msgid "UDP relay mode" msgstr "UDP 中继模式" @@ -2822,15 +2830,15 @@ msgstr "UDP 中继模式" msgid "URL test" msgstr "自动选择" -#: htdocs/luci-static/resources/view/fchomo/node.js:448 -#: htdocs/luci-static/resources/view/fchomo/node.js:566 +#: htdocs/luci-static/resources/view/fchomo/node.js:449 +#: htdocs/luci-static/resources/view/fchomo/node.js:567 #: htdocs/luci-static/resources/view/fchomo/server.js:297 -#: htdocs/luci-static/resources/view/fchomo/server.js:410 -#: htdocs/luci-static/resources/view/fchomo/server.js:474 +#: htdocs/luci-static/resources/view/fchomo/server.js:422 +#: htdocs/luci-static/resources/view/fchomo/server.js:486 msgid "UUID" msgstr "UUID" -#: htdocs/luci-static/resources/fchomo.js:1133 +#: htdocs/luci-static/resources/fchomo.js:1157 msgid "Unable to download unsupported type: %s" msgstr "无法下载不支持的类型: %s" @@ -2855,8 +2863,8 @@ msgstr "未知错误。" msgid "Unknown error: %s" msgstr "未知错误:%s" -#: htdocs/luci-static/resources/view/fchomo/node.js:739 -#: htdocs/luci-static/resources/view/fchomo/node.js:1450 +#: htdocs/luci-static/resources/view/fchomo/node.js:740 +#: htdocs/luci-static/resources/view/fchomo/node.js:1451 msgid "UoT" msgstr "UDP over TCP (UoT)" @@ -2864,29 +2872,29 @@ msgstr "UDP over TCP (UoT)" msgid "Update failed." msgstr "更新失败。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1382 +#: htdocs/luci-static/resources/view/fchomo/node.js:1383 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:367 msgid "Update interval" msgstr "更新间隔" -#: htdocs/luci-static/resources/view/fchomo/node.js:426 -#: htdocs/luci-static/resources/view/fchomo/server.js:404 +#: htdocs/luci-static/resources/view/fchomo/node.js:427 +#: htdocs/luci-static/resources/view/fchomo/server.js:416 msgid "" "Uplink keeps the Sudoku protocol, and downlink characteristics are " "consistent with uplink characteristics." msgstr "上行链路保持数独协议,下行链路特性与上行链路特性一致。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1141 +#: htdocs/luci-static/resources/view/fchomo/node.js:1142 msgid "Upload bandwidth" msgstr "上传带宽" -#: htdocs/luci-static/resources/view/fchomo/node.js:1142 +#: htdocs/luci-static/resources/view/fchomo/node.js:1143 msgid "Upload bandwidth in Mbps." msgstr "上传带宽(单位:Mbps)。" -#: htdocs/luci-static/resources/view/fchomo/node.js:917 -#: htdocs/luci-static/resources/view/fchomo/server.js:785 -#: htdocs/luci-static/resources/view/fchomo/server.js:825 +#: htdocs/luci-static/resources/view/fchomo/node.js:918 +#: htdocs/luci-static/resources/view/fchomo/server.js:797 +#: htdocs/luci-static/resources/view/fchomo/server.js:837 msgid "Upload certificate" msgstr "上传证书" @@ -2894,17 +2902,17 @@ msgstr "上传证书" msgid "Upload initial package" msgstr "上传初始资源包" -#: htdocs/luci-static/resources/view/fchomo/node.js:931 -#: htdocs/luci-static/resources/view/fchomo/server.js:800 +#: htdocs/luci-static/resources/view/fchomo/node.js:932 +#: htdocs/luci-static/resources/view/fchomo/server.js:812 msgid "Upload key" msgstr "上传密钥" #: htdocs/luci-static/resources/view/fchomo/global.js:306 -#: htdocs/luci-static/resources/view/fchomo/node.js:920 -#: htdocs/luci-static/resources/view/fchomo/node.js:934 -#: htdocs/luci-static/resources/view/fchomo/server.js:788 -#: htdocs/luci-static/resources/view/fchomo/server.js:803 -#: htdocs/luci-static/resources/view/fchomo/server.js:828 +#: htdocs/luci-static/resources/view/fchomo/node.js:921 +#: htdocs/luci-static/resources/view/fchomo/node.js:935 +#: htdocs/luci-static/resources/view/fchomo/server.js:800 +#: htdocs/luci-static/resources/view/fchomo/server.js:815 +#: htdocs/luci-static/resources/view/fchomo/server.js:840 msgid "Upload..." msgstr "上传..." @@ -2928,7 +2936,7 @@ msgstr "用于解析 DNS 服务器的域名。必须是 IP。" msgid "Used to resolve the domain of the Proxy node." msgstr "用于解析代理节点的域名。" -#: htdocs/luci-static/resources/view/fchomo/node.js:846 +#: htdocs/luci-static/resources/view/fchomo/node.js:847 msgid "Used to verify the hostname on the returned certificates." msgstr "用于验证返回的证书上的主机名。" @@ -2945,11 +2953,11 @@ msgstr "用户名" msgid "Users filter mode" msgstr "使用者过滤模式" -#: htdocs/luci-static/resources/view/fchomo/node.js:1071 +#: htdocs/luci-static/resources/view/fchomo/node.js:1072 msgid "V2ray HTTPUpgrade" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1076 +#: htdocs/luci-static/resources/view/fchomo/node.js:1077 msgid "V2ray HTTPUpgrade fast open" msgstr "" @@ -2963,8 +2971,8 @@ msgstr "" msgid "VMess" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1319 -#: htdocs/luci-static/resources/view/fchomo/node.js:1604 +#: htdocs/luci-static/resources/view/fchomo/node.js:1320 +#: htdocs/luci-static/resources/view/fchomo/node.js:1605 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:304 msgid "Value" msgstr "可视化值" @@ -2973,13 +2981,13 @@ msgstr "可视化值" msgid "Verify if given" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:439 -#: htdocs/luci-static/resources/view/fchomo/node.js:713 -#: htdocs/luci-static/resources/view/fchomo/server.js:516 +#: htdocs/luci-static/resources/view/fchomo/node.js:440 +#: htdocs/luci-static/resources/view/fchomo/node.js:714 +#: htdocs/luci-static/resources/view/fchomo/server.js:528 msgid "Version" msgstr "版本" -#: htdocs/luci-static/resources/view/fchomo/node.js:721 +#: htdocs/luci-static/resources/view/fchomo/node.js:722 msgid "Version hint" msgstr "" @@ -2996,17 +3004,17 @@ msgstr "以 75% 的概率等待随机 0-111 毫秒。" msgid "Warning" msgstr "警告" -#: htdocs/luci-static/resources/view/fchomo/node.js:993 -#: htdocs/luci-static/resources/view/fchomo/node.js:1004 -#: htdocs/luci-static/resources/view/fchomo/node.js:1009 -#: htdocs/luci-static/resources/view/fchomo/server.js:933 -#: htdocs/luci-static/resources/view/fchomo/server.js:944 -#: htdocs/luci-static/resources/view/fchomo/server.js:949 +#: htdocs/luci-static/resources/view/fchomo/node.js:994 +#: htdocs/luci-static/resources/view/fchomo/node.js:1005 +#: htdocs/luci-static/resources/view/fchomo/node.js:1010 +#: htdocs/luci-static/resources/view/fchomo/server.js:945 +#: htdocs/luci-static/resources/view/fchomo/server.js:956 +#: htdocs/luci-static/resources/view/fchomo/server.js:961 msgid "WebSocket" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:425 -#: htdocs/luci-static/resources/view/fchomo/server.js:403 +#: htdocs/luci-static/resources/view/fchomo/node.js:426 +#: htdocs/luci-static/resources/view/fchomo/server.js:415 msgid "" "When disabled, downlink ciphertext is split into 6-bit segments, reusing the " "original padding pool and obfuscate type to reduce downlink overhead." @@ -3025,23 +3033,23 @@ msgstr "白名单" msgid "WireGuard" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:638 +#: htdocs/luci-static/resources/view/fchomo/node.js:639 msgid "WireGuard peer public key." msgstr "WireGuard 对端公钥。" -#: htdocs/luci-static/resources/view/fchomo/node.js:645 +#: htdocs/luci-static/resources/view/fchomo/node.js:646 msgid "WireGuard pre-shared key." msgstr "WireGuard 预共享密钥。" -#: htdocs/luci-static/resources/view/fchomo/node.js:630 +#: htdocs/luci-static/resources/view/fchomo/node.js:631 msgid "WireGuard requires base64-encoded private keys." msgstr "WireGuard 要求 base64 编码的私钥。" -#: htdocs/luci-static/resources/view/fchomo/server.js:579 +#: htdocs/luci-static/resources/view/fchomo/server.js:591 msgid "XOR mode" msgstr "XOR 模式" -#: htdocs/luci-static/resources/view/fchomo/node.js:611 +#: htdocs/luci-static/resources/view/fchomo/node.js:612 msgid "Xudp (Xray-core)" msgstr "" @@ -3053,14 +3061,14 @@ msgstr "Yaml 格式文本" msgid "YouTube" msgstr "油管" -#: htdocs/luci-static/resources/fchomo.js:1550 +#: htdocs/luci-static/resources/fchomo.js:1596 msgid "Your %s was successfully uploaded. Size: %sB." msgstr "您的 %s 已成功上传。大小:%sB。" #: htdocs/luci-static/resources/fchomo.js:289 #: htdocs/luci-static/resources/fchomo.js:302 #: htdocs/luci-static/resources/fchomo.js:307 -#: htdocs/luci-static/resources/view/fchomo/node.js:591 +#: htdocs/luci-static/resources/view/fchomo/node.js:592 msgid "aes-128-gcm" msgstr "" @@ -3073,18 +3081,18 @@ msgstr "" msgid "aes-256-gcm" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:588 +#: htdocs/luci-static/resources/view/fchomo/node.js:589 msgid "auto" msgstr "自动" -#: htdocs/luci-static/resources/view/fchomo/node.js:465 -#: htdocs/luci-static/resources/view/fchomo/server.js:421 +#: htdocs/luci-static/resources/view/fchomo/node.js:466 +#: htdocs/luci-static/resources/view/fchomo/server.js:433 msgid "bbr" msgstr "bbr" -#: htdocs/luci-static/resources/view/fchomo/node.js:922 -#: htdocs/luci-static/resources/view/fchomo/server.js:790 -#: htdocs/luci-static/resources/view/fchomo/server.js:830 +#: htdocs/luci-static/resources/view/fchomo/node.js:923 +#: htdocs/luci-static/resources/view/fchomo/server.js:802 +#: htdocs/luci-static/resources/view/fchomo/server.js:842 msgid "certificate" msgstr "证书" @@ -3094,17 +3102,17 @@ msgstr "证书" msgid "chacha20-ietf-poly1305" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:592 +#: htdocs/luci-static/resources/view/fchomo/node.js:593 msgid "chacha20-poly1305" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:463 -#: htdocs/luci-static/resources/view/fchomo/server.js:419 +#: htdocs/luci-static/resources/view/fchomo/node.js:464 +#: htdocs/luci-static/resources/view/fchomo/server.js:431 msgid "cubic" msgstr "cubic" -#: htdocs/luci-static/resources/view/fchomo/server.js:531 -#: htdocs/luci-static/resources/view/fchomo/server.js:562 +#: htdocs/luci-static/resources/view/fchomo/server.js:543 +#: htdocs/luci-static/resources/view/fchomo/server.js:574 msgid "decryption" msgstr "decryption" @@ -3112,27 +3120,27 @@ msgstr "decryption" msgid "dnsmasq selects upstream on its own. (may affect CDN accuracy)" msgstr "dnsmasq 自行选择上游服务器。 (可能影响 CDN 准确性)" -#: htdocs/luci-static/resources/view/fchomo/node.js:1462 +#: htdocs/luci-static/resources/view/fchomo/node.js:1463 msgid "down" msgstr "Hysteria 下载速率" -#: htdocs/luci-static/resources/view/fchomo/node.js:753 -#: htdocs/luci-static/resources/view/fchomo/node.js:776 -#: htdocs/luci-static/resources/view/fchomo/server.js:566 +#: htdocs/luci-static/resources/view/fchomo/node.js:754 +#: htdocs/luci-static/resources/view/fchomo/node.js:777 +#: htdocs/luci-static/resources/view/fchomo/server.js:578 msgid "encryption" msgstr "encryption" -#: htdocs/luci-static/resources/view/fchomo/node.js:992 -#: htdocs/luci-static/resources/view/fchomo/node.js:1003 -#: htdocs/luci-static/resources/view/fchomo/node.js:1008 -#: htdocs/luci-static/resources/view/fchomo/server.js:932 -#: htdocs/luci-static/resources/view/fchomo/server.js:943 -#: htdocs/luci-static/resources/view/fchomo/server.js:948 +#: htdocs/luci-static/resources/view/fchomo/node.js:993 +#: htdocs/luci-static/resources/view/fchomo/node.js:1004 +#: htdocs/luci-static/resources/view/fchomo/node.js:1009 +#: htdocs/luci-static/resources/view/fchomo/server.js:944 +#: htdocs/luci-static/resources/view/fchomo/server.js:955 +#: htdocs/luci-static/resources/view/fchomo/server.js:960 msgid "gRPC" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1055 -#: htdocs/luci-static/resources/view/fchomo/server.js:967 +#: htdocs/luci-static/resources/view/fchomo/node.js:1056 +#: htdocs/luci-static/resources/view/fchomo/server.js:979 msgid "gRPC service name" msgstr "gRPC 服务名称" @@ -3140,11 +3148,11 @@ msgstr "gRPC 服务名称" msgid "gVisor" msgstr "gVisor" -#: htdocs/luci-static/resources/view/fchomo/node.js:1092 +#: htdocs/luci-static/resources/view/fchomo/node.js:1093 msgid "h2mux" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:731 +#: htdocs/luci-static/resources/view/fchomo/server.js:743 msgid "least one keypair required" msgstr "至少需要一对密钥" @@ -3157,7 +3165,7 @@ msgstr "metacubexd" #: htdocs/luci-static/resources/view/fchomo/client.js:1216 #: htdocs/luci-static/resources/view/fchomo/client.js:1353 #: htdocs/luci-static/resources/view/fchomo/client.js:1571 -#: htdocs/luci-static/resources/view/fchomo/node.js:1285 +#: htdocs/luci-static/resources/view/fchomo/node.js:1286 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:224 msgid "mihomo config" msgstr "mihomo 配置" @@ -3166,13 +3174,13 @@ msgstr "mihomo 配置" msgid "mlkem768x25519plus" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1158 -#: htdocs/luci-static/resources/view/fchomo/node.js:1440 +#: htdocs/luci-static/resources/view/fchomo/node.js:1159 +#: htdocs/luci-static/resources/view/fchomo/node.js:1441 msgid "mpTCP" msgstr "多路径 TCP (mpTCP)" -#: htdocs/luci-static/resources/view/fchomo/node.js:464 -#: htdocs/luci-static/resources/view/fchomo/server.js:420 +#: htdocs/luci-static/resources/view/fchomo/node.js:465 +#: htdocs/luci-static/resources/view/fchomo/server.js:432 msgid "new_reno" msgstr "new_reno" @@ -3180,21 +3188,21 @@ msgstr "new_reno" msgid "no-resolve" msgstr "no-resolve" -#: htdocs/luci-static/resources/fchomo.js:1301 -#: htdocs/luci-static/resources/fchomo.js:1396 -#: htdocs/luci-static/resources/fchomo.js:1431 -#: htdocs/luci-static/resources/fchomo.js:1443 +#: htdocs/luci-static/resources/fchomo.js:1331 +#: htdocs/luci-static/resources/fchomo.js:1426 +#: htdocs/luci-static/resources/fchomo.js:1461 +#: htdocs/luci-static/resources/fchomo.js:1489 msgid "non-empty value" msgstr "非空值" #: htdocs/luci-static/resources/fchomo.js:287 #: htdocs/luci-static/resources/fchomo.js:301 #: htdocs/luci-static/resources/fchomo.js:313 -#: htdocs/luci-static/resources/view/fchomo/node.js:589 -#: htdocs/luci-static/resources/view/fchomo/node.js:609 -#: htdocs/luci-static/resources/view/fchomo/node.js:682 +#: htdocs/luci-static/resources/view/fchomo/node.js:590 +#: htdocs/luci-static/resources/view/fchomo/node.js:610 +#: htdocs/luci-static/resources/view/fchomo/node.js:683 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:300 -#: htdocs/luci-static/resources/view/fchomo/server.js:497 +#: htdocs/luci-static/resources/view/fchomo/server.js:509 msgid "none" msgstr "无" @@ -3210,20 +3218,20 @@ msgstr "不包含 \",\"" msgid "null" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:683 +#: htdocs/luci-static/resources/view/fchomo/node.js:684 msgid "obfs-simple" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1420 +#: htdocs/luci-static/resources/view/fchomo/node.js:1421 msgid "override.proxy-name" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:610 +#: htdocs/luci-static/resources/view/fchomo/node.js:611 msgid "packet addr (v2ray-core v5+)" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:936 -#: htdocs/luci-static/resources/view/fchomo/server.js:805 +#: htdocs/luci-static/resources/view/fchomo/node.js:937 +#: htdocs/luci-static/resources/view/fchomo/server.js:817 msgid "private key" msgstr "私钥" @@ -3236,7 +3244,7 @@ msgstr "razord-meta" msgid "requires front-end adaptation using the API." msgstr "需要使用 API 的前端适配。" -#: htdocs/luci-static/resources/view/fchomo/node.js:687 +#: htdocs/luci-static/resources/view/fchomo/node.js:688 msgid "restls" msgstr "" @@ -3244,12 +3252,12 @@ msgstr "" msgid "rule-set" msgstr "规则集" -#: htdocs/luci-static/resources/view/fchomo/node.js:686 -#: htdocs/luci-static/resources/view/fchomo/server.js:498 +#: htdocs/luci-static/resources/view/fchomo/node.js:687 +#: htdocs/luci-static/resources/view/fchomo/server.js:510 msgid "shadow-tls" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1090 +#: htdocs/luci-static/resources/view/fchomo/node.js:1091 msgid "smux" msgstr "" @@ -3265,70 +3273,75 @@ msgstr "" msgid "unchecked" msgstr "未检查" -#: htdocs/luci-static/resources/fchomo.js:396 +#: htdocs/luci-static/resources/fchomo.js:398 msgid "unique UCI identifier" msgstr "独立 UCI 标识" -#: htdocs/luci-static/resources/fchomo.js:399 +#: htdocs/luci-static/resources/fchomo.js:401 msgid "unique identifier" msgstr "独立标识" -#: htdocs/luci-static/resources/fchomo.js:1452 +#: htdocs/luci-static/resources/fchomo.js:1498 msgid "unique value" msgstr "独立值" -#: htdocs/luci-static/resources/view/fchomo/node.js:1456 +#: htdocs/luci-static/resources/view/fchomo/node.js:1457 msgid "up" msgstr "Hysteria 上传速率" -#: htdocs/luci-static/resources/view/fchomo/node.js:440 -#: htdocs/luci-static/resources/view/fchomo/node.js:484 -#: htdocs/luci-static/resources/view/fchomo/node.js:714 -#: htdocs/luci-static/resources/view/fchomo/node.js:746 -#: htdocs/luci-static/resources/view/fchomo/server.js:517 -msgid "v1" -msgstr "" - #: htdocs/luci-static/resources/view/fchomo/node.js:441 +#: htdocs/luci-static/resources/view/fchomo/node.js:485 #: htdocs/luci-static/resources/view/fchomo/node.js:715 #: htdocs/luci-static/resources/view/fchomo/node.js:747 -#: htdocs/luci-static/resources/view/fchomo/server.js:518 -msgid "v2" +#: htdocs/luci-static/resources/view/fchomo/server.js:529 +msgid "v1" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:442 #: htdocs/luci-static/resources/view/fchomo/node.js:716 -#: htdocs/luci-static/resources/view/fchomo/server.js:519 +#: htdocs/luci-static/resources/view/fchomo/node.js:748 +#: htdocs/luci-static/resources/view/fchomo/server.js:530 +msgid "v2" +msgstr "" + +#: htdocs/luci-static/resources/view/fchomo/node.js:443 +#: htdocs/luci-static/resources/view/fchomo/node.js:717 +#: htdocs/luci-static/resources/view/fchomo/server.js:531 msgid "v3" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1348 -#: htdocs/luci-static/resources/fchomo.js:1351 +#: htdocs/luci-static/resources/fchomo.js:1378 +#: htdocs/luci-static/resources/fchomo.js:1381 msgid "valid JSON format" msgstr "有效的 JSON 格式" -#: htdocs/luci-static/resources/view/fchomo/node.js:896 +#: htdocs/luci-static/resources/view/fchomo/node.js:897 msgid "valid SHA256 string with %d characters" msgstr "包含 %d 个字符的有效 SHA256 字符串" -#: htdocs/luci-static/resources/fchomo.js:1373 -#: htdocs/luci-static/resources/fchomo.js:1376 +#: htdocs/luci-static/resources/fchomo.js:1403 +#: htdocs/luci-static/resources/fchomo.js:1406 msgid "valid URL" msgstr "有效网址" -#: htdocs/luci-static/resources/fchomo.js:1386 +#: htdocs/luci-static/resources/fchomo.js:1416 msgid "valid base64 key with %d characters" msgstr "包含 %d 个字符的有效 base64 密钥" -#: htdocs/luci-static/resources/fchomo.js:1433 +#: htdocs/luci-static/resources/fchomo.js:1476 +#: htdocs/luci-static/resources/fchomo.js:1482 +msgid "valid format: 2x, 2p, 4v" +msgstr "" + +#: htdocs/luci-static/resources/fchomo.js:1463 msgid "valid key length with %d characters" msgstr "包含 %d 个字符的有效密钥" -#: htdocs/luci-static/resources/fchomo.js:1311 +#: htdocs/luci-static/resources/fchomo.js:1341 msgid "valid port value" msgstr "有效端口值" -#: htdocs/luci-static/resources/fchomo.js:1361 +#: htdocs/luci-static/resources/fchomo.js:1391 msgid "valid uuid" msgstr "有效 uuid" @@ -3348,7 +3361,7 @@ msgstr "" msgid "yacd-meta" msgstr "yacd-meta" -#: htdocs/luci-static/resources/view/fchomo/node.js:1091 +#: htdocs/luci-static/resources/view/fchomo/node.js:1092 msgid "yamux" msgstr "" @@ -3356,11 +3369,11 @@ msgstr "" msgid "zashboard" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:590 +#: htdocs/luci-static/resources/view/fchomo/node.js:591 msgid "zero" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1135 +#: htdocs/luci-static/resources/fchomo.js:1159 msgid "🡇" msgstr "" diff --git a/small/luci-app-fchomo/po/zh_Hant/fchomo.po b/small/luci-app-fchomo/po/zh_Hant/fchomo.po index 2a5856c7e8..b5200eb2fd 100644 --- a/small/luci-app-fchomo/po/zh_Hant/fchomo.po +++ b/small/luci-app-fchomo/po/zh_Hant/fchomo.po @@ -12,21 +12,21 @@ msgstr "" msgid "%s log" msgstr "%s 日誌" -#: htdocs/luci-static/resources/fchomo.js:558 -#: htdocs/luci-static/resources/fchomo.js:561 +#: htdocs/luci-static/resources/fchomo.js:560 +#: htdocs/luci-static/resources/fchomo.js:563 #: htdocs/luci-static/resources/view/fchomo/client.js:293 msgid "(Imported)" msgstr "(已導入)" #: htdocs/luci-static/resources/view/fchomo/global.js:549 #: htdocs/luci-static/resources/view/fchomo/global.js:555 -#: htdocs/luci-static/resources/view/fchomo/node.js:911 -#: htdocs/luci-static/resources/view/fchomo/node.js:917 -#: htdocs/luci-static/resources/view/fchomo/node.js:925 -#: htdocs/luci-static/resources/view/fchomo/node.js:931 -#: htdocs/luci-static/resources/view/fchomo/server.js:808 -#: htdocs/luci-static/resources/view/fchomo/server.js:816 -#: htdocs/luci-static/resources/view/fchomo/server.js:825 +#: htdocs/luci-static/resources/view/fchomo/node.js:912 +#: htdocs/luci-static/resources/view/fchomo/node.js:918 +#: htdocs/luci-static/resources/view/fchomo/node.js:926 +#: htdocs/luci-static/resources/view/fchomo/node.js:932 +#: htdocs/luci-static/resources/view/fchomo/server.js:820 +#: htdocs/luci-static/resources/view/fchomo/server.js:828 +#: htdocs/luci-static/resources/view/fchomo/server.js:837 msgid "(mTLS)" msgstr "" @@ -37,10 +37,10 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1153 #: htdocs/luci-static/resources/view/fchomo/client.js:1612 #: htdocs/luci-static/resources/view/fchomo/client.js:1613 -#: htdocs/luci-static/resources/view/fchomo/node.js:1608 -#: htdocs/luci-static/resources/view/fchomo/node.js:1614 -#: htdocs/luci-static/resources/view/fchomo/node.js:1628 -#: htdocs/luci-static/resources/view/fchomo/node.js:1634 +#: htdocs/luci-static/resources/view/fchomo/node.js:1609 +#: htdocs/luci-static/resources/view/fchomo/node.js:1615 +#: htdocs/luci-static/resources/view/fchomo/node.js:1629 +#: htdocs/luci-static/resources/view/fchomo/node.js:1635 msgid "-- Please choose --" msgstr "-- 請選擇 --" @@ -73,11 +73,11 @@ msgstr "" msgid "0 or 1 only." msgstr "僅限 01。" -#: htdocs/luci-static/resources/view/fchomo/node.js:918 -#: htdocs/luci-static/resources/view/fchomo/node.js:932 -#: htdocs/luci-static/resources/view/fchomo/server.js:786 -#: htdocs/luci-static/resources/view/fchomo/server.js:801 -#: htdocs/luci-static/resources/view/fchomo/server.js:826 +#: htdocs/luci-static/resources/view/fchomo/node.js:919 +#: htdocs/luci-static/resources/view/fchomo/node.js:933 +#: htdocs/luci-static/resources/view/fchomo/server.js:798 +#: htdocs/luci-static/resources/view/fchomo/server.js:813 +#: htdocs/luci-static/resources/view/fchomo/server.js:838 msgid "Save your configuration before uploading files!" msgstr "上傳文件前請先保存配置!" @@ -146,11 +146,11 @@ msgstr "新增 DNS 伺服器" msgid "Add a Node" msgstr "新增 節點" -#: htdocs/luci-static/resources/view/fchomo/node.js:1198 +#: htdocs/luci-static/resources/view/fchomo/node.js:1199 msgid "Add a provider" msgstr "新增 供應商" -#: htdocs/luci-static/resources/view/fchomo/node.js:1584 +#: htdocs/luci-static/resources/view/fchomo/node.js:1585 msgid "Add a proxy chain" msgstr "新增 代理鏈" @@ -174,11 +174,11 @@ msgstr "新增 伺服器" msgid "Add a sub rule" msgstr "新增 子規則" -#: htdocs/luci-static/resources/view/fchomo/node.js:1409 +#: htdocs/luci-static/resources/view/fchomo/node.js:1410 msgid "Add prefix" msgstr "添加前綴" -#: htdocs/luci-static/resources/view/fchomo/node.js:1413 +#: htdocs/luci-static/resources/view/fchomo/node.js:1414 msgid "Add suffix" msgstr "添加後綴" @@ -215,7 +215,7 @@ msgid "" msgstr "" "允許從私有網路訪問。
要從公共網站訪問私有網路上的 API,則必須啟用。" -#: htdocs/luci-static/resources/view/fchomo/node.js:651 +#: htdocs/luci-static/resources/view/fchomo/node.js:652 msgid "Allowed IPs" msgstr "允許的 IP" @@ -227,8 +227,8 @@ msgstr "已是最新版本。" msgid "Already in updating." msgstr "已在更新中。" -#: htdocs/luci-static/resources/view/fchomo/node.js:580 -#: htdocs/luci-static/resources/view/fchomo/server.js:488 +#: htdocs/luci-static/resources/view/fchomo/node.js:581 +#: htdocs/luci-static/resources/view/fchomo/server.js:500 msgid "Alter ID" msgstr "額外 ID" @@ -250,11 +250,11 @@ msgstr "作為 dnsmasq 的最優先上游" msgid "As the TOP upstream of dnsmasq." msgstr "作為 dnsmasq 的最優先上游。" -#: htdocs/luci-static/resources/view/fchomo/server.js:438 +#: htdocs/luci-static/resources/view/fchomo/server.js:450 msgid "Auth timeout" msgstr "認證超時" -#: htdocs/luci-static/resources/view/fchomo/node.js:602 +#: htdocs/luci-static/resources/view/fchomo/node.js:603 msgid "Authenticated length" msgstr "認證長度" @@ -296,13 +296,13 @@ msgid "Binary mrs" msgstr "二進位 mrs" #: htdocs/luci-static/resources/view/fchomo/global.js:740 -#: htdocs/luci-static/resources/view/fchomo/node.js:1168 -#: htdocs/luci-static/resources/view/fchomo/node.js:1482 +#: htdocs/luci-static/resources/view/fchomo/node.js:1169 +#: htdocs/luci-static/resources/view/fchomo/node.js:1483 msgid "Bind interface" msgstr "綁定介面" -#: htdocs/luci-static/resources/view/fchomo/node.js:1169 -#: htdocs/luci-static/resources/view/fchomo/node.js:1483 +#: htdocs/luci-static/resources/view/fchomo/node.js:1170 +#: htdocs/luci-static/resources/view/fchomo/node.js:1484 msgid "Bind outbound interface.
" msgstr "綁定出站介面。
" @@ -347,21 +347,21 @@ msgstr "CORS 允許私有網路" msgid "CORS allowed origins, * will be used if empty." msgstr "CORS 允許的來源,留空則使用 *。" -#: htdocs/luci-static/resources/fchomo.js:674 +#: htdocs/luci-static/resources/fchomo.js:676 msgid "Cancel" msgstr "取消" -#: htdocs/luci-static/resources/view/fchomo/node.js:890 +#: htdocs/luci-static/resources/view/fchomo/node.js:891 msgid "Cert fingerprint" msgstr "憑證指紋" -#: htdocs/luci-static/resources/view/fchomo/node.js:891 +#: htdocs/luci-static/resources/view/fchomo/node.js:892 msgid "" "Certificate fingerprint. Used to implement SSL Pinning and prevent MitM." msgstr "憑證指紋。用於實現 SSL憑證固定 並防止 MitM。" -#: htdocs/luci-static/resources/view/fchomo/node.js:911 -#: htdocs/luci-static/resources/view/fchomo/server.js:778 +#: htdocs/luci-static/resources/view/fchomo/node.js:912 +#: htdocs/luci-static/resources/view/fchomo/server.js:790 msgid "Certificate path" msgstr "憑證路徑" @@ -392,7 +392,7 @@ msgstr "大陸網域清單版本" #: htdocs/luci-static/resources/view/fchomo/node.js:326 #: htdocs/luci-static/resources/view/fchomo/node.js:379 -#: htdocs/luci-static/resources/view/fchomo/node.js:586 +#: htdocs/luci-static/resources/view/fchomo/node.js:587 #: htdocs/luci-static/resources/view/fchomo/server.js:269 #: htdocs/luci-static/resources/view/fchomo/server.js:356 msgid "Chipher" @@ -416,24 +416,24 @@ msgstr "" "最新的初始包。" #: htdocs/luci-static/resources/view/fchomo/global.js:556 -#: htdocs/luci-static/resources/view/fchomo/node.js:788 -#: htdocs/luci-static/resources/view/fchomo/node.js:912 -#: htdocs/luci-static/resources/view/fchomo/node.js:926 -#: htdocs/luci-static/resources/view/fchomo/server.js:607 -#: htdocs/luci-static/resources/view/fchomo/server.js:817 +#: htdocs/luci-static/resources/view/fchomo/node.js:789 +#: htdocs/luci-static/resources/view/fchomo/node.js:913 +#: htdocs/luci-static/resources/view/fchomo/node.js:927 +#: htdocs/luci-static/resources/view/fchomo/server.js:619 +#: htdocs/luci-static/resources/view/fchomo/server.js:829 #: root/usr/share/luci/menu.d/luci-app-fchomo.json:22 msgid "Client" msgstr "客戶端" -#: htdocs/luci-static/resources/view/fchomo/server.js:816 +#: htdocs/luci-static/resources/view/fchomo/server.js:828 msgid "Client Auth Certificate path" msgstr "客戶端認證憑證路徑" -#: htdocs/luci-static/resources/view/fchomo/server.js:808 +#: htdocs/luci-static/resources/view/fchomo/server.js:820 msgid "Client Auth type" msgstr "客戶端認證類型" -#: htdocs/luci-static/resources/view/fchomo/node.js:952 +#: htdocs/luci-static/resources/view/fchomo/node.js:953 msgid "Client fingerprint" msgstr "客戶端指紋" @@ -454,16 +454,16 @@ msgstr "收集資料中..." msgid "Common ports (bypass P2P traffic)" msgstr "常用連接埠(繞過 P2P 流量)" -#: htdocs/luci-static/resources/fchomo.js:1245 +#: htdocs/luci-static/resources/fchomo.js:1275 msgid "Complete" msgstr "完成" -#: htdocs/luci-static/resources/view/fchomo/node.js:1429 +#: htdocs/luci-static/resources/view/fchomo/node.js:1430 msgid "Configuration Items" msgstr "配置項" -#: htdocs/luci-static/resources/view/fchomo/node.js:460 -#: htdocs/luci-static/resources/view/fchomo/server.js:416 +#: htdocs/luci-static/resources/view/fchomo/node.js:461 +#: htdocs/luci-static/resources/view/fchomo/server.js:428 msgid "Congestion controller" msgstr "擁塞控制器" @@ -471,19 +471,19 @@ msgstr "擁塞控制器" msgid "Connection check" msgstr "連接檢查" -#: htdocs/luci-static/resources/fchomo.js:543 +#: htdocs/luci-static/resources/fchomo.js:545 msgid "Content copied to clipboard!" msgstr "內容已複製到剪貼簿!" #: htdocs/luci-static/resources/view/fchomo/client.js:608 -#: htdocs/luci-static/resources/view/fchomo/node.js:1339 -#: htdocs/luci-static/resources/view/fchomo/node.js:1365 +#: htdocs/luci-static/resources/view/fchomo/node.js:1340 +#: htdocs/luci-static/resources/view/fchomo/node.js:1366 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:324 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:350 msgid "Content will not be verified, Please make sure you enter it correctly." msgstr "內容將不會被驗證,請確保輸入正確。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1338 +#: htdocs/luci-static/resources/view/fchomo/node.js:1339 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:323 msgid "Contents" msgstr "內容" @@ -492,7 +492,7 @@ msgstr "內容" msgid "Contents have been saved." msgstr "" -#: htdocs/luci-static/resources/fchomo.js:545 +#: htdocs/luci-static/resources/fchomo.js:547 msgid "Copy" msgstr "複製" @@ -508,7 +508,7 @@ msgstr "Cron 表達式" msgid "Custom Direct List" msgstr "自訂直連清單" -#: htdocs/luci-static/resources/view/fchomo/node.js:1400 +#: htdocs/luci-static/resources/view/fchomo/node.js:1401 msgid "Custom HTTP header." msgstr "自訂 HTTP header。" @@ -542,7 +542,7 @@ msgstr " DNS 連接埠" #: htdocs/luci-static/resources/view/fchomo/client.js:1303 #: htdocs/luci-static/resources/view/fchomo/client.js:1312 #: htdocs/luci-static/resources/view/fchomo/client.js:1625 -#: htdocs/luci-static/resources/view/fchomo/node.js:675 +#: htdocs/luci-static/resources/view/fchomo/node.js:676 msgid "DNS server" msgstr "DNS 伺服器" @@ -570,15 +570,15 @@ msgstr "預設 DNS(由 WAN 下發)" msgid "Default DNS server" msgstr "預設 DNS 伺服器" -#: htdocs/luci-static/resources/view/fchomo/node.js:652 +#: htdocs/luci-static/resources/view/fchomo/node.js:653 msgid "Destination addresses allowed to be forwarded via Wireguard." msgstr "允許通過 WireGuard 轉發的目的位址" -#: htdocs/luci-static/resources/view/fchomo/node.js:1607 +#: htdocs/luci-static/resources/view/fchomo/node.js:1608 msgid "Destination provider" msgstr "落地供應商" -#: htdocs/luci-static/resources/view/fchomo/node.js:1613 +#: htdocs/luci-static/resources/view/fchomo/node.js:1614 msgid "Destination proxy node" msgstr "落地代理節點" @@ -586,8 +586,8 @@ msgstr "落地代理節點" msgid "Dial fields" msgstr "撥號欄位" -#: htdocs/luci-static/resources/view/fchomo/node.js:1620 -#: htdocs/luci-static/resources/view/fchomo/node.js:1640 +#: htdocs/luci-static/resources/view/fchomo/node.js:1621 +#: htdocs/luci-static/resources/view/fchomo/node.js:1641 msgid "Different chain head/tail" msgstr "不同的鏈頭/鏈尾" @@ -625,7 +625,7 @@ msgstr "停用 quic-go 的 通用分段卸載(GSO)" msgid "Disable ICMP Forwarding" msgstr "禁用 ICMP 轉發" -#: htdocs/luci-static/resources/view/fchomo/node.js:839 +#: htdocs/luci-static/resources/view/fchomo/node.js:840 msgid "Disable SNI" msgstr "停用 SNI" @@ -661,29 +661,29 @@ msgstr "" msgid "Domain" msgstr "網域" -#: htdocs/luci-static/resources/view/fchomo/node.js:840 +#: htdocs/luci-static/resources/view/fchomo/node.js:841 msgid "Donot send server name in ClientHello." msgstr "不要在 ClientHello 中傳送伺服器名稱。" #: htdocs/luci-static/resources/view/fchomo/client.js:1450 -#: htdocs/luci-static/resources/view/fchomo/node.js:904 -#: htdocs/luci-static/resources/view/fchomo/node.js:1469 +#: htdocs/luci-static/resources/view/fchomo/node.js:905 +#: htdocs/luci-static/resources/view/fchomo/node.js:1470 msgid "Donot verifying server certificate." msgstr "不驗證伺服器憑證。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1147 +#: htdocs/luci-static/resources/view/fchomo/node.js:1148 msgid "Download bandwidth" msgstr "下載頻寬" -#: htdocs/luci-static/resources/view/fchomo/node.js:1148 +#: htdocs/luci-static/resources/view/fchomo/node.js:1149 msgid "Download bandwidth in Mbps." msgstr "下載頻寬(單位:Mbps)。" -#: htdocs/luci-static/resources/fchomo.js:1130 +#: htdocs/luci-static/resources/fchomo.js:1154 msgid "Download failed: %s" msgstr "下載失敗: %s" -#: htdocs/luci-static/resources/fchomo.js:1128 +#: htdocs/luci-static/resources/fchomo.js:1152 msgid "Download successful." msgstr "下載成功。" @@ -691,12 +691,12 @@ msgstr "下載成功。" msgid "Dual stack" msgstr "雙棧" -#: htdocs/luci-static/resources/view/fchomo/node.js:945 -#: htdocs/luci-static/resources/view/fchomo/server.js:874 +#: htdocs/luci-static/resources/view/fchomo/node.js:946 +#: htdocs/luci-static/resources/view/fchomo/server.js:886 msgid "ECH config" msgstr "ECH 配置" -#: htdocs/luci-static/resources/view/fchomo/server.js:833 +#: htdocs/luci-static/resources/view/fchomo/server.js:845 msgid "ECH key" msgstr "ECH 密鑰" @@ -712,11 +712,11 @@ msgstr "" msgid "ETag support" msgstr "ETag 支援" -#: htdocs/luci-static/resources/view/fchomo/node.js:1060 +#: htdocs/luci-static/resources/view/fchomo/node.js:1061 msgid "Early Data first packet length limit." msgstr "前置數據長度閾值" -#: htdocs/luci-static/resources/view/fchomo/node.js:1066 +#: htdocs/luci-static/resources/view/fchomo/node.js:1067 msgid "Early Data header name" msgstr "前置數據標頭" @@ -728,7 +728,7 @@ msgstr "編輯節點" msgid "Edit ruleset" msgstr "編輯規則集" -#: htdocs/luci-static/resources/view/fchomo/node.js:1336 +#: htdocs/luci-static/resources/view/fchomo/node.js:1337 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:321 msgid "Editer" msgstr "編輯器" @@ -746,16 +746,16 @@ msgstr "消除加密頭特徵" #: htdocs/luci-static/resources/view/fchomo/global.js:401 #: htdocs/luci-static/resources/view/fchomo/global.js:686 #: htdocs/luci-static/resources/view/fchomo/node.js:234 -#: htdocs/luci-static/resources/view/fchomo/node.js:1309 -#: htdocs/luci-static/resources/view/fchomo/node.js:1505 -#: htdocs/luci-static/resources/view/fchomo/node.js:1594 +#: htdocs/luci-static/resources/view/fchomo/node.js:1310 +#: htdocs/luci-static/resources/view/fchomo/node.js:1506 +#: htdocs/luci-static/resources/view/fchomo/node.js:1595 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:249 #: htdocs/luci-static/resources/view/fchomo/server.js:157 #: htdocs/luci-static/resources/view/fchomo/server.js:184 msgid "Enable" msgstr "啟用" -#: htdocs/luci-static/resources/view/fchomo/node.js:495 +#: htdocs/luci-static/resources/view/fchomo/node.js:496 msgid "" "Enable 0-RTT QUIC connection handshake on the client side. This is not " "impacting much on the performance, as the protocol is fully multiplexed.
強烈建議停用此功能,因為它容易受到重放攻擊。" -#: htdocs/luci-static/resources/view/fchomo/node.js:494 +#: htdocs/luci-static/resources/view/fchomo/node.js:495 msgid "Enable 0-RTT handshake" msgstr "啟用 0-RTT 握手" @@ -776,37 +776,37 @@ msgstr "" "為出站連線啟用 IP4P 轉換" -#: htdocs/luci-static/resources/view/fchomo/node.js:939 +#: htdocs/luci-static/resources/view/fchomo/node.js:940 msgid "Enable ECH" msgstr "啟用 ECH" -#: htdocs/luci-static/resources/view/fchomo/node.js:1135 +#: htdocs/luci-static/resources/view/fchomo/node.js:1136 msgid "Enable TCP Brutal" msgstr "啟用 TCP Brutal" -#: htdocs/luci-static/resources/view/fchomo/node.js:1136 +#: htdocs/luci-static/resources/view/fchomo/node.js:1137 msgid "Enable TCP Brutal congestion control algorithm" msgstr "啟用 TCP Brutal 擁塞控制演算法。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1124 +#: htdocs/luci-static/resources/view/fchomo/node.js:1125 msgid "Enable multiplexing only for TCP." msgstr "僅為 TCP 啟用多路復用。" -#: htdocs/luci-static/resources/view/fchomo/node.js:424 -#: htdocs/luci-static/resources/view/fchomo/server.js:402 +#: htdocs/luci-static/resources/view/fchomo/node.js:425 +#: htdocs/luci-static/resources/view/fchomo/server.js:414 msgid "Enable obfuscate for downlink" msgstr "啟用下行鏈路混淆" -#: htdocs/luci-static/resources/view/fchomo/node.js:1118 +#: htdocs/luci-static/resources/view/fchomo/node.js:1119 msgid "Enable padding" msgstr "啟用填充" -#: htdocs/luci-static/resources/view/fchomo/node.js:1129 +#: htdocs/luci-static/resources/view/fchomo/node.js:1130 msgid "Enable statistic" msgstr "啟用統計" -#: htdocs/luci-static/resources/view/fchomo/node.js:740 -#: htdocs/luci-static/resources/view/fchomo/node.js:1451 +#: htdocs/luci-static/resources/view/fchomo/node.js:741 +#: htdocs/luci-static/resources/view/fchomo/node.js:1452 msgid "" "Enable the SUoT protocol, requires server support. Conflict with Multiplex." msgstr "啟用 SUoT 協議,需要服務端支援。與多路復用衝突。" @@ -818,7 +818,7 @@ msgid "" "connections, losing the ability to masquerade with HTTP/3." msgstr "啟用混淆將使伺服器與標準的 QUIC 連線不相容,失去 HTTP/3 偽裝的能力。" -#: htdocs/luci-static/resources/view/fchomo/server.js:570 +#: htdocs/luci-static/resources/view/fchomo/server.js:582 msgid "Encryption method" msgstr "加密方法" @@ -841,7 +841,7 @@ msgid "" "if empty." msgstr "超過此限制將會觸發強制健康檢查。留空則使用 5。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1563 +#: htdocs/luci-static/resources/view/fchomo/node.js:1564 msgid "Exclude matched node types." msgstr "排除匹配的節點類型。" @@ -854,7 +854,7 @@ msgstr "" "rel=\"noreferrer noopener\">此處。" #: htdocs/luci-static/resources/view/fchomo/client.js:1049 -#: htdocs/luci-static/resources/view/fchomo/node.js:1556 +#: htdocs/luci-static/resources/view/fchomo/node.js:1557 msgid "Exclude nodes that meet keywords or regexps." msgstr "排除匹配關鍵字或表達式的節點。" @@ -863,59 +863,61 @@ msgid "Expand/Collapse result" msgstr "展開/收起 結果" #: htdocs/luci-static/resources/view/fchomo/client.js:1009 -#: htdocs/luci-static/resources/view/fchomo/node.js:1541 +#: htdocs/luci-static/resources/view/fchomo/node.js:1542 msgid "Expected HTTP code. 204 will be used if empty." msgstr "預期的 HTTP code。留空則使用 204。" #: htdocs/luci-static/resources/view/fchomo/client.js:1011 -#: htdocs/luci-static/resources/view/fchomo/node.js:1543 +#: htdocs/luci-static/resources/view/fchomo/node.js:1544 msgid "Expected status" msgstr "預期狀態" -#: htdocs/luci-static/resources/fchomo.js:393 -#: htdocs/luci-static/resources/fchomo.js:396 -#: htdocs/luci-static/resources/fchomo.js:399 -#: htdocs/luci-static/resources/fchomo.js:1262 -#: htdocs/luci-static/resources/fchomo.js:1270 -#: htdocs/luci-static/resources/fchomo.js:1278 -#: htdocs/luci-static/resources/fchomo.js:1301 -#: htdocs/luci-static/resources/fchomo.js:1304 -#: htdocs/luci-static/resources/fchomo.js:1311 -#: htdocs/luci-static/resources/fchomo.js:1327 -#: htdocs/luci-static/resources/fchomo.js:1336 -#: htdocs/luci-static/resources/fchomo.js:1348 -#: htdocs/luci-static/resources/fchomo.js:1351 -#: htdocs/luci-static/resources/fchomo.js:1361 -#: htdocs/luci-static/resources/fchomo.js:1373 -#: htdocs/luci-static/resources/fchomo.js:1376 -#: htdocs/luci-static/resources/fchomo.js:1386 -#: htdocs/luci-static/resources/fchomo.js:1396 -#: htdocs/luci-static/resources/fchomo.js:1431 -#: htdocs/luci-static/resources/fchomo.js:1433 -#: htdocs/luci-static/resources/fchomo.js:1443 -#: htdocs/luci-static/resources/fchomo.js:1452 +#: htdocs/luci-static/resources/fchomo.js:395 +#: htdocs/luci-static/resources/fchomo.js:398 +#: htdocs/luci-static/resources/fchomo.js:401 +#: htdocs/luci-static/resources/fchomo.js:1292 +#: htdocs/luci-static/resources/fchomo.js:1300 +#: htdocs/luci-static/resources/fchomo.js:1308 +#: htdocs/luci-static/resources/fchomo.js:1331 +#: htdocs/luci-static/resources/fchomo.js:1334 +#: htdocs/luci-static/resources/fchomo.js:1341 +#: htdocs/luci-static/resources/fchomo.js:1357 +#: htdocs/luci-static/resources/fchomo.js:1366 +#: htdocs/luci-static/resources/fchomo.js:1378 +#: htdocs/luci-static/resources/fchomo.js:1381 +#: htdocs/luci-static/resources/fchomo.js:1391 +#: htdocs/luci-static/resources/fchomo.js:1403 +#: htdocs/luci-static/resources/fchomo.js:1406 +#: htdocs/luci-static/resources/fchomo.js:1416 +#: htdocs/luci-static/resources/fchomo.js:1426 +#: htdocs/luci-static/resources/fchomo.js:1461 +#: htdocs/luci-static/resources/fchomo.js:1463 +#: htdocs/luci-static/resources/fchomo.js:1476 +#: htdocs/luci-static/resources/fchomo.js:1482 +#: htdocs/luci-static/resources/fchomo.js:1489 +#: htdocs/luci-static/resources/fchomo.js:1498 #: htdocs/luci-static/resources/view/fchomo/client.js:68 #: htdocs/luci-static/resources/view/fchomo/client.js:906 #: htdocs/luci-static/resources/view/fchomo/client.js:1381 #: htdocs/luci-static/resources/view/fchomo/global.js:886 #: htdocs/luci-static/resources/view/fchomo/node.js:388 -#: htdocs/luci-static/resources/view/fchomo/node.js:811 -#: htdocs/luci-static/resources/view/fchomo/node.js:896 -#: htdocs/luci-static/resources/view/fchomo/node.js:1620 -#: htdocs/luci-static/resources/view/fchomo/node.js:1640 +#: htdocs/luci-static/resources/view/fchomo/node.js:812 +#: htdocs/luci-static/resources/view/fchomo/node.js:897 +#: htdocs/luci-static/resources/view/fchomo/node.js:1621 +#: htdocs/luci-static/resources/view/fchomo/node.js:1641 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:276 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:290 #: htdocs/luci-static/resources/view/fchomo/server.js:365 -#: htdocs/luci-static/resources/view/fchomo/server.js:599 -#: htdocs/luci-static/resources/view/fchomo/server.js:630 -#: htdocs/luci-static/resources/view/fchomo/server.js:731 +#: htdocs/luci-static/resources/view/fchomo/server.js:611 +#: htdocs/luci-static/resources/view/fchomo/server.js:642 +#: htdocs/luci-static/resources/view/fchomo/server.js:743 msgid "Expecting: %s" msgstr "請輸入:%s" -#: htdocs/luci-static/resources/view/fchomo/node.js:1001 -#: htdocs/luci-static/resources/view/fchomo/node.js:1008 -#: htdocs/luci-static/resources/view/fchomo/server.js:941 -#: htdocs/luci-static/resources/view/fchomo/server.js:948 +#: htdocs/luci-static/resources/view/fchomo/node.js:1002 +#: htdocs/luci-static/resources/view/fchomo/node.js:1009 +#: htdocs/luci-static/resources/view/fchomo/server.js:953 +#: htdocs/luci-static/resources/view/fchomo/server.js:960 msgid "Expecting: only support %s." msgstr "請輸入:僅支援 %s." @@ -934,19 +936,19 @@ msgstr "實驗性" msgid "Factor" msgstr "條件" -#: htdocs/luci-static/resources/fchomo.js:1203 +#: htdocs/luci-static/resources/fchomo.js:1233 msgid "Failed to execute \"/etc/init.d/fchomo %s %s\" reason: %s" msgstr "無法執行 \"/etc/init.d/fchomo %s %s\" 原因: %s" -#: htdocs/luci-static/resources/fchomo.js:1162 +#: htdocs/luci-static/resources/fchomo.js:1186 msgid "Failed to generate %s, error: %s." msgstr "生成 %s 失敗,錯誤:%s。" -#: htdocs/luci-static/resources/fchomo.js:1552 +#: htdocs/luci-static/resources/fchomo.js:1598 msgid "Failed to upload %s, error: %s." msgstr "上傳 %s 失敗,錯誤:%s。" -#: htdocs/luci-static/resources/fchomo.js:1571 +#: htdocs/luci-static/resources/fchomo.js:1617 msgid "Failed to upload, error: %s." msgstr "上傳失敗,錯誤:%s。" @@ -964,7 +966,7 @@ msgid "Fallback filter" msgstr "後備過濾器" #: htdocs/luci-static/resources/view/fchomo/client.js:1044 -#: htdocs/luci-static/resources/view/fchomo/node.js:1550 +#: htdocs/luci-static/resources/view/fchomo/node.js:1551 msgid "Filter nodes that meet keywords or regexps." msgstr "過濾匹配關鍵字或表達式的節點。" @@ -984,8 +986,8 @@ msgstr "兜底 DNS 伺服器 (用於已被投毒汙染的網域)" msgid "Firewall" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:572 -#: htdocs/luci-static/resources/view/fchomo/server.js:480 +#: htdocs/luci-static/resources/view/fchomo/node.js:573 +#: htdocs/luci-static/resources/view/fchomo/server.js:492 msgid "Flow" msgstr "流控" @@ -998,8 +1000,8 @@ msgstr "" "noopener\">%s." #: htdocs/luci-static/resources/view/fchomo/client.js:1010 -#: htdocs/luci-static/resources/view/fchomo/node.js:1419 -#: htdocs/luci-static/resources/view/fchomo/node.js:1542 +#: htdocs/luci-static/resources/view/fchomo/node.js:1420 +#: htdocs/luci-static/resources/view/fchomo/node.js:1543 msgid "" "For format see %s." @@ -1007,7 +1009,7 @@ msgstr "" "格式請參閱 %s." -#: htdocs/luci-static/resources/view/fchomo/node.js:670 +#: htdocs/luci-static/resources/view/fchomo/node.js:671 msgid "Force DNS remote resolution." msgstr "強制 DNS 遠端解析。" @@ -1026,7 +1028,7 @@ msgstr "格式" msgid "FullCombo Shark!" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1027 +#: htdocs/luci-static/resources/view/fchomo/node.js:1028 msgid "GET" msgstr "" @@ -1040,7 +1042,7 @@ msgstr "常規" #: htdocs/luci-static/resources/view/fchomo/client.js:897 #: htdocs/luci-static/resources/view/fchomo/node.js:222 -#: htdocs/luci-static/resources/view/fchomo/node.js:1299 +#: htdocs/luci-static/resources/view/fchomo/node.js:1300 #: htdocs/luci-static/resources/view/fchomo/server.js:171 msgid "General fields" msgstr "常規欄位" @@ -1049,14 +1051,16 @@ msgstr "常規欄位" msgid "General settings" msgstr "常規設定" -#: htdocs/luci-static/resources/fchomo.js:494 #: htdocs/luci-static/resources/fchomo.js:496 -#: htdocs/luci-static/resources/fchomo.js:510 +#: htdocs/luci-static/resources/fchomo.js:498 #: htdocs/luci-static/resources/fchomo.js:512 +#: htdocs/luci-static/resources/fchomo.js:514 #: htdocs/luci-static/resources/view/fchomo/global.js:593 #: htdocs/luci-static/resources/view/fchomo/server.js:343 -#: htdocs/luci-static/resources/view/fchomo/server.js:703 -#: htdocs/luci-static/resources/view/fchomo/server.js:866 +#: htdocs/luci-static/resources/view/fchomo/server.js:384 +#: htdocs/luci-static/resources/view/fchomo/server.js:386 +#: htdocs/luci-static/resources/view/fchomo/server.js:715 +#: htdocs/luci-static/resources/view/fchomo/server.js:878 msgid "Generate" msgstr "生成" @@ -1103,7 +1107,7 @@ msgstr "全域認證" msgid "Global client fingerprint" msgstr "全域客戶端指紋" -#: htdocs/luci-static/resources/view/fchomo/node.js:596 +#: htdocs/luci-static/resources/view/fchomo/node.js:597 msgid "Global padding" msgstr "全域填充" @@ -1125,24 +1129,24 @@ msgstr "組" #: htdocs/luci-static/resources/fchomo.js:126 #: htdocs/luci-static/resources/fchomo.js:158 -#: htdocs/luci-static/resources/view/fchomo/node.js:693 -#: htdocs/luci-static/resources/view/fchomo/node.js:990 -#: htdocs/luci-static/resources/view/fchomo/node.js:1001 -#: htdocs/luci-static/resources/view/fchomo/server.js:941 +#: htdocs/luci-static/resources/view/fchomo/node.js:694 +#: htdocs/luci-static/resources/view/fchomo/node.js:991 +#: htdocs/luci-static/resources/view/fchomo/node.js:1002 +#: htdocs/luci-static/resources/view/fchomo/server.js:953 msgid "HTTP" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:267 -#: htdocs/luci-static/resources/view/fchomo/node.js:1049 -#: htdocs/luci-static/resources/view/fchomo/node.js:1399 +#: htdocs/luci-static/resources/view/fchomo/node.js:1050 +#: htdocs/luci-static/resources/view/fchomo/node.js:1400 msgid "HTTP header" msgstr "HTTP header" -#: htdocs/luci-static/resources/view/fchomo/node.js:419 +#: htdocs/luci-static/resources/view/fchomo/node.js:420 msgid "HTTP mask" msgstr "HTTP 遮罩" -#: htdocs/luci-static/resources/view/fchomo/node.js:1026 +#: htdocs/luci-static/resources/view/fchomo/node.js:1027 msgid "HTTP request method" msgstr "HTTP 請求方法" @@ -1156,9 +1160,9 @@ msgid "" "returned if empty." msgstr "身份驗證失敗時的 HTTP3 伺服器回應。預設回傳 404 頁面。" -#: htdocs/luci-static/resources/view/fchomo/node.js:991 -#: htdocs/luci-static/resources/view/fchomo/node.js:1002 -#: htdocs/luci-static/resources/view/fchomo/server.js:942 +#: htdocs/luci-static/resources/view/fchomo/node.js:992 +#: htdocs/luci-static/resources/view/fchomo/node.js:1003 +#: htdocs/luci-static/resources/view/fchomo/server.js:954 msgid "HTTPUpgrade" msgstr "" @@ -1170,40 +1174,40 @@ msgstr "處理網域" msgid "Handshake mode" msgstr "握手模式" -#: htdocs/luci-static/resources/view/fchomo/server.js:503 +#: htdocs/luci-static/resources/view/fchomo/server.js:515 msgid "Handshake target that supports TLS 1.3" msgstr "握手目標 (支援 TLS 1.3)" -#: htdocs/luci-static/resources/view/fchomo/server.js:396 +#: htdocs/luci-static/resources/view/fchomo/server.js:408 msgid "Handshake timeout" msgstr "握手超時" #: htdocs/luci-static/resources/view/fchomo/client.js:979 -#: htdocs/luci-static/resources/view/fchomo/node.js:1510 +#: htdocs/luci-static/resources/view/fchomo/node.js:1511 msgid "Health check URL" msgstr "健康檢查 URL" #: htdocs/luci-static/resources/view/fchomo/client.js:1008 -#: htdocs/luci-static/resources/view/fchomo/node.js:1540 +#: htdocs/luci-static/resources/view/fchomo/node.js:1541 msgid "Health check expected status" msgstr "健康檢查预期状态" #: htdocs/luci-static/resources/view/fchomo/client.js:988 -#: htdocs/luci-static/resources/view/fchomo/node.js:1520 +#: htdocs/luci-static/resources/view/fchomo/node.js:1521 msgid "Health check interval" msgstr "健康檢查间隔" #: htdocs/luci-static/resources/view/fchomo/client.js:995 -#: htdocs/luci-static/resources/view/fchomo/node.js:1527 +#: htdocs/luci-static/resources/view/fchomo/node.js:1528 msgid "Health check timeout" msgstr "健康檢查超时" #: htdocs/luci-static/resources/view/fchomo/client.js:899 -#: htdocs/luci-static/resources/view/fchomo/node.js:1301 +#: htdocs/luci-static/resources/view/fchomo/node.js:1302 msgid "Health fields" msgstr "健康欄位" -#: htdocs/luci-static/resources/view/fchomo/node.js:501 +#: htdocs/luci-static/resources/view/fchomo/node.js:502 msgid "Heartbeat interval" msgstr "心跳間隔" @@ -1211,7 +1215,7 @@ msgstr "心跳間隔" msgid "Hidden" msgstr "隱藏" -#: htdocs/luci-static/resources/view/fchomo/node.js:699 +#: htdocs/luci-static/resources/view/fchomo/node.js:700 msgid "Host that supports TLS 1.3" msgstr "主機名稱 (支援 TLS 1.3)" @@ -1242,12 +1246,12 @@ msgstr "" msgid "IP CIDR" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:454 +#: htdocs/luci-static/resources/view/fchomo/node.js:455 msgid "IP override" msgstr "IP 覆寫" -#: htdocs/luci-static/resources/view/fchomo/node.js:1180 -#: htdocs/luci-static/resources/view/fchomo/node.js:1496 +#: htdocs/luci-static/resources/view/fchomo/node.js:1181 +#: htdocs/luci-static/resources/view/fchomo/node.js:1497 msgid "IP version" msgstr "IP 版本" @@ -1268,19 +1272,19 @@ msgstr "IPv6 支援" msgid "Icon" msgstr "圖標" -#: htdocs/luci-static/resources/view/fchomo/node.js:545 +#: htdocs/luci-static/resources/view/fchomo/node.js:546 msgid "Idle session check interval" msgstr "閒置會話檢查間隔" -#: htdocs/luci-static/resources/view/fchomo/node.js:552 +#: htdocs/luci-static/resources/view/fchomo/node.js:553 msgid "Idle session timeout" msgstr "閒置會話逾時" -#: htdocs/luci-static/resources/view/fchomo/server.js:431 +#: htdocs/luci-static/resources/view/fchomo/server.js:443 msgid "Idle timeout" msgstr "閒置逾時" -#: htdocs/luci-static/resources/fchomo.js:1304 +#: htdocs/luci-static/resources/fchomo.js:1334 msgid "If All ports is selected, uncheck others" msgstr "如果選擇了“所有連接埠”,則取消選取“其他”" @@ -1292,7 +1296,7 @@ msgstr "如果選擇了“封鎖”,則取消選取“其他”" msgid "Ignore client bandwidth" msgstr "忽略客戶端頻寬" -#: htdocs/luci-static/resources/fchomo.js:679 +#: htdocs/luci-static/resources/fchomo.js:681 msgid "Import" msgstr "導入" @@ -1306,8 +1310,8 @@ msgstr "導入" #: htdocs/luci-static/resources/view/fchomo/client.js:1355 #: htdocs/luci-static/resources/view/fchomo/client.js:1552 #: htdocs/luci-static/resources/view/fchomo/client.js:1573 -#: htdocs/luci-static/resources/view/fchomo/node.js:1205 -#: htdocs/luci-static/resources/view/fchomo/node.js:1287 +#: htdocs/luci-static/resources/view/fchomo/node.js:1206 +#: htdocs/luci-static/resources/view/fchomo/node.js:1288 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:142 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:226 msgid "Import mihomo config" @@ -1321,33 +1325,33 @@ msgstr "導入規則集連結" #: htdocs/luci-static/resources/view/fchomo/node.js:280 #: htdocs/luci-static/resources/view/fchomo/node.js:286 -#: htdocs/luci-static/resources/view/fchomo/node.js:1457 -#: htdocs/luci-static/resources/view/fchomo/node.js:1463 +#: htdocs/luci-static/resources/view/fchomo/node.js:1458 +#: htdocs/luci-static/resources/view/fchomo/node.js:1464 #: htdocs/luci-static/resources/view/fchomo/server.js:231 #: htdocs/luci-static/resources/view/fchomo/server.js:237 msgid "In Mbps." msgstr "單位為 Mbps。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1377 +#: htdocs/luci-static/resources/view/fchomo/node.js:1378 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:362 msgid "In bytes. %s will be used if empty." msgstr "單位為位元組。留空則使用 %s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:502 -#: htdocs/luci-static/resources/view/fchomo/node.js:509 +#: htdocs/luci-static/resources/view/fchomo/node.js:503 +#: htdocs/luci-static/resources/view/fchomo/node.js:510 msgid "In millisecond." msgstr "單位為毫秒。" #: htdocs/luci-static/resources/view/fchomo/client.js:996 #: htdocs/luci-static/resources/view/fchomo/client.js:1025 -#: htdocs/luci-static/resources/view/fchomo/node.js:1528 +#: htdocs/luci-static/resources/view/fchomo/node.js:1529 msgid "In millisecond. %s will be used if empty." msgstr "單位為毫秒。留空則使用 %s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:546 -#: htdocs/luci-static/resources/view/fchomo/node.js:553 -#: htdocs/luci-static/resources/view/fchomo/server.js:432 -#: htdocs/luci-static/resources/view/fchomo/server.js:439 +#: htdocs/luci-static/resources/view/fchomo/node.js:547 +#: htdocs/luci-static/resources/view/fchomo/node.js:554 +#: htdocs/luci-static/resources/view/fchomo/server.js:444 +#: htdocs/luci-static/resources/view/fchomo/server.js:451 msgid "In seconds." msgstr "單位為秒。" @@ -1355,14 +1359,14 @@ msgstr "單位為秒。" #: htdocs/luci-static/resources/view/fchomo/global.js:425 #: htdocs/luci-static/resources/view/fchomo/global.js:430 #: htdocs/luci-static/resources/view/fchomo/global.js:515 -#: htdocs/luci-static/resources/view/fchomo/node.js:1383 -#: htdocs/luci-static/resources/view/fchomo/node.js:1521 +#: htdocs/luci-static/resources/view/fchomo/node.js:1384 +#: htdocs/luci-static/resources/view/fchomo/node.js:1522 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:368 msgid "In seconds. %s will be used if empty." msgstr "單位為秒。留空則使用 %s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:800 -#: htdocs/luci-static/resources/view/fchomo/server.js:619 +#: htdocs/luci-static/resources/view/fchomo/node.js:801 +#: htdocs/luci-static/resources/view/fchomo/server.js:631 msgid "" "In the order of one Padding-Length and one Padding-" "Interval, infinite concatenation." @@ -1402,7 +1406,7 @@ msgstr "引入所有代理節點。" msgid "Info" msgstr "訊息" -#: htdocs/luci-static/resources/view/fchomo/node.js:1316 +#: htdocs/luci-static/resources/view/fchomo/node.js:1317 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:264 msgid "Inline" msgstr "內嵌" @@ -1420,12 +1424,12 @@ msgstr "保持預設" msgid "Key" msgstr "密鑰" -#: htdocs/luci-static/resources/view/fchomo/node.js:925 -#: htdocs/luci-static/resources/view/fchomo/server.js:793 +#: htdocs/luci-static/resources/view/fchomo/node.js:926 +#: htdocs/luci-static/resources/view/fchomo/server.js:805 msgid "Key path" msgstr "憑證路徑" -#: htdocs/luci-static/resources/view/fchomo/server.js:638 +#: htdocs/luci-static/resources/view/fchomo/server.js:650 msgid "Keypairs" msgstr "密鑰對" @@ -1435,19 +1439,19 @@ msgstr "密鑰對" #: htdocs/luci-static/resources/view/fchomo/client.js:1361 #: htdocs/luci-static/resources/view/fchomo/client.js:1579 #: htdocs/luci-static/resources/view/fchomo/node.js:229 -#: htdocs/luci-static/resources/view/fchomo/node.js:1304 -#: htdocs/luci-static/resources/view/fchomo/node.js:1589 +#: htdocs/luci-static/resources/view/fchomo/node.js:1305 +#: htdocs/luci-static/resources/view/fchomo/node.js:1590 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:244 #: htdocs/luci-static/resources/view/fchomo/server.js:179 msgid "Label" msgstr "標籤" #: htdocs/luci-static/resources/view/fchomo/client.js:1002 -#: htdocs/luci-static/resources/view/fchomo/node.js:1534 +#: htdocs/luci-static/resources/view/fchomo/node.js:1535 msgid "Lazy" msgstr "懶惰狀態" -#: htdocs/luci-static/resources/view/fchomo/server.js:489 +#: htdocs/luci-static/resources/view/fchomo/server.js:501 msgid "" "Legacy protocol support (VMess MD5 Authentication) is provided for " "compatibility purposes only, use of alterId > 1 is not recommended." @@ -1459,8 +1463,8 @@ msgstr "" msgid "Less compatibility and sometimes better performance." msgstr "有時效能較好。" -#: htdocs/luci-static/resources/view/fchomo/node.js:852 -#: htdocs/luci-static/resources/view/fchomo/server.js:774 +#: htdocs/luci-static/resources/view/fchomo/node.js:853 +#: htdocs/luci-static/resources/view/fchomo/server.js:786 msgid "List of supported application level protocols, in order of preference." msgstr "支援的應用層協議協商清單,依序排列。" @@ -1489,16 +1493,16 @@ msgstr "監聽埠" msgid "Load balance" msgstr "負載均衡" -#: htdocs/luci-static/resources/view/fchomo/node.js:1314 +#: htdocs/luci-static/resources/view/fchomo/node.js:1315 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:262 msgid "Local" msgstr "本地" -#: htdocs/luci-static/resources/view/fchomo/node.js:623 +#: htdocs/luci-static/resources/view/fchomo/node.js:624 msgid "Local IPv6 address" msgstr "本地 IPv6 位址" -#: htdocs/luci-static/resources/view/fchomo/node.js:616 +#: htdocs/luci-static/resources/view/fchomo/node.js:617 msgid "Local address" msgstr "本地位址" @@ -1518,12 +1522,12 @@ msgstr "日誌為空。" msgid "Log level" msgstr "日誌等級" -#: htdocs/luci-static/resources/fchomo.js:393 +#: htdocs/luci-static/resources/fchomo.js:395 msgid "Lowercase only" msgstr "僅限小寫" #: htdocs/luci-static/resources/view/fchomo/global.js:502 -#: htdocs/luci-static/resources/view/fchomo/node.js:663 +#: htdocs/luci-static/resources/view/fchomo/node.js:664 msgid "MTU" msgstr "" @@ -1559,12 +1563,12 @@ msgstr "匹配回應通過 ipcidr
" msgid "Match rule set." msgstr "匹配規則集。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1059 +#: htdocs/luci-static/resources/view/fchomo/node.js:1060 msgid "Max Early Data" msgstr "前置數據最大值" -#: htdocs/luci-static/resources/view/fchomo/node.js:488 -#: htdocs/luci-static/resources/view/fchomo/server.js:425 +#: htdocs/luci-static/resources/view/fchomo/node.js:489 +#: htdocs/luci-static/resources/view/fchomo/server.js:437 msgid "Max UDP relay packet size" msgstr "UDP 中繼數據包最大尺寸" @@ -1577,7 +1581,7 @@ msgstr "最大失敗次數" msgid "Max download speed" msgstr "最大下載速度" -#: htdocs/luci-static/resources/view/fchomo/node.js:515 +#: htdocs/luci-static/resources/view/fchomo/node.js:516 msgid "Max open streams" msgstr "限制打開流的數量" @@ -1586,12 +1590,12 @@ msgstr "限制打開流的數量" msgid "Max upload speed" msgstr "最大上傳速度" -#: htdocs/luci-static/resources/view/fchomo/node.js:1096 -#: htdocs/luci-static/resources/view/fchomo/node.js:1112 +#: htdocs/luci-static/resources/view/fchomo/node.js:1097 +#: htdocs/luci-static/resources/view/fchomo/node.js:1113 msgid "Maximum connections" msgstr "最大連線數" -#: htdocs/luci-static/resources/view/fchomo/node.js:1110 +#: htdocs/luci-static/resources/view/fchomo/node.js:1111 msgid "" "Maximum multiplexed streams in a connection before opening a new connection." "
Conflict with %s and %s." @@ -1599,12 +1603,12 @@ msgstr "" "在開啟新連線之前,連線中的最大多路復用流數量。
%s 和 " "%s 衝突。" -#: htdocs/luci-static/resources/view/fchomo/node.js:412 -#: htdocs/luci-static/resources/view/fchomo/server.js:389 +#: htdocs/luci-static/resources/view/fchomo/node.js:413 +#: htdocs/luci-static/resources/view/fchomo/server.js:401 msgid "Maximum padding" msgstr "最大填充" -#: htdocs/luci-static/resources/view/fchomo/node.js:1109 +#: htdocs/luci-static/resources/view/fchomo/node.js:1110 msgid "Maximum streams" msgstr "最大流數量" @@ -1625,22 +1629,22 @@ msgstr "Mihomo 客戶端" msgid "Mihomo server" msgstr "Mihomo 服務端" -#: htdocs/luci-static/resources/view/fchomo/node.js:559 +#: htdocs/luci-static/resources/view/fchomo/node.js:560 msgid "Min of idle sessions to keep" msgstr "要保留的最少閒置會話數" -#: htdocs/luci-static/resources/view/fchomo/node.js:1103 +#: htdocs/luci-static/resources/view/fchomo/node.js:1104 msgid "" "Minimum multiplexed streams in a connection before opening a new connection." msgstr "在開啟新連線之前,連線中的最小多路復用流數量。" -#: htdocs/luci-static/resources/view/fchomo/node.js:405 -#: htdocs/luci-static/resources/view/fchomo/server.js:382 +#: htdocs/luci-static/resources/view/fchomo/node.js:406 +#: htdocs/luci-static/resources/view/fchomo/server.js:394 msgid "Minimum padding" msgstr "最小填充" -#: htdocs/luci-static/resources/view/fchomo/node.js:1102 -#: htdocs/luci-static/resources/view/fchomo/node.js:1112 +#: htdocs/luci-static/resources/view/fchomo/node.js:1103 +#: htdocs/luci-static/resources/view/fchomo/node.js:1113 msgid "Minimum streams" msgstr "最小流數量" @@ -1657,7 +1661,7 @@ msgstr "混合 系統 TCP 堆栈和 gVisor UDP 堆栈 msgid "Mixed port" msgstr "混合連接埠" -#: htdocs/luci-static/resources/view/fchomo/node.js:1082 +#: htdocs/luci-static/resources/view/fchomo/node.js:1083 msgid "Multiplex" msgstr "多路復用" @@ -1675,7 +1679,7 @@ msgstr "多路復用" msgid "NOT" msgstr "NOT" -#: htdocs/luci-static/resources/view/fchomo/node.js:1389 +#: htdocs/luci-static/resources/view/fchomo/node.js:1390 msgid "Name of the Proxy group to download provider." msgstr "用於下載供應商訂閱的代理組名稱。" @@ -1683,7 +1687,7 @@ msgstr "用於下載供應商訂閱的代理組名稱。" msgid "Name of the Proxy group to download rule set." msgstr "用於下載規則集訂閱的代理組名稱。" -#: htdocs/luci-static/resources/view/fchomo/node.js:472 +#: htdocs/luci-static/resources/view/fchomo/node.js:473 msgid "Native UDP" msgstr "原生 UDP" @@ -1700,11 +1704,11 @@ msgid "No add'l params" msgstr "無附加參數" #: htdocs/luci-static/resources/view/fchomo/client.js:1003 -#: htdocs/luci-static/resources/view/fchomo/node.js:1535 +#: htdocs/luci-static/resources/view/fchomo/node.js:1536 msgid "No testing is performed when this provider node is not in use." msgstr "當此供應商的節點未使用時,不執行任何測試。" -#: htdocs/luci-static/resources/fchomo.js:640 +#: htdocs/luci-static/resources/fchomo.js:642 msgid "No valid %s found." msgstr "未找到有效的%s。" @@ -1719,17 +1723,17 @@ msgid "Node" msgstr "節點" #: htdocs/luci-static/resources/view/fchomo/client.js:1048 -#: htdocs/luci-static/resources/view/fchomo/node.js:1555 +#: htdocs/luci-static/resources/view/fchomo/node.js:1556 msgid "Node exclude filter" msgstr "排除節點" #: htdocs/luci-static/resources/view/fchomo/client.js:1053 -#: htdocs/luci-static/resources/view/fchomo/node.js:1562 +#: htdocs/luci-static/resources/view/fchomo/node.js:1563 msgid "Node exclude type" msgstr "排除節點類型" #: htdocs/luci-static/resources/view/fchomo/client.js:1043 -#: htdocs/luci-static/resources/view/fchomo/node.js:1549 +#: htdocs/luci-static/resources/view/fchomo/node.js:1550 msgid "Node filter" msgstr "過濾節點" @@ -1745,11 +1749,11 @@ msgstr "無" msgid "Not Installed" msgstr "未安裝" -#: htdocs/luci-static/resources/fchomo.js:1088 +#: htdocs/luci-static/resources/fchomo.js:1112 msgid "Not Running" msgstr "未在運作" -#: htdocs/luci-static/resources/view/fchomo/node.js:692 +#: htdocs/luci-static/resources/view/fchomo/node.js:693 msgid "Obfs Mode" msgstr "Obfs 模式" @@ -1783,7 +1787,7 @@ msgstr "0-63 範圍內的一個或多個數字,以逗號分隔" msgid "Only process traffic from specific interfaces. Leave empty for all." msgstr "只處理來自指定介面的流量。留空表示全部。" -#: htdocs/luci-static/resources/fchomo.js:1082 +#: htdocs/luci-static/resources/fchomo.js:1106 msgid "Open Dashboard" msgstr "打開面板" @@ -1797,11 +1801,11 @@ msgid "Override destination" msgstr "覆蓋目標位址" #: htdocs/luci-static/resources/view/fchomo/client.js:898 -#: htdocs/luci-static/resources/view/fchomo/node.js:1300 +#: htdocs/luci-static/resources/view/fchomo/node.js:1301 msgid "Override fields" msgstr "覆蓋欄位" -#: htdocs/luci-static/resources/view/fchomo/node.js:455 +#: htdocs/luci-static/resources/view/fchomo/node.js:456 msgid "Override the IP address of the server that DNS response." msgstr "覆蓋 DNS 回應的伺服器的 IP 位址。" @@ -1821,43 +1825,43 @@ msgstr "覆蓋原始請求中已有的 ECS。" msgid "Overview" msgstr "概覽" -#: htdocs/luci-static/resources/view/fchomo/node.js:1028 +#: htdocs/luci-static/resources/view/fchomo/node.js:1029 msgid "POST" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1029 +#: htdocs/luci-static/resources/view/fchomo/node.js:1030 msgid "PUT" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:608 +#: htdocs/luci-static/resources/view/fchomo/node.js:609 msgid "Packet encoding" msgstr "數據包編碼" -#: htdocs/luci-static/resources/view/fchomo/server.js:469 +#: htdocs/luci-static/resources/view/fchomo/server.js:481 msgid "Padding scheme" msgstr "填充方案" -#: htdocs/luci-static/resources/view/fchomo/node.js:798 -#: htdocs/luci-static/resources/view/fchomo/server.js:617 +#: htdocs/luci-static/resources/view/fchomo/node.js:799 +#: htdocs/luci-static/resources/view/fchomo/server.js:629 msgid "Paddings" msgstr "填充 (Paddings)" #: htdocs/luci-static/resources/view/fchomo/node.js:261 #: htdocs/luci-static/resources/view/fchomo/node.js:334 -#: htdocs/luci-static/resources/view/fchomo/node.js:707 +#: htdocs/luci-static/resources/view/fchomo/node.js:708 #: htdocs/luci-static/resources/view/fchomo/server.js:221 #: htdocs/luci-static/resources/view/fchomo/server.js:277 -#: htdocs/luci-static/resources/view/fchomo/server.js:510 +#: htdocs/luci-static/resources/view/fchomo/server.js:522 msgid "Password" msgstr "密碼" -#: htdocs/luci-static/resources/view/fchomo/node.js:1364 +#: htdocs/luci-static/resources/view/fchomo/node.js:1365 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:349 -#: htdocs/luci-static/resources/view/fchomo/server.js:557 +#: htdocs/luci-static/resources/view/fchomo/server.js:569 msgid "Payload" msgstr "Payload" -#: htdocs/luci-static/resources/view/fchomo/node.js:637 +#: htdocs/luci-static/resources/view/fchomo/node.js:638 msgid "Peer pubkic key" msgstr "對端公鑰" @@ -1886,8 +1890,8 @@ msgid "" "standards." msgstr "連結格式標準請參考
%s。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1337 -#: htdocs/luci-static/resources/view/fchomo/node.js:1363 +#: htdocs/luci-static/resources/view/fchomo/node.js:1338 +#: htdocs/luci-static/resources/view/fchomo/node.js:1364 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:322 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:348 msgid "" @@ -1901,25 +1905,25 @@ msgstr "" #: htdocs/luci-static/resources/view/fchomo/client.js:1195 #: htdocs/luci-static/resources/view/fchomo/client.js:1320 #: htdocs/luci-static/resources/view/fchomo/client.js:1553 -#: htdocs/luci-static/resources/view/fchomo/node.js:1206 +#: htdocs/luci-static/resources/view/fchomo/node.js:1207 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:143 msgid "Please type %s fields of mihomo config.
" msgstr "請輸入 mihomo 配置的 %s 欄位。
" -#: htdocs/luci-static/resources/view/fchomo/node.js:681 -#: htdocs/luci-static/resources/view/fchomo/server.js:496 +#: htdocs/luci-static/resources/view/fchomo/node.js:682 +#: htdocs/luci-static/resources/view/fchomo/server.js:508 msgid "Plugin" msgstr "插件" -#: htdocs/luci-static/resources/view/fchomo/node.js:692 -#: htdocs/luci-static/resources/view/fchomo/node.js:699 -#: htdocs/luci-static/resources/view/fchomo/node.js:707 -#: htdocs/luci-static/resources/view/fchomo/node.js:713 -#: htdocs/luci-static/resources/view/fchomo/node.js:721 -#: htdocs/luci-static/resources/view/fchomo/node.js:727 -#: htdocs/luci-static/resources/view/fchomo/server.js:503 -#: htdocs/luci-static/resources/view/fchomo/server.js:510 -#: htdocs/luci-static/resources/view/fchomo/server.js:516 +#: htdocs/luci-static/resources/view/fchomo/node.js:693 +#: htdocs/luci-static/resources/view/fchomo/node.js:700 +#: htdocs/luci-static/resources/view/fchomo/node.js:708 +#: htdocs/luci-static/resources/view/fchomo/node.js:714 +#: htdocs/luci-static/resources/view/fchomo/node.js:722 +#: htdocs/luci-static/resources/view/fchomo/node.js:728 +#: htdocs/luci-static/resources/view/fchomo/server.js:515 +#: htdocs/luci-static/resources/view/fchomo/server.js:522 +#: htdocs/luci-static/resources/view/fchomo/server.js:528 msgid "Plugin:" msgstr "插件:" @@ -1927,7 +1931,7 @@ msgstr "插件:" msgid "Port" msgstr "連接埠" -#: htdocs/luci-static/resources/fchomo.js:1313 +#: htdocs/luci-static/resources/fchomo.js:1343 msgid "Port %s alrealy exists!" msgstr "連接埠 %s 已存在!" @@ -1944,8 +1948,8 @@ msgstr "連接埠" msgid "Ports pool" msgstr "連接埠池" -#: htdocs/luci-static/resources/view/fchomo/node.js:432 -#: htdocs/luci-static/resources/view/fchomo/node.js:644 +#: htdocs/luci-static/resources/view/fchomo/node.js:433 +#: htdocs/luci-static/resources/view/fchomo/node.js:645 msgid "Pre-shared key" msgstr "預先共用金鑰" @@ -1964,10 +1968,10 @@ msgstr "防止某些情況下的 ICMP 環回問題。 Ping 不會顯示實際延 #: htdocs/luci-static/resources/view/fchomo/global.js:742 #: htdocs/luci-static/resources/view/fchomo/global.js:759 -#: htdocs/luci-static/resources/view/fchomo/node.js:1170 -#: htdocs/luci-static/resources/view/fchomo/node.js:1176 -#: htdocs/luci-static/resources/view/fchomo/node.js:1484 -#: htdocs/luci-static/resources/view/fchomo/node.js:1491 +#: htdocs/luci-static/resources/view/fchomo/node.js:1171 +#: htdocs/luci-static/resources/view/fchomo/node.js:1177 +#: htdocs/luci-static/resources/view/fchomo/node.js:1485 +#: htdocs/luci-static/resources/view/fchomo/node.js:1492 msgid "Priority: Proxy Node > Global." msgstr "優先權: 代理節點 > 全域。" @@ -1979,7 +1983,7 @@ msgstr "金鑰" msgid "Priv-key passphrase" msgstr "金鑰密碼" -#: htdocs/luci-static/resources/view/fchomo/node.js:629 +#: htdocs/luci-static/resources/view/fchomo/node.js:630 msgid "Private key" msgstr "私鑰" @@ -1988,28 +1992,28 @@ msgid "Process matching mode" msgstr "進程匹配模式" #: htdocs/luci-static/resources/view/fchomo/global.js:690 -#: htdocs/luci-static/resources/view/fchomo/node.js:1088 +#: htdocs/luci-static/resources/view/fchomo/node.js:1089 msgid "Protocol" msgstr "協議" -#: htdocs/luci-static/resources/view/fchomo/node.js:603 +#: htdocs/luci-static/resources/view/fchomo/node.js:604 msgid "Protocol parameter. Enable length block encryption." msgstr "協議參數。啟用長度塊加密。" -#: htdocs/luci-static/resources/view/fchomo/node.js:597 +#: htdocs/luci-static/resources/view/fchomo/node.js:598 msgid "" "Protocol parameter. Will waste traffic randomly if enabled (enabled by " "default in v2ray and cannot be disabled)." msgstr "協議參數。 如啟用會隨機浪費流量(在 v2ray 中預設為啟用且無法停用)。" #: htdocs/luci-static/resources/view/fchomo/client.js:943 -#: htdocs/luci-static/resources/view/fchomo/node.js:1189 -#: htdocs/luci-static/resources/view/fchomo/node.js:1198 -#: htdocs/luci-static/resources/view/fchomo/node.js:1600 +#: htdocs/luci-static/resources/view/fchomo/node.js:1190 +#: htdocs/luci-static/resources/view/fchomo/node.js:1199 +#: htdocs/luci-static/resources/view/fchomo/node.js:1601 msgid "Provider" msgstr "供應商" -#: htdocs/luci-static/resources/view/fchomo/node.js:1370 +#: htdocs/luci-static/resources/view/fchomo/node.js:1371 msgid "Provider URL" msgstr "供應商訂閱 URL" @@ -2032,18 +2036,18 @@ msgid "Proxy MAC-s" msgstr "代理 MAC 位址" #: htdocs/luci-static/resources/view/fchomo/node.js:208 -#: htdocs/luci-static/resources/view/fchomo/node.js:1599 +#: htdocs/luci-static/resources/view/fchomo/node.js:1600 msgid "Proxy Node" msgstr "代理節點" -#: htdocs/luci-static/resources/view/fchomo/node.js:1575 -#: htdocs/luci-static/resources/view/fchomo/node.js:1584 +#: htdocs/luci-static/resources/view/fchomo/node.js:1576 +#: htdocs/luci-static/resources/view/fchomo/node.js:1585 msgid "Proxy chain" msgstr "代理鏈" #: htdocs/luci-static/resources/view/fchomo/client.js:723 #: htdocs/luci-static/resources/view/fchomo/client.js:1416 -#: htdocs/luci-static/resources/view/fchomo/node.js:1388 +#: htdocs/luci-static/resources/view/fchomo/node.js:1389 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:373 msgid "Proxy group" msgstr "代理組" @@ -2060,12 +2064,12 @@ msgstr "代理模式" msgid "Proxy routerself" msgstr "代理路由器自身" -#: htdocs/luci-static/resources/view/fchomo/node.js:473 +#: htdocs/luci-static/resources/view/fchomo/node.js:474 msgid "QUIC" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:461 -#: htdocs/luci-static/resources/view/fchomo/server.js:417 +#: htdocs/luci-static/resources/view/fchomo/node.js:462 +#: htdocs/luci-static/resources/view/fchomo/server.js:429 msgid "QUIC congestion controller." msgstr "QUIC 壅塞控制器。" @@ -2074,40 +2078,40 @@ msgstr "QUIC 壅塞控制器。" msgid "Quick Reload" msgstr "快速重載" -#: htdocs/luci-static/resources/view/fchomo/node.js:961 -#: htdocs/luci-static/resources/view/fchomo/server.js:881 +#: htdocs/luci-static/resources/view/fchomo/node.js:962 +#: htdocs/luci-static/resources/view/fchomo/server.js:893 msgid "REALITY" msgstr "REALITY" -#: htdocs/luci-static/resources/view/fchomo/node.js:976 +#: htdocs/luci-static/resources/view/fchomo/node.js:977 msgid "REALITY X25519MLKEM768 PQC support" msgstr "REALITY X25519MLKEM768 後量子加密支援" -#: htdocs/luci-static/resources/view/fchomo/server.js:918 +#: htdocs/luci-static/resources/view/fchomo/server.js:930 msgid "REALITY certificate issued to" msgstr "REALITY 證書頒發給" -#: htdocs/luci-static/resources/view/fchomo/server.js:886 +#: htdocs/luci-static/resources/view/fchomo/server.js:898 msgid "REALITY handshake server" msgstr "REALITY 握手伺服器" -#: htdocs/luci-static/resources/view/fchomo/server.js:893 +#: htdocs/luci-static/resources/view/fchomo/server.js:905 msgid "REALITY private key" msgstr "REALITY 私鑰" -#: htdocs/luci-static/resources/view/fchomo/node.js:966 -#: htdocs/luci-static/resources/view/fchomo/server.js:908 +#: htdocs/luci-static/resources/view/fchomo/node.js:967 +#: htdocs/luci-static/resources/view/fchomo/server.js:920 msgid "REALITY public key" msgstr "REALITY 公鑰" -#: htdocs/luci-static/resources/view/fchomo/node.js:971 -#: htdocs/luci-static/resources/view/fchomo/server.js:912 +#: htdocs/luci-static/resources/view/fchomo/node.js:972 +#: htdocs/luci-static/resources/view/fchomo/server.js:924 msgid "REALITY short ID" msgstr "REALITY 標識符" -#: htdocs/luci-static/resources/view/fchomo/node.js:788 -#: htdocs/luci-static/resources/view/fchomo/server.js:588 -#: htdocs/luci-static/resources/view/fchomo/server.js:607 +#: htdocs/luci-static/resources/view/fchomo/node.js:789 +#: htdocs/luci-static/resources/view/fchomo/server.js:600 +#: htdocs/luci-static/resources/view/fchomo/server.js:619 msgid "RTT" msgstr "" @@ -2143,7 +2147,7 @@ msgstr "Redirect TCP + Tun UDP" msgid "Refresh every %s seconds." msgstr "每 %s 秒刷新。" -#: htdocs/luci-static/resources/fchomo.js:1075 +#: htdocs/luci-static/resources/fchomo.js:1099 #: htdocs/luci-static/resources/view/fchomo/client.js:815 #: htdocs/luci-static/resources/view/fchomo/global.js:193 #: htdocs/luci-static/resources/view/fchomo/server.js:153 @@ -2154,32 +2158,32 @@ msgstr "重載" msgid "Reload All" msgstr "重載所有" -#: htdocs/luci-static/resources/view/fchomo/node.js:1315 +#: htdocs/luci-static/resources/view/fchomo/node.js:1316 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:263 msgid "Remote" msgstr "遠端" -#: htdocs/luci-static/resources/view/fchomo/node.js:669 +#: htdocs/luci-static/resources/view/fchomo/node.js:670 msgid "Remote DNS resolve" msgstr "遠端 DNS 解析" -#: htdocs/luci-static/resources/fchomo.js:1234 +#: htdocs/luci-static/resources/fchomo.js:1264 msgid "Remove" msgstr "移除" -#: htdocs/luci-static/resources/fchomo.js:1239 -#: htdocs/luci-static/resources/view/fchomo/node.js:1291 -#: htdocs/luci-static/resources/view/fchomo/node.js:1293 +#: htdocs/luci-static/resources/fchomo.js:1269 +#: htdocs/luci-static/resources/view/fchomo/node.js:1292 +#: htdocs/luci-static/resources/view/fchomo/node.js:1294 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:236 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:238 msgid "Remove idles" msgstr "移除閒置" -#: htdocs/luci-static/resources/view/fchomo/node.js:1417 +#: htdocs/luci-static/resources/view/fchomo/node.js:1418 msgid "Replace name" msgstr "名稱替換" -#: htdocs/luci-static/resources/view/fchomo/node.js:1418 +#: htdocs/luci-static/resources/view/fchomo/node.js:1419 msgid "Replace node name." msgstr "替換節點名稱" @@ -2187,13 +2191,13 @@ msgstr "替換節點名稱" msgid "Request" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1035 -#: htdocs/luci-static/resources/view/fchomo/node.js:1042 -#: htdocs/luci-static/resources/view/fchomo/server.js:960 +#: htdocs/luci-static/resources/view/fchomo/node.js:1036 +#: htdocs/luci-static/resources/view/fchomo/node.js:1043 +#: htdocs/luci-static/resources/view/fchomo/server.js:972 msgid "Request path" msgstr "請求路徑" -#: htdocs/luci-static/resources/view/fchomo/node.js:508 +#: htdocs/luci-static/resources/view/fchomo/node.js:509 msgid "Request timeout" msgstr "請求逾時" @@ -2206,11 +2210,11 @@ msgid "Require any" msgstr "" #: htdocs/luci-static/resources/fchomo.js:347 -#: htdocs/luci-static/resources/view/fchomo/node.js:977 +#: htdocs/luci-static/resources/view/fchomo/node.js:978 msgid "Requires server support." msgstr "需要伺服器支援。" -#: htdocs/luci-static/resources/view/fchomo/node.js:658 +#: htdocs/luci-static/resources/view/fchomo/node.js:659 msgid "Reserved field bytes" msgstr "保留字段位元組" @@ -2218,7 +2222,7 @@ msgstr "保留字段位元組" msgid "Resources management" msgstr "資源管理" -#: htdocs/luci-static/resources/view/fchomo/node.js:727 +#: htdocs/luci-static/resources/view/fchomo/node.js:728 msgid "Restls script" msgstr "Restls 劇本" @@ -2245,8 +2249,8 @@ msgstr "路由 DSCP" msgid "Routing GFW" msgstr "路由 GFW 流量" -#: htdocs/luci-static/resources/view/fchomo/node.js:1175 -#: htdocs/luci-static/resources/view/fchomo/node.js:1490 +#: htdocs/luci-static/resources/view/fchomo/node.js:1176 +#: htdocs/luci-static/resources/view/fchomo/node.js:1491 msgid "Routing mark" msgstr "路由標記" @@ -2306,7 +2310,7 @@ msgstr "規則集" msgid "Ruleset-URI-Scheme" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1088 +#: htdocs/luci-static/resources/fchomo.js:1112 msgid "Running" msgstr "正在運作" @@ -2334,7 +2338,7 @@ msgstr "STUN 連接埠" msgid "SUB-RULE" msgstr "SUB-RULE" -#: htdocs/luci-static/resources/view/fchomo/node.js:745 +#: htdocs/luci-static/resources/view/fchomo/node.js:746 msgid "SUoT version" msgstr "SUoT 版本" @@ -2373,9 +2377,9 @@ msgid "Send random ticket of 300s-600s duration for client 0-RTT reuse." msgstr "發送 300-600 秒的隨機票證,以供客戶端 0-RTT 重用。" #: htdocs/luci-static/resources/view/fchomo/server.js:166 -#: htdocs/luci-static/resources/view/fchomo/server.js:588 -#: htdocs/luci-static/resources/view/fchomo/server.js:779 -#: htdocs/luci-static/resources/view/fchomo/server.js:794 +#: htdocs/luci-static/resources/view/fchomo/server.js:600 +#: htdocs/luci-static/resources/view/fchomo/server.js:791 +#: htdocs/luci-static/resources/view/fchomo/server.js:806 #: root/usr/share/luci/menu.d/luci-app-fchomo.json:54 msgid "Server" msgstr "服務端" @@ -2384,7 +2388,7 @@ msgstr "服務端" msgid "Server address" msgstr "伺服器位址" -#: htdocs/luci-static/resources/view/fchomo/node.js:1020 +#: htdocs/luci-static/resources/view/fchomo/node.js:1021 msgid "Server hostname" msgstr "伺服器主機名稱" @@ -2401,22 +2405,22 @@ msgstr "服務狀態" msgid "Shadowsocks" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:527 -#: htdocs/luci-static/resources/view/fchomo/server.js:451 +#: htdocs/luci-static/resources/view/fchomo/node.js:528 +#: htdocs/luci-static/resources/view/fchomo/server.js:463 msgid "Shadowsocks chipher" msgstr "Shadowsocks 加密方法" -#: htdocs/luci-static/resources/view/fchomo/node.js:522 -#: htdocs/luci-static/resources/view/fchomo/server.js:446 +#: htdocs/luci-static/resources/view/fchomo/node.js:523 +#: htdocs/luci-static/resources/view/fchomo/server.js:458 msgid "Shadowsocks encrypt" msgstr "Shadowsocks 加密" -#: htdocs/luci-static/resources/view/fchomo/node.js:535 -#: htdocs/luci-static/resources/view/fchomo/server.js:459 +#: htdocs/luci-static/resources/view/fchomo/node.js:536 +#: htdocs/luci-static/resources/view/fchomo/server.js:471 msgid "Shadowsocks password" msgstr "Shadowsocks 密碼" -#: htdocs/luci-static/resources/view/fchomo/node.js:1130 +#: htdocs/luci-static/resources/view/fchomo/node.js:1131 msgid "Show connections in the dashboard for breaking connections easier." msgstr "在面板中顯示連線以便於打斷連線。" @@ -2428,14 +2432,14 @@ msgstr "靜音" msgid "Simple round-robin all nodes" msgstr "簡單輪替所有節點" -#: htdocs/luci-static/resources/view/fchomo/node.js:1376 +#: htdocs/luci-static/resources/view/fchomo/node.js:1377 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:361 msgid "Size limit" msgstr "大小限制" #: htdocs/luci-static/resources/view/fchomo/client.js:1449 -#: htdocs/luci-static/resources/view/fchomo/node.js:903 -#: htdocs/luci-static/resources/view/fchomo/node.js:1468 +#: htdocs/luci-static/resources/view/fchomo/node.js:904 +#: htdocs/luci-static/resources/view/fchomo/node.js:1469 msgid "Skip cert verify" msgstr "跳過憑證驗證" @@ -2467,6 +2471,10 @@ msgstr "嗅探器" msgid "Sniffer settings" msgstr "嗅探器設定" +#: htdocs/luci-static/resources/fchomo.js:385 +msgid "Specify a ID" +msgstr "指定一個ID" + #: htdocs/luci-static/resources/view/fchomo/global.js:823 #: htdocs/luci-static/resources/view/fchomo/global.js:832 msgid "" @@ -2500,7 +2508,7 @@ msgstr "子規則" msgid "Sub rule group" msgstr "子規則組" -#: htdocs/luci-static/resources/fchomo.js:643 +#: htdocs/luci-static/resources/fchomo.js:645 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:207 msgid "Successfully imported %s %s of total %s." msgstr "已成功匯入 %s 個%s (共 %s 個)。" @@ -2509,7 +2517,7 @@ msgstr "已成功匯入 %s 個%s (共 %s 個)。" msgid "Successfully updated." msgstr "更新成功。" -#: htdocs/luci-static/resources/fchomo.js:1568 +#: htdocs/luci-static/resources/fchomo.js:1614 msgid "Successfully uploaded." msgstr "已成功上傳。" @@ -2557,7 +2565,7 @@ msgstr "TCP" msgid "TCP concurrency" msgstr "TCP 併發" -#: htdocs/luci-static/resources/view/fchomo/node.js:1123 +#: htdocs/luci-static/resources/view/fchomo/node.js:1124 msgid "TCP only" msgstr "僅 TCP" @@ -2580,24 +2588,24 @@ msgstr "TCP-Keep-Alive 間隔" msgid "TCP/UDP" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1154 -#: htdocs/luci-static/resources/view/fchomo/node.js:1435 +#: htdocs/luci-static/resources/view/fchomo/node.js:1155 +#: htdocs/luci-static/resources/view/fchomo/node.js:1436 msgid "TFO" msgstr "TCP 快速開啟 (TFO)" #: htdocs/luci-static/resources/view/fchomo/global.js:529 -#: htdocs/luci-static/resources/view/fchomo/node.js:694 -#: htdocs/luci-static/resources/view/fchomo/node.js:820 -#: htdocs/luci-static/resources/view/fchomo/server.js:742 +#: htdocs/luci-static/resources/view/fchomo/node.js:695 +#: htdocs/luci-static/resources/view/fchomo/node.js:821 +#: htdocs/luci-static/resources/view/fchomo/server.js:754 msgid "TLS" msgstr "TLS" -#: htdocs/luci-static/resources/view/fchomo/node.js:851 -#: htdocs/luci-static/resources/view/fchomo/server.js:773 +#: htdocs/luci-static/resources/view/fchomo/node.js:852 +#: htdocs/luci-static/resources/view/fchomo/server.js:785 msgid "TLS ALPN" msgstr "TLS ALPN" -#: htdocs/luci-static/resources/view/fchomo/node.js:845 +#: htdocs/luci-static/resources/view/fchomo/node.js:846 msgid "TLS SNI" msgstr "" @@ -2620,24 +2628,24 @@ msgid "" "Tell the client to use the BBR flow control algorithm instead of Hysteria CC." msgstr "讓客戶端使用 BBR 流控演算法。" -#: htdocs/luci-static/resources/view/fchomo/node.js:617 -#: htdocs/luci-static/resources/view/fchomo/node.js:624 +#: htdocs/luci-static/resources/view/fchomo/node.js:618 +#: htdocs/luci-static/resources/view/fchomo/node.js:625 msgid "The %s address used by local machine in the Wireguard network." msgstr "WireGuard 網路中使用的本機 %s 位址。" -#: htdocs/luci-static/resources/view/fchomo/node.js:926 -#: htdocs/luci-static/resources/view/fchomo/server.js:794 +#: htdocs/luci-static/resources/view/fchomo/node.js:927 +#: htdocs/luci-static/resources/view/fchomo/server.js:806 msgid "The %s private key, in PEM format." msgstr "%s私鑰,需要 PEM 格式。" #: htdocs/luci-static/resources/view/fchomo/global.js:556 -#: htdocs/luci-static/resources/view/fchomo/node.js:912 -#: htdocs/luci-static/resources/view/fchomo/server.js:779 -#: htdocs/luci-static/resources/view/fchomo/server.js:817 +#: htdocs/luci-static/resources/view/fchomo/node.js:913 +#: htdocs/luci-static/resources/view/fchomo/server.js:791 +#: htdocs/luci-static/resources/view/fchomo/server.js:829 msgid "The %s public key, in PEM format." msgstr "%s公鑰,需要 PEM 格式。" -#: htdocs/luci-static/resources/view/fchomo/node.js:946 +#: htdocs/luci-static/resources/view/fchomo/node.js:947 msgid "" "The ECH parameter of the HTTPS record for the domain. Leave empty to resolve " "via DNS." @@ -2655,8 +2663,8 @@ msgstr "Sudoku 產生的 ED25519 主公鑰 或 UUID。" msgid "The default value is 2:00 every day." msgstr "預設值為每天 2:00。" -#: htdocs/luci-static/resources/view/fchomo/node.js:801 -#: htdocs/luci-static/resources/view/fchomo/server.js:620 +#: htdocs/luci-static/resources/view/fchomo/node.js:802 +#: htdocs/luci-static/resources/view/fchomo/server.js:632 msgid "" "The first padding must have a probability of 100% and at least 35 bytes." msgstr "首個填充必須為 100% 的機率並且至少 35 位元組。" @@ -2671,26 +2679,26 @@ msgstr "匹配 %s 的將被視為未被投毒汙染。" msgid "The matching %s will be deemed as poisoned." msgstr "匹配 %s 的將被視為已被投毒汙染。" -#: htdocs/luci-static/resources/view/fchomo/node.js:799 -#: htdocs/luci-static/resources/view/fchomo/server.js:618 +#: htdocs/luci-static/resources/view/fchomo/node.js:800 +#: htdocs/luci-static/resources/view/fchomo/server.js:630 msgid "The server and client can set different padding parameters." msgstr "伺服器和客戶端可以設定不同的填充參數。" #: htdocs/luci-static/resources/view/fchomo/global.js:600 -#: htdocs/luci-static/resources/view/fchomo/server.js:875 +#: htdocs/luci-static/resources/view/fchomo/server.js:887 msgid "This ECH parameter needs to be added to the HTTPS record of the domain." msgstr "此 ECH 參數需要加入到網域的 HTTPS 記錄中。" #: htdocs/luci-static/resources/view/fchomo/client.js:1452 -#: htdocs/luci-static/resources/view/fchomo/node.js:906 -#: htdocs/luci-static/resources/view/fchomo/node.js:1471 +#: htdocs/luci-static/resources/view/fchomo/node.js:907 +#: htdocs/luci-static/resources/view/fchomo/node.js:1472 msgid "" "This is DANGEROUS, your traffic is almost like " "PLAIN TEXT! Use at your own risk!" msgstr "" "這是危險行為,您的流量將幾乎等同於明文!使用風險自負!" -#: htdocs/luci-static/resources/view/fchomo/node.js:478 +#: htdocs/luci-static/resources/view/fchomo/node.js:479 msgid "" "This is the TUIC port of the SUoT protocol, designed to provide a QUIC " "stream based UDP relay mode that TUIC does not provide." @@ -2722,18 +2730,18 @@ msgstr "Tproxy Fwmark/fwmask" msgid "Tproxy port" msgstr "Tproxy 連接埠" -#: htdocs/luci-static/resources/view/fchomo/node.js:1627 +#: htdocs/luci-static/resources/view/fchomo/node.js:1628 msgid "Transit proxy group" msgstr "中轉代理組" -#: htdocs/luci-static/resources/view/fchomo/node.js:1633 +#: htdocs/luci-static/resources/view/fchomo/node.js:1634 msgid "Transit proxy node" msgstr "中轉代理節點" #: htdocs/luci-static/resources/view/fchomo/node.js:349 -#: htdocs/luci-static/resources/view/fchomo/node.js:983 +#: htdocs/luci-static/resources/view/fchomo/node.js:984 #: htdocs/luci-static/resources/view/fchomo/server.js:287 -#: htdocs/luci-static/resources/view/fchomo/server.js:926 +#: htdocs/luci-static/resources/view/fchomo/server.js:938 msgid "Transport" msgstr "傳輸層" @@ -2742,8 +2750,8 @@ msgstr "傳輸層" msgid "Transport fields" msgstr "傳輸層欄位" -#: htdocs/luci-static/resources/view/fchomo/node.js:988 -#: htdocs/luci-static/resources/view/fchomo/server.js:931 +#: htdocs/luci-static/resources/view/fchomo/node.js:989 +#: htdocs/luci-static/resources/view/fchomo/server.js:943 msgid "Transport type" msgstr "傳輸層類型" @@ -2778,8 +2786,8 @@ msgstr "Tun 堆栈" #: htdocs/luci-static/resources/view/fchomo/client.js:916 #: htdocs/luci-static/resources/view/fchomo/client.js:1594 #: htdocs/luci-static/resources/view/fchomo/node.js:238 -#: htdocs/luci-static/resources/view/fchomo/node.js:1313 -#: htdocs/luci-static/resources/view/fchomo/node.js:1598 +#: htdocs/luci-static/resources/view/fchomo/node.js:1314 +#: htdocs/luci-static/resources/view/fchomo/node.js:1599 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:261 #: htdocs/luci-static/resources/view/fchomo/server.js:193 msgid "Type" @@ -2792,9 +2800,9 @@ msgstr "類型" #: htdocs/luci-static/resources/fchomo.js:172 #: htdocs/luci-static/resources/view/fchomo/client.js:526 #: htdocs/luci-static/resources/view/fchomo/client.js:616 -#: htdocs/luci-static/resources/view/fchomo/node.js:734 -#: htdocs/luci-static/resources/view/fchomo/node.js:1445 -#: htdocs/luci-static/resources/view/fchomo/server.js:525 +#: htdocs/luci-static/resources/view/fchomo/node.js:735 +#: htdocs/luci-static/resources/view/fchomo/node.js:1446 +#: htdocs/luci-static/resources/view/fchomo/server.js:537 msgid "UDP" msgstr "UDP" @@ -2802,19 +2810,19 @@ msgstr "UDP" msgid "UDP NAT expiration time" msgstr "UDP NAT 過期時間" -#: htdocs/luci-static/resources/view/fchomo/node.js:477 +#: htdocs/luci-static/resources/view/fchomo/node.js:478 msgid "UDP over stream" msgstr "UDP over stream" -#: htdocs/luci-static/resources/view/fchomo/node.js:483 +#: htdocs/luci-static/resources/view/fchomo/node.js:484 msgid "UDP over stream version" msgstr "UDP over stream 版本" -#: htdocs/luci-static/resources/view/fchomo/node.js:470 +#: htdocs/luci-static/resources/view/fchomo/node.js:471 msgid "UDP packet relay mode." msgstr "UDP 包中繼模式。" -#: htdocs/luci-static/resources/view/fchomo/node.js:469 +#: htdocs/luci-static/resources/view/fchomo/node.js:470 msgid "UDP relay mode" msgstr "UDP 中繼模式" @@ -2822,15 +2830,15 @@ msgstr "UDP 中繼模式" msgid "URL test" msgstr "自動選擇" -#: htdocs/luci-static/resources/view/fchomo/node.js:448 -#: htdocs/luci-static/resources/view/fchomo/node.js:566 +#: htdocs/luci-static/resources/view/fchomo/node.js:449 +#: htdocs/luci-static/resources/view/fchomo/node.js:567 #: htdocs/luci-static/resources/view/fchomo/server.js:297 -#: htdocs/luci-static/resources/view/fchomo/server.js:410 -#: htdocs/luci-static/resources/view/fchomo/server.js:474 +#: htdocs/luci-static/resources/view/fchomo/server.js:422 +#: htdocs/luci-static/resources/view/fchomo/server.js:486 msgid "UUID" msgstr "UUID" -#: htdocs/luci-static/resources/fchomo.js:1133 +#: htdocs/luci-static/resources/fchomo.js:1157 msgid "Unable to download unsupported type: %s" msgstr "無法下載不支援的類型: %s" @@ -2855,8 +2863,8 @@ msgstr "未知錯誤。" msgid "Unknown error: %s" msgstr "未知錯誤:%s" -#: htdocs/luci-static/resources/view/fchomo/node.js:739 -#: htdocs/luci-static/resources/view/fchomo/node.js:1450 +#: htdocs/luci-static/resources/view/fchomo/node.js:740 +#: htdocs/luci-static/resources/view/fchomo/node.js:1451 msgid "UoT" msgstr "UDP over TCP (UoT)" @@ -2864,29 +2872,29 @@ msgstr "UDP over TCP (UoT)" msgid "Update failed." msgstr "更新失敗。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1382 +#: htdocs/luci-static/resources/view/fchomo/node.js:1383 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:367 msgid "Update interval" msgstr "更新間隔" -#: htdocs/luci-static/resources/view/fchomo/node.js:426 -#: htdocs/luci-static/resources/view/fchomo/server.js:404 +#: htdocs/luci-static/resources/view/fchomo/node.js:427 +#: htdocs/luci-static/resources/view/fchomo/server.js:416 msgid "" "Uplink keeps the Sudoku protocol, and downlink characteristics are " "consistent with uplink characteristics." msgstr "上行鏈路保持數獨協議,下行鏈路特性與上行鏈路特性一致。" -#: htdocs/luci-static/resources/view/fchomo/node.js:1141 +#: htdocs/luci-static/resources/view/fchomo/node.js:1142 msgid "Upload bandwidth" msgstr "上傳頻寬" -#: htdocs/luci-static/resources/view/fchomo/node.js:1142 +#: htdocs/luci-static/resources/view/fchomo/node.js:1143 msgid "Upload bandwidth in Mbps." msgstr "上傳頻寬(單位:Mbps)。" -#: htdocs/luci-static/resources/view/fchomo/node.js:917 -#: htdocs/luci-static/resources/view/fchomo/server.js:785 -#: htdocs/luci-static/resources/view/fchomo/server.js:825 +#: htdocs/luci-static/resources/view/fchomo/node.js:918 +#: htdocs/luci-static/resources/view/fchomo/server.js:797 +#: htdocs/luci-static/resources/view/fchomo/server.js:837 msgid "Upload certificate" msgstr "上傳憑證" @@ -2894,17 +2902,17 @@ msgstr "上傳憑證" msgid "Upload initial package" msgstr "上傳初始資源包" -#: htdocs/luci-static/resources/view/fchomo/node.js:931 -#: htdocs/luci-static/resources/view/fchomo/server.js:800 +#: htdocs/luci-static/resources/view/fchomo/node.js:932 +#: htdocs/luci-static/resources/view/fchomo/server.js:812 msgid "Upload key" msgstr "上傳金鑰" #: htdocs/luci-static/resources/view/fchomo/global.js:306 -#: htdocs/luci-static/resources/view/fchomo/node.js:920 -#: htdocs/luci-static/resources/view/fchomo/node.js:934 -#: htdocs/luci-static/resources/view/fchomo/server.js:788 -#: htdocs/luci-static/resources/view/fchomo/server.js:803 -#: htdocs/luci-static/resources/view/fchomo/server.js:828 +#: htdocs/luci-static/resources/view/fchomo/node.js:921 +#: htdocs/luci-static/resources/view/fchomo/node.js:935 +#: htdocs/luci-static/resources/view/fchomo/server.js:800 +#: htdocs/luci-static/resources/view/fchomo/server.js:815 +#: htdocs/luci-static/resources/view/fchomo/server.js:840 msgid "Upload..." msgstr "上傳..." @@ -2928,7 +2936,7 @@ msgstr "用於解析 DNS 伺服器的網域。必須是 IP。" msgid "Used to resolve the domain of the Proxy node." msgstr "用於解析代理節點的網域。" -#: htdocs/luci-static/resources/view/fchomo/node.js:846 +#: htdocs/luci-static/resources/view/fchomo/node.js:847 msgid "Used to verify the hostname on the returned certificates." msgstr "用於驗證傳回的憑證上的主機名稱。" @@ -2945,11 +2953,11 @@ msgstr "使用者名稱" msgid "Users filter mode" msgstr "使用者過濾模式" -#: htdocs/luci-static/resources/view/fchomo/node.js:1071 +#: htdocs/luci-static/resources/view/fchomo/node.js:1072 msgid "V2ray HTTPUpgrade" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1076 +#: htdocs/luci-static/resources/view/fchomo/node.js:1077 msgid "V2ray HTTPUpgrade fast open" msgstr "" @@ -2963,8 +2971,8 @@ msgstr "" msgid "VMess" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1319 -#: htdocs/luci-static/resources/view/fchomo/node.js:1604 +#: htdocs/luci-static/resources/view/fchomo/node.js:1320 +#: htdocs/luci-static/resources/view/fchomo/node.js:1605 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:304 msgid "Value" msgstr "可視化值" @@ -2973,13 +2981,13 @@ msgstr "可視化值" msgid "Verify if given" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:439 -#: htdocs/luci-static/resources/view/fchomo/node.js:713 -#: htdocs/luci-static/resources/view/fchomo/server.js:516 +#: htdocs/luci-static/resources/view/fchomo/node.js:440 +#: htdocs/luci-static/resources/view/fchomo/node.js:714 +#: htdocs/luci-static/resources/view/fchomo/server.js:528 msgid "Version" msgstr "版本" -#: htdocs/luci-static/resources/view/fchomo/node.js:721 +#: htdocs/luci-static/resources/view/fchomo/node.js:722 msgid "Version hint" msgstr "" @@ -2996,17 +3004,17 @@ msgstr "以 75% 的機率等待隨機 0-111 毫秒。" msgid "Warning" msgstr "警告" -#: htdocs/luci-static/resources/view/fchomo/node.js:993 -#: htdocs/luci-static/resources/view/fchomo/node.js:1004 -#: htdocs/luci-static/resources/view/fchomo/node.js:1009 -#: htdocs/luci-static/resources/view/fchomo/server.js:933 -#: htdocs/luci-static/resources/view/fchomo/server.js:944 -#: htdocs/luci-static/resources/view/fchomo/server.js:949 +#: htdocs/luci-static/resources/view/fchomo/node.js:994 +#: htdocs/luci-static/resources/view/fchomo/node.js:1005 +#: htdocs/luci-static/resources/view/fchomo/node.js:1010 +#: htdocs/luci-static/resources/view/fchomo/server.js:945 +#: htdocs/luci-static/resources/view/fchomo/server.js:956 +#: htdocs/luci-static/resources/view/fchomo/server.js:961 msgid "WebSocket" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:425 -#: htdocs/luci-static/resources/view/fchomo/server.js:403 +#: htdocs/luci-static/resources/view/fchomo/node.js:426 +#: htdocs/luci-static/resources/view/fchomo/server.js:415 msgid "" "When disabled, downlink ciphertext is split into 6-bit segments, reusing the " "original padding pool and obfuscate type to reduce downlink overhead." @@ -3026,23 +3034,23 @@ msgstr "白名單" msgid "WireGuard" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:638 +#: htdocs/luci-static/resources/view/fchomo/node.js:639 msgid "WireGuard peer public key." msgstr "WireGuard 對端公鑰。" -#: htdocs/luci-static/resources/view/fchomo/node.js:645 +#: htdocs/luci-static/resources/view/fchomo/node.js:646 msgid "WireGuard pre-shared key." msgstr "WireGuard 預先共用金鑰。" -#: htdocs/luci-static/resources/view/fchomo/node.js:630 +#: htdocs/luci-static/resources/view/fchomo/node.js:631 msgid "WireGuard requires base64-encoded private keys." msgstr "WireGuard 要求 base64 編碼的私鑰。" -#: htdocs/luci-static/resources/view/fchomo/server.js:579 +#: htdocs/luci-static/resources/view/fchomo/server.js:591 msgid "XOR mode" msgstr "XOR 模式" -#: htdocs/luci-static/resources/view/fchomo/node.js:611 +#: htdocs/luci-static/resources/view/fchomo/node.js:612 msgid "Xudp (Xray-core)" msgstr "" @@ -3054,14 +3062,14 @@ msgstr "Yaml 格式文本" msgid "YouTube" msgstr "YouTube" -#: htdocs/luci-static/resources/fchomo.js:1550 +#: htdocs/luci-static/resources/fchomo.js:1596 msgid "Your %s was successfully uploaded. Size: %sB." msgstr "您的 %s 已成功上傳。大小:%sB。" #: htdocs/luci-static/resources/fchomo.js:289 #: htdocs/luci-static/resources/fchomo.js:302 #: htdocs/luci-static/resources/fchomo.js:307 -#: htdocs/luci-static/resources/view/fchomo/node.js:591 +#: htdocs/luci-static/resources/view/fchomo/node.js:592 msgid "aes-128-gcm" msgstr "" @@ -3074,18 +3082,18 @@ msgstr "" msgid "aes-256-gcm" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:588 +#: htdocs/luci-static/resources/view/fchomo/node.js:589 msgid "auto" msgstr "自動" -#: htdocs/luci-static/resources/view/fchomo/node.js:465 -#: htdocs/luci-static/resources/view/fchomo/server.js:421 +#: htdocs/luci-static/resources/view/fchomo/node.js:466 +#: htdocs/luci-static/resources/view/fchomo/server.js:433 msgid "bbr" msgstr "bbr" -#: htdocs/luci-static/resources/view/fchomo/node.js:922 -#: htdocs/luci-static/resources/view/fchomo/server.js:790 -#: htdocs/luci-static/resources/view/fchomo/server.js:830 +#: htdocs/luci-static/resources/view/fchomo/node.js:923 +#: htdocs/luci-static/resources/view/fchomo/server.js:802 +#: htdocs/luci-static/resources/view/fchomo/server.js:842 msgid "certificate" msgstr "憑證" @@ -3095,17 +3103,17 @@ msgstr "憑證" msgid "chacha20-ietf-poly1305" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:592 +#: htdocs/luci-static/resources/view/fchomo/node.js:593 msgid "chacha20-poly1305" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:463 -#: htdocs/luci-static/resources/view/fchomo/server.js:419 +#: htdocs/luci-static/resources/view/fchomo/node.js:464 +#: htdocs/luci-static/resources/view/fchomo/server.js:431 msgid "cubic" msgstr "cubic" -#: htdocs/luci-static/resources/view/fchomo/server.js:531 -#: htdocs/luci-static/resources/view/fchomo/server.js:562 +#: htdocs/luci-static/resources/view/fchomo/server.js:543 +#: htdocs/luci-static/resources/view/fchomo/server.js:574 msgid "decryption" msgstr "decryption" @@ -3113,27 +3121,27 @@ msgstr "decryption" msgid "dnsmasq selects upstream on its own. (may affect CDN accuracy)" msgstr "dnsmasq 自行選擇上游服務器。 (可能影響 CDN 準確性)" -#: htdocs/luci-static/resources/view/fchomo/node.js:1462 +#: htdocs/luci-static/resources/view/fchomo/node.js:1463 msgid "down" msgstr "Hysteria 下載速率" -#: htdocs/luci-static/resources/view/fchomo/node.js:753 -#: htdocs/luci-static/resources/view/fchomo/node.js:776 -#: htdocs/luci-static/resources/view/fchomo/server.js:566 +#: htdocs/luci-static/resources/view/fchomo/node.js:754 +#: htdocs/luci-static/resources/view/fchomo/node.js:777 +#: htdocs/luci-static/resources/view/fchomo/server.js:578 msgid "encryption" msgstr "encryption" -#: htdocs/luci-static/resources/view/fchomo/node.js:992 -#: htdocs/luci-static/resources/view/fchomo/node.js:1003 -#: htdocs/luci-static/resources/view/fchomo/node.js:1008 -#: htdocs/luci-static/resources/view/fchomo/server.js:932 -#: htdocs/luci-static/resources/view/fchomo/server.js:943 -#: htdocs/luci-static/resources/view/fchomo/server.js:948 +#: htdocs/luci-static/resources/view/fchomo/node.js:993 +#: htdocs/luci-static/resources/view/fchomo/node.js:1004 +#: htdocs/luci-static/resources/view/fchomo/node.js:1009 +#: htdocs/luci-static/resources/view/fchomo/server.js:944 +#: htdocs/luci-static/resources/view/fchomo/server.js:955 +#: htdocs/luci-static/resources/view/fchomo/server.js:960 msgid "gRPC" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1055 -#: htdocs/luci-static/resources/view/fchomo/server.js:967 +#: htdocs/luci-static/resources/view/fchomo/node.js:1056 +#: htdocs/luci-static/resources/view/fchomo/server.js:979 msgid "gRPC service name" msgstr "gRPC 服務名稱" @@ -3141,11 +3149,11 @@ msgstr "gRPC 服務名稱" msgid "gVisor" msgstr "gVisor" -#: htdocs/luci-static/resources/view/fchomo/node.js:1092 +#: htdocs/luci-static/resources/view/fchomo/node.js:1093 msgid "h2mux" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/server.js:731 +#: htdocs/luci-static/resources/view/fchomo/server.js:743 msgid "least one keypair required" msgstr "至少需要一對密鑰" @@ -3158,7 +3166,7 @@ msgstr "metacubexd" #: htdocs/luci-static/resources/view/fchomo/client.js:1216 #: htdocs/luci-static/resources/view/fchomo/client.js:1353 #: htdocs/luci-static/resources/view/fchomo/client.js:1571 -#: htdocs/luci-static/resources/view/fchomo/node.js:1285 +#: htdocs/luci-static/resources/view/fchomo/node.js:1286 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:224 msgid "mihomo config" msgstr "mihomo 配置" @@ -3167,13 +3175,13 @@ msgstr "mihomo 配置" msgid "mlkem768x25519plus" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1158 -#: htdocs/luci-static/resources/view/fchomo/node.js:1440 +#: htdocs/luci-static/resources/view/fchomo/node.js:1159 +#: htdocs/luci-static/resources/view/fchomo/node.js:1441 msgid "mpTCP" msgstr "多路徑 TCP (mpTCP)" -#: htdocs/luci-static/resources/view/fchomo/node.js:464 -#: htdocs/luci-static/resources/view/fchomo/server.js:420 +#: htdocs/luci-static/resources/view/fchomo/node.js:465 +#: htdocs/luci-static/resources/view/fchomo/server.js:432 msgid "new_reno" msgstr "new_reno" @@ -3181,21 +3189,21 @@ msgstr "new_reno" msgid "no-resolve" msgstr "no-resolve" -#: htdocs/luci-static/resources/fchomo.js:1301 -#: htdocs/luci-static/resources/fchomo.js:1396 -#: htdocs/luci-static/resources/fchomo.js:1431 -#: htdocs/luci-static/resources/fchomo.js:1443 +#: htdocs/luci-static/resources/fchomo.js:1331 +#: htdocs/luci-static/resources/fchomo.js:1426 +#: htdocs/luci-static/resources/fchomo.js:1461 +#: htdocs/luci-static/resources/fchomo.js:1489 msgid "non-empty value" msgstr "非空值" #: htdocs/luci-static/resources/fchomo.js:287 #: htdocs/luci-static/resources/fchomo.js:301 #: htdocs/luci-static/resources/fchomo.js:313 -#: htdocs/luci-static/resources/view/fchomo/node.js:589 -#: htdocs/luci-static/resources/view/fchomo/node.js:609 -#: htdocs/luci-static/resources/view/fchomo/node.js:682 +#: htdocs/luci-static/resources/view/fchomo/node.js:590 +#: htdocs/luci-static/resources/view/fchomo/node.js:610 +#: htdocs/luci-static/resources/view/fchomo/node.js:683 #: htdocs/luci-static/resources/view/fchomo/ruleset.js:300 -#: htdocs/luci-static/resources/view/fchomo/server.js:497 +#: htdocs/luci-static/resources/view/fchomo/server.js:509 msgid "none" msgstr "無" @@ -3211,20 +3219,20 @@ msgstr "不包含 \",\"" msgid "null" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:683 +#: htdocs/luci-static/resources/view/fchomo/node.js:684 msgid "obfs-simple" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1420 +#: htdocs/luci-static/resources/view/fchomo/node.js:1421 msgid "override.proxy-name" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:610 +#: htdocs/luci-static/resources/view/fchomo/node.js:611 msgid "packet addr (v2ray-core v5+)" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:936 -#: htdocs/luci-static/resources/view/fchomo/server.js:805 +#: htdocs/luci-static/resources/view/fchomo/node.js:937 +#: htdocs/luci-static/resources/view/fchomo/server.js:817 msgid "private key" msgstr "私鑰" @@ -3237,7 +3245,7 @@ msgstr "razord-meta" msgid "requires front-end adaptation using the API." msgstr "需要使用 API 的前端適配。" -#: htdocs/luci-static/resources/view/fchomo/node.js:687 +#: htdocs/luci-static/resources/view/fchomo/node.js:688 msgid "restls" msgstr "" @@ -3245,12 +3253,12 @@ msgstr "" msgid "rule-set" msgstr "規則集" -#: htdocs/luci-static/resources/view/fchomo/node.js:686 -#: htdocs/luci-static/resources/view/fchomo/server.js:498 +#: htdocs/luci-static/resources/view/fchomo/node.js:687 +#: htdocs/luci-static/resources/view/fchomo/server.js:510 msgid "shadow-tls" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:1090 +#: htdocs/luci-static/resources/view/fchomo/node.js:1091 msgid "smux" msgstr "" @@ -3266,70 +3274,75 @@ msgstr "" msgid "unchecked" msgstr "未檢查" -#: htdocs/luci-static/resources/fchomo.js:396 +#: htdocs/luci-static/resources/fchomo.js:398 msgid "unique UCI identifier" msgstr "獨立 UCI 識別" -#: htdocs/luci-static/resources/fchomo.js:399 +#: htdocs/luci-static/resources/fchomo.js:401 msgid "unique identifier" msgstr "獨立標識" -#: htdocs/luci-static/resources/fchomo.js:1452 +#: htdocs/luci-static/resources/fchomo.js:1498 msgid "unique value" msgstr "獨立值" -#: htdocs/luci-static/resources/view/fchomo/node.js:1456 +#: htdocs/luci-static/resources/view/fchomo/node.js:1457 msgid "up" msgstr "Hysteria 上傳速率" -#: htdocs/luci-static/resources/view/fchomo/node.js:440 -#: htdocs/luci-static/resources/view/fchomo/node.js:484 -#: htdocs/luci-static/resources/view/fchomo/node.js:714 -#: htdocs/luci-static/resources/view/fchomo/node.js:746 -#: htdocs/luci-static/resources/view/fchomo/server.js:517 -msgid "v1" -msgstr "" - #: htdocs/luci-static/resources/view/fchomo/node.js:441 +#: htdocs/luci-static/resources/view/fchomo/node.js:485 #: htdocs/luci-static/resources/view/fchomo/node.js:715 #: htdocs/luci-static/resources/view/fchomo/node.js:747 -#: htdocs/luci-static/resources/view/fchomo/server.js:518 -msgid "v2" +#: htdocs/luci-static/resources/view/fchomo/server.js:529 +msgid "v1" msgstr "" #: htdocs/luci-static/resources/view/fchomo/node.js:442 #: htdocs/luci-static/resources/view/fchomo/node.js:716 -#: htdocs/luci-static/resources/view/fchomo/server.js:519 +#: htdocs/luci-static/resources/view/fchomo/node.js:748 +#: htdocs/luci-static/resources/view/fchomo/server.js:530 +msgid "v2" +msgstr "" + +#: htdocs/luci-static/resources/view/fchomo/node.js:443 +#: htdocs/luci-static/resources/view/fchomo/node.js:717 +#: htdocs/luci-static/resources/view/fchomo/server.js:531 msgid "v3" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1348 -#: htdocs/luci-static/resources/fchomo.js:1351 +#: htdocs/luci-static/resources/fchomo.js:1378 +#: htdocs/luci-static/resources/fchomo.js:1381 msgid "valid JSON format" msgstr "有效的 JSON 格式" -#: htdocs/luci-static/resources/view/fchomo/node.js:896 +#: htdocs/luci-static/resources/view/fchomo/node.js:897 msgid "valid SHA256 string with %d characters" msgstr "包含 %d 個字元的有效 SHA256 字串" -#: htdocs/luci-static/resources/fchomo.js:1373 -#: htdocs/luci-static/resources/fchomo.js:1376 +#: htdocs/luci-static/resources/fchomo.js:1403 +#: htdocs/luci-static/resources/fchomo.js:1406 msgid "valid URL" msgstr "有效網址" -#: htdocs/luci-static/resources/fchomo.js:1386 +#: htdocs/luci-static/resources/fchomo.js:1416 msgid "valid base64 key with %d characters" msgstr "包含 %d 個字元的有效 base64 金鑰" -#: htdocs/luci-static/resources/fchomo.js:1433 +#: htdocs/luci-static/resources/fchomo.js:1476 +#: htdocs/luci-static/resources/fchomo.js:1482 +msgid "valid format: 2x, 2p, 4v" +msgstr "" + +#: htdocs/luci-static/resources/fchomo.js:1463 msgid "valid key length with %d characters" msgstr "包含 %d 個字元的有效金鑰" -#: htdocs/luci-static/resources/fchomo.js:1311 +#: htdocs/luci-static/resources/fchomo.js:1341 msgid "valid port value" msgstr "有效連接埠值" -#: htdocs/luci-static/resources/fchomo.js:1361 +#: htdocs/luci-static/resources/fchomo.js:1391 msgid "valid uuid" msgstr "有效 uuid" @@ -3349,7 +3362,7 @@ msgstr "" msgid "yacd-meta" msgstr "yacd-meta" -#: htdocs/luci-static/resources/view/fchomo/node.js:1091 +#: htdocs/luci-static/resources/view/fchomo/node.js:1092 msgid "yamux" msgstr "" @@ -3357,11 +3370,11 @@ msgstr "" msgid "zashboard" msgstr "" -#: htdocs/luci-static/resources/view/fchomo/node.js:590 +#: htdocs/luci-static/resources/view/fchomo/node.js:591 msgid "zero" msgstr "" -#: htdocs/luci-static/resources/fchomo.js:1135 +#: htdocs/luci-static/resources/fchomo.js:1159 msgid "🡇" msgstr "" diff --git a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua index 3862bab83f..eba4bb6672 100644 --- a/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua +++ b/small/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua @@ -250,27 +250,17 @@ if has_xray then end if has_singbox then - local version = api.get_app_version("sing-box"):match("[^v]+") - local version_ge_1_12_0 = api.compare_versions(version, ">=", "1.12.0") - s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings")) s.anonymous = true s.addremove = false - o = s:option(Flag, "sniff_override_destination", translate("Override the connection destination address")) + o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"), + translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first.")) o.default = 0 - o.rmempty = false - o.description = translate("Override the connection destination address with the sniffed domain.
When enabled, traffic will match only by domain, ignoring IP rules.
If using shunt nodes, configure the domain shunt rules correctly.") - if version_ge_1_12_0 then - o = s:option(Flag, "record_fragment", "TLS Record " .. translate("Fragment"), - translate("Split handshake data into multiple TLS records for better censorship evasion. Low overhead. Recommended to enable first.")) - o.default = 0 - - o = s:option(Flag, "fragment", "TLS TCP " .. translate("Fragment"), - translate("Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed.")) - o.default = 0 - end + o = s:option(Flag, "fragment", "TLS TCP " .. translate("Fragment"), + translate("Split handshake into multiple TCP segments. Enhances obfuscation. May increase delay. Use only if needed.")) + o.default = 0 end return m diff --git a/small/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/small/luci-app-passwall/luasrc/passwall/util_sing-box.lua index b60dc9922a..22d8dcda05 100644 --- a/small/luci-app-passwall/luasrc/passwall/util_sing-box.lua +++ b/small/luci-app-passwall/luasrc/passwall/util_sing-box.lua @@ -1006,8 +1006,7 @@ function gen_config(var) tag = "redirect_tcp", listen = "::", listen_port = tonumber(tcp_redir_port), - sniff = true, - sniff_override_destination = (singbox_settings.sniff_override_destination == "1") and true or false, + sniff = true } table.insert(inbounds, inbound) else @@ -1017,8 +1016,7 @@ function gen_config(var) network = "tcp", listen = "::", listen_port = tonumber(tcp_redir_port), - sniff = true, - sniff_override_destination = (singbox_settings.sniff_override_destination == "1") and true or false, + sniff = true } table.insert(inbounds, inbound) end @@ -1031,8 +1029,7 @@ function gen_config(var) network = "udp", listen = "::", listen_port = tonumber(udp_redir_port), - sniff = true, - sniff_override_destination = (singbox_settings.sniff_override_destination == "1") and true or false, + sniff = true } table.insert(inbounds, inbound) end @@ -1970,7 +1967,6 @@ function gen_config(var) action = "sniff" }) value.sniff = nil - value.sniff_override_destination = nil end if value.domain_strategy then table.insert(config.route.rules, 1, { diff --git a/small/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/small/luci-app-ssr-plus/root/etc/init.d/shadowsocksr index 4a1e2b8630..d905c97ca9 100755 --- a/small/luci-app-ssr-plus/root/etc/init.d/shadowsocksr +++ b/small/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -1405,6 +1405,45 @@ start_monitor() { fi } +start_xhttp_addr() { + local xhttp_addr_file="/etc/ssrplus/xhttp_address.txt" + local tmp_file="/tmp/.xhttp_addr.tmp" + + # 收集所有 xhttp_extra 地址,去掉空行并去重排序 + { + for sec in "$GLOBAL_SERVER" "$SHUNT_SERVER" "$UDP_RELAY_SERVER"; do + local extra + extra=$(uci_get_by_name "$sec" xhttp_extra) + [ -n "$extra" ] && \ + echo "$extra" | sed -n 's/.*"address":[[:space:]]*"\([^"]*\)".*/\1/p' + done + } | grep -v '^$' | sort -u > "$tmp_file" + + # 如果没有 xhttp_extra 地址,删除旧文件并退出 + if [ ! -s "$tmp_file" ]; then + [ -f "$xhttp_addr_file" ] && rm -f "$xhttp_addr_file" + rm -f "$tmp_file" + return 0 + fi + + # 比较 MD5 判断 xhttp_extra 地址是否有变化 + local md5_new md5_old + md5_new=$(md5sum "$tmp_file" | awk '{print $1}') + if [ -f "$xhttp_addr_file" ]; then + md5_old=$(md5sum "$xhttp_addr_file" | awk '{print $1}') + else + md5_old="" + fi + + # MD5 不同更新 xhttp_extra 地址文件 + if [ "$md5_new" != "$md5_old" ]; then + mv -f "$tmp_file" "$xhttp_addr_file" + logger -t ssrplus-xhttp "xhttp_address.txt updated" + else + rm -f "$tmp_file" + fi +} + start_rules() { local server=$(get_host_ip $GLOBAL_SERVER) local local_port=$(uci_get_by_name $GLOBAL_SERVER local_port) @@ -1483,6 +1522,7 @@ start() { echo "conf-dir=${TMP_DNSMASQ_PATH}" >"$DNSMASQ_CONF_DIR/dnsmasq-ssrplus.conf" if load_config; then Start_Run + start_xhttp_addr start_rules start_dns add_cron @@ -1604,6 +1644,7 @@ reset() { stop set_lock rm -rf /etc/config/shadowsocksr $LOG_FILE + [ -f "/etc/ssrplus/xhttp_address.txt" ] && rm -f /etc/ssrplus/xhttp_address.txt touch /etc/config/shadowsocksr $LOG_FILE cp /usr/share/shadowsocksr/shadowsocksr.config /etc/config/shadowsocksr unset_lock diff --git a/small/luci-app-ssr-plus/root/usr/bin/ssr-rules b/small/luci-app-ssr-plus/root/usr/bin/ssr-rules index e67d6143e1..a60f5644bc 100755 --- a/small/luci-app-ssr-plus/root/usr/bin/ssr-rules +++ b/small/luci-app-ssr-plus/root/usr/bin/ssr-rules @@ -190,6 +190,16 @@ cleanup_persistence_files() { loger 5 "Removed run mode file: /tmp/.last_lan_gm_ip" fi + # Remove xhttp file state and hash files + if [ -f "/tmp/.last_xhttp_file" ]; then + rm -f "/tmp/.last_xhttp_file" 2>/dev/null + loger 5 "Removed xhttp file state: /tmp/.last_xhttp_file" + fi + if [ -f "/tmp/.last_xhttp_hash" ]; then + rm -f "/tmp/.last_xhttp_hash" 2>/dev/null + loger 5 "Removed xhttp hash file: /tmp/.last_xhttp_hash" + fi + loger 5 "Persistence cleanup completed" return 0 } @@ -323,6 +333,11 @@ ipset_nft() { $NFT add element inet ss_spec china "{ $(tr '\n' ',' < "${china_ip}" | sed 's/,$//') }" 2>/dev/null fi + # Bulk import xhttp ip list into nft whitelist (server + shunt) + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + $NFT add element inet ss_spec whitelist "{ $(tr '\n' ',' < "${xhttp_ip}" | sed 's/,$//') }" 2>/dev/null + fi + # Add IP addresses to sets for ip in $LAN_GM_IP; do [ -n "$ip" ] && $NFT add element inet ss_spec gmlan "{ $ip }" 2>/dev/null @@ -493,6 +508,11 @@ ipset_iptables() { for ip in $LAN_BP_IP; do ipset -! add bplan "$ip"; done $IPT -I SS_SPEC_WAN_AC -m set --match-set bplan src -j RETURN ipset -N whitelist hash:net 2>/dev/null + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + while IFS= read -r ip; do + [ -n "$ip" ] && ipset add whitelist "$ip" -exist + done < "$xhttp_ip" + fi ipset -N blacklist hash:net 2>/dev/null $IPT -I SS_SPEC_WAN_AC -m set --match-set blacklist dst -j SS_SPEC_WAN_FW $IPT -I SS_SPEC_WAN_AC -m set --match-set whitelist dst -j RETURN @@ -919,6 +939,11 @@ tp_rule_nft() { $NFT add element ip ss_spec_mangle china "{ $(tr '\n' ',' < "${china_ip}" | sed 's/,$//') }" 2>/dev/null fi + # Bulk import xhttp ip list into nft whitelist (server + shunt) + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + $NFT add element ip ss_spec_mangle whitelist "{ $(tr '\n' ',' < "${xhttp_ip}" | sed 's/,$//') }" 2>/dev/null + fi + # use priority mangle for compatibility with other rules if ! $NFT list chain ip ss_spec_mangle ss_spec_tproxy >/dev/null 2>&1; then $NFT add chain ip ss_spec_mangle ss_spec_tproxy 2>/dev/null @@ -1047,6 +1072,11 @@ tp_rule_iptables() { $ipt -A SS_SPEC_TPROXY -p udp -d 240.0.0.0/4 -j RETURN $ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d "$SERVER" -j RETURN [ "$server" != "$SERVER" ] && ipset -! add whitelist "$SERVER" + if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then + while IFS= read -r ip; do + [ -n "$ip" ] && ipset add whitelist "$ip" -exist + done < "$xhttp_ip" + fi $ipt -A SS_SPEC_TPROXY -p udp -m set --match-set bplan src -j RETURN $ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set fplan src -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark 0x01/0x01 case "$RUNMODE" in @@ -1207,7 +1237,7 @@ compare_rules() { # Generate temporary file for current rules local temp_file=$(mktemp) local rules_file=$(mktemp) - loger 7 "DEBUG: Temporary file path: $current_rules_file" + loger 7 "DEBUG: Temporary file path: $rules_file" # Export current rules to temporary file $NFT list ruleset | awk ' @@ -1723,6 +1753,31 @@ if [ -n "$server" ] && [ -n "$local_port" ]; then LAST_LAN_GM_IP="" fi + # Check for changes in the existence and content of the server XHTTP address file + XHTTP_FILE_STATE_FILE="/tmp/.last_xhttp_file" + XHTTP_FILE_HASH_FILE="/tmp/.last_xhttp_hash" + + # Get the current server XHTTP file status + XHTTP_FILE_EXISTS=0 + XHTTP_FILE_HASH="" + if [ -f "/etc/ssrplus/xhttp_address.txt" ]; then + XHTTP_FILE_EXISTS=1 + XHTTP_FILE_HASH=$(md5sum /etc/ssrplus/xhttp_address.txt 2>/dev/null | awk '{print $1}') + fi + + # Read the previous server XHTTP file status and hash + if [ -f "$XHTTP_FILE_STATE_FILE" ]; then + LAST_XHTTP_FILE_EXISTS=$(cat "$XHTTP_FILE_STATE_FILE") + else + LAST_XHTTP_FILE_EXISTS="" + fi + + if [ -f "$XHTTP_FILE_HASH_FILE" ]; then + LAST_XHTTP_FILE_HASH=$(cat "$XHTTP_FILE_HASH_FILE") + else + LAST_XHTTP_FILE_HASH="" + fi + # STEP 1: Check if TPROXY has value (1 or 2) if [ "$TPROXY" = "1" ] || [ "$TPROXY" = "2" ]; then TPROXY_HAS_VALUE=1 @@ -1788,6 +1843,28 @@ if [ -n "$server" ] && [ -n "$local_port" ]; then ANY_IP_LIST_CHANGED=1 fi + # Check for changes in the existence of the server XHTTP address file. + if [ "$XHTTP_FILE_EXISTS" != "$LAST_XHTTP_FILE_EXISTS" ]; then + loger 6 "xhttp address file existence changed: '$LAST_XHTTP_FILE_EXISTS' -> '$XHTTP_FILE_EXISTS'" + ANY_IP_LIST_CHANGED=1 + fi + + # Check for XHTTP file content changes (compare hashes only when the file exists in both checks) + if [ "$XHTTP_FILE_EXISTS" = "1" ] && [ "$LAST_XHTTP_FILE_EXISTS" = "1" ]; then + if [ "$XHTTP_FILE_HASH" != "$LAST_XHTTP_FILE_HASH" ]; then + loger 6 "xhttp address file content changed (hash: '$LAST_XHTTP_FILE_HASH' -> '$XHTTP_FILE_HASH')" + ANY_IP_LIST_CHANGED=1 + else + loger 6 "xhttp address file content unchanged" + fi + elif [ "$XHTTP_FILE_EXISTS" = "0" ] && [ "$LAST_XHTTP_FILE_EXISTS" = "1" ]; then + loger 6 "xhttp address file deleted" + ANY_IP_LIST_CHANGED=1 + elif [ "$XHTTP_FILE_EXISTS" = "1" ] && [ "$LAST_XHTTP_FILE_EXISTS" = "0" ]; then + loger 6 "xhttp address file created" + ANY_IP_LIST_CHANGED=1 + fi + # STEP 3: Determine if forced rebuild is needed FORCE_RECREATE=0 PERSISTENCE_EXISTS=0 @@ -1822,6 +1899,8 @@ if [ -n "$server" ] && [ -n "$local_port" ]; then echo "$(normalize_ip_list "$WAN_FW_IP")" > "$WAN_FW_IP_STATE_FILE" echo "$(normalize_ip_list "$LAN_FP_IP")" > "$LAN_FP_IP_STATE_FILE" echo "$(normalize_ip_list "$LAN_GM_IP")" > "$LAN_GM_IP_STATE_FILE" + echo "$XHTTP_FILE_EXISTS" > "$XHTTP_FILE_STATE_FILE" + echo "$XHTTP_FILE_HASH" > "$XHTTP_FILE_HASH_FILE" # STEP 5: Check if run mode changed if runmode_change "$RUNMODE"; then diff --git a/small/v2ray-geodata/Makefile b/small/v2ray-geodata/Makefile index 637e10a4fa..f3dfcdab97 100644 --- a/small/v2ray-geodata/Makefile +++ b/small/v2ray-geodata/Makefile @@ -21,13 +21,13 @@ define Download/geoip HASH:=6878dbacfb1fcb1ee022f63ed6934bcefc95a3c4ba10c88f1131fb88dbf7c337 endef -GEOSITE_VER:=20251219085711 +GEOSITE_VER:=20251219140209 GEOSITE_FILE:=dlc.dat.$(GEOSITE_VER) define Download/geosite URL:=https://github.com/v2fly/domain-list-community/releases/download/$(GEOSITE_VER)/ URL_FILE:=dlc.dat FILE:=$(GEOSITE_FILE) - HASH:=400183fe3f4e74fd970536507b0245df364ba8fd1b1f128106992862ab259e9d + HASH:=3449c57f7cd1f3f19f53840de554f14cfbe8787ec9e1a0ef9e2e910cefb3fcf2 endef GEOSITE_IRAN_VER:=202512150045 diff --git a/v2rayn/v2rayN/Directory.Build.props b/v2rayn/v2rayN/Directory.Build.props index eec3a432a4..3a12e1e420 100644 --- a/v2rayn/v2rayN/Directory.Build.props +++ b/v2rayn/v2rayN/Directory.Build.props @@ -1,7 +1,7 @@ - 7.16.6 + 7.16.7 diff --git a/v2rayn/v2rayN/Directory.Packages.props b/v2rayn/v2rayN/Directory.Packages.props index 070b5c4d04..263b401a19 100644 --- a/v2rayn/v2rayN/Directory.Packages.props +++ b/v2rayn/v2rayN/Directory.Packages.props @@ -6,9 +6,9 @@ - - - + + + diff --git a/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs b/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs index 88272bf12b..d368108ccc 100644 --- a/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs +++ b/v2rayn/v2rayN/ServiceLib/Services/UpdateService.cs @@ -291,13 +291,6 @@ public class UpdateService(Config config, Func updateFunc) return url; } - //Check for standalone windows .Net version - if (File.Exists(Path.Combine(Utils.GetBaseDirectory(), "wpfgfx_cor3.dll")) - && File.Exists(Path.Combine(Utils.GetBaseDirectory(), "D3DCompiler_47_cor3.dll"))) - { - return url?.Replace(".zip", "-SelfContained.zip"); - } - //Check for avalonia desktop windows version if (File.Exists(Path.Combine(Utils.GetBaseDirectory(), "libHarfBuzzSharp.dll"))) { diff --git a/yt-dlp/.github/workflows/build.yml b/yt-dlp/.github/workflows/build.yml index 9b58653bd7..b5033341ad 100644 --- a/yt-dlp/.github/workflows/build.yml +++ b/yt-dlp/.github/workflows/build.yml @@ -74,8 +74,7 @@ on: default: true type: boolean -permissions: - contents: read +permissions: {} jobs: process: @@ -186,8 +185,10 @@ jobs: f.write(f'matrix={json.dumps(matrix)}') unix: - needs: process + needs: [process] if: inputs.unix + permissions: + contents: read runs-on: ubuntu-latest env: CHANNEL: ${{ inputs.channel }} @@ -199,6 +200,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 # Needed for changelog + persist-credentials: false - uses: actions/setup-python@v6 with: @@ -229,7 +231,7 @@ jobs: [[ "${version}" != "${downgraded_version}" ]] - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: build-bin-${{ github.job }} path: | @@ -239,8 +241,10 @@ jobs: linux: name: ${{ matrix.os }} (${{ matrix.arch }}) + needs: [process] if: inputs.linux || inputs.linux_armv7l || inputs.musllinux - needs: process + permissions: + contents: read runs-on: ${{ matrix.runner }} strategy: fail-fast: false @@ -258,11 +262,13 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Cache requirements if: matrix.cache_requirements id: cache-venv - uses: actions/cache@v4 + uses: actions/cache@v5 env: SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1 with: @@ -300,7 +306,7 @@ jobs: docker compose up --build --exit-code-from "${SERVICE}" "${SERVICE}" - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: build-bin-${{ matrix.os }}_${{ matrix.arch }} path: | @@ -308,7 +314,7 @@ jobs: compression-level: 0 macos: - needs: process + needs: [process] if: inputs.macos permissions: contents: read @@ -321,11 +327,14 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + # NB: Building universal2 does not work with python from actions/setup-python - name: Cache requirements id: cache-venv - uses: actions/cache@v4 + uses: actions/cache@v5 env: SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1 with: @@ -399,7 +408,7 @@ jobs: [[ "$version" != "$downgraded_version" ]] - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: build-bin-${{ github.job }} path: | @@ -409,7 +418,7 @@ jobs: windows: name: windows (${{ matrix.arch }}) - needs: process + needs: [process] if: inputs.windows permissions: contents: read @@ -451,6 +460,9 @@ jobs: steps: - uses: actions/checkout@v6 + with: + persist-credentials: false + - uses: actions/setup-python@v6 with: python-version: ${{ matrix.python_version }} @@ -459,7 +471,7 @@ jobs: - name: Cache requirements id: cache-venv if: matrix.arch == 'arm64' - uses: actions/cache@v4 + uses: actions/cache@v5 env: SEGMENT_DOWNLOAD_TIMEOUT_MINS: 1 with: @@ -519,7 +531,7 @@ jobs: } - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: build-bin-${{ github.job }}-${{ matrix.arch }} path: | @@ -528,17 +540,17 @@ jobs: compression-level: 0 meta_files: - if: always() && !cancelled() needs: - process - unix - linux - macos - windows + if: always() && !failure() && !cancelled() runs-on: ubuntu-latest steps: - name: Download artifacts - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: path: artifact pattern: build-bin-* @@ -600,13 +612,13 @@ jobs: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} if: env.GPG_SIGNING_KEY run: | - gpg --batch --import <<< "${{ secrets.GPG_SIGNING_KEY }}" + gpg --batch --import <<< "${GPG_SIGNING_KEY}" for signfile in ./SHA*SUMS; do gpg --batch --detach-sign "$signfile" done - name: Upload artifacts - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: build-${{ github.job }} path: | diff --git a/yt-dlp/.github/workflows/cache-warmer.yml b/yt-dlp/.github/workflows/cache-warmer.yml index 00ec1e1f96..4a5589c7a2 100644 --- a/yt-dlp/.github/workflows/cache-warmer.yml +++ b/yt-dlp/.github/workflows/cache-warmer.yml @@ -4,10 +4,14 @@ on: schedule: - cron: '0 22 1,6,11,16,21,27 * *' +permissions: {} + jobs: build: if: | vars.KEEP_CACHE_WARM || github.event_name == 'workflow_dispatch' + permissions: + contents: read uses: ./.github/workflows/build.yml with: version: '999999' @@ -19,5 +23,3 @@ jobs: musllinux: false macos: true windows: true - permissions: - contents: read diff --git a/yt-dlp/.github/workflows/challenge-tests.yml b/yt-dlp/.github/workflows/challenge-tests.yml index 68fe117191..fa684e6644 100644 --- a/yt-dlp/.github/workflows/challenge-tests.yml +++ b/yt-dlp/.github/workflows/challenge-tests.yml @@ -16,8 +16,8 @@ on: - yt_dlp/extractor/youtube/jsc/**.py - yt_dlp/extractor/youtube/pot/**.py - yt_dlp/utils/_jsruntime.py -permissions: - contents: read + +permissions: {} concurrency: group: challenge-tests-${{ github.event.pull_request.number || github.ref }} @@ -26,6 +26,8 @@ concurrency: jobs: tests: name: Challenge Tests + permissions: + contents: read runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -36,6 +38,8 @@ jobs: QJS_VERSION: '2025-04-26' # Earliest version with rope strings steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: diff --git a/yt-dlp/.github/workflows/codeql.yml b/yt-dlp/.github/workflows/codeql.yml index fda5351c08..5d0d06e095 100644 --- a/yt-dlp/.github/workflows/codeql.yml +++ b/yt-dlp/.github/workflows/codeql.yml @@ -9,6 +9,8 @@ on: schedule: - cron: '59 11 * * 5' +permissions: {} + jobs: analyze: name: Analyze (${{ matrix.language }}) @@ -26,6 +28,8 @@ jobs: steps: - name: Checkout repository uses: actions/checkout@v6 + with: + persist-credentials: false - name: Initialize CodeQL uses: github/codeql-action/init@v4 diff --git a/yt-dlp/.github/workflows/core.yml b/yt-dlp/.github/workflows/core.yml index 16c2b92b40..3ac9495cea 100644 --- a/yt-dlp/.github/workflows/core.yml +++ b/yt-dlp/.github/workflows/core.yml @@ -22,8 +22,8 @@ on: - yt_dlp/extractor/__init__.py - yt_dlp/extractor/common.py - yt_dlp/extractor/extractors.py -permissions: - contents: read + +permissions: {} concurrency: group: core-${{ github.event.pull_request.number || github.ref }} @@ -33,6 +33,8 @@ jobs: tests: name: Core Tests if: "!contains(github.event.head_commit.message, 'ci skip')" + permissions: + contents: read runs-on: ${{ matrix.os }} strategy: fail-fast: false @@ -58,6 +60,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: diff --git a/yt-dlp/.github/workflows/download.yml b/yt-dlp/.github/workflows/download.yml index 62a2cf9ba0..e9c4d75a71 100644 --- a/yt-dlp/.github/workflows/download.yml +++ b/yt-dlp/.github/workflows/download.yml @@ -1,15 +1,19 @@ name: Download Tests on: [push, pull_request] -permissions: - contents: read + +permissions: {} jobs: quick: name: Quick Download Tests if: "contains(github.event.head_commit.message, 'ci run dl')" + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python uses: actions/setup-python@v6 with: @@ -23,6 +27,8 @@ jobs: full: name: Full Download Tests if: "contains(github.event.head_commit.message, 'ci run dl all')" + permissions: + contents: read runs-on: ${{ matrix.os }} strategy: fail-fast: true @@ -37,6 +43,8 @@ jobs: python-version: pypy-3.11 steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v6 with: diff --git a/yt-dlp/.github/workflows/issue-lockdown.yml b/yt-dlp/.github/workflows/issue-lockdown.yml index 4b973e2e61..100b9f93f2 100644 --- a/yt-dlp/.github/workflows/issue-lockdown.yml +++ b/yt-dlp/.github/workflows/issue-lockdown.yml @@ -3,13 +3,14 @@ on: issues: types: [opened] -permissions: - issues: write +permissions: {} jobs: lockdown: name: Issue Lockdown if: vars.ISSUE_LOCKDOWN + permissions: + issues: write runs-on: ubuntu-latest steps: - name: "Lock new issue" diff --git a/yt-dlp/.github/workflows/quick-test.yml b/yt-dlp/.github/workflows/quick-test.yml index f72f6a5651..410bf3520f 100644 --- a/yt-dlp/.github/workflows/quick-test.yml +++ b/yt-dlp/.github/workflows/quick-test.yml @@ -1,15 +1,19 @@ name: Quick Test on: [push, pull_request] -permissions: - contents: read + +permissions: {} jobs: tests: name: Core Test if: "!contains(github.event.head_commit.message, 'ci skip all')" + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - name: Set up Python 3.10 uses: actions/setup-python@v6 with: @@ -24,9 +28,13 @@ jobs: check: name: Code check if: "!contains(github.event.head_commit.message, 'ci skip all')" + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/setup-python@v6 with: python-version: '3.10' diff --git a/yt-dlp/.github/workflows/release-master.yml b/yt-dlp/.github/workflows/release-master.yml index f44da792f8..0e7478e452 100644 --- a/yt-dlp/.github/workflows/release-master.yml +++ b/yt-dlp/.github/workflows/release-master.yml @@ -14,31 +14,31 @@ on: - ".github/workflows/release-master.yml" concurrency: group: release-master -permissions: - contents: read + +permissions: {} jobs: release: if: vars.BUILD_MASTER + permissions: + contents: write + id-token: write # mandatory for trusted publishing uses: ./.github/workflows/release.yml with: prerelease: true source: ${{ (github.repository != 'yt-dlp/yt-dlp' && vars.MASTER_ARCHIVE_REPO) || 'master' }} target: 'master' - permissions: - contents: write - id-token: write # mandatory for trusted publishing secrets: inherit publish_pypi: needs: [release] if: vars.MASTER_PYPI_PROJECT - runs-on: ubuntu-latest permissions: id-token: write # mandatory for trusted publishing + runs-on: ubuntu-latest steps: - name: Download artifacts - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: path: dist name: build-pypi diff --git a/yt-dlp/.github/workflows/release-nightly.yml b/yt-dlp/.github/workflows/release-nightly.yml index ac7e8cc675..e0b7a3729c 100644 --- a/yt-dlp/.github/workflows/release-nightly.yml +++ b/yt-dlp/.github/workflows/release-nightly.yml @@ -2,12 +2,14 @@ name: Release (nightly) on: schedule: - cron: '23 23 * * *' -permissions: - contents: read + +permissions: {} jobs: check_nightly: if: vars.BUILD_NIGHTLY + permissions: + contents: read runs-on: ubuntu-latest outputs: commit: ${{ steps.check_for_new_commits.outputs.commit }} @@ -15,6 +17,7 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 + persist-credentials: false - name: Check for new commits id: check_for_new_commits run: | @@ -35,25 +38,25 @@ jobs: release: needs: [check_nightly] if: ${{ needs.check_nightly.outputs.commit }} + permissions: + contents: write + id-token: write # mandatory for trusted publishing uses: ./.github/workflows/release.yml with: prerelease: true source: ${{ (github.repository != 'yt-dlp/yt-dlp' && vars.NIGHTLY_ARCHIVE_REPO) || 'nightly' }} target: 'nightly' - permissions: - contents: write - id-token: write # mandatory for trusted publishing secrets: inherit publish_pypi: needs: [release] if: vars.NIGHTLY_PYPI_PROJECT - runs-on: ubuntu-latest permissions: id-token: write # mandatory for trusted publishing + runs-on: ubuntu-latest steps: - name: Download artifacts - uses: actions/download-artifact@v5 + uses: actions/download-artifact@v7 with: path: dist name: build-pypi diff --git a/yt-dlp/.github/workflows/release.yml b/yt-dlp/.github/workflows/release.yml index e9facc0430..e06bd09f0d 100644 --- a/yt-dlp/.github/workflows/release.yml +++ b/yt-dlp/.github/workflows/release.yml @@ -56,8 +56,7 @@ on: default: false type: boolean -permissions: - contents: read +permissions: {} jobs: prepare: @@ -150,29 +149,31 @@ jobs: run: git push origin "${GITHUB_EVENT_REF}" build: - needs: prepare + needs: [prepare] + permissions: + contents: read uses: ./.github/workflows/build.yml with: version: ${{ needs.prepare.outputs.version }} channel: ${{ needs.prepare.outputs.channel }} origin: ${{ needs.prepare.outputs.target_repo }} linux_armv7l: ${{ inputs.linux_armv7l }} - permissions: - contents: read secrets: GPG_SIGNING_KEY: ${{ secrets.GPG_SIGNING_KEY }} publish_pypi: needs: [prepare, build] if: ${{ needs.prepare.outputs.pypi_project }} - runs-on: ubuntu-latest permissions: + contents: read id-token: write # mandatory for trusted publishing + runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 with: - fetch-depth: 0 + fetch-depth: 0 # Needed for changelog + persist-credentials: false - uses: actions/setup-python@v6 with: python-version: "3.10" @@ -209,7 +210,7 @@ jobs: - name: Upload artifacts if: github.event_name != 'workflow_dispatch' - uses: actions/upload-artifact@v4 + uses: actions/upload-artifact@v6 with: name: build-pypi path: | @@ -236,7 +237,8 @@ jobs: - uses: actions/checkout@v6 with: fetch-depth: 0 - - uses: actions/download-artifact@v5 + persist-credentials: false + - uses: actions/download-artifact@v7 with: path: artifact pattern: build-* diff --git a/yt-dlp/.github/workflows/sanitize-comment.yml b/yt-dlp/.github/workflows/sanitize-comment.yml index 45c87cdd47..a14c5a8eb0 100644 --- a/yt-dlp/.github/workflows/sanitize-comment.yml +++ b/yt-dlp/.github/workflows/sanitize-comment.yml @@ -4,13 +4,14 @@ on: issue_comment: types: [created, edited] -permissions: - issues: write +permissions: {} jobs: sanitize-comment: name: Sanitize comment if: vars.SANITIZE_COMMENT && !github.event.issue.pull_request + permissions: + issues: write runs-on: ubuntu-latest steps: - name: Sanitize comment diff --git a/yt-dlp/.github/workflows/test-workflows.yml b/yt-dlp/.github/workflows/test-workflows.yml index e1a125461a..f82ce5b91a 100644 --- a/yt-dlp/.github/workflows/test-workflows.yml +++ b/yt-dlp/.github/workflows/test-workflows.yml @@ -14,8 +14,9 @@ on: - devscripts/setup_variables.py - devscripts/setup_variables_tests.py - devscripts/utils.py -permissions: - contents: read + +permissions: {} + env: ACTIONLINT_VERSION: "1.7.9" ACTIONLINT_SHA256SUM: 233b280d05e100837f4af1433c7b40a5dcb306e3aa68fb4f17f8a7f45a7df7b4 @@ -24,9 +25,13 @@ env: jobs: check: name: Check workflows + permissions: + contents: read runs-on: ubuntu-latest steps: - uses: actions/checkout@v6 + with: + persist-credentials: false - uses: actions/setup-python@v6 with: python-version: "3.10" # Keep this in sync with release.yml's prepare job diff --git a/yt-dlp/yt_dlp/YoutubeDL.py b/yt-dlp/yt_dlp/YoutubeDL.py index 539b10fe29..b9bc9c9caa 100644 --- a/yt-dlp/yt_dlp/YoutubeDL.py +++ b/yt-dlp/yt_dlp/YoutubeDL.py @@ -3026,6 +3026,10 @@ class YoutubeDL: format_selector = self.format_selector while True: if interactive_format_selection: + if not formats: + # Bypass interactive format selection if no formats & --ignore-no-formats-error + formats_to_download = None + break req_format = input(self._format_screen('\nEnter format selector ', self.Styles.EMPHASIS) + '(Press ENTER for default, or Ctrl+C to quit)' + self._format_screen(': ', self.Styles.EMPHASIS)) diff --git a/yt-dlp/yt_dlp/extractor/_extractors.py b/yt-dlp/yt_dlp/extractor/_extractors.py index 62d431e640..2cf475602d 100644 --- a/yt-dlp/yt_dlp/extractor/_extractors.py +++ b/yt-dlp/yt_dlp/extractor/_extractors.py @@ -1279,6 +1279,7 @@ from .nebula import ( NebulaChannelIE, NebulaClassIE, NebulaIE, + NebulaSeasonIE, NebulaSubscriptionsIE, ) from .nekohacker import NekoHackerIE diff --git a/yt-dlp/yt_dlp/extractor/bandcamp.py b/yt-dlp/yt_dlp/extractor/bandcamp.py index 0a8f88fa8c..510fc5f91d 100644 --- a/yt-dlp/yt_dlp/extractor/bandcamp.py +++ b/yt-dlp/yt_dlp/extractor/bandcamp.py @@ -5,16 +5,18 @@ import time from .common import InfoExtractor from ..utils import ( - KNOWN_EXTENSIONS, ExtractorError, clean_html, extract_attributes, float_or_none, + format_field, int_or_none, + join_nonempty, parse_filesize, + parse_qs, str_or_none, + strftime_or_none, try_get, - unified_strdate, unified_timestamp, update_url_query, url_or_none, @@ -411,70 +413,67 @@ class BandcampAlbumIE(BandcampIE): # XXX: Do not subclass from concrete IE class BandcampWeeklyIE(BandcampIE): # XXX: Do not subclass from concrete IE IE_NAME = 'Bandcamp:weekly' - _VALID_URL = r'https?://(?:www\.)?bandcamp\.com/?\?(?:.*?&)?show=(?P\d+)' + _VALID_URL = r'https?://(?:www\.)?bandcamp\.com/radio/?\?(?:[^#]+&)?show=(?P\d+)' _TESTS = [{ - 'url': 'https://bandcamp.com/?show=224', + 'url': 'https://bandcamp.com/radio?show=224', 'md5': '61acc9a002bed93986b91168aa3ab433', 'info_dict': { 'id': '224', 'ext': 'mp3', - 'title': 'BC Weekly April 4th 2017 - Magic Moments', + 'title': 'Bandcamp Weekly, 2017-04-04', 'description': 'md5:5d48150916e8e02d030623a48512c874', - 'duration': 5829.77, - 'release_date': '20170404', + 'thumbnail': 'https://f4.bcbits.com/img/9982549_0.jpg', 'series': 'Bandcamp Weekly', - 'episode': 'Magic Moments', 'episode_id': '224', + 'release_timestamp': 1491264000, + 'release_date': '20170404', + 'duration': 5829.77, }, 'params': { 'format': 'mp3-128', }, }, { - 'url': 'https://bandcamp.com/?blah/blah@&show=228', + 'url': 'https://bandcamp.com/radio/?foo=bar&show=224', 'only_matching': True, }] def _real_extract(self, url): show_id = self._match_id(url) - webpage = self._download_webpage(url, show_id) + audio_data = self._download_json( + 'https://bandcamp.com/api/bcradio_api/1/get_show', + show_id, 'Downloading radio show JSON', + data=json.dumps({'id': show_id}).encode(), + headers={'Content-Type': 'application/json'})['radioShowAudio'] - blob = self._extract_data_attr(webpage, show_id, 'blob') + stream_url = audio_data['streamUrl'] + format_id = traverse_obj(stream_url, ({parse_qs}, 'enc', -1)) + encoding, _, bitrate_str = (format_id or '').partition('-') - show = blob['bcw_data'][show_id] + webpage = self._download_webpage(url, show_id, fatal=False) + metadata = traverse_obj( + self._extract_data_attr(webpage, show_id, 'blob', fatal=False), + ('appData', 'shows', lambda _, v: str(v['showId']) == show_id, any)) or {} - formats = [] - for format_id, format_url in show['audio_stream'].items(): - if not url_or_none(format_url): - continue - for known_ext in KNOWN_EXTENSIONS: - if known_ext in format_id: - ext = known_ext - break - else: - ext = None - formats.append({ - 'format_id': format_id, - 'url': format_url, - 'ext': ext, - 'vcodec': 'none', - }) - - title = show.get('audio_title') or 'Bandcamp Weekly' - subtitle = show.get('subtitle') - if subtitle: - title += f' - {subtitle}' + series_title = audio_data.get('title') or metadata.get('title') + release_timestamp = unified_timestamp(audio_data.get('date')) or unified_timestamp(metadata.get('date')) return { 'id': show_id, - 'title': title, - 'description': show.get('desc') or show.get('short_desc'), - 'duration': float_or_none(show.get('audio_duration')), - 'is_live': False, - 'release_date': unified_strdate(show.get('published_date')), - 'series': 'Bandcamp Weekly', - 'episode': show.get('subtitle'), 'episode_id': show_id, - 'formats': formats, + 'title': join_nonempty(series_title, strftime_or_none(release_timestamp, '%Y-%m-%d'), delim=', '), + 'series': series_title, + 'thumbnail': format_field(metadata, 'imageId', 'https://f4.bcbits.com/img/%s_0.jpg', default=None), + 'description': metadata.get('desc') or metadata.get('short_desc'), + 'duration': float_or_none(audio_data.get('duration')), + 'release_timestamp': release_timestamp, + 'formats': [{ + 'url': stream_url, + 'format_id': format_id, + 'ext': encoding or 'mp3', + 'acodec': encoding or None, + 'vcodec': 'none', + 'abr': int_or_none(bitrate_str), + }], } diff --git a/yt-dlp/yt_dlp/extractor/nebula.py b/yt-dlp/yt_dlp/extractor/nebula.py index 6ced19d6a2..93d01092d6 100644 --- a/yt-dlp/yt_dlp/extractor/nebula.py +++ b/yt-dlp/yt_dlp/extractor/nebula.py @@ -478,3 +478,56 @@ class NebulaChannelIE(NebulaBaseIE): playlist_id=collection_slug, playlist_title=channel.get('title'), playlist_description=channel.get('description')) + + +class NebulaSeasonIE(NebulaBaseIE): + IE_NAME = 'nebula:season' + _VALID_URL = rf'{_BASE_URL_RE}/(?P[\w-]+)/season/(?P\d+)' + _TESTS = [{ + 'url': 'https://nebula.tv/jetlag/season/15', + 'info_dict': { + 'id': 'jetlag_15', + 'title': 'Tag: All Stars', + 'description': 'md5:5aa5b8abf3de71756448dc44ffebb674', + }, + 'playlist_count': 8, + }, { + 'url': 'https://nebula.tv/jetlag/season/14', + 'info_dict': { + 'id': 'jetlag_14', + 'title': 'Snake', + 'description': 'md5:6da9040f1c2ac559579738bfb6919d1e', + }, + 'playlist_count': 8, + }] + + def _build_url_result(self, item): + url = ( + traverse_obj(item, ('share_url', {url_or_none})) + or urljoin('https://nebula.tv/', item.get('app_path')) + or f'https://nebula.tv/videos/{item["slug"]}') + return self.url_result( + smuggle_url(url, {'id': item['id']}), + NebulaIE, url_transparent=True, + **self._extract_video_metadata(item)) + + def _entries(self, data): + for episode in traverse_obj(data, ('episodes', lambda _, v: v['video']['id'], 'video')): + yield self._build_url_result(episode) + for extra in traverse_obj(data, ('extras', ..., 'items', lambda _, v: v['id'])): + yield self._build_url_result(extra) + for trailer in traverse_obj(data, ('trailers', lambda _, v: v['id'])): + yield self._build_url_result(trailer) + + def _real_extract(self, url): + series, season_id = self._match_valid_url(url).group('series', 'season_number') + playlist_id = f'{series}_{season_id}' + data = self._call_api( + f'https://content.api.nebula.app/content/{series}/season/{season_id}', playlist_id) + + return self.playlist_result( + self._entries(data), playlist_id, + **traverse_obj(data, { + 'title': ('title', {str}), + 'description': ('description', {str}), + })) diff --git a/yt-dlp/yt_dlp/extractor/neteasemusic.py b/yt-dlp/yt_dlp/extractor/neteasemusic.py index 6c47086b9b..8f3a7d2358 100644 --- a/yt-dlp/yt_dlp/extractor/neteasemusic.py +++ b/yt-dlp/yt_dlp/extractor/neteasemusic.py @@ -528,7 +528,7 @@ class NetEaseMusicMvIE(NetEaseMusicBaseIE): class NetEaseMusicProgramIE(NetEaseMusicBaseIE): IE_NAME = 'netease:program' IE_DESC = '网易云音乐 - 电台节目' - _VALID_URL = r'https?://music\.163\.com/(?:#/)?program\?id=(?P[0-9]+)' + _VALID_URL = r'https?://music\.163\.com/(?:#/)?(?:dj|program)\?id=(?P[0-9]+)' _TESTS = [{ 'url': 'http://music.163.com/#/program?id=10109055', 'info_dict': { @@ -572,6 +572,9 @@ class NetEaseMusicProgramIE(NetEaseMusicBaseIE): 'params': { 'noplaylist': True, }, + }, { + 'url': 'https://music.163.com/#/dj?id=3706179315', + 'only_matching': True, }] def _real_extract(self, url): diff --git a/yt-dlp/yt_dlp/extractor/yahoo.py b/yt-dlp/yt_dlp/extractor/yahoo.py index 35e71209c5..876601a511 100644 --- a/yt-dlp/yt_dlp/extractor/yahoo.py +++ b/yt-dlp/yt_dlp/extractor/yahoo.py @@ -13,55 +13,16 @@ from ..utils import ( parse_iso8601, traverse_obj, try_get, + update_url, url_or_none, ) class YahooIE(InfoExtractor): - IE_DESC = 'Yahoo screen and movies' + IE_NAME = 'yahoo' _VALID_URL = r'(?Phttps?://(?:(?P[a-zA-Z]{2}(?:-[a-zA-Z]{2})?|malaysia)\.)?(?:[\da-zA-Z_-]+\.)?yahoo\.com/(?:[^/]+/)*(?P[^?&#]*-[0-9]+(?:-[a-z]+)?)\.html)' - _EMBED_REGEX = [r']+?src=(["\'])(?Phttps?://(?:screen|movies)\.yahoo\.com/.+?\.html\?format=embed)\1'] - _TESTS = [{ - 'url': 'http://screen.yahoo.com/julian-smith-travis-legg-watch-214727115.html', - 'info_dict': { - 'id': '2d25e626-2378-391f-ada0-ddaf1417e588', - 'ext': 'mp4', - 'title': 'Julian Smith & Travis Legg Watch Julian Smith', - 'description': 'Julian and Travis watch Julian Smith', - 'duration': 6863, - 'timestamp': 1369812016, - 'upload_date': '20130529', - }, - 'skip': 'No longer exists', - }, { - 'url': 'https://screen.yahoo.com/community/community-sizzle-reel-203225340.html?format=embed', - 'md5': '7993e572fac98e044588d0b5260f4352', - 'info_dict': { - 'id': '4fe78544-8d48-39d8-97cd-13f205d9fcdb', - 'ext': 'mp4', - 'title': "Yahoo Saves 'Community'", - 'description': 'md5:4d4145af2fd3de00cbb6c1d664105053', - 'duration': 170, - 'timestamp': 1406838636, - 'upload_date': '20140731', - }, - 'skip': 'Unfortunately, this video is not available in your region', - }, { - 'url': 'https://uk.screen.yahoo.com/editor-picks/cute-raccoon-freed-drain-using-091756545.html', - 'md5': '71298482f7c64cbb7fa064e4553ff1c1', - 'info_dict': { - 'id': 'b3affa53-2e14-3590-852b-0e0db6cd1a58', - 'ext': 'webm', - 'title': 'Cute Raccoon Freed From Drain\u00a0Using Angle Grinder', - 'description': 'md5:f66c890e1490f4910a9953c941dee944', - 'duration': 97, - 'timestamp': 1414489862, - 'upload_date': '20141028', - }, - 'skip': 'No longer exists', - }, { - 'url': 'http://news.yahoo.com/video/china-moses-crazy-blues-104538833.html', + 'url': 'https://news.yahoo.com/video/china-moses-crazy-blues-104538833.html', 'md5': '88e209b417f173d86186bef6e4d1f160', 'info_dict': { 'id': 'f885cf7f-43d4-3450-9fac-46ac30ece521', @@ -69,27 +30,33 @@ class YahooIE(InfoExtractor): 'title': 'China Moses Is Crazy About the Blues', 'description': 'md5:9900ab8cd5808175c7b3fe55b979bed0', 'duration': 128, - 'timestamp': 1385722202, + 'timestamp': 1385721938, 'upload_date': '20131129', + 'display_id': 'china-moses-crazy-blues-104538833', + 'view_count': int, + 'thumbnail': r're:https://media\.zenfs\.com/.+', }, }, { 'url': 'https://www.yahoo.com/movies/v/true-story-trailer-173000497.html', - 'md5': '2a9752f74cb898af5d1083ea9f661b58', + # 'md5': '989396ae73d20c6f057746fb226aa215', # varies between this and 'b17ac378b1134fa44370fb27db09a744' 'info_dict': { 'id': '071c4013-ce30-3a93-a5b2-e0413cd4a9d1', 'ext': 'mp4', 'title': '\'True Story\' Trailer', 'description': 'True Story', 'duration': 150, - 'timestamp': 1418919206, + 'timestamp': 1418923800, 'upload_date': '20141218', + 'display_id': 'true-story-trailer-173000497', + 'view_count': int, + 'thumbnail': r're:https://media\.zenfs\.com/.+\.jpg', }, }, { 'url': 'https://gma.yahoo.com/pizza-delivery-man-surprised-huge-tip-college-kids-195200785.html', 'only_matching': True, }, { 'note': 'NBC Sports embeds', - 'url': 'http://sports.yahoo.com/blogs/ncaab-the-dagger/tyler-kalinoski-s-buzzer-beater-caps-davidson-s-comeback-win-185609842.html?guid=nbc_cbk_davidsonbuzzerbeater_150313', + 'url': 'https://sports.yahoo.com/blogs/ncaab-the-dagger/tyler-kalinoski-s-buzzer-beater-caps-davidson-s-comeback-win-185609842.html?guid=nbc_cbk_davidsonbuzzerbeater_150313', 'info_dict': { 'id': '9CsDKds0kvHI', 'ext': 'flv', @@ -99,26 +66,10 @@ class YahooIE(InfoExtractor): 'uploader': 'NBCU-SPORTS', 'timestamp': 1426270238, }, + 'skip': 'Page no longer has video', }, { 'url': 'https://tw.news.yahoo.com/-100120367.html', 'only_matching': True, - }, { - # Query result is embedded in webpage, but explicit request to video API fails with geo restriction - 'url': 'https://screen.yahoo.com/community/communitary-community-episode-1-ladders-154501237.html', - 'md5': '4fbafb9c9b6f07aa8f870629f6671b35', - 'info_dict': { - 'id': '1f32853c-a271-3eef-8cb6-f6d6872cb504', - 'ext': 'mp4', - 'title': 'Communitary - Community Episode 1: Ladders', - 'description': 'md5:8fc39608213295748e1e289807838c97', - 'duration': 1646, - 'timestamp': 1440436550, - 'upload_date': '20150824', - 'series': 'Communitary', - 'season_number': 6, - 'episode_number': 1, - }, - 'skip': 'No longer exists', }, { # ytwnews://cavideo/ 'url': 'https://tw.video.yahoo.com/movie-tw/單車天使-中文版預-092316541.html', @@ -129,12 +80,16 @@ class YahooIE(InfoExtractor): 'description': '中文版預', 'timestamp': 1476696196, 'upload_date': '20161017', + 'view_count': int, + 'duration': 141, + 'thumbnail': r're:https://media\.zenfs\.com/.+\.jpg', + 'series': '電影', + 'display_id': '單車天使-中文版預-092316541', }, 'params': { 'skip_download': True, }, }, { - # Contains both a Yahoo hosted video and multiple Youtube embeds 'url': 'https://www.yahoo.com/entertainment/gwen-stefani-reveals-the-pop-hit-she-passed-on-assigns-it-to-her-voice-contestant-instead-033045672.html', 'info_dict': { 'id': '46c5d95a-528f-3d03-b732-732fcadd51de', @@ -147,24 +102,29 @@ class YahooIE(InfoExtractor): 'ext': 'mp4', 'title': 'Gwen Stefani reveals she turned down one of Sia\'s best songs', 'description': 'On "The Voice" Tuesday, Gwen Stefani told Taylor Swift which Sia hit was almost hers.', - 'timestamp': 1572406500, + 'timestamp': 1572406499, 'upload_date': '20191030', - }, - }, { - 'info_dict': { - 'id': '352CFDOQrKg', - 'ext': 'mp4', - 'title': 'Kyndal Inskeep "Performs the Hell Out of" Sia\'s "Elastic Heart" - The Voice Knockouts 2019', - 'description': 'md5:7fe8e3d5806f96002e55f190d1d94479', - 'uploader': 'The Voice', - 'uploader_id': 'NBCTheVoice', - 'upload_date': '20191029', + 'display_id': 'gwen-stefani-reveals-she-turned-033459311', + 'view_count': int, + 'duration': 97, + 'thumbnail': 'https://s.yimg.com/os/creatr-uploaded-images/2019-10/348bb330-fac6-11e9-8d27-38e85d573702', + 'series': 'Last Night Now', }, }], - 'params': { - 'playlistend': 2, + }, { + 'url': 'https://sports.yahoo.com/video/rams-lose-grip-nfcs-top-174614409.html', + 'info_dict': { + 'id': '6b15f100-cf5c-3ad0-9c96-87cbd2f72d4a', + 'ext': 'mp4', + 'display_id': 'rams-lose-grip-nfcs-top-174614409', + 'title': 'Rams lose their grip on NFC\'s top seed — can they still secure the bye?', + 'description': 'md5:5f4f98ab3c4de80e54c105b6bbb1d024', + 'view_count': int, + 'duration': 85, + 'thumbnail': 'https://s.yimg.com/os/creatr-uploaded-images/2025-12/94fc4840-dd02-11f0-beff-38ba3a4992e3', + 'timestamp': 1766166374, + 'upload_date': '20251219', }, - 'expected_warnings': ['HTTP Error 404', 'Ignoring subtitle tracks'], }, { 'url': 'https://malaysia.news.yahoo.com/video/bystanders-help-ontario-policeman-bust-190932818.html', 'only_matching': True, @@ -178,14 +138,12 @@ class YahooIE(InfoExtractor): def _extract_yahoo_video(self, video_id, country): video = self._download_json( - f'https://{country}.yahoo.com/_td/api/resource/VideoService.videos;view=full;video_ids=["{video_id}"]', - video_id, 'Downloading video JSON metadata')[0] - title = video['title'] - + f'https://video-api.yql.yahoo.com/v1/video/sapi/streams/{video_id}', + video_id, 'Downloading video JSON metadata')['query']['results']['mediaObj'][0]['meta'] if country == 'malaysia': country = 'my' - is_live = video.get('live_state') == 'live' + is_live = traverse_obj(video, ('uplynk_live', {bool})) is True fmts = ('m3u8',) if is_live else ('webm', 'mp4') urls = [] @@ -231,43 +189,23 @@ class YahooIE(InfoExtractor): 'ext': mimetype2ext(cc.get('content_type')), }) - streaming_url = video.get('streaming_url') - if streaming_url and not is_live: - formats.extend(self._extract_m3u8_formats( - streaming_url, video_id, 'mp4', - 'm3u8_native', m3u8_id='hls', fatal=False)) - if not formats and msg == 'geo restricted': self.raise_geo_restricted(metadata_available=True) - thumbnails = [] - for thumb in video.get('thumbnails', []): - thumb_url = thumb.get('url') - if not thumb_url: - continue - thumbnails.append({ - 'id': thumb.get('tag'), - 'url': thumb.get('url'), - 'width': int_or_none(thumb.get('width')), - 'height': int_or_none(thumb.get('height')), - }) - - series_info = video.get('series_info') or {} - return { 'id': video_id, - 'title': title, 'formats': formats, - 'thumbnails': thumbnails, - 'description': clean_html(video.get('description')), - 'timestamp': parse_iso8601(video.get('publish_time')), 'subtitles': subtitles, - 'duration': int_or_none(video.get('duration')), - 'view_count': int_or_none(video.get('view_count')), 'is_live': is_live, - 'series': video.get('show_name'), - 'season_number': int_or_none(series_info.get('season_number')), - 'episode_number': int_or_none(series_info.get('episode_number')), + **traverse_obj(video, { + 'title': ('title', {clean_html}), + 'description': ('description', {clean_html}), + 'thumbnail': ('thumbnail', {url_or_none}, {update_url(scheme='https')}), + 'timestamp': ('publish_time', {parse_iso8601}), + 'duration': ('duration', {int_or_none}), + 'view_count': ('view_count', {int_or_none}), + 'series': ('show_name', {str}, filter), + }), } def _real_extract(self, url): @@ -321,14 +259,13 @@ class YahooIE(InfoExtractor): class YahooSearchIE(SearchInfoExtractor): - IE_DESC = 'Yahoo screen search' _MAX_RESULTS = 1000 - IE_NAME = 'screen.yahoo:search' + IE_NAME = 'yahoo:search' _SEARCH_KEY = 'yvsearch' def _search_results(self, query): for pagenum in itertools.count(0): - result_url = f'http://video.search.yahoo.com/search/?p={urllib.parse.quote_plus(query)}&fr=screen&o=js&gs=0&b={pagenum * 30}' + result_url = f'https://video.search.yahoo.com/search/?p={urllib.parse.quote_plus(query)}&fr=screen&o=js&gs=0&b={pagenum * 30}' info = self._download_json(result_url, query, note='Downloading results page ' + str(pagenum + 1)) yield from (self.url_result(result['rurl']) for result in info['results'])