mirror of
https://github.com/bolucat/Archive.git
synced 2026-04-23 00:17:16 +08:00
Update On Tue Mar 18 19:36:33 CET 2025
This commit is contained in:
@@ -945,3 +945,4 @@ Update On Fri Mar 14 19:34:32 CET 2025
|
||||
Update On Sat Mar 15 19:32:45 CET 2025
|
||||
Update On Sun Mar 16 19:33:44 CET 2025
|
||||
Update On Mon Mar 17 19:35:42 CET 2025
|
||||
Update On Tue Mar 18 19:36:24 CET 2025
|
||||
|
||||
@@ -75,7 +75,15 @@ func GetRealityConn(ctx context.Context, conn net.Conn, ClientFingerprint string
|
||||
|
||||
//log.Debugln("REALITY hello.sessionId[:16]: %v", hello.SessionId[:16])
|
||||
|
||||
ecdheKey := uConn.HandshakeState.State13.EcdheKey
|
||||
keyShareKeys := uConn.HandshakeState.State13.KeyShareKeys
|
||||
if keyShareKeys == nil {
|
||||
// WTF???
|
||||
if retry > 2 {
|
||||
return nil, errors.New("nil keyShareKeys")
|
||||
}
|
||||
continue // retry
|
||||
}
|
||||
ecdheKey := keyShareKeys.Ecdhe
|
||||
if ecdheKey == nil {
|
||||
// WTF???
|
||||
if retry > 2 {
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ require (
|
||||
github.com/metacubex/sing-vmess v0.1.14-0.20250228002636-abc39e113b82
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589
|
||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422
|
||||
github.com/metacubex/utls v1.6.6
|
||||
github.com/metacubex/utls v1.6.8-alpha.4
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181
|
||||
github.com/miekg/dns v1.1.63
|
||||
github.com/mroth/weightedrand/v2 v2.1.0
|
||||
|
||||
+2
-2
@@ -129,8 +129,8 @@ github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589 h1:Z6bNy0
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589/go.mod h1:4NclTLIZuk+QkHVCGrP87rHi/y8YjgPytxTgApJNMhc=
|
||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422 h1:zGeQt3UyNydIVrMRB97AA5WsYEau/TyCnRtTf1yUmJY=
|
||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8=
|
||||
github.com/metacubex/utls v1.6.6/go.mod h1:+WLFUnXjcpdxXCnyX25nggw8C6YonZ8zOK2Zm/oRvdo=
|
||||
github.com/metacubex/utls v1.6.8-alpha.4 h1:5EvsCHxDNneaOtAyc8CztoNSpmonLvkvuGs01lIeeEI=
|
||||
github.com/metacubex/utls v1.6.8-alpha.4/go.mod h1:MEZ5WO/VLKYs/s/dOzEK/mlXOQxc04ESeLzRgjmLYtk=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
|
||||
Generated
+27
-27
@@ -592,7 +592,7 @@ dependencies = [
|
||||
"futures-timer",
|
||||
"futures-util",
|
||||
"http 1.2.0",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"mime",
|
||||
"multer",
|
||||
"num-traits",
|
||||
@@ -641,7 +641,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "741110dda927420a28fbc1c310543d3416f789a6ba96859c2c265843a0a96887"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
@@ -1258,7 +1258,7 @@ dependencies = [
|
||||
"boa_interner",
|
||||
"boa_macros",
|
||||
"boa_string",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"num-bigint",
|
||||
"rustc-hash 2.1.1",
|
||||
]
|
||||
@@ -1284,7 +1284,7 @@ dependencies = [
|
||||
"fast-float2",
|
||||
"hashbrown 0.15.2",
|
||||
"icu_normalizer",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"intrusive-collections",
|
||||
"itertools 0.13.0",
|
||||
"num-bigint",
|
||||
@@ -1330,7 +1330,7 @@ dependencies = [
|
||||
"boa_gc",
|
||||
"boa_macros",
|
||||
"hashbrown 0.15.2",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"once_cell",
|
||||
"phf 0.11.3",
|
||||
"rustc-hash 2.1.1",
|
||||
@@ -1950,7 +1950,7 @@ dependencies = [
|
||||
"hex",
|
||||
"humansize",
|
||||
"image",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"itertools 0.14.0",
|
||||
"log",
|
||||
"md-5",
|
||||
@@ -4357,7 +4357,7 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http 1.2.0",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
@@ -4975,9 +4975,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.7.1"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
|
||||
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.2",
|
||||
@@ -6061,7 +6061,7 @@ dependencies = [
|
||||
"cfg_aliases 0.2.1",
|
||||
"codespan-reporting",
|
||||
"hexf-parse",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"log",
|
||||
"rustc-hash 1.1.0",
|
||||
"spirv",
|
||||
@@ -6537,7 +6537,7 @@ dependencies = [
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"interprocess",
|
||||
"nyanpasu-utils",
|
||||
"pin-project-lite",
|
||||
@@ -7573,7 +7573,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db"
|
||||
dependencies = [
|
||||
"fixedbitset 0.4.2",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -7794,7 +7794,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"quick-xml 0.32.0",
|
||||
"serde",
|
||||
"time",
|
||||
@@ -9290,7 +9290,7 @@ version = "1.0.140"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"itoa 1.0.14",
|
||||
"memchr",
|
||||
"ryu",
|
||||
@@ -9349,7 +9349,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"hex",
|
||||
"indexmap 1.9.3",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
@@ -9375,7 +9375,7 @@ version = "0.9.34+deprecated"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"itoa 1.0.14",
|
||||
"ryu",
|
||||
"serde",
|
||||
@@ -9387,7 +9387,7 @@ name = "serde_yaml_ng"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/libnyanpasu/serde-yaml-ng.git?branch=feat/specta#3078760ab9e9a3a9e18ebb4c5d3e577eb74c4a5c"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"itoa 1.0.14",
|
||||
"ryu",
|
||||
"serde",
|
||||
@@ -9401,7 +9401,7 @@ version = "0.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59e2dd588bf1597a252c3b920e0143eb99b0f76e4e082f4c92ce34fbc9e71ddd"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"itoa 1.0.14",
|
||||
"libyml",
|
||||
"memchr",
|
||||
@@ -9820,7 +9820,7 @@ version = "2.0.0-rc.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab7f01e9310a820edd31c80fde3cae445295adde21a3f9416517d7d65015b971"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"paste",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -10034,7 +10034,7 @@ dependencies = [
|
||||
"dmp",
|
||||
"futures",
|
||||
"geo",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"path-clean",
|
||||
"pharos",
|
||||
"reblessive",
|
||||
@@ -10680,9 +10680,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-updater"
|
||||
version = "2.6.0"
|
||||
version = "2.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "67cd78a6cbd1255e989e96eedec004e9e8949e6c6359b41f861279aba64ea306"
|
||||
checksum = "a31bfcfb4a8318008d2108ccfba439d8263cf48867baabf372cb0e9f24771896"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"dirs 6.0.0",
|
||||
@@ -11283,7 +11283,7 @@ version = "0.19.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"toml_datetime",
|
||||
"winnow 0.5.40",
|
||||
]
|
||||
@@ -11294,7 +11294,7 @@ version = "0.20.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"toml_datetime",
|
||||
"winnow 0.5.40",
|
||||
]
|
||||
@@ -11305,7 +11305,7 @@ version = "0.22.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474"
|
||||
dependencies = [
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
@@ -12473,7 +12473,7 @@ dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"cfg_aliases 0.2.1",
|
||||
"document-features",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"log",
|
||||
"naga",
|
||||
"once_cell",
|
||||
@@ -13914,7 +13914,7 @@ dependencies = [
|
||||
"displaydoc",
|
||||
"flate2",
|
||||
"hmac",
|
||||
"indexmap 2.7.1",
|
||||
"indexmap 2.8.0",
|
||||
"lzma-rs",
|
||||
"memchr",
|
||||
"pbkdf2",
|
||||
|
||||
@@ -265,6 +265,7 @@ fn test_http_module_loader() -> JsResult<()> {
|
||||
import YAML from 'https://esm.run/yaml@2.3.4';
|
||||
import fromAsync from 'https://esm.run/array-from-async@3.0.0';
|
||||
import { Base64 } from 'https://esm.run/js-base64@3.7.6';
|
||||
import { text } from 'https://github.com/libnyanpasu/clash-nyanpasu/raw/refs/heads/main/pnpm-workspace.yaml';
|
||||
|
||||
const data = `
|
||||
object:
|
||||
@@ -279,6 +280,9 @@ fn test_http_module_loader() -> JsResult<()> {
|
||||
Promise.resolve(Base64.encode(object.array[1])),
|
||||
]);
|
||||
|
||||
const parsed = YAML.parse(text);
|
||||
result.push(JSON.stringify(parsed));
|
||||
|
||||
export default result;
|
||||
"#;
|
||||
|
||||
@@ -341,6 +345,15 @@ fn test_http_module_loader() -> JsResult<()> {
|
||||
.ok_or_else(|| JsNativeError::typ().with_message("array element was not a string"))?,
|
||||
&js_string!("d29ybGQ=")
|
||||
);
|
||||
assert!(
|
||||
default
|
||||
.get(2, context)?
|
||||
.as_string()
|
||||
.ok_or_else(|| JsNativeError::typ().with_message("array element was not a string"))?
|
||||
.to_std_string_escaped()
|
||||
.contains("packages"),
|
||||
"YAML content should contain 'packages' field"
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -22,6 +22,6 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/lodash-es": "4.17.12",
|
||||
"@types/react": "19.0.10"
|
||||
"@types/react": "19.0.11"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,11 @@ export const NYANPASU_SETTING_QUERY_KEY = 'settings'
|
||||
*/
|
||||
export const NYANPASU_SYSTEM_PROXY_QUERY_KEY = 'system-proxy'
|
||||
|
||||
/**
|
||||
* Nyanpasu chains log query key, fn: getPostProcessingOutput
|
||||
*/
|
||||
export const NYANPASU_POST_PROCESSING_QUERY_KEY = 'post-processing'
|
||||
|
||||
/**
|
||||
* Clash version query key, used to fetch clash version from query
|
||||
*/
|
||||
@@ -21,7 +26,7 @@ export const CLASH_VERSION_QUERY_KEY = 'clash-version'
|
||||
/**
|
||||
* Nyanpasu profile query key, used to fetch profiles from query
|
||||
*/
|
||||
export const ROFILES_QUERY_KEY = 'profiles'
|
||||
export const RROFILES_QUERY_KEY = 'profiles'
|
||||
|
||||
/**
|
||||
* Clash log query key, used by clash ws provider to mutate logs via clash logs ws api
|
||||
|
||||
@@ -9,6 +9,7 @@ export * from './use-clash-logs'
|
||||
export * from './use-clash-memory'
|
||||
export * from './use-clash-traffic'
|
||||
export * from './use-clash-version'
|
||||
export * from './use-post-processing-output'
|
||||
export * from './use-profile-content'
|
||||
export * from './use-profile'
|
||||
export * from './use-proxy-mode'
|
||||
@@ -16,7 +17,6 @@ export * from './use-runtime-profile'
|
||||
export * from './use-settings'
|
||||
export * from './use-system-proxy'
|
||||
export * from './use-system-service'
|
||||
export * from './useClash'
|
||||
export * from './useClashCore'
|
||||
|
||||
export { commands } from './bindings'
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { unwrapResult } from '@/utils'
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { commands } from './bindings'
|
||||
import { NYANPASU_POST_PROCESSING_QUERY_KEY } from './consts'
|
||||
|
||||
/**
|
||||
* Custom hook for fetching post-processing output using React Query.
|
||||
* Another name is chains/script logs.
|
||||
*
|
||||
* This hook queries post-processing output data using a predefined query key
|
||||
* and fetches the data through the `commands.getPostprocessingOutput` command.
|
||||
* The result is unwrapped using the `unwrapResult` utility function.
|
||||
*/
|
||||
export const usePostProcessingOutput = () => {
|
||||
const query = useQuery({
|
||||
queryKey: [NYANPASU_POST_PROCESSING_QUERY_KEY],
|
||||
queryFn: async () => {
|
||||
return unwrapResult(await commands.getPostprocessingOutput())
|
||||
},
|
||||
})
|
||||
|
||||
return {
|
||||
...query,
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
type ProfilesBuilder,
|
||||
type RemoteProfileOptionsBuilder,
|
||||
} from './bindings'
|
||||
import { ROFILES_QUERY_KEY } from './consts'
|
||||
import { RROFILES_QUERY_KEY } from './consts'
|
||||
|
||||
type URLImportParams = Parameters<typeof commands.importProfile>
|
||||
|
||||
@@ -106,7 +106,7 @@ export const useProfile = (options?: { without_helper_fn?: boolean }) => {
|
||||
* @returns A promise resolving to an object containing the profile list along with the extended helper functions.
|
||||
*/
|
||||
const query = useQuery({
|
||||
queryKey: [ROFILES_QUERY_KEY],
|
||||
queryKey: [RROFILES_QUERY_KEY],
|
||||
queryFn: async () => {
|
||||
const result = unwrapResult(await commands.getProfiles())
|
||||
|
||||
@@ -157,7 +157,7 @@ export const useProfile = (options?: { without_helper_fn?: boolean }) => {
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Invalidate and refetch
|
||||
queryClient.invalidateQueries({ queryKey: [ROFILES_QUERY_KEY] })
|
||||
queryClient.invalidateQueries({ queryKey: [RROFILES_QUERY_KEY] })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -185,7 +185,7 @@ export const useProfile = (options?: { without_helper_fn?: boolean }) => {
|
||||
return unwrapResult(await commands.updateProfile(uid, option))
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [ROFILES_QUERY_KEY] })
|
||||
queryClient.invalidateQueries({ queryKey: [RROFILES_QUERY_KEY] })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -216,7 +216,7 @@ export const useProfile = (options?: { without_helper_fn?: boolean }) => {
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Invalidate and refetch
|
||||
queryClient.invalidateQueries({ queryKey: [ROFILES_QUERY_KEY] })
|
||||
queryClient.invalidateQueries({ queryKey: [RROFILES_QUERY_KEY] })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -240,7 +240,7 @@ export const useProfile = (options?: { without_helper_fn?: boolean }) => {
|
||||
},
|
||||
onSuccess: () => {
|
||||
// Invalidate and refetch
|
||||
queryClient.invalidateQueries({ queryKey: [ROFILES_QUERY_KEY] })
|
||||
queryClient.invalidateQueries({ queryKey: [RROFILES_QUERY_KEY] })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -263,7 +263,7 @@ export const useProfile = (options?: { without_helper_fn?: boolean }) => {
|
||||
)
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [ROFILES_QUERY_KEY] })
|
||||
queryClient.invalidateQueries({ queryKey: [RROFILES_QUERY_KEY] })
|
||||
},
|
||||
})
|
||||
|
||||
@@ -280,7 +280,7 @@ export const useProfile = (options?: { without_helper_fn?: boolean }) => {
|
||||
return unwrapResult(await commands.deleteProfile(uid))
|
||||
},
|
||||
onSuccess: () => {
|
||||
queryClient.invalidateQueries({ queryKey: [ROFILES_QUERY_KEY] })
|
||||
queryClient.invalidateQueries({ queryKey: [RROFILES_QUERY_KEY] })
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -1,132 +0,0 @@
|
||||
import useSWR from 'swr'
|
||||
import {
|
||||
ClashConfig,
|
||||
Profile,
|
||||
ProfilesBuilder,
|
||||
RemoteProfileOptionsBuilder,
|
||||
} from '@/index'
|
||||
import * as tauri from '@/service/tauri'
|
||||
import { clash } from '../service/clash'
|
||||
|
||||
/**
|
||||
* useClash with swr.
|
||||
* Data from tauri backend.
|
||||
*/
|
||||
export const useClash = () => {
|
||||
const { deleteConnections, ...api } = clash()
|
||||
|
||||
const getClashInfo = useSWR('getClashInfo', tauri.getClashInfo)
|
||||
const getConfigs = useSWR('getClashConfig', api.getConfigs)
|
||||
|
||||
const setConfigs = async (payload: Partial<ClashConfig>) => {
|
||||
try {
|
||||
await tauri.patchClashConfig(payload)
|
||||
|
||||
await Promise.all([getClashInfo.mutate(), getConfigs.mutate()])
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
}
|
||||
|
||||
return getClashInfo.data
|
||||
}
|
||||
|
||||
const getVersion = useSWR('getClashVersion', api.getVersion)
|
||||
|
||||
const getRules = useSWR('getClashRules', api.getRules)
|
||||
|
||||
const getRuntimeExists = useSWR('getRuntimeExists', tauri.getRuntimeExists)
|
||||
|
||||
const getProfiles = useSWR('getProfiles', tauri.getProfiles)
|
||||
|
||||
const setProfiles = async (uid: string, profile: Partial<Profile>) => {
|
||||
await tauri.setProfiles({ uid, profile })
|
||||
|
||||
await getProfiles.mutate()
|
||||
|
||||
await getRuntimeLogs.mutate()
|
||||
}
|
||||
|
||||
const setProfilesConfig = async (profiles: ProfilesBuilder) => {
|
||||
await tauri.setProfilesConfig(profiles)
|
||||
|
||||
await getProfiles.mutate()
|
||||
|
||||
await getRuntimeLogs.mutate()
|
||||
}
|
||||
|
||||
const createProfile = async (item: Partial<Profile>, data?: string) => {
|
||||
await tauri.createProfile(item, data)
|
||||
|
||||
await getProfiles.mutate()
|
||||
}
|
||||
|
||||
const updateProfile = async (
|
||||
uid: string,
|
||||
option?: RemoteProfileOptionsBuilder,
|
||||
) => {
|
||||
await tauri.updateProfile(uid, option)
|
||||
|
||||
await getProfiles.mutate()
|
||||
}
|
||||
|
||||
const deleteProfile = async (uid: string) => {
|
||||
await tauri.deleteProfile(uid)
|
||||
|
||||
await getProfiles.mutate()
|
||||
}
|
||||
|
||||
const getProfileFile = async (id?: string) => {
|
||||
if (id) {
|
||||
const result = await tauri.readProfileFile(id)
|
||||
|
||||
if (result) {
|
||||
return result
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
} else {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
|
||||
const importProfile = async (
|
||||
url: string,
|
||||
option: RemoteProfileOptionsBuilder,
|
||||
) => {
|
||||
await tauri.importProfile(url, option)
|
||||
|
||||
await getProfiles.mutate()
|
||||
}
|
||||
|
||||
const getRuntimeLogs = useSWR('getRuntimeLogs', tauri.getRuntimeLogs, {
|
||||
refreshInterval: 1000,
|
||||
})
|
||||
|
||||
const reorderProfilesByList = async (list: string[]) => {
|
||||
await tauri.reorderProfilesByList(list)
|
||||
|
||||
await getProfiles.mutate()
|
||||
}
|
||||
|
||||
return {
|
||||
getClashInfo,
|
||||
getConfigs,
|
||||
setConfigs,
|
||||
getVersion,
|
||||
getRules,
|
||||
deleteConnections,
|
||||
getRuntimeExists,
|
||||
getProfiles,
|
||||
setProfiles,
|
||||
setProfilesConfig,
|
||||
createProfile,
|
||||
updateProfile,
|
||||
deleteProfile,
|
||||
importProfile,
|
||||
viewProfile: tauri.viewProfile,
|
||||
getProfileFile,
|
||||
getRuntimeLogs,
|
||||
setProfileFile: tauri.saveProfileFile,
|
||||
reorderProfilesByList,
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import {
|
||||
NYANPASU_BACKEND_EVENT_NAME,
|
||||
NYANPASU_SETTING_QUERY_KEY,
|
||||
NYANPASU_SYSTEM_PROXY_QUERY_KEY,
|
||||
RROFILES_QUERY_KEY,
|
||||
} from '../ipc/consts'
|
||||
|
||||
type EventPayload = 'nyanpasu_config' | 'clash_config' | 'proxies' | 'profiles'
|
||||
@@ -24,6 +25,7 @@ const CLASH_CONFIG_MUTATION_KEYS = [
|
||||
CLASH_VERSION_QUERY_KEY,
|
||||
CLASH_INFO_QUERY_KEY,
|
||||
CLASH_CONFIG_QUERY_KEY,
|
||||
RROFILES_QUERY_KEY,
|
||||
// TODO: clash rules hook refetch
|
||||
// TODO: clash rules providers hook refetch
|
||||
// TODO: proxies hook refetch
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Retry a function with exponential backoff
|
||||
*
|
||||
* @param fn - The function to retry
|
||||
* @param options - Retry options
|
||||
* @returns The result of the function
|
||||
* @throws The last error encountered
|
||||
*/
|
||||
export async function retry<T>(
|
||||
fn: () => Promise<T>,
|
||||
options: {
|
||||
maxRetries?: number
|
||||
initialDelay?: number
|
||||
maxDelay?: number
|
||||
factor?: number
|
||||
retryCondition?: (error: Error) => boolean
|
||||
} = {},
|
||||
): Promise<T> {
|
||||
const {
|
||||
maxRetries = 3,
|
||||
initialDelay = 200,
|
||||
maxDelay = 5000,
|
||||
factor = 2,
|
||||
retryCondition = () => true,
|
||||
} = options
|
||||
|
||||
let lastError: Error = new Error('Unknown error occurred')
|
||||
|
||||
let delay = initialDelay
|
||||
|
||||
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
||||
try {
|
||||
return await fn()
|
||||
} catch (error) {
|
||||
if (attempt === maxRetries || !retryCondition(error as Error)) {
|
||||
throw error
|
||||
}
|
||||
|
||||
lastError = error as Error
|
||||
|
||||
// Wait for the specified delay
|
||||
await new Promise((resolve) => setTimeout(resolve, delay))
|
||||
|
||||
// Increase the delay for the next attempt (exponential backoff)
|
||||
delay = Math.min(delay * factor, maxDelay)
|
||||
}
|
||||
}
|
||||
|
||||
throw lastError
|
||||
}
|
||||
@@ -53,12 +53,12 @@
|
||||
"@csstools/normalize.css": "12.1.1",
|
||||
"@emotion/babel-plugin": "11.13.5",
|
||||
"@emotion/react": "11.14.0",
|
||||
"@iconify/json": "2.2.317",
|
||||
"@iconify/json": "2.2.318",
|
||||
"@monaco-editor/react": "4.7.0",
|
||||
"@tanstack/react-query": "5.68.0",
|
||||
"@tanstack/react-router": "1.114.23",
|
||||
"@tanstack/router-devtools": "1.114.23",
|
||||
"@tanstack/router-plugin": "1.114.23",
|
||||
"@tanstack/react-router": "1.114.24",
|
||||
"@tanstack/router-devtools": "1.114.24",
|
||||
"@tanstack/router-plugin": "1.114.24",
|
||||
"@tauri-apps/plugin-clipboard-manager": "2.2.2",
|
||||
"@tauri-apps/plugin-dialog": "2.2.0",
|
||||
"@tauri-apps/plugin-fs": "2.2.0",
|
||||
@@ -66,8 +66,8 @@
|
||||
"@tauri-apps/plugin-os": "2.2.1",
|
||||
"@tauri-apps/plugin-process": "2.2.0",
|
||||
"@tauri-apps/plugin-shell": "2.2.0",
|
||||
"@tauri-apps/plugin-updater": "2.6.0",
|
||||
"@types/react": "19.0.10",
|
||||
"@tauri-apps/plugin-updater": "2.6.1",
|
||||
"@types/react": "19.0.11",
|
||||
"@types/react-dom": "19.0.4",
|
||||
"@types/validator": "13.12.2",
|
||||
"@vitejs/plugin-legacy": "6.0.2",
|
||||
|
||||
@@ -7,11 +7,7 @@ import { formatError } from '@/utils'
|
||||
import { message } from '@/utils/notification'
|
||||
import { Add } from '@mui/icons-material'
|
||||
import { alpha, ListItemButton, useTheme } from '@mui/material'
|
||||
import {
|
||||
ProfileQueryResultItem,
|
||||
useClash,
|
||||
useProfile,
|
||||
} from '@nyanpasu/interface'
|
||||
import { ProfileQueryResultItem, useProfile } from '@nyanpasu/interface'
|
||||
import { ClashProfile, filterProfiles } from '../utils'
|
||||
import ChainItem from './chain-item'
|
||||
import { atomChainsSelected, atomGlobalChainCurrent } from './store'
|
||||
@@ -29,11 +25,11 @@ export const SideChain = ({ onChainEdit }: SideChainProps) => {
|
||||
|
||||
const currentProfileUid = useAtomValue(atomChainsSelected)
|
||||
|
||||
const { setProfiles, reorderProfilesByList } = useClash()
|
||||
const { query, upsert, patch, sort } = useProfile()
|
||||
|
||||
const { query, upsert } = useProfile()
|
||||
const profiles = query.data
|
||||
|
||||
const { clash, chain } = filterProfiles(query.data?.items)
|
||||
const { clash, chain } = filterProfiles(profiles?.items)
|
||||
|
||||
const currentProfile = useMemo(() => {
|
||||
return clash?.find((item) => item.uid === currentProfileUid) as ClashProfile
|
||||
@@ -41,7 +37,7 @@ export const SideChain = ({ onChainEdit }: SideChainProps) => {
|
||||
|
||||
const handleChainClick = useLockFn(async (uid: string) => {
|
||||
const chains = isGlobalChainCurrent
|
||||
? (query.data?.chain ?? [])
|
||||
? (profiles?.chain ?? [])
|
||||
: (currentProfile?.chain ?? [])
|
||||
|
||||
const updatedChains = chains.includes(uid)
|
||||
@@ -55,7 +51,13 @@ export const SideChain = ({ onChainEdit }: SideChainProps) => {
|
||||
if (!currentProfile?.uid) {
|
||||
return
|
||||
}
|
||||
await setProfiles(currentProfile!.uid, { chain: updatedChains })
|
||||
await patch.mutateAsync({
|
||||
uid: currentProfile.uid,
|
||||
profile: {
|
||||
...currentProfile,
|
||||
chain: updatedChains,
|
||||
},
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
message(`Apply error: ${formatError(e)}`, {
|
||||
@@ -77,14 +79,14 @@ export const SideChain = ({ onChainEdit }: SideChainProps) => {
|
||||
values={reorderValues}
|
||||
onReorder={(values) => {
|
||||
const profileUids = clash?.map((item) => item.uid) || []
|
||||
reorderProfilesByList([...profileUids, ...values])
|
||||
sort.mutate([...profileUids, ...values])
|
||||
}}
|
||||
layoutScroll
|
||||
style={{ overflowY: 'scroll' }}
|
||||
>
|
||||
{chain?.map((item, index) => {
|
||||
const selected = isGlobalChainCurrent
|
||||
? query.data?.chain?.includes(item.uid)
|
||||
? profiles?.chain?.includes(item.uid)
|
||||
: currentProfile?.chain?.includes(item.uid)
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { isEmpty } from 'lodash-es'
|
||||
import { memo } from 'react'
|
||||
import { useAtomValue } from 'jotai'
|
||||
import { memo, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { VList } from 'virtua'
|
||||
import { RamenDining, Terminal } from '@mui/icons-material'
|
||||
import { Divider } from '@mui/material'
|
||||
import { useClash, useProfile } from '@nyanpasu/interface'
|
||||
import { usePostProcessingOutput, useProfile } from '@nyanpasu/interface'
|
||||
import { cn } from '@nyanpasu/ui'
|
||||
import { filterProfiles } from '../utils'
|
||||
import { atomChainsSelected, atomGlobalChainCurrent } from './store'
|
||||
|
||||
const LogListItem = memo(function LogListItem({
|
||||
name,
|
||||
@@ -37,11 +37,25 @@ export interface SideLogProps {
|
||||
export const SideLog = ({ className }: SideLogProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
// const { getRuntimeLogs, getProfiles } = useClash()
|
||||
|
||||
const { query } = useProfile()
|
||||
|
||||
const { chain } = filterProfiles(query.data?.items)
|
||||
const profiles = query.data?.items
|
||||
|
||||
const { data } = usePostProcessingOutput()
|
||||
|
||||
const isGlobalChainCurrent = useAtomValue(atomGlobalChainCurrent)
|
||||
|
||||
const currentProfileUid = useAtomValue(atomChainsSelected)
|
||||
|
||||
const currentLogs = useMemo(() => {
|
||||
if (currentProfileUid) {
|
||||
return data?.scopes[currentProfileUid]
|
||||
}
|
||||
|
||||
if (isGlobalChainCurrent) {
|
||||
return data?.scopes.global
|
||||
}
|
||||
}, [currentProfileUid, data, isGlobalChainCurrent])
|
||||
|
||||
return (
|
||||
<div className={cn('w-full', className)}>
|
||||
@@ -56,10 +70,10 @@ export const SideLog = ({ className }: SideLogProps) => {
|
||||
<Divider />
|
||||
|
||||
<VList className="flex flex-col gap-2 overflow-auto p-2 select-text">
|
||||
{/* {!isEmpty(getRuntimeLogs.data) ? (
|
||||
Object.entries(getRuntimeLogs.data).map(([uid, content]) => {
|
||||
return content.map((item, index) => {
|
||||
const name = scripts?.find((script) => script.uid === uid)?.name
|
||||
{currentLogs ? (
|
||||
Object.entries(currentLogs).map(([uid, content]) => {
|
||||
return content?.map((item, index) => {
|
||||
const name = profiles?.find((script) => script.uid === uid)?.name
|
||||
|
||||
return (
|
||||
<LogListItem
|
||||
@@ -71,12 +85,12 @@ export const SideLog = ({ className }: SideLogProps) => {
|
||||
)
|
||||
})
|
||||
})
|
||||
) : ( */}
|
||||
<div className="flex h-full min-h-48 w-full flex-col items-center justify-center">
|
||||
<RamenDining className="!size-10" />
|
||||
<p>{t('No Logs')}</p>
|
||||
</div>
|
||||
{/* )} */}
|
||||
) : (
|
||||
<div className="flex h-full min-h-48 w-full flex-col items-center justify-center">
|
||||
<RamenDining className="!size-10" />
|
||||
<p>{t('No Logs')}</p>
|
||||
</div>
|
||||
)}
|
||||
</VList>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -8,7 +8,6 @@ import { Divider } from '@mui/material'
|
||||
import {
|
||||
Profile,
|
||||
ProfileTemplate,
|
||||
useClash,
|
||||
useProfile,
|
||||
useProfileContent,
|
||||
} from '@nyanpasu/interface'
|
||||
@@ -69,9 +68,6 @@ export const ScriptDialog = ({
|
||||
}: ScriptDialogProps) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
// const { getProfileFile, setProfileFile, createProfile, setProfiles } =
|
||||
// useClash()
|
||||
|
||||
const { create, patch } = useProfile()
|
||||
|
||||
const contentFn = useProfileContent(profile?.uid ?? '')
|
||||
@@ -149,9 +145,9 @@ export const ScriptDialog = ({
|
||||
|
||||
useAsyncEffect(async () => {
|
||||
if (isEdit) {
|
||||
await contentFn.query.refetch()
|
||||
const result = await contentFn.query.refetch()
|
||||
|
||||
editor.value = contentFn.query.data ?? ''
|
||||
editor.value = result.data ?? ''
|
||||
editor.language = getLanguage(profile!.type)!
|
||||
} else {
|
||||
editor.value = ProfileTemplate.merge
|
||||
@@ -253,7 +249,7 @@ export const ScriptDialog = ({
|
||||
<Divider orientation="vertical" />
|
||||
|
||||
<Suspense fallback={null}>
|
||||
{openMonaco && (
|
||||
{openMonaco && !contentFn.query.isPending && (
|
||||
<ProfileMonacoViewer
|
||||
className="w-full"
|
||||
value={editor.value}
|
||||
|
||||
@@ -8,7 +8,6 @@ import { message } from '@/utils/notification'
|
||||
import { Box, List, ListItem } from '@mui/material'
|
||||
import {
|
||||
ClashCore,
|
||||
useClash,
|
||||
useClashConnections,
|
||||
useClashCores,
|
||||
useClashVersion,
|
||||
|
||||
@@ -28,7 +28,6 @@ import { Badge, Button, CircularProgress, IconButton } from '@mui/material'
|
||||
import Grid from '@mui/material/Grid2'
|
||||
import {
|
||||
RemoteProfileOptionsBuilder,
|
||||
useClash,
|
||||
useProfile,
|
||||
type RemoteProfile,
|
||||
} from '@nyanpasu/interface'
|
||||
@@ -50,51 +49,50 @@ export const Route = createFileRoute('/profiles')({
|
||||
function ProfilePage() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const { getRuntimeLogs } = useClash()
|
||||
|
||||
const { query, update } = useProfile()
|
||||
|
||||
const profiles = useMemo(() => {
|
||||
return filterProfiles(query.data?.items)
|
||||
}, [query.data?.items])
|
||||
|
||||
const maxLogLevelTriggered = useMemo(() => {
|
||||
const currentProfileChains =
|
||||
(
|
||||
query.data?.items?.find(
|
||||
// TODO: 支持多 Profile
|
||||
(item) => query.data?.current?.[0] === item.uid,
|
||||
// TODO: fix any type
|
||||
) as any
|
||||
)?.chain || []
|
||||
return Object.entries(getRuntimeLogs.data || {}).reduce(
|
||||
(acc, [key, value]) => {
|
||||
const accKey = currentProfileChains.includes(key) ? 'current' : 'global'
|
||||
if (acc[accKey] === 'error') {
|
||||
return acc
|
||||
}
|
||||
for (const log of value) {
|
||||
switch (log[0]) {
|
||||
case 'error':
|
||||
return { ...acc, [accKey]: 'error' }
|
||||
case 'warn':
|
||||
acc = { ...acc, [accKey]: 'warn' }
|
||||
break
|
||||
case 'info':
|
||||
if (acc[accKey] !== 'warn') {
|
||||
acc = { ...acc, [accKey]: 'info' }
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
return acc
|
||||
},
|
||||
{} as {
|
||||
global: undefined | 'info' | 'error' | 'warn'
|
||||
current: undefined | 'info' | 'error' | 'warn'
|
||||
},
|
||||
)
|
||||
}, [query.data, getRuntimeLogs.data])
|
||||
// TODO: fix me
|
||||
// const maxLogLevelTriggered = useMemo(() => {
|
||||
// const currentProfileChains =
|
||||
// (
|
||||
// query.data?.items?.find(
|
||||
// // TODO: 支持多 Profile
|
||||
// (item) => query.data?.current?.[0] === item.uid,
|
||||
// // TODO: fix any type
|
||||
// ) as any
|
||||
// )?.chain || []
|
||||
// return Object.entries(getRuntimeLogs.data || {}).reduce(
|
||||
// (acc, [key, value]) => {
|
||||
// const accKey = currentProfileChains.includes(key) ? 'current' : 'global'
|
||||
// if (acc[accKey] === 'error') {
|
||||
// return acc
|
||||
// }
|
||||
// for (const log of value) {
|
||||
// switch (log[0]) {
|
||||
// case 'error':
|
||||
// return { ...acc, [accKey]: 'error' }
|
||||
// case 'warn':
|
||||
// acc = { ...acc, [accKey]: 'warn' }
|
||||
// break
|
||||
// case 'info':
|
||||
// if (acc[accKey] !== 'warn') {
|
||||
// acc = { ...acc, [accKey]: 'info' }
|
||||
// }
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// return acc
|
||||
// },
|
||||
// {} as {
|
||||
// global: undefined | 'info' | 'error' | 'warn'
|
||||
// current: undefined | 'info' | 'error' | 'warn'
|
||||
// },
|
||||
// )
|
||||
// }, [query.data, getRuntimeLogs.data])
|
||||
|
||||
const [globalChain, setGlobalChain] = useAtom(atomGlobalChainCurrent)
|
||||
|
||||
@@ -198,14 +196,14 @@ function ProfilePage() {
|
||||
</IconButton>
|
||||
<Badge
|
||||
variant="dot"
|
||||
color={
|
||||
maxLogLevelTriggered.global === 'error'
|
||||
? 'error'
|
||||
: maxLogLevelTriggered.global === 'warn'
|
||||
? 'warning'
|
||||
: 'primary'
|
||||
}
|
||||
invisible={!maxLogLevelTriggered.global}
|
||||
// color={
|
||||
// maxLogLevelTriggered.global === 'error'
|
||||
// ? 'error'
|
||||
// : maxLogLevelTriggered.global === 'warn'
|
||||
// ? 'warning'
|
||||
// : 'primary'
|
||||
// }
|
||||
// invisible={!maxLogLevelTriggered.global}
|
||||
>
|
||||
<Button
|
||||
size="small"
|
||||
@@ -248,7 +246,7 @@ function ProfilePage() {
|
||||
item={item}
|
||||
onClickChains={onClickChains}
|
||||
selected={query.data?.current?.includes(item.uid)}
|
||||
maxLogLevelTriggered={maxLogLevelTriggered}
|
||||
// maxLogLevelTriggered={maxLogLevelTriggered}
|
||||
chainsSelected={chainsSelected === item.uid}
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
"@radix-ui/react-scroll-area": "1.2.3",
|
||||
"@tauri-apps/api": "2.3.0",
|
||||
"@types/d3": "7.4.3",
|
||||
"@types/react": "19.0.10",
|
||||
"@types/react": "19.0.11",
|
||||
"@vitejs/plugin-react": "4.3.4",
|
||||
"ahooks": "3.8.4",
|
||||
"d3": "7.9.0",
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
"manifest_version": 1,
|
||||
"latest": {
|
||||
"mihomo": "v1.19.3",
|
||||
"mihomo_alpha": "alpha-dee5898",
|
||||
"mihomo_alpha": "alpha-7c444a9",
|
||||
"clash_rs": "v0.7.6",
|
||||
"clash_premium": "2023-09-05-gdcc8d87",
|
||||
"clash_rs_alpha": "0.7.6-alpha+sha.47236aa"
|
||||
"clash_rs_alpha": "0.7.6-alpha+sha.3cc3aa2"
|
||||
},
|
||||
"arch_template": {
|
||||
"mihomo": {
|
||||
@@ -69,5 +69,5 @@
|
||||
"linux-armv7hf": "clash-armv7-unknown-linux-gnueabihf"
|
||||
}
|
||||
},
|
||||
"updated_at": "2025-03-16T22:20:31.758Z"
|
||||
"updated_at": "2025-03-17T22:20:57.095Z"
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
"typescript": "5.8.2",
|
||||
"typescript-eslint": "8.26.1"
|
||||
},
|
||||
"packageManager": "pnpm@10.6.3",
|
||||
"packageManager": "pnpm@10.6.4",
|
||||
"engines": {
|
||||
"node": "22.14.0"
|
||||
},
|
||||
|
||||
Generated
+214
-214
@@ -203,8 +203,8 @@ importers:
|
||||
specifier: 4.17.12
|
||||
version: 4.17.12
|
||||
'@types/react':
|
||||
specifier: 19.0.10
|
||||
version: 19.0.10
|
||||
specifier: 19.0.11
|
||||
version: 19.0.11
|
||||
|
||||
frontend/nyanpasu:
|
||||
dependencies:
|
||||
@@ -219,7 +219,7 @@ importers:
|
||||
version: 3.2.2(react@19.0.0)
|
||||
'@emotion/styled':
|
||||
specifier: 11.14.0
|
||||
version: 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
version: 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@juggle/resize-observer':
|
||||
specifier: 3.4.0
|
||||
version: 3.4.0
|
||||
@@ -228,13 +228,13 @@ importers:
|
||||
version: 0.3.0
|
||||
'@mui/icons-material':
|
||||
specifier: 6.4.7
|
||||
version: 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
version: 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/lab':
|
||||
specifier: 6.0.0-beta.30
|
||||
version: 6.0.0-beta.30(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 6.0.0-beta.30(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material':
|
||||
specifier: 6.4.7
|
||||
version: 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@nyanpasu/interface':
|
||||
specifier: workspace:^
|
||||
version: link:../interface
|
||||
@@ -246,7 +246,7 @@ importers:
|
||||
version: 4.0.14
|
||||
'@tanstack/router-zod-adapter':
|
||||
specifier: 1.81.5
|
||||
version: 1.81.5(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2)
|
||||
version: 1.81.5(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2)
|
||||
'@tauri-apps/api':
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0
|
||||
@@ -273,19 +273,19 @@ importers:
|
||||
version: 24.2.3(typescript@5.8.2)
|
||||
jotai:
|
||||
specifier: 2.12.2
|
||||
version: 2.12.2(@types/react@19.0.10)(react@19.0.0)
|
||||
version: 2.12.2(@types/react@19.0.11)(react@19.0.0)
|
||||
json-schema:
|
||||
specifier: 0.4.0
|
||||
version: 0.4.0
|
||||
material-react-table:
|
||||
specifier: 3.2.1
|
||||
version: 3.2.1(2e84544a0e977e5cbb40e088279de64c)
|
||||
version: 3.2.1(654f09cb8207d585a138693171e30e7f)
|
||||
monaco-editor:
|
||||
specifier: 0.52.2
|
||||
version: 0.52.2
|
||||
mui-color-input:
|
||||
specifier: 5.0.1
|
||||
version: 5.0.1(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 5.0.1(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
react:
|
||||
specifier: 19.0.0
|
||||
version: 19.0.0
|
||||
@@ -300,13 +300,13 @@ importers:
|
||||
version: 1.6.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
react-hook-form-mui:
|
||||
specifier: 7.5.0
|
||||
version: 7.5.0(b98e4d9419cc277791cc5997c01ae06f)
|
||||
version: 7.5.0(ea3e5f5c412ba73f5e2ef92ffc8e5c95)
|
||||
react-i18next:
|
||||
specifier: 15.4.1
|
||||
version: 15.4.1(i18next@24.2.3(typescript@5.8.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
react-markdown:
|
||||
specifier: 10.1.0
|
||||
version: 10.1.0(@types/react@19.0.10)(react@19.0.0)
|
||||
version: 10.1.0(@types/react@19.0.11)(react@19.0.0)
|
||||
react-split-grid:
|
||||
specifier: 1.0.4
|
||||
version: 1.0.4(react@19.0.0)
|
||||
@@ -331,10 +331,10 @@ importers:
|
||||
version: 11.13.5
|
||||
'@emotion/react':
|
||||
specifier: 11.14.0
|
||||
version: 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
version: 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@iconify/json':
|
||||
specifier: 2.2.317
|
||||
version: 2.2.317
|
||||
specifier: 2.2.318
|
||||
version: 2.2.318
|
||||
'@monaco-editor/react':
|
||||
specifier: 4.7.0
|
||||
version: 4.7.0(monaco-editor@0.52.2)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
@@ -342,14 +342,14 @@ importers:
|
||||
specifier: 5.68.0
|
||||
version: 5.68.0(react@19.0.0)
|
||||
'@tanstack/react-router':
|
||||
specifier: 1.114.23
|
||||
version: 1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
specifier: 1.114.24
|
||||
version: 1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/router-devtools':
|
||||
specifier: 1.114.23
|
||||
version: 1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.23)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)
|
||||
specifier: 1.114.24
|
||||
version: 1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.24)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)
|
||||
'@tanstack/router-plugin':
|
||||
specifier: 1.114.23
|
||||
version: 1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0))
|
||||
specifier: 1.114.24
|
||||
version: 1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0))
|
||||
'@tauri-apps/plugin-clipboard-manager':
|
||||
specifier: 2.2.2
|
||||
version: 2.2.2
|
||||
@@ -372,14 +372,14 @@ importers:
|
||||
specifier: 2.2.0
|
||||
version: 2.2.0
|
||||
'@tauri-apps/plugin-updater':
|
||||
specifier: 2.6.0
|
||||
version: 2.6.0
|
||||
specifier: 2.6.1
|
||||
version: 2.6.1
|
||||
'@types/react':
|
||||
specifier: 19.0.10
|
||||
version: 19.0.10
|
||||
specifier: 19.0.11
|
||||
version: 19.0.11
|
||||
'@types/react-dom':
|
||||
specifier: 19.0.4
|
||||
version: 19.0.4(@types/react@19.0.10)
|
||||
version: 19.0.4(@types/react@19.0.11)
|
||||
'@types/validator':
|
||||
specifier: 13.12.2
|
||||
version: 13.12.2
|
||||
@@ -454,19 +454,19 @@ importers:
|
||||
version: 0.3.0
|
||||
'@mui/icons-material':
|
||||
specifier: 6.4.7
|
||||
version: 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
version: 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/lab':
|
||||
specifier: 6.0.0-beta.30
|
||||
version: 6.0.0-beta.30(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 6.0.0-beta.30(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material':
|
||||
specifier: 6.4.7
|
||||
version: 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-portal':
|
||||
specifier: 1.1.4
|
||||
version: 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-scroll-area':
|
||||
specifier: 1.2.3
|
||||
version: 1.2.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
version: 1.2.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tauri-apps/api':
|
||||
specifier: 2.3.0
|
||||
version: 2.3.0
|
||||
@@ -474,8 +474,8 @@ importers:
|
||||
specifier: 7.4.3
|
||||
version: 7.4.3
|
||||
'@types/react':
|
||||
specifier: 19.0.10
|
||||
version: 19.0.10
|
||||
specifier: 19.0.11
|
||||
version: 19.0.11
|
||||
'@vitejs/plugin-react':
|
||||
specifier: 4.3.4
|
||||
version: 4.3.4(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0))
|
||||
@@ -515,7 +515,7 @@ importers:
|
||||
devDependencies:
|
||||
'@emotion/react':
|
||||
specifier: 11.14.0
|
||||
version: 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
version: 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@types/d3-interpolate-path':
|
||||
specifier: 2.0.3
|
||||
version: 2.0.3
|
||||
@@ -1674,8 +1674,8 @@ packages:
|
||||
'@vue/compiler-sfc':
|
||||
optional: true
|
||||
|
||||
'@iconify/json@2.2.317':
|
||||
resolution: {integrity: sha512-RMf7b3Wd4FMKR7roYmJ8mO6Lwm1JCzuuuVCi0aPcBvBwZkgoWSNHEOFG504L3GMz95cid5KS5Yc4Gt1TPA5bJA==}
|
||||
'@iconify/json@2.2.318':
|
||||
resolution: {integrity: sha512-8hmJxD/l322LLyQzt9s6aPCE6O+p86H9GVFhoH3hEQ9PRrU5O3Ptf8tlzFKzkBrBoEqdSzkAG5j8bwGt47Ragw==}
|
||||
|
||||
'@iconify/types@2.0.0':
|
||||
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
|
||||
@@ -2746,16 +2746,16 @@ packages:
|
||||
peerDependencies:
|
||||
react: ^18 || ^19
|
||||
|
||||
'@tanstack/react-router-devtools@1.114.23':
|
||||
resolution: {integrity: sha512-eOTlXeLlT5PfSrOrDEljTz8F7Sl3YjjI+yTGn5ern0FrFlc3GlBxJqFaKC19mT9H4ZkwETnSqDHrLZKV06ykRA==}
|
||||
'@tanstack/react-router-devtools@1.114.24':
|
||||
resolution: {integrity: sha512-sxfrcT/1QWwp/FP7U8y8AMIeRkw8uTvWguRpTfpow2zML6/U1PSKz7ShpXD7NZ2MakrD14nidq1rruC1D39kTA==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@tanstack/react-router': ^1.114.23
|
||||
'@tanstack/react-router': ^1.114.24
|
||||
react: '>=18.0.0 || >=19.0.0'
|
||||
react-dom: '>=18.0.0 || >=19.0.0'
|
||||
|
||||
'@tanstack/react-router@1.114.23':
|
||||
resolution: {integrity: sha512-L9TS8HE5nvXzCyjwlwfXwnC7pfiofbDLCSAGN7Me2jUbxHPyQpAtxRYqtByANaFVclOJgYBmZkx1m6/GVk9oiA==}
|
||||
'@tanstack/react-router@1.114.24':
|
||||
resolution: {integrity: sha512-xHrgcYi/GvwBh/lTpVpZtDFGA8f8oBSSsFagAGgSGkvz+EPTIhAML0hvwKCV1jP2HaIdU/7aJk14y4q8TT2M4Q==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
react: '>=18.0.0 || >=19.0.0'
|
||||
@@ -2780,15 +2780,15 @@ packages:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
'@tanstack/router-core@1.114.23':
|
||||
resolution: {integrity: sha512-aJkqAtVyRbdNBuoAsiy5Jmc9MYa2Gt9r1s/xlYBDfSEWoJzhMmWVoKfgBI6Ggeu3dwe6uCr/gkBRmpRkgWjg1w==}
|
||||
'@tanstack/router-core@1.114.24':
|
||||
resolution: {integrity: sha512-OmYX/oPby8CMfpm3a4xCBB9mfo6mqe2OAByz62XFD8ZcXvcDEcpHB5t2/ZrX2CCNH4gXQHUyZzl9+PxqqIpNPw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@tanstack/router-devtools-core@1.114.23':
|
||||
resolution: {integrity: sha512-PP2JFokatFdL3RANKibZPWK1L1vy4LM2chEvwyJYVUhAKg+gWPIB4aE5FnhkI/sn7N/8dzt83Xbruj+NPEPfmg==}
|
||||
'@tanstack/router-devtools-core@1.114.24':
|
||||
resolution: {integrity: sha512-xGy0SmvWqS1r/sDCdqfdRRNlhUmNSRABcX95xoAXaBsRFmd7Gn6i/TfW9waZyCFTkfLq6Hs8ixFBXo+BGOG0mg==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@tanstack/router-core': ^1.114.23
|
||||
'@tanstack/router-core': ^1.114.24
|
||||
csstype: ^3.0.10
|
||||
solid-js: '>=1.9.5'
|
||||
tiny-invariant: ^1.3.3
|
||||
@@ -2796,11 +2796,11 @@ packages:
|
||||
csstype:
|
||||
optional: true
|
||||
|
||||
'@tanstack/router-devtools@1.114.23':
|
||||
resolution: {integrity: sha512-i7F7VkA73fVvaZuPc/hsAiTlkDu/PF11Y3ERDNGL8G9NUaDEKeW8rvK0V+KTNNg8Tnm0FOHH4xohquzBXPkcuA==}
|
||||
'@tanstack/router-devtools@1.114.24':
|
||||
resolution: {integrity: sha512-+WOTp05bp33bQmqCz2hifCT3dqwUp+KabcYArSuGhNp7AoU784EvKetYAky0zb/ezrwcD3PoujI3bDCKh+cAwg==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@tanstack/react-router': ^1.114.23
|
||||
'@tanstack/react-router': ^1.114.24
|
||||
csstype: ^3.0.10
|
||||
react: '>=18.0.0 || >=19.0.0'
|
||||
react-dom: '>=18.0.0 || >=19.0.0'
|
||||
@@ -2808,21 +2808,21 @@ packages:
|
||||
csstype:
|
||||
optional: true
|
||||
|
||||
'@tanstack/router-generator@1.114.23':
|
||||
resolution: {integrity: sha512-+6YwCXXL4H6CwdWLIrO8Bmy9HZIB8p9yJGcIBGXefN3D0vOUOi7EJa2+MQgQCQgjdygP4zuutqXD/5qxEZQQNw==}
|
||||
'@tanstack/router-generator@1.114.24':
|
||||
resolution: {integrity: sha512-rKVyT9ArplwzLIGdENUxAFJdWsCrCLh9+Kts59EPv5fNvJLZX14NNcnh1hn8gq3dfRu3HmBU68NRG0d4dcw3kA==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@tanstack/react-router': ^1.114.23
|
||||
'@tanstack/react-router': ^1.114.24
|
||||
peerDependenciesMeta:
|
||||
'@tanstack/react-router':
|
||||
optional: true
|
||||
|
||||
'@tanstack/router-plugin@1.114.23':
|
||||
resolution: {integrity: sha512-4D5558eQ4So2HXnVrN5inZs4tU5nlv75VH6u95NZvVSGc+zUBryzBg7ElkhzMh+UPQoJ0RTf4NxNcKG3vw2+6w==}
|
||||
'@tanstack/router-plugin@1.114.24':
|
||||
resolution: {integrity: sha512-3RYR2gct2iR5nO0Vc+ShhS9VlUHrV2im+RuPKXGB04PdWWrRoM2EDkhjepg0CzmD5zgT2Tafp5Nysu9XyR0CGA==}
|
||||
engines: {node: '>=12'}
|
||||
peerDependencies:
|
||||
'@rsbuild/core': '>=1.0.2'
|
||||
'@tanstack/react-router': ^1.114.23
|
||||
'@tanstack/react-router': ^1.114.24
|
||||
vite: '>=5.0.0 || >=6.0.0'
|
||||
vite-plugin-solid: ^2.11.2
|
||||
webpack: '>=5.92.0'
|
||||
@@ -2958,8 +2958,8 @@ packages:
|
||||
'@tauri-apps/plugin-shell@2.2.0':
|
||||
resolution: {integrity: sha512-iC3Ic1hLmasoboG7BO+7p+AriSoqAwKrIk+Hpk+S/bjTQdXqbl2GbdclghI4gM32X0bls7xHzIFqhRdrlvJeaA==}
|
||||
|
||||
'@tauri-apps/plugin-updater@2.6.0':
|
||||
resolution: {integrity: sha512-j74RUolLIhQDQwrff6R28xIewYVXME1gFU+d+4LYN1dLRzLD+ySa7VHqzyWYxWEvm+TPZ7lkUxa5a9uH9Ist3A==}
|
||||
'@tauri-apps/plugin-updater@2.6.1':
|
||||
resolution: {integrity: sha512-iiOevw4kc12Ok99J9KthXwUqwPv1sYjG+tNEDZqPmwvOmIq7s58nKMRz6NJPKXT4U16NzMPffFcP/LUOsz6c4A==}
|
||||
|
||||
'@trivago/prettier-plugin-sort-imports@4.3.0':
|
||||
resolution: {integrity: sha512-r3n0onD3BTOVUNPhR4lhVK4/pABGpbA7bW3eumZnYdKaHkf1qEC+Mag6DPbGNuuh0eG8AaYj+YqmVHSiGslaTQ==}
|
||||
@@ -3175,8 +3175,8 @@ packages:
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
|
||||
'@types/react@19.0.10':
|
||||
resolution: {integrity: sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==}
|
||||
'@types/react@19.0.11':
|
||||
resolution: {integrity: sha512-vrdxRZfo9ALXth6yPfV16PYTLZwsUWhVjjC+DkfE5t1suNSbBrWC9YqSuuxJZ8Ps6z1o2ycRpIqzZJIgklq4Tw==}
|
||||
|
||||
'@types/responselike@1.0.3':
|
||||
resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
|
||||
@@ -9234,7 +9234,7 @@ snapshots:
|
||||
|
||||
'@emotion/memoize@0.9.0': {}
|
||||
|
||||
'@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@emotion/babel-plugin': 11.13.5
|
||||
@@ -9246,7 +9246,7 @@ snapshots:
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -9260,18 +9260,18 @@ snapshots:
|
||||
|
||||
'@emotion/sheet@1.4.0': {}
|
||||
|
||||
'@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@emotion/babel-plugin': 11.13.5
|
||||
'@emotion/is-prop-valid': 1.3.0
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/serialize': 1.3.3
|
||||
'@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@19.0.0)
|
||||
'@emotion/utils': 1.4.2
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -9453,7 +9453,7 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@iconify/json@2.2.317':
|
||||
'@iconify/json@2.2.318':
|
||||
dependencies:
|
||||
'@iconify/types': 2.0.0
|
||||
pathe: 1.1.2
|
||||
@@ -9562,56 +9562,56 @@ snapshots:
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
|
||||
'@mui/base@5.0.0-beta.69(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@mui/base@5.0.0-beta.69(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@floating-ui/react-dom': 2.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.10)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.11)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.11)(react@19.0.0)
|
||||
'@popperjs/core': 2.11.8
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/core-downloads-tracker@6.4.7': {}
|
||||
|
||||
'@mui/icons-material@6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@mui/icons-material@6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/lab@6.0.0-beta.30(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@mui/lab@6.0.0-beta.30(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@mui/base': 5.0.0-beta.69(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/system': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.10)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/base': 5.0.0-beta.69(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/system': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.11)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.11)(react@19.0.0)
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@types/react': 19.0.10
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@mui/core-downloads-tracker': 6.4.7
|
||||
'@mui/system': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.10)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/system': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.11)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.11)(react@19.0.0)
|
||||
'@popperjs/core': 2.11.8
|
||||
'@types/react-transition-group': 4.4.12(@types/react@19.0.10)
|
||||
'@types/react-transition-group': 4.4.12(@types/react@19.0.11)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
@@ -9620,29 +9620,29 @@ snapshots:
|
||||
react-is: 19.0.0
|
||||
react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@types/react': 19.0.10
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/private-theming@5.16.6(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@mui/private-theming@5.16.6(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
'@mui/utils': 5.16.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/utils': 5.16.6(@types/react@19.0.11)(react@19.0.0)
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/private-theming@6.4.6(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@mui/private-theming@6.4.6(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.11)(react@19.0.0)
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/styled-engine@5.16.6(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(react@19.0.0)':
|
||||
'@mui/styled-engine@5.16.6(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
'@emotion/cache': 11.14.0
|
||||
@@ -9650,10 +9650,10 @@ snapshots:
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
|
||||
'@mui/styled-engine@6.4.6(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(react@19.0.0)':
|
||||
'@mui/styled-engine@6.4.6(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@emotion/cache': 11.14.0
|
||||
@@ -9663,85 +9663,85 @@ snapshots:
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
|
||||
'@mui/system@5.16.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@mui/system@5.16.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
'@mui/private-theming': 5.16.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/styled-engine': 5.16.6(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.10)
|
||||
'@mui/utils': 5.16.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/private-theming': 5.16.6(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/styled-engine': 5.16.6(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.11)
|
||||
'@mui/utils': 5.16.6(@types/react@19.0.11)(react@19.0.0)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@types/react': 19.0.10
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/system@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@mui/system@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@mui/private-theming': 6.4.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/styled-engine': 6.4.6(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.10)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/private-theming': 6.4.6(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/styled-engine': 6.4.6(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(react@19.0.0)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.11)
|
||||
'@mui/utils': 6.4.6(@types/react@19.0.11)(react@19.0.0)
|
||||
clsx: 2.1.1
|
||||
csstype: 3.1.3
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@types/react': 19.0.10
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/types@7.2.21(@types/react@19.0.10)':
|
||||
'@mui/types@7.2.21(@types/react@19.0.11)':
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/utils@5.16.6(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@mui/utils@5.16.6(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
'@mui/types': 7.2.21(@types/react@19.0.10)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.11)
|
||||
'@types/prop-types': 15.7.14
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
react-is: 18.3.1
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/utils@6.4.6(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@mui/utils@6.4.6(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.0
|
||||
'@mui/types': 7.2.21(@types/react@19.0.10)
|
||||
'@mui/types': 7.2.21(@types/react@19.0.11)
|
||||
'@types/prop-types': 15.7.14
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
react-is: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@mui/x-date-pickers@7.9.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@mui/x-date-pickers@7.9.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@babel/runtime': 7.26.10
|
||||
'@mui/base': 5.0.0-beta.69(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/system': 5.16.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/utils': 5.16.6(@types/react@19.0.10)(react@19.0.0)
|
||||
'@types/react-transition-group': 4.4.12(@types/react@19.0.10)
|
||||
'@mui/base': 5.0.0-beta.69(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/system': 5.16.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/utils': 5.16.6(@types/react@19.0.11)(react@19.0.0)
|
||||
'@types/react-transition-group': 4.4.12(@types/react@19.0.11)
|
||||
clsx: 2.1.1
|
||||
prop-types: 15.8.1
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
dayjs: 1.11.13
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
@@ -10039,88 +10039,88 @@ snapshots:
|
||||
|
||||
'@radix-ui/primitive@1.1.1': {}
|
||||
|
||||
'@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@radix-ui/react-compose-refs@1.1.1(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@radix-ui/react-context@1.1.1(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@radix-ui/react-context@1.1.1(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@radix-ui/react-direction@1.1.0(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@radix-ui/react-direction@1.1.0(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@radix-ui/react-portal@1.1.4(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@radix-ui/react-portal@1.1.4(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.11)(react@19.0.0)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.10)
|
||||
'@types/react': 19.0.11
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.11)
|
||||
|
||||
'@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@radix-ui/react-presence@1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.11)(react@19.0.0)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.10)
|
||||
'@types/react': 19.0.11
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.11)
|
||||
|
||||
'@radix-ui/react-primitive@2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@radix-ui/react-primitive@2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-slot': 1.1.2(@types/react@19.0.11)(react@19.0.0)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.10)
|
||||
'@types/react': 19.0.11
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.11)
|
||||
|
||||
'@radix-ui/react-scroll-area@1.2.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@radix-ui/react-scroll-area@1.2.3(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@radix-ui/number': 1.1.0
|
||||
'@radix-ui/primitive': 1.1.1
|
||||
'@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-context': 1.1.1(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-direction': 1.1.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
|
||||
'@radix-ui/react-context': 1.1.1(@types/react@19.0.11)(react@19.0.0)
|
||||
'@radix-ui/react-direction': 1.1.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@radix-ui/react-presence': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-primitive': 2.0.2(@types/react-dom@19.0.4(@types/react@19.0.11))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@radix-ui/react-use-callback-ref': 1.1.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@radix-ui/react-use-layout-effect': 1.1.0(@types/react@19.0.11)(react@19.0.0)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.10)
|
||||
'@types/react': 19.0.11
|
||||
'@types/react-dom': 19.0.4(@types/react@19.0.11)
|
||||
|
||||
'@radix-ui/react-slot@1.1.2(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@radix-ui/react-slot@1.1.2(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
'@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.10)(react@19.0.0)
|
||||
'@radix-ui/react-compose-refs': 1.1.1(@types/react@19.0.11)(react@19.0.0)
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@radix-ui/react-use-callback-ref@1.1.0(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.10)(react@19.0.0)':
|
||||
'@radix-ui/react-use-layout-effect@1.1.0(@types/react@19.0.11)(react@19.0.0)':
|
||||
dependencies:
|
||||
react: 19.0.0
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@rollup/pluginutils@4.2.1':
|
||||
dependencies:
|
||||
@@ -10492,10 +10492,10 @@ snapshots:
|
||||
'@tanstack/query-core': 5.68.0
|
||||
react: 19.0.0
|
||||
|
||||
'@tanstack/react-router-devtools@1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.23)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)':
|
||||
'@tanstack/react-router-devtools@1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.24)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/router-devtools-core': 1.114.23(@tanstack/router-core@1.114.23)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)
|
||||
'@tanstack/react-router': 1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/router-devtools-core': 1.114.24(@tanstack/router-core@1.114.24)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
solid-js: 1.9.5
|
||||
@@ -10504,11 +10504,11 @@ snapshots:
|
||||
- csstype
|
||||
- tiny-invariant
|
||||
|
||||
'@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
'@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.114.22
|
||||
'@tanstack/react-store': 0.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/router-core': 1.114.23
|
||||
'@tanstack/router-core': 1.114.24
|
||||
jsesc: 3.1.0
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
@@ -10534,14 +10534,14 @@ snapshots:
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
|
||||
'@tanstack/router-core@1.114.23':
|
||||
'@tanstack/router-core@1.114.24':
|
||||
dependencies:
|
||||
'@tanstack/history': 1.114.22
|
||||
'@tanstack/store': 0.7.0
|
||||
|
||||
'@tanstack/router-devtools-core@1.114.23(@tanstack/router-core@1.114.23)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)':
|
||||
'@tanstack/router-devtools-core@1.114.24(@tanstack/router-core@1.114.24)(csstype@3.1.3)(solid-js@1.9.5)(tiny-invariant@1.3.3)':
|
||||
dependencies:
|
||||
'@tanstack/router-core': 1.114.23
|
||||
'@tanstack/router-core': 1.114.24
|
||||
clsx: 2.1.1
|
||||
goober: 2.1.16(csstype@3.1.3)
|
||||
solid-js: 1.9.5
|
||||
@@ -10549,10 +10549,10 @@ snapshots:
|
||||
optionalDependencies:
|
||||
csstype: 3.1.3
|
||||
|
||||
'@tanstack/router-devtools@1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.23)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)':
|
||||
'@tanstack/router-devtools@1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.24)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/react-router-devtools': 1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.23)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)
|
||||
'@tanstack/react-router': 1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/react-router-devtools': 1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@tanstack/router-core@1.114.24)(csstype@3.1.3)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(tiny-invariant@1.3.3)
|
||||
clsx: 2.1.1
|
||||
goober: 2.1.16(csstype@3.1.3)
|
||||
react: 19.0.0
|
||||
@@ -10563,16 +10563,16 @@ snapshots:
|
||||
- '@tanstack/router-core'
|
||||
- tiny-invariant
|
||||
|
||||
'@tanstack/router-generator@1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))':
|
||||
'@tanstack/router-generator@1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))':
|
||||
dependencies:
|
||||
'@tanstack/virtual-file-routes': 1.114.12
|
||||
prettier: 3.5.3
|
||||
tsx: 4.19.3
|
||||
zod: 3.24.2
|
||||
optionalDependencies:
|
||||
'@tanstack/react-router': 1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/react-router': 1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
|
||||
'@tanstack/router-plugin@1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0))':
|
||||
'@tanstack/router-plugin@1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(vite@6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0))':
|
||||
dependencies:
|
||||
'@babel/core': 7.26.9
|
||||
'@babel/plugin-syntax-jsx': 7.25.9(@babel/core@7.26.9)
|
||||
@@ -10580,8 +10580,8 @@ snapshots:
|
||||
'@babel/template': 7.26.9
|
||||
'@babel/traverse': 7.26.9
|
||||
'@babel/types': 7.26.9
|
||||
'@tanstack/router-core': 1.114.23
|
||||
'@tanstack/router-generator': 1.114.23(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))
|
||||
'@tanstack/router-core': 1.114.24
|
||||
'@tanstack/router-generator': 1.114.24(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))
|
||||
'@tanstack/router-utils': 1.114.12
|
||||
'@tanstack/virtual-file-routes': 1.114.12
|
||||
'@types/babel__core': 7.20.5
|
||||
@@ -10592,7 +10592,7 @@ snapshots:
|
||||
unplugin: 2.2.0
|
||||
zod: 3.24.2
|
||||
optionalDependencies:
|
||||
'@tanstack/react-router': 1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/react-router': 1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
vite: 6.2.2(@types/node@22.13.10)(jiti@2.4.2)(less@4.2.0)(lightningcss@1.29.2)(sass-embedded@1.85.1)(sass@1.83.0)(stylus@0.62.0)(terser@5.36.0)(tsx@4.19.3)(yaml@2.7.0)
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
@@ -10604,9 +10604,9 @@ snapshots:
|
||||
ansis: 3.12.0
|
||||
diff: 7.0.0
|
||||
|
||||
'@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2)':
|
||||
'@tanstack/router-zod-adapter@1.81.5(@tanstack/react-router@1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(zod@3.24.2)':
|
||||
dependencies:
|
||||
'@tanstack/react-router': 1.114.23(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/react-router': 1.114.24(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
zod: 3.24.2
|
||||
|
||||
'@tanstack/store@0.7.0': {}
|
||||
@@ -10696,7 +10696,7 @@ snapshots:
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.3.0
|
||||
|
||||
'@tauri-apps/plugin-updater@2.6.0':
|
||||
'@tauri-apps/plugin-updater@2.6.1':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.3.0
|
||||
|
||||
@@ -10945,15 +10945,15 @@ snapshots:
|
||||
|
||||
'@types/prop-types@15.7.14': {}
|
||||
|
||||
'@types/react-dom@19.0.4(@types/react@19.0.10)':
|
||||
'@types/react-dom@19.0.4(@types/react@19.0.11)':
|
||||
dependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@types/react-transition-group@4.4.12(@types/react@19.0.10)':
|
||||
'@types/react-transition-group@4.4.12(@types/react@19.0.11)':
|
||||
dependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
'@types/react@19.0.10':
|
||||
'@types/react@19.0.11':
|
||||
dependencies:
|
||||
csstype: 3.1.3
|
||||
|
||||
@@ -13664,9 +13664,9 @@ snapshots:
|
||||
|
||||
jju@1.4.0: {}
|
||||
|
||||
jotai@2.12.2(@types/react@19.0.10)(react@19.0.0):
|
||||
jotai@2.12.2(@types/react@19.0.11)(react@19.0.0):
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
react: 19.0.0
|
||||
|
||||
js-cookie@2.2.1: {}
|
||||
@@ -13966,13 +13966,13 @@ snapshots:
|
||||
escape-string-regexp: 4.0.0
|
||||
optional: true
|
||||
|
||||
material-react-table@3.2.1(2e84544a0e977e5cbb40e088279de64c):
|
||||
material-react-table@3.2.1(654f09cb8207d585a138693171e30e7f):
|
||||
dependencies:
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/icons-material': 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/icons-material': 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/match-sorter-utils': 8.19.4
|
||||
'@tanstack/react-table': 8.20.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@tanstack/react-virtual': 3.11.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
@@ -14323,16 +14323,16 @@ snapshots:
|
||||
|
||||
muggle-string@0.4.1: {}
|
||||
|
||||
mui-color-input@5.0.1(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||
mui-color-input@5.0.1(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||
dependencies:
|
||||
'@ctrl/tinycolor': 4.1.0
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.10)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@emotion/react': 11.14.0(@types/react@19.0.11)(react@19.0.0)
|
||||
'@emotion/styled': 11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
|
||||
nano-css@5.6.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
|
||||
dependencies:
|
||||
@@ -14888,14 +14888,14 @@ snapshots:
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
|
||||
react-hook-form-mui@7.5.0(b98e4d9419cc277791cc5997c01ae06f):
|
||||
react-hook-form-mui@7.5.0(ea3e5f5c412ba73f5e2ef92ffc8e5c95):
|
||||
dependencies:
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/material': 6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
react: 19.0.0
|
||||
react-hook-form: 7.52.1(react@19.0.0)
|
||||
optionalDependencies:
|
||||
'@mui/icons-material': 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(react@19.0.0)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.10)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
'@mui/icons-material': 6.4.7(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(react@19.0.0)
|
||||
'@mui/x-date-pickers': 7.9.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@mui/material@6.4.7(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@emotion/styled@11.14.0(@emotion/react@11.14.0(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react@19.0.0))(@types/react@19.0.11)(react-dom@19.0.0(react@19.0.0))(react@19.0.0))(@types/react@19.0.11)(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
|
||||
|
||||
react-hook-form@7.52.1(react@19.0.0):
|
||||
dependencies:
|
||||
@@ -14916,11 +14916,11 @@ snapshots:
|
||||
|
||||
react-is@19.0.0: {}
|
||||
|
||||
react-markdown@10.1.0(@types/react@19.0.10)(react@19.0.0):
|
||||
react-markdown@10.1.0(@types/react@19.0.11)(react@19.0.0):
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
'@types/mdast': 4.0.3
|
||||
'@types/react': 19.0.10
|
||||
'@types/react': 19.0.11
|
||||
devlop: 1.1.0
|
||||
hast-util-to-jsx-runtime: 2.3.0
|
||||
html-url-attributes: 3.0.0
|
||||
|
||||
-8
@@ -269,9 +269,6 @@ jobs:
|
||||
- name: Checkout Repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install Rust Stable
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
|
||||
- name: Add Rust Target
|
||||
run: rustup target add ${{ matrix.target }}
|
||||
|
||||
@@ -313,11 +310,6 @@ jobs:
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
|
||||
with:
|
||||
tagName: alpha
|
||||
releaseName: "Clash Verge Rev Alpha"
|
||||
releaseBody: "More new features are now supported."
|
||||
releaseDraft: false
|
||||
prerelease: true
|
||||
tauriScript: pnpm
|
||||
args: --target ${{ matrix.target }}
|
||||
|
||||
|
||||
@@ -4,13 +4,21 @@ use crate::module::mihomo::MihomoManager;
|
||||
#[tauri::command]
|
||||
pub async fn get_proxies() -> CmdResult<serde_json::Value> {
|
||||
let mannager = MihomoManager::global();
|
||||
mannager.refresh_proxies().await.unwrap();
|
||||
Ok(mannager.get_proxies())
|
||||
let proxies = mannager
|
||||
.refresh_proxies()
|
||||
.await
|
||||
.map(|_| mannager.get_proxies())
|
||||
.or_else(|_| Ok(mannager.get_proxies()));
|
||||
proxies
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub async fn get_providers_proxies() -> CmdResult<serde_json::Value> {
|
||||
let mannager = MihomoManager::global();
|
||||
mannager.refresh_providers_proxies().await.unwrap();
|
||||
Ok(mannager.get_providers_proxies())
|
||||
let providers = mannager
|
||||
.refresh_providers_proxies()
|
||||
.await
|
||||
.map(|_| mannager.get_providers_proxies())
|
||||
.or_else(|_| Ok(mannager.get_providers_proxies()));
|
||||
providers
|
||||
}
|
||||
|
||||
@@ -41,6 +41,18 @@ impl Handle {
|
||||
window
|
||||
}
|
||||
|
||||
pub fn destroy_window(&self) -> Result<(), String> {
|
||||
if let Some(window) = self.get_window() {
|
||||
log_err!(window.close());
|
||||
}
|
||||
if let Some(window) = Self::global().get_window() {
|
||||
if let Some(webview) = window.get_webview_window("main") {
|
||||
log_err!(webview.destroy());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn refresh_clash() {
|
||||
if let Some(window) = Self::global().get_window() {
|
||||
log_err!(window.emit("verge://refresh-clash-config", "yes"));
|
||||
|
||||
@@ -194,18 +194,11 @@ pub async fn patch_verge(patch: IVerge, not_save_file: bool) -> Result<()> {
|
||||
}
|
||||
|
||||
// Handle lite mode switch
|
||||
if lite_mode.is_some() {
|
||||
if let Some(window) = handle::Handle::global().get_window() {
|
||||
if lite_mode.unwrap() {
|
||||
// 完全退出 webview 进程
|
||||
window.close()?; // 先关闭窗口
|
||||
let app_handle = handle::Handle::global().app_handle().unwrap();
|
||||
if let Some(webview) = app_handle.get_webview_window("main") {
|
||||
webview.destroy()?; // 销毁 webview 进程
|
||||
}
|
||||
} else {
|
||||
resolve::create_window(); // 重新创建窗口
|
||||
}
|
||||
if let Some(enable) = lite_mode {
|
||||
if enable {
|
||||
handle::Handle::global().destroy_window().ok();
|
||||
} else {
|
||||
resolve::create_window();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,9 +11,12 @@ use crate::{
|
||||
};
|
||||
use config::Config;
|
||||
use std::sync::{Mutex, Once};
|
||||
use tauri::AppHandle;
|
||||
#[cfg(target_os = "macos")]
|
||||
use tauri::Manager;
|
||||
use tauri::{
|
||||
menu::{Menu, MenuItem, Submenu},
|
||||
AppHandle,
|
||||
};
|
||||
use tauri_plugin_autostart::MacosLauncher;
|
||||
use tauri_plugin_deep_link::DeepLinkExt;
|
||||
|
||||
@@ -99,7 +102,6 @@ pub fn run() {
|
||||
|
||||
#[cfg(debug_assertions)]
|
||||
let devtools = tauri_plugin_devtools::init();
|
||||
|
||||
#[allow(unused_mut)]
|
||||
let mut builder = tauri::Builder::default()
|
||||
.plugin(tauri_plugin_autostart::init(
|
||||
@@ -220,6 +222,23 @@ pub fn run() {
|
||||
builder = builder.plugin(devtools);
|
||||
}
|
||||
|
||||
// Macos Application Menu
|
||||
#[cfg(target_os = "macos")]
|
||||
{
|
||||
builder = builder.menu(|handle| {
|
||||
Menu::with_items(
|
||||
handle,
|
||||
&[&Submenu::with_items(
|
||||
handle,
|
||||
"Menu",
|
||||
true,
|
||||
&[&MenuItem::new(handle, "Clash Verge", true, None::<String>).unwrap()],
|
||||
)
|
||||
.unwrap()],
|
||||
)
|
||||
});
|
||||
}
|
||||
|
||||
let app = builder
|
||||
.build(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
@@ -30,11 +30,5 @@
|
||||
],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"trayIcon": {
|
||||
"iconPath": "icons/tray-icon.ico",
|
||||
"iconAsTemplate": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,5 @@
|
||||
],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"trayIcon": {
|
||||
"iconPath": "icons/tray-icon.ico",
|
||||
"iconAsTemplate": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,11 +30,5 @@
|
||||
],
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEQyOEMyRjBCQkVGOUJEREYKUldUZnZmbStDeStNMHU5Mmo1N24xQXZwSVRYbXA2NUpzZE5oVzlqeS9Bc0t6RVV4MmtwVjBZaHgK"
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"trayIcon": {
|
||||
"iconPath": "icons/tray-icon.ico",
|
||||
"iconAsTemplate": true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 48 KiB |
@@ -0,0 +1,10 @@
|
||||
<svg width="36" height="36" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect width="36" height="36" rx="18" fill="url(#paint0_linear_3004_316)"/>
|
||||
<path d="M23 14.6666H22.1667V13C22.1667 10.7 20.3 8.83331 18 8.83331C15.7 8.83331 13.8334 10.7 13.8334 13H15.5C15.5 11.6166 16.6167 10.5 18 10.5C19.3834 10.5 20.5 11.6166 20.5 13V14.6666H13C12.0834 14.6666 11.3334 15.4166 11.3334 16.3333V24.6666C11.3334 25.5833 12.0834 26.3333 13 26.3333H23C23.9167 26.3333 24.6667 25.5833 24.6667 24.6666V16.3333C24.6667 15.4166 23.9167 14.6666 23 14.6666ZM23 24.6666H13V16.3333H23V24.6666ZM18 22.1666C18.9167 22.1666 19.6667 21.4166 19.6667 20.5C19.6667 19.5833 18.9167 18.8333 18 18.8333C17.0834 18.8333 16.3334 19.5833 16.3334 20.5C16.3334 21.4166 17.0834 22.1666 18 22.1666Z" fill="white"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_3004_316" x1="31" y1="27.5" x2="6.5" y2="7" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#FFA800"/>
|
||||
<stop offset="1" stop-color="#FFAC4B"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1020 B |
@@ -182,22 +182,13 @@ export const EnhancedTrafficStats = () => {
|
||||
|
||||
try {
|
||||
const connections = await getConnections();
|
||||
if (connections && connections.connections) {
|
||||
const uploadTotal = connections.connections.reduce(
|
||||
(sum, conn) => sum + conn.upload,
|
||||
0,
|
||||
);
|
||||
const downloadTotal = connections.connections.reduce(
|
||||
(sum, conn) => sum + conn.download,
|
||||
0,
|
||||
);
|
||||
|
||||
if (connections) {
|
||||
setStats(prev => ({
|
||||
...prev,
|
||||
connections: {
|
||||
uploadTotal,
|
||||
downloadTotal,
|
||||
activeConnections: connections.connections.length,
|
||||
uploadTotal: connections.uploadTotal || 0,
|
||||
downloadTotal: connections.downloadTotal || 0,
|
||||
activeConnections: connections.connections ? connections.connections.length : 0,
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -8,11 +8,13 @@ import HomePage from "./home";
|
||||
import UnlockPage from "./unlock";
|
||||
import { BaseErrorBoundary } from "@/components/base";
|
||||
|
||||
import HomeSvg from "@/assets/image/itemicon/home.svg?react";
|
||||
import ProxiesSvg from "@/assets/image/itemicon/proxies.svg?react";
|
||||
import ProfilesSvg from "@/assets/image/itemicon/profiles.svg?react";
|
||||
import ConnectionsSvg from "@/assets/image/itemicon/connections.svg?react";
|
||||
import RulesSvg from "@/assets/image/itemicon/rules.svg?react";
|
||||
import LogsSvg from "@/assets/image/itemicon/logs.svg?react";
|
||||
import UnlockSvg from "@/assets/image/itemicon/unlock.svg?react";
|
||||
import SettingsSvg from "@/assets/image/itemicon/settings.svg?react";
|
||||
|
||||
import WifiRoundedIcon from "@mui/icons-material/WifiRounded";
|
||||
@@ -20,7 +22,6 @@ import DnsRoundedIcon from "@mui/icons-material/DnsRounded";
|
||||
import LanguageRoundedIcon from "@mui/icons-material/LanguageRounded";
|
||||
import ForkRightRoundedIcon from "@mui/icons-material/ForkRightRounded";
|
||||
import SubjectRoundedIcon from "@mui/icons-material/SubjectRounded";
|
||||
import WifiTetheringRoundedIcon from "@mui/icons-material/WifiTetheringRounded";
|
||||
import SettingsRoundedIcon from "@mui/icons-material/SettingsRounded";
|
||||
import HomeRoundedIcon from "@mui/icons-material/HomeRounded";
|
||||
import LockOpenRoundedIcon from "@mui/icons-material/LockOpenRounded";
|
||||
@@ -29,7 +30,7 @@ export const routers = [
|
||||
{
|
||||
label: "Label-Home",
|
||||
path: "/home",
|
||||
icon: [<HomeRoundedIcon />],
|
||||
icon: [<HomeRoundedIcon />, <HomeSvg />],
|
||||
element: <HomePage />,
|
||||
},
|
||||
{
|
||||
@@ -65,7 +66,7 @@ export const routers = [
|
||||
{
|
||||
label: "Label-Unlock",
|
||||
path: "/unlock",
|
||||
icon: [<LockOpenRoundedIcon />],
|
||||
icon: [<LockOpenRoundedIcon />, <UnlockSvg />],
|
||||
element: <UnlockPage />,
|
||||
},
|
||||
{
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
DnsOutlined,
|
||||
SpeedOutlined,
|
||||
HelpOutlineRounded,
|
||||
HistoryEduOutlined,
|
||||
} from "@mui/icons-material";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { ProxyTunCard } from "@/components/home/proxy-tun-card";
|
||||
@@ -36,7 +37,7 @@ import { BasePage } from "@/components/base";
|
||||
import { ClashInfoCard } from "@/components/home/clash-info-card";
|
||||
import { SystemInfoCard } from "@/components/home/system-info-card";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { openWebUrl } from "@/services/cmds";
|
||||
import { openWebUrl, patchVergeConfig } from "@/services/cmds";
|
||||
import { TestCard } from "@/components/home/test-card";
|
||||
import { IpInfoCard } from "@/components/home/ip-info-card";
|
||||
|
||||
@@ -258,6 +259,11 @@ const HomePage = () => {
|
||||
contentStyle={{ padding: 2 }}
|
||||
header={
|
||||
<Box sx={{ display: "flex", alignItems: "center" }}>
|
||||
<Tooltip title={t("Lite Mode")} arrow>
|
||||
<IconButton onClick={() => patchVergeConfig({ enable_lite_mode: true })} size="small" color="inherit">
|
||||
<HistoryEduOutlined />
|
||||
</IconButton>
|
||||
</Tooltip>
|
||||
<Tooltip title={t("Manual")} arrow>
|
||||
<IconButton onClick={toGithubDoc} size="small" color="inherit">
|
||||
<HelpOutlineRounded />
|
||||
@@ -275,9 +281,9 @@ const HomePage = () => {
|
||||
{/* 订阅和当前节点部分 */}
|
||||
{homeCards.profile && (
|
||||
<Grid size={6}>
|
||||
<HomeProfileCard
|
||||
current={current}
|
||||
onProfileUpdated={mutateProfiles}
|
||||
<HomeProfileCard
|
||||
current={current}
|
||||
onProfileUpdated={mutateProfiles}
|
||||
/>
|
||||
</Grid>
|
||||
)}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
|
||||
/dts-v1/;
|
||||
#include "mt7981b-cmcc-a10.dts"
|
||||
|
||||
/ {
|
||||
model = "CMCC A10 (U-Boot mod)";
|
||||
compatible = "cmcc,a10-mod", "mediatek,mt7981";
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
spi_nand@0 {
|
||||
partitions {
|
||||
partition@580000 {
|
||||
label = "ubi";
|
||||
reg = <0x0580000 0x6000000>;
|
||||
};
|
||||
|
||||
/delete-node/ partition@4580000;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,260 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
|
||||
/dts-v1/;
|
||||
#include <dt-bindings/gpio/gpio.h>
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
#include "mt7981.dtsi"
|
||||
|
||||
/ {
|
||||
model = "CMCC A10";
|
||||
compatible = "cmcc,a10", "mediatek,mt7981";
|
||||
|
||||
aliases {
|
||||
serial0 = &uart0;
|
||||
label-mac-device = &gmac0;
|
||||
|
||||
led-boot = &led_status_red;
|
||||
led-failsafe = &led_status_red;
|
||||
led-running = &led_status_blue;
|
||||
led-upgrade = &led_status_green;
|
||||
};
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0:115200n8";
|
||||
};
|
||||
|
||||
memory {
|
||||
reg = <0 0x40000000 0 0x10000000>;
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
reset {
|
||||
label = "reset";
|
||||
linux,code = <KEY_RESTART>;
|
||||
gpios = <&pio 1 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
wps {
|
||||
label = "wps";
|
||||
linux,code = <KEY_WPS_BUTTON>;
|
||||
gpios = <&pio 0 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
|
||||
leds {
|
||||
compatible = "gpio-leds";
|
||||
|
||||
led_status_blue: blue {
|
||||
label = "blue:status";
|
||||
gpios = <&pio 9 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_status_green: green {
|
||||
label = "green:status";
|
||||
gpios = <&pio 10 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
|
||||
led_status_red: red {
|
||||
label = "red:status";
|
||||
gpios = <&pio 11 GPIO_ACTIVE_LOW>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
ð {
|
||||
status = "okay";
|
||||
|
||||
gmac0: mac@0 {
|
||||
compatible = "mediatek,eth-mac";
|
||||
reg = <0>;
|
||||
phy-mode = "2500base-x";
|
||||
|
||||
nvmem-cells = <&macaddr_factory_2a>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&mdio_bus {
|
||||
switch: switch@0 {
|
||||
compatible = "mediatek,mt7531";
|
||||
reg = <31>;
|
||||
reset-gpios = <&pio 39 GPIO_ACTIVE_HIGH>;
|
||||
interrupt-controller;
|
||||
#interrupt-cells = <1>;
|
||||
interrupt-parent = <&pio>;
|
||||
interrupts = <38 IRQ_TYPE_LEVEL_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
&spi0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&spi0_flash_pins>;
|
||||
status = "okay";
|
||||
|
||||
spi_nand@0 {
|
||||
compatible = "spi-nand";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
reg = <0>;
|
||||
|
||||
spi-max-frequency = <52000000>;
|
||||
spi-tx-bus-width = <4>;
|
||||
spi-rx-bus-width = <4>;
|
||||
|
||||
mediatek,nmbm;
|
||||
mediatek,bmt-max-ratio = <1>;
|
||||
mediatek,bmt-max-reserved-blocks = <64>;
|
||||
|
||||
partitions {
|
||||
compatible = "fixed-partitions";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
partition@0 {
|
||||
label = "BL2";
|
||||
reg = <0x0000000 0x0100000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@100000 {
|
||||
label = "u-boot-env";
|
||||
reg = <0x0100000 0x0080000>;
|
||||
};
|
||||
|
||||
factory: partition@180000 {
|
||||
label = "Factory";
|
||||
reg = <0x0180000 0x0200000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@380000 {
|
||||
label = "FIP";
|
||||
reg = <0x0380000 0x0200000>;
|
||||
read-only;
|
||||
};
|
||||
|
||||
partition@580000 {
|
||||
label = "ubi";
|
||||
reg = <0x0580000 0x4000000>;
|
||||
};
|
||||
|
||||
partition@4580000 {
|
||||
label = "backup";
|
||||
reg = <0x4580000 0x2000000>;
|
||||
};
|
||||
|
||||
partition@6580000 {
|
||||
label = "zrsave";
|
||||
reg = <0x6580000 0x0100000>;
|
||||
};
|
||||
|
||||
partition@6680000 {
|
||||
label = "config2";
|
||||
reg = <0x6680000 0x0100000>;
|
||||
read-only;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&switch {
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
reg = <0>;
|
||||
label = "lan1";
|
||||
};
|
||||
|
||||
port@2 {
|
||||
reg = <2>;
|
||||
label = "lan2";
|
||||
};
|
||||
|
||||
port@3 {
|
||||
reg = <3>;
|
||||
label = "lan3";
|
||||
};
|
||||
|
||||
port@4 {
|
||||
reg = <4>;
|
||||
label = "wan";
|
||||
nvmem-cells = <&macaddr_factory_24>;
|
||||
nvmem-cell-names = "mac-address";
|
||||
};
|
||||
|
||||
port@6 {
|
||||
reg = <6>;
|
||||
label = "cpu";
|
||||
ethernet = <&gmac0>;
|
||||
phy-mode = "2500base-x";
|
||||
|
||||
fixed-link {
|
||||
speed = <2500>;
|
||||
full-duplex;
|
||||
pause;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&pio {
|
||||
spi0_flash_pins: spi0-pins {
|
||||
mux {
|
||||
function = "spi";
|
||||
groups = "spi0", "spi0_wp_hold";
|
||||
};
|
||||
|
||||
conf-pu {
|
||||
pins = "SPI0_CS", "SPI0_HOLD", "SPI0_WP";
|
||||
drive-strength = <8>;
|
||||
mediatek,pull-up-adv = <0>; /* bias-disable */
|
||||
};
|
||||
|
||||
conf-pd {
|
||||
pins = "SPI0_CLK", "SPI0_MOSI", "SPI0_MISO";
|
||||
drive-strength = <8>;
|
||||
mediatek,pull-up-adv = <0>; /* bias-disable */
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
&uart0 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&watchdog {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&wifi {
|
||||
status = "okay";
|
||||
|
||||
mediatek,mtd-eeprom = <&factory 0x0>;
|
||||
};
|
||||
|
||||
&factory {
|
||||
nvmem-layout {
|
||||
compatible = "fixed-layout";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
macaddr_factory_24: macaddr@24 {
|
||||
reg = <0x24 0x6>;
|
||||
};
|
||||
|
||||
macaddr_factory_2a: macaddr@2a {
|
||||
reg = <0x2a 0x6>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -42,6 +42,7 @@ mediatek_setup_interfaces()
|
||||
ucidef_set_interfaces_lan_wan "lan1 lan2 lan3 eth1" "wan eth2"
|
||||
;;
|
||||
cetron,ct3003*|\
|
||||
cmcc,a10*|\
|
||||
fzs,5gcpe-p3|\
|
||||
jcg,q30-pro|\
|
||||
qihoo,360t7|\
|
||||
|
||||
@@ -282,6 +282,35 @@ define Device/cetron_ct3003-mod
|
||||
endef
|
||||
TARGET_DEVICES += cetron_ct3003-mod
|
||||
|
||||
define Device/cmcc_a10
|
||||
DEVICE_VENDOR := CMCC
|
||||
DEVICE_MODEL := A10
|
||||
DEVICE_DTS := mt7981b-cmcc-a10
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
UBINIZE_OPTS := -E 5
|
||||
BLOCKSIZE := 128k
|
||||
PAGESIZE := 2048
|
||||
KERNEL_IN_UBI := 1
|
||||
SUPPORTED_DEVICES += mediatek,mt7981-spim-snand-rfb
|
||||
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
|
||||
DEVICE_PACKAGES := kmod-mt7981-firmware mt7981-wo-firmware
|
||||
endef
|
||||
TARGET_DEVICES += cmcc_a10
|
||||
|
||||
define Device/cmcc_a10-mod
|
||||
DEVICE_VENDOR := CMCC
|
||||
DEVICE_MODEL := A10 (U-Boot mod)
|
||||
DEVICE_DTS := mt7981b-cmcc-a10-mod
|
||||
DEVICE_DTS_DIR := ../dts
|
||||
UBINIZE_OPTS := -E 5
|
||||
BLOCKSIZE := 128k
|
||||
PAGESIZE := 2048
|
||||
KERNEL_IN_UBI := 1
|
||||
IMAGE/sysupgrade.bin := sysupgrade-tar | append-metadata
|
||||
DEVICE_PACKAGES := kmod-mt7981-firmware mt7981-wo-firmware
|
||||
endef
|
||||
TARGET_DEVICES += cmcc_a10-mod
|
||||
|
||||
define Device/cmcc_rax3000m-emmc
|
||||
DEVICE_VENDOR := CMCC
|
||||
DEVICE_MODEL := RAX3000M (eMMC version)
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Safonov <andrey.safonov@gmail.com>
|
||||
Date: Sat, 16 Dec 2023 22:46:35 +0300
|
||||
Subject: rk3399 PCIE PHY reset on probe
|
||||
|
||||
This patches the PCIE initialization error after warm reboot.
|
||||
The root of cause is, when the device is booted after power on,
|
||||
PHY stays in 'factory' state. After warm boot PHY stays in the
|
||||
previous state and prevents any training, thus PCIE init fails.
|
||||
|
||||
Signed-off-by: Andrey Safonov <andrey.safonov@gmail.com>
|
||||
---
|
||||
drivers/phy/rockchip/phy-rockchip-pcie.c | 16 ++++++++++++++++
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
|
||||
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
|
||||
@@ -344,6 +344,20 @@ static const struct of_device_id rockchi
|
||||
|
||||
MODULE_DEVICE_TABLE(of, rockchip_pcie_phy_dt_ids);
|
||||
|
||||
+static void rockchip_pcie_phy_reset(struct rockchip_pcie_phy *rk_phy)
|
||||
+{
|
||||
+ int i;
|
||||
+
|
||||
+ for (i = 0; i < PHY_MAX_LANE_NUM; i++)
|
||||
+ regmap_write(rk_phy->reg_base,
|
||||
+ rk_phy->phy_data->pcie_laneoff,
|
||||
+ HIWORD_UPDATE(PHY_LANE_IDLE_OFF,
|
||||
+ PHY_LANE_IDLE_MASK,
|
||||
+ PHY_LANE_IDLE_A_SHIFT + i));
|
||||
+
|
||||
+ reset_control_assert(rk_phy->phy_rst);
|
||||
+}
|
||||
+
|
||||
static int rockchip_pcie_phy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
@@ -393,6 +407,8 @@ static int rockchip_pcie_phy_probe(struc
|
||||
|
||||
phy_num = (phy_num == 0) ? 1 : PHY_MAX_LANE_NUM;
|
||||
dev_dbg(dev, "phy number is %d\n", phy_num);
|
||||
+
|
||||
+ rockchip_pcie_phy_reset(rk_phy);
|
||||
|
||||
for (i = 0; i < phy_num; i++) {
|
||||
rk_phy->phys[i].phy = devm_phy_create(dev, dev->of_node, &ops);
|
||||
@@ -0,0 +1,44 @@
|
||||
From 77f6dfcb20c2dc6a4a2f5303709c6fa0c7b65f30 Mon Sep 17 00:00:00 2001
|
||||
From: Valmantas Paliksa <walmis@gmail.com>
|
||||
Date: Thu, 12 Dec 2024 12:24:33 +0200
|
||||
Subject: [PATCH] Disable PHY_LANE_IDLE_OFF for each instance of rockchip_pcie_phy_power_one
|
||||
|
||||
This patch fixes an issue in the Rockchip PCIe PHY driver where, after
|
||||
a warm restart of the rockchip_pcie_phy module, PCIe lanes other than
|
||||
lane 0 could remain stuck in the PHY_LANE_IDLE_OFF state. This resulted
|
||||
in the PCIe link being restricted to x1 mode, even in configurations
|
||||
designed to use multiple lanes.
|
||||
|
||||
Signed-off-by: Valmantas Paliksa <walmis@gmail.com>
|
||||
---
|
||||
drivers/phy/rockchip/phy-rockchip-pcie.c | 12 ++++++------
|
||||
1 file changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
--- a/drivers/phy/rockchip/phy-rockchip-pcie.c
|
||||
+++ b/drivers/phy/rockchip/phy-rockchip-pcie.c
|
||||
@@ -166,6 +166,12 @@ static int rockchip_pcie_phy_power_on(st
|
||||
unsigned long timeout;
|
||||
|
||||
mutex_lock(&rk_phy->pcie_mutex);
|
||||
+
|
||||
+ regmap_write(rk_phy->reg_base,
|
||||
+ rk_phy->phy_data->pcie_laneoff,
|
||||
+ HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
|
||||
+ PHY_LANE_IDLE_MASK,
|
||||
+ PHY_LANE_IDLE_A_SHIFT + inst->index));
|
||||
|
||||
if (rk_phy->pwr_cnt++)
|
||||
goto err_out;
|
||||
@@ -181,12 +187,6 @@ static int rockchip_pcie_phy_power_on(st
|
||||
PHY_CFG_ADDR_MASK,
|
||||
PHY_CFG_ADDR_SHIFT));
|
||||
|
||||
- regmap_write(rk_phy->reg_base,
|
||||
- rk_phy->phy_data->pcie_laneoff,
|
||||
- HIWORD_UPDATE(!PHY_LANE_IDLE_OFF,
|
||||
- PHY_LANE_IDLE_MASK,
|
||||
- PHY_LANE_IDLE_A_SHIFT + inst->index));
|
||||
-
|
||||
/*
|
||||
* No documented timeout value for phy operation below,
|
||||
* so we make it large enough here. And we use loop-break
|
||||
@@ -39,47 +39,37 @@ type PacketOverStreamTunnel struct {
|
||||
var _ net.PacketConn = (*PacketOverStreamTunnel)(nil)
|
||||
|
||||
func (c *PacketOverStreamTunnel) Read(p []byte) (n int, err error) {
|
||||
n, _, err = c.ReadFrom(p)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *PacketOverStreamTunnel) Write(p []byte) (int, error) {
|
||||
return c.WriteTo(p, c.RemoteAddr())
|
||||
}
|
||||
|
||||
func (c *PacketOverStreamTunnel) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
addr = c.RemoteAddr()
|
||||
delim := make([]byte, 1)
|
||||
if _, err = io.ReadFull(c.Conn, delim); err != nil {
|
||||
return 0, addr, err
|
||||
return 0, err
|
||||
}
|
||||
if delim[0] != 0x00 {
|
||||
return 0, addr, fmt.Errorf("packet prefix 0x%x is not 0x00", delim[0])
|
||||
return 0, fmt.Errorf("packet prefix 0x%x is not 0x00", delim[0])
|
||||
}
|
||||
|
||||
lengthBytes := make([]byte, 2)
|
||||
if _, err = io.ReadFull(c.Conn, lengthBytes); err != nil {
|
||||
return 0, addr, err
|
||||
return 0, err
|
||||
}
|
||||
length := int(binary.BigEndian.Uint16(lengthBytes))
|
||||
if length > len(p) {
|
||||
return 0, addr, io.ErrShortBuffer
|
||||
return 0, io.ErrShortBuffer
|
||||
}
|
||||
|
||||
if n, err = io.ReadFull(c.Conn, p[:length]); err != nil {
|
||||
return 0, addr, err
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if _, err = io.ReadFull(c.Conn, delim); err != nil {
|
||||
return 0, addr, err
|
||||
return 0, err
|
||||
}
|
||||
if delim[0] != 0xff {
|
||||
return 0, addr, fmt.Errorf("packet suffix 0x%x is not 0xff", delim[0])
|
||||
return 0, fmt.Errorf("packet suffix 0x%x is not 0xff", delim[0])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (c *PacketOverStreamTunnel) WriteTo(p []byte, _ net.Addr) (n int, err error) {
|
||||
func (c *PacketOverStreamTunnel) Write(p []byte) (int, error) {
|
||||
if len(p) > 65535 {
|
||||
return 0, fmt.Errorf("packet length %d is larger than maximum length 65535", len(p))
|
||||
}
|
||||
@@ -95,6 +85,16 @@ func (c *PacketOverStreamTunnel) WriteTo(p []byte, _ net.Addr) (n int, err error
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (c *PacketOverStreamTunnel) ReadFrom(p []byte) (n int, addr net.Addr, err error) {
|
||||
addr = c.RemoteAddr()
|
||||
n, err = c.Read(p)
|
||||
return
|
||||
}
|
||||
|
||||
func (c *PacketOverStreamTunnel) WriteTo(p []byte, _ net.Addr) (n int, err error) {
|
||||
return c.Write(p)
|
||||
}
|
||||
|
||||
func (c *PacketOverStreamTunnel) Close() error {
|
||||
return c.Conn.Close()
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ proxies:
|
||||
type: mieru
|
||||
server: 127.0.0.1
|
||||
port: 8964
|
||||
udp: true
|
||||
transport: TCP
|
||||
username: baozi
|
||||
password: manlianpenfen
|
||||
|
||||
@@ -75,7 +75,15 @@ func GetRealityConn(ctx context.Context, conn net.Conn, ClientFingerprint string
|
||||
|
||||
//log.Debugln("REALITY hello.sessionId[:16]: %v", hello.SessionId[:16])
|
||||
|
||||
ecdheKey := uConn.HandshakeState.State13.EcdheKey
|
||||
keyShareKeys := uConn.HandshakeState.State13.KeyShareKeys
|
||||
if keyShareKeys == nil {
|
||||
// WTF???
|
||||
if retry > 2 {
|
||||
return nil, errors.New("nil keyShareKeys")
|
||||
}
|
||||
continue // retry
|
||||
}
|
||||
ecdheKey := keyShareKeys.Ecdhe
|
||||
if ecdheKey == nil {
|
||||
// WTF???
|
||||
if retry > 2 {
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ require (
|
||||
github.com/metacubex/sing-vmess v0.1.14-0.20250228002636-abc39e113b82
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589
|
||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422
|
||||
github.com/metacubex/utls v1.6.6
|
||||
github.com/metacubex/utls v1.6.8-alpha.4
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181
|
||||
github.com/miekg/dns v1.1.63
|
||||
github.com/mroth/weightedrand/v2 v2.1.0
|
||||
|
||||
+2
-2
@@ -129,8 +129,8 @@ github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589 h1:Z6bNy0
|
||||
github.com/metacubex/sing-wireguard v0.0.0-20241126021510-0827d417b589/go.mod h1:4NclTLIZuk+QkHVCGrP87rHi/y8YjgPytxTgApJNMhc=
|
||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422 h1:zGeQt3UyNydIVrMRB97AA5WsYEau/TyCnRtTf1yUmJY=
|
||||
github.com/metacubex/tfo-go v0.0.0-20241231083714-66613d49c422/go.mod h1:l9oLnLoEXyGZ5RVLsh7QCC5XsouTUyKk4F2nLm2DHLw=
|
||||
github.com/metacubex/utls v1.6.6 h1:3D12YKHTf2Z41UPhQU2dWerNWJ5TVQD9gKoQ+H+iLC8=
|
||||
github.com/metacubex/utls v1.6.6/go.mod h1:+WLFUnXjcpdxXCnyX25nggw8C6YonZ8zOK2Zm/oRvdo=
|
||||
github.com/metacubex/utls v1.6.8-alpha.4 h1:5EvsCHxDNneaOtAyc8CztoNSpmonLvkvuGs01lIeeEI=
|
||||
github.com/metacubex/utls v1.6.8-alpha.4/go.mod h1:MEZ5WO/VLKYs/s/dOzEK/mlXOQxc04ESeLzRgjmLYtk=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181 h1:hJLQviGySBuaynlCwf/oYgIxbVbGRUIKZCxdya9YrbQ=
|
||||
github.com/metacubex/wireguard-go v0.0.0-20240922131502-c182e7471181/go.mod h1:phewKljNYiTVT31Gcif8RiCKnTUOgVWFJjccqYM8s+Y=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
|
||||
Generated
+8
-8
@@ -813,9 +813,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.11"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
@@ -3783,9 +3783,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.39"
|
||||
version = "0.3.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8"
|
||||
checksum = "9d9c75b47bdff86fa3334a3db91356b8d7d86a9b839dab7d0bdc5c3d3a077618"
|
||||
dependencies = [
|
||||
"deranged",
|
||||
"itoa",
|
||||
@@ -3800,15 +3800,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "time-core"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef"
|
||||
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
|
||||
|
||||
[[package]]
|
||||
name = "time-macros"
|
||||
version = "0.2.20"
|
||||
version = "0.2.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c"
|
||||
checksum = "29aa485584182073ed57fd5004aa09c371f021325014694e432313345865fd04"
|
||||
dependencies = [
|
||||
"num-conv",
|
||||
"time-core",
|
||||
|
||||
@@ -5,6 +5,8 @@ import (
|
||||
"errors"
|
||||
"net"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
@@ -20,6 +22,8 @@ import (
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
"github.com/sagernet/sing/service"
|
||||
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -35,6 +39,7 @@ type DefaultDialer struct {
|
||||
udpListener net.ListenConfig
|
||||
udpAddr4 string
|
||||
udpAddr6 string
|
||||
netns string
|
||||
networkManager adapter.NetworkManager
|
||||
networkStrategy *C.NetworkStrategy
|
||||
defaultNetworkStrategy bool
|
||||
@@ -198,6 +203,7 @@ func NewDefault(ctx context.Context, options option.DialerOptions) (*DefaultDial
|
||||
udpListener: listener,
|
||||
udpAddr4: udpAddr4,
|
||||
udpAddr6: udpAddr6,
|
||||
netns: options.NetNs,
|
||||
networkManager: networkManager,
|
||||
networkStrategy: networkStrategy,
|
||||
defaultNetworkStrategy: defaultNetworkStrategy,
|
||||
@@ -214,6 +220,29 @@ func (d *DefaultDialer) DialContext(ctx context.Context, network string, address
|
||||
return nil, E.New("domain not resolved")
|
||||
}
|
||||
if d.networkStrategy == nil {
|
||||
if d.netns != "" {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
currentNs, err := netns.Get()
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get current netns")
|
||||
}
|
||||
defer netns.Set(currentNs)
|
||||
var targetNs netns.NsHandle
|
||||
if strings.HasPrefix(d.netns, "/") {
|
||||
targetNs, err = netns.GetFromPath(d.netns)
|
||||
} else {
|
||||
targetNs, err = netns.GetFromName(d.netns)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get netns ", d.netns)
|
||||
}
|
||||
defer targetNs.Close()
|
||||
err = netns.Set(targetNs)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "set netns to ", d.netns)
|
||||
}
|
||||
}
|
||||
switch N.NetworkName(network) {
|
||||
case N.NetworkUDP:
|
||||
if !address.IsIPv6() {
|
||||
@@ -282,6 +311,29 @@ func (d *DefaultDialer) DialParallelInterface(ctx context.Context, network strin
|
||||
|
||||
func (d *DefaultDialer) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
|
||||
if d.networkStrategy == nil {
|
||||
if d.netns != "" {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
currentNs, err := netns.Get()
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get current netns")
|
||||
}
|
||||
defer netns.Set(currentNs)
|
||||
var targetNs netns.NsHandle
|
||||
if strings.HasPrefix(d.netns, "/") {
|
||||
targetNs, err = netns.GetFromPath(d.netns)
|
||||
} else {
|
||||
targetNs, err = netns.GetFromName(d.netns)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get netns ", d.netns)
|
||||
}
|
||||
defer targetNs.Close()
|
||||
err = netns.Set(targetNs)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "set netns to ", d.netns)
|
||||
}
|
||||
}
|
||||
if destination.IsIPv6() {
|
||||
return trackPacketConn(d.udpListener.ListenPacket(ctx, N.NetworkUDP, d.udpAddr6))
|
||||
} else if destination.IsIPv4() && !destination.Addr.IsUnspecified() {
|
||||
|
||||
@@ -3,6 +3,8 @@ package listener
|
||||
import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/sagernet/sing-box/adapter"
|
||||
@@ -13,6 +15,7 @@ import (
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"github.com/metacubex/tfo-go"
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
func (l *Listener) ListenTCP() (net.Listener, error) {
|
||||
@@ -37,6 +40,29 @@ func (l *Listener) ListenTCP() (net.Listener, error) {
|
||||
}
|
||||
setMultiPathTCP(&listenConfig)
|
||||
}
|
||||
if l.listenOptions.NetNs != "" {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
currentNs, err := netns.Get()
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get current netns")
|
||||
}
|
||||
defer netns.Set(currentNs)
|
||||
var targetNs netns.NsHandle
|
||||
if strings.HasPrefix(l.listenOptions.NetNs, "/") {
|
||||
targetNs, err = netns.GetFromPath(l.listenOptions.NetNs)
|
||||
} else {
|
||||
targetNs, err = netns.GetFromName(l.listenOptions.NetNs)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get netns ", l.listenOptions.NetNs)
|
||||
}
|
||||
defer targetNs.Close()
|
||||
err = netns.Set(targetNs)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "set netns to ", l.listenOptions.NetNs)
|
||||
}
|
||||
}
|
||||
if l.listenOptions.TCPFastOpen {
|
||||
var tfoConfig tfo.ListenConfig
|
||||
tfoConfig.ListenConfig = listenConfig
|
||||
|
||||
@@ -4,12 +4,16 @@ import (
|
||||
"net"
|
||||
"net/netip"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
|
||||
"github.com/sagernet/sing/common/buf"
|
||||
"github.com/sagernet/sing/common/control"
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
M "github.com/sagernet/sing/common/metadata"
|
||||
N "github.com/sagernet/sing/common/network"
|
||||
|
||||
"github.com/vishvananda/netns"
|
||||
)
|
||||
|
||||
func (l *Listener) ListenUDP() (net.PacketConn, error) {
|
||||
@@ -24,6 +28,29 @@ func (l *Listener) ListenUDP() (net.PacketConn, error) {
|
||||
if !udpFragment {
|
||||
lc.Control = control.Append(lc.Control, control.DisableUDPFragment())
|
||||
}
|
||||
if l.listenOptions.NetNs != "" {
|
||||
runtime.LockOSThread()
|
||||
defer runtime.UnlockOSThread()
|
||||
currentNs, err := netns.Get()
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get current netns")
|
||||
}
|
||||
defer netns.Set(currentNs)
|
||||
var targetNs netns.NsHandle
|
||||
if strings.HasPrefix(l.listenOptions.NetNs, "/") {
|
||||
targetNs, err = netns.GetFromPath(l.listenOptions.NetNs)
|
||||
} else {
|
||||
targetNs, err = netns.GetFromName(l.listenOptions.NetNs)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "get netns ", l.listenOptions.NetNs)
|
||||
}
|
||||
defer targetNs.Close()
|
||||
err = netns.Set(targetNs)
|
||||
if err != nil {
|
||||
return nil, E.Cause(err, "set netns to ", l.listenOptions.NetNs)
|
||||
}
|
||||
}
|
||||
udpConn, err := lc.ListenPacket(l.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
+1
-14
@@ -263,20 +263,7 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg, options adapte
|
||||
return nil, tun.ErrDrop
|
||||
}
|
||||
case *R.RuleActionPredefined:
|
||||
return &mDNS.Msg{
|
||||
MsgHdr: mDNS.MsgHdr{
|
||||
Id: message.Id,
|
||||
Response: true,
|
||||
Authoritative: true,
|
||||
RecursionDesired: true,
|
||||
RecursionAvailable: true,
|
||||
Rcode: action.Rcode,
|
||||
},
|
||||
Question: message.Question,
|
||||
Answer: action.Answer,
|
||||
Ns: action.Ns,
|
||||
Extra: action.Extra,
|
||||
}, nil
|
||||
return action.Response(message), nil
|
||||
}
|
||||
}
|
||||
var responseCheck func(responseAddrs []netip.Addr) bool
|
||||
|
||||
@@ -5,7 +5,8 @@ icon: material/new-box
|
||||
!!! quote "Changes in sing-box 1.12.0"
|
||||
|
||||
:material-plus: [domain_resolver](#domain_resolver)
|
||||
:material-delete-clock: [domain_strategy](#domain_strategy)
|
||||
:material-delete-clock: [domain_strategy](#domain_strategy)
|
||||
:material-plus: [netns](#netns)
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
@@ -18,24 +19,25 @@ icon: material/new-box
|
||||
|
||||
```json
|
||||
{
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"inet4_bind_address": "0.0.0.0",
|
||||
"inet6_bind_address": "::",
|
||||
"routing_mark": 1234,
|
||||
"detour": "",
|
||||
"bind_interface": "",
|
||||
"inet4_bind_address": "",
|
||||
"inet6_bind_address": "",
|
||||
"routing_mark": 0,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"connect_timeout": "",
|
||||
"tcp_fast_open": false,
|
||||
"tcp_multi_path": false,
|
||||
"udp_fragment": false,
|
||||
"netns": "",
|
||||
"domain_resolver": "", // or {}
|
||||
"network_strategy": "default",
|
||||
"network_strategy": "",
|
||||
"network_type": [],
|
||||
"fallback_network_type": [],
|
||||
"fallback_delay": "300ms",
|
||||
"fallback_delay": "",
|
||||
|
||||
// Deprecated
|
||||
"domain_strategy": "prefer_ipv6"
|
||||
"domain_strategy": ""
|
||||
}
|
||||
```
|
||||
|
||||
@@ -75,6 +77,15 @@ Set netfilter routing mark.
|
||||
|
||||
Reuse listener address.
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
Enable TCP Fast Open.
|
||||
@@ -91,14 +102,15 @@ Enable TCP Multi Path.
|
||||
|
||||
Enable UDP fragmentation.
|
||||
|
||||
#### connect_timeout
|
||||
#### netns
|
||||
|
||||
Connect timeout, in golang's Duration format.
|
||||
!!! question "Since sing-box 1.12.0"
|
||||
|
||||
A duration string is a possibly signed sequence of
|
||||
decimal numbers, each with optional fraction and a unit suffix,
|
||||
such as "300ms", "-1.5h" or "2h45m".
|
||||
Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
|
||||
!!! quote ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set network namespace, name or path.
|
||||
|
||||
#### domain_resolver
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ icon: material/new-box
|
||||
!!! quote "sing-box 1.12.0 中的更改"
|
||||
|
||||
:material-plus: [domain_resolver](#domain_resolver)
|
||||
:material-delete-clock: [domain_strategy](#domain_strategy)
|
||||
:material-delete-clock: [domain_strategy](#domain_strategy)
|
||||
:material-plus: [netns](#netns)
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
@@ -18,25 +19,26 @@ icon: material/new-box
|
||||
|
||||
```json
|
||||
{
|
||||
"detour": "upstream-out",
|
||||
"bind_interface": "en0",
|
||||
"inet4_bind_address": "0.0.0.0",
|
||||
"inet6_bind_address": "::",
|
||||
"routing_mark": 1234,
|
||||
"detour": "",
|
||||
"bind_interface": "",
|
||||
"inet4_bind_address": "",
|
||||
"inet6_bind_address": "",
|
||||
"routing_mark": 0,
|
||||
"reuse_addr": false,
|
||||
"connect_timeout": "5s",
|
||||
"connect_timeout": "",
|
||||
"tcp_fast_open": false,
|
||||
"tcp_multi_path": false,
|
||||
"udp_fragment": false,
|
||||
"netns": "",
|
||||
"domain_resolver": "", // 或 {}
|
||||
"network_strategy": "",
|
||||
"network_type": [],
|
||||
"fallback_network_type": [],
|
||||
"fallback_delay": "300ms",
|
||||
"fallback_delay": "",
|
||||
|
||||
// 废弃的
|
||||
|
||||
"domain_strategy": "prefer_ipv6"
|
||||
"domain_strategy": ""
|
||||
}
|
||||
```
|
||||
|
||||
@@ -76,6 +78,13 @@ icon: material/new-box
|
||||
|
||||
重用监听地址。
|
||||
|
||||
#### connect_timeout
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
|
||||
#### tcp_fast_open
|
||||
|
||||
启用 TCP Fast Open。
|
||||
@@ -92,12 +101,15 @@ icon: material/new-box
|
||||
|
||||
启用 UDP 分段。
|
||||
|
||||
#### connect_timeout
|
||||
#### netns
|
||||
|
||||
连接超时,采用 golang 的 Duration 格式。
|
||||
!!! question "自 sing-box 1.12.0 起"
|
||||
|
||||
持续时间字符串是一个可能有符号的序列十进制数,每个都有可选的分数和单位后缀, 例如 "300ms"、"-1.5h" 或 "2h45m"。
|
||||
有效时间单位为 "ns"、"us"(或 "µs")、"ms"、"s"、"m"、"h"。
|
||||
!!! quote ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置网络命名空间,名称或路径。
|
||||
|
||||
#### domain_resolver
|
||||
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
---
|
||||
icon: material/delete-clock
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "Changes in sing-box 1.12.0"
|
||||
|
||||
:material-plus: [netns](#netns)
|
||||
|
||||
!!! quote "Changes in sing-box 1.11.0"
|
||||
|
||||
:material-delete-clock: [sniff](#sniff)
|
||||
@@ -14,17 +18,18 @@ icon: material/delete-clock
|
||||
|
||||
```json
|
||||
{
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"listen": "",
|
||||
"listen_port": 0,
|
||||
"tcp_fast_open": false,
|
||||
"tcp_multi_path": false,
|
||||
"udp_fragment": false,
|
||||
"udp_timeout": "5m",
|
||||
"detour": "another-in",
|
||||
"udp_timeout": "",
|
||||
"netns": "",
|
||||
"detour": "",
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"sniff_timeout": "300ms",
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"sniff_timeout": "",
|
||||
"domain_strategy": "",
|
||||
"udp_disable_domain_unmapping": false
|
||||
}
|
||||
```
|
||||
@@ -72,6 +77,16 @@ UDP NAT expiration time.
|
||||
|
||||
`5m` will be used by default.
|
||||
|
||||
#### netns
|
||||
|
||||
!!! question "Since sing-box 1.12.0"
|
||||
|
||||
!!! quote ""
|
||||
|
||||
Only supported on Linux.
|
||||
|
||||
Set network namespace, name or path.
|
||||
|
||||
#### detour
|
||||
|
||||
If set, connections will be forwarded to the specified inbound.
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
---
|
||||
icon: material/delete-clock
|
||||
icon: material/new-box
|
||||
---
|
||||
|
||||
!!! quote "Changes in sing-box 1.12.0"
|
||||
|
||||
:material-plus: [netns](#netns)
|
||||
|
||||
!!! quote "sing-box 1.11.0 中的更改"
|
||||
|
||||
:material-delete-clock: [sniff](#sniff)
|
||||
@@ -14,17 +18,18 @@ icon: material/delete-clock
|
||||
|
||||
```json
|
||||
{
|
||||
"listen": "::",
|
||||
"listen_port": 5353,
|
||||
"listen": "",
|
||||
"listen_port": 0,
|
||||
"tcp_fast_open": false,
|
||||
"tcp_multi_path": false,
|
||||
"udp_fragment": false,
|
||||
"udp_timeout": "5m",
|
||||
"detour": "another-in",
|
||||
"udp_timeout": "",
|
||||
"netns": "",
|
||||
"detour": "",
|
||||
"sniff": false,
|
||||
"sniff_override_destination": false,
|
||||
"sniff_timeout": "300ms",
|
||||
"domain_strategy": "prefer_ipv6",
|
||||
"sniff_timeout": "",
|
||||
"domain_strategy": "",
|
||||
"udp_disable_domain_unmapping": false
|
||||
}
|
||||
```
|
||||
@@ -73,6 +78,16 @@ UDP NAT 过期时间。
|
||||
|
||||
默认使用 `5m`。
|
||||
|
||||
#### netns
|
||||
|
||||
!!! question "自 sing-box 1.12.0 起"
|
||||
|
||||
!!! quote ""
|
||||
|
||||
仅支持 Linux。
|
||||
|
||||
设置网络命名空间,名称或路径。
|
||||
|
||||
#### detour
|
||||
|
||||
如果设置,连接将被转发到指定的入站。
|
||||
|
||||
+15
-26
@@ -191,34 +191,23 @@ func (o *DNSServerOptions) Upgrade(ctx context.Context) error {
|
||||
serverType = C.DNSTypeUDP
|
||||
}
|
||||
}
|
||||
var remoteOptions RemoteDNSServerOptions
|
||||
if options.Detour == "" {
|
||||
remoteOptions = RemoteDNSServerOptions{
|
||||
LocalDNSServerOptions: LocalDNSServerOptions{
|
||||
LegacyStrategy: options.Strategy,
|
||||
LegacyDefaultDialer: options.Detour == "",
|
||||
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
|
||||
},
|
||||
LegacyAddressResolver: options.AddressResolver,
|
||||
LegacyAddressStrategy: options.AddressStrategy,
|
||||
LegacyAddressFallbackDelay: options.AddressFallbackDelay,
|
||||
}
|
||||
} else {
|
||||
remoteOptions = RemoteDNSServerOptions{
|
||||
LocalDNSServerOptions: LocalDNSServerOptions{
|
||||
DialerOptions: DialerOptions{
|
||||
Detour: options.Detour,
|
||||
DomainResolver: &DomainResolveOptions{
|
||||
Server: options.AddressResolver,
|
||||
Strategy: options.AddressStrategy,
|
||||
},
|
||||
FallbackDelay: options.AddressFallbackDelay,
|
||||
remoteOptions := RemoteDNSServerOptions{
|
||||
LocalDNSServerOptions: LocalDNSServerOptions{
|
||||
DialerOptions: DialerOptions{
|
||||
Detour: options.Detour,
|
||||
DomainResolver: &DomainResolveOptions{
|
||||
Server: options.AddressResolver,
|
||||
Strategy: options.AddressStrategy,
|
||||
},
|
||||
LegacyStrategy: options.Strategy,
|
||||
LegacyDefaultDialer: options.Detour == "",
|
||||
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
|
||||
FallbackDelay: options.AddressFallbackDelay,
|
||||
},
|
||||
}
|
||||
LegacyStrategy: options.Strategy,
|
||||
LegacyDefaultDialer: options.Detour == "",
|
||||
LegacyClientSubnet: options.ClientSubnet.Build(netip.Prefix{}),
|
||||
},
|
||||
LegacyAddressResolver: options.AddressResolver,
|
||||
LegacyAddressStrategy: options.AddressStrategy,
|
||||
LegacyAddressFallbackDelay: options.AddressFallbackDelay,
|
||||
}
|
||||
switch serverType {
|
||||
case C.DNSTypeLocal:
|
||||
|
||||
@@ -68,6 +68,7 @@ type ListenOptions struct {
|
||||
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
||||
UDPFragmentDefault bool `json:"-"`
|
||||
UDPTimeout UDPTimeoutCompat `json:"udp_timeout,omitempty"`
|
||||
NetNs string `json:"netns,omitempty"`
|
||||
|
||||
// Deprecated: removed
|
||||
ProxyProtocol bool `json:"proxy_protocol,omitempty"`
|
||||
|
||||
@@ -77,6 +77,7 @@ type DialerOptions struct {
|
||||
TCPMultiPath bool `json:"tcp_multi_path,omitempty"`
|
||||
UDPFragment *bool `json:"udp_fragment,omitempty"`
|
||||
UDPFragmentDefault bool `json:"-"`
|
||||
NetNs string `json:"netns,omitempty"`
|
||||
DomainResolver *DomainResolveOptions `json:"domain_resolver,omitempty"`
|
||||
NetworkStrategy *NetworkStrategy `json:"network_strategy,omitempty"`
|
||||
NetworkType badoption.Listable[InterfaceType] `json:"network_type,omitempty"`
|
||||
|
||||
@@ -4,17 +4,18 @@ import (
|
||||
"encoding/json"
|
||||
|
||||
E "github.com/sagernet/sing/common/exceptions"
|
||||
"github.com/sagernet/sing/common/json/badjson"
|
||||
)
|
||||
|
||||
type ShadowTLSInboundOptions struct {
|
||||
ListenOptions
|
||||
Version int `json:"version,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Users []ShadowTLSUser `json:"users,omitempty"`
|
||||
Handshake ShadowTLSHandshakeOptions `json:"handshake,omitempty"`
|
||||
HandshakeForServerName map[string]ShadowTLSHandshakeOptions `json:"handshake_for_server_name,omitempty"`
|
||||
StrictMode bool `json:"strict_mode,omitempty"`
|
||||
WildcardSNI WildcardSNI `json:"wildcard_sni,omitempty"`
|
||||
Version int `json:"version,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Users []ShadowTLSUser `json:"users,omitempty"`
|
||||
Handshake ShadowTLSHandshakeOptions `json:"handshake,omitempty"`
|
||||
HandshakeForServerName *badjson.TypedMap[string, ShadowTLSHandshakeOptions] `json:"handshake_for_server_name,omitempty"`
|
||||
StrictMode bool `json:"strict_mode,omitempty"`
|
||||
WildcardSNI WildcardSNI `json:"wildcard_sni,omitempty"`
|
||||
}
|
||||
|
||||
type WildcardSNI int
|
||||
|
||||
@@ -46,14 +46,16 @@ func NewInbound(ctx context.Context, router adapter.Router, logger log.ContextLo
|
||||
var handshakeForServerName map[string]shadowtls.HandshakeConfig
|
||||
if options.Version > 1 {
|
||||
handshakeForServerName = make(map[string]shadowtls.HandshakeConfig)
|
||||
for serverName, serverOptions := range options.HandshakeForServerName {
|
||||
handshakeDialer, err := dialer.New(ctx, serverOptions.DialerOptions, serverOptions.ServerIsDomain())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handshakeForServerName[serverName] = shadowtls.HandshakeConfig{
|
||||
Server: serverOptions.ServerOptions.Build(),
|
||||
Dialer: handshakeDialer,
|
||||
if options.HandshakeForServerName != nil {
|
||||
for _, entry := range options.HandshakeForServerName.Entries() {
|
||||
handshakeDialer, err := dialer.New(ctx, entry.Value.DialerOptions, entry.Value.ServerIsDomain())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handshakeForServerName[entry.Key] = shadowtls.HandshakeConfig{
|
||||
Server: entry.Value.ServerOptions.Build(),
|
||||
Dialer: handshakeDialer,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,3 +444,32 @@ func (r *RuleActionPredefined) String() string {
|
||||
options = append(options, common.Map(r.Extra, dns.RR.String)...)
|
||||
return F.ToString("predefined(", strings.Join(options, ","), ")")
|
||||
}
|
||||
|
||||
func (r *RuleActionPredefined) Response(request *dns.Msg) *dns.Msg {
|
||||
return &dns.Msg{
|
||||
MsgHdr: dns.MsgHdr{
|
||||
Id: request.Id,
|
||||
Response: true,
|
||||
Authoritative: true,
|
||||
RecursionDesired: true,
|
||||
RecursionAvailable: true,
|
||||
Rcode: r.Rcode,
|
||||
},
|
||||
Question: request.Question,
|
||||
Answer: rewriteRecords(r.Answer, request.Question[0]),
|
||||
Ns: rewriteRecords(r.Ns, request.Question[0]),
|
||||
Extra: rewriteRecords(r.Extra, request.Question[0]),
|
||||
}
|
||||
}
|
||||
|
||||
func rewriteRecords(records []dns.RR, question dns.Question) []dns.RR {
|
||||
return common.Map(records, func(it dns.RR) dns.RR {
|
||||
if strings.HasPrefix(it.Header().Name, "*") {
|
||||
if strings.HasSuffix(question.Name, it.Header().Name[1:]) {
|
||||
it = dns.Copy(it)
|
||||
it.Header().Name = question.Name
|
||||
}
|
||||
}
|
||||
return it
|
||||
})
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-ssr-plus
|
||||
PKG_VERSION:=189
|
||||
PKG_RELEASE:=5
|
||||
PKG_RELEASE:=6
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_NONE_V2RAY \
|
||||
@@ -34,10 +34,7 @@ LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:= \
|
||||
+coreutils +coreutils-base64 +dns2socks +dns2tcp +dnsmasq-full +@PACKAGE_dnsmasq_full_ipset +ipset +kmod-ipt-nat +jq \
|
||||
+ip-full +iptables +iptables-mod-tproxy +lua +lua-neturl +libuci-lua +microsocks \
|
||||
+tcping +resolveip +shadowsocksr-libev-ssr-check +uclient-fetch \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_libustream-mbedtls:libustream-mbedtls \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_libustream-openssl:libustream-openssl \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_libustream-wolfssl:libustream-wolfssl \
|
||||
+tcping +resolveip +shadowsocksr-libev-ssr-check +wget-ssl \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:curl \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:curl \
|
||||
@@ -67,20 +64,6 @@ LUCI_DEPENDS:= \
|
||||
define Package/$(PKG_NAME)/config
|
||||
select PACKAGE_luci-lib-ipkg if PACKAGE_$(PKG_NAME)
|
||||
|
||||
choice
|
||||
prompt "Uclient SSL Lib Selection"
|
||||
default PACKAGE_$(PKG_NAME)_INCLUDE_libustream-openssl
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_libustream-mbedtls
|
||||
bool "libustream-mbedtls"
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_libustream-openssl
|
||||
bool "libustream-openssl"
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_PACKAGE_libustream-wolfssl
|
||||
bool "libustream-wolfssl"
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Shadowsocks Client Selection"
|
||||
default PACKAGE_$(PKG_NAME)_INCLUDE_Shadowsocks_Rust_Client if aarch64 || x86_64
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ jobs:
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Setup
|
||||
uses: actions/setup-dotnet@v4.3.0
|
||||
uses: actions/setup-dotnet@v4.3.1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ jobs:
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Setup
|
||||
uses: actions/setup-dotnet@v4.3.0
|
||||
uses: actions/setup-dotnet@v4.3.1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ jobs:
|
||||
fetch-depth: '0'
|
||||
|
||||
- name: Setup
|
||||
uses: actions/setup-dotnet@v4.3.0
|
||||
uses: actions/setup-dotnet@v4.3.1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ jobs:
|
||||
uses: actions/checkout@v4.2.2
|
||||
|
||||
- name: Setup
|
||||
uses: actions/setup-dotnet@v4.3.0
|
||||
uses: actions/setup-dotnet@v4.3.1
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
|
||||
|
||||
@@ -63,6 +63,10 @@ public partial class App : Application
|
||||
if (desktop.MainWindow != null)
|
||||
{
|
||||
var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow);
|
||||
if (clipboardData.IsNullOrEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null)
|
||||
{
|
||||
|
||||
@@ -14,7 +14,10 @@ namespace v2rayN.Desktop.Common
|
||||
{
|
||||
var clipboard = TopLevel.GetTopLevel(owner)?.Clipboard;
|
||||
if (clipboard == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return await clipboard.GetTextAsync();
|
||||
}
|
||||
catch
|
||||
|
||||
@@ -247,7 +247,7 @@ namespace v2rayN.Desktop.Views
|
||||
|
||||
case EViewAction.AddServerViaClipboard:
|
||||
var clipboardData = await AvaUtils.GetClipboardData(this);
|
||||
if (ViewModel != null)
|
||||
if (clipboardData.IsNotEmpty() && ViewModel != null)
|
||||
{
|
||||
await ViewModel.AddServerViaClipboardAsync(clipboardData);
|
||||
}
|
||||
@@ -315,7 +315,7 @@ namespace v2rayN.Desktop.Views
|
||||
{
|
||||
case Key.V:
|
||||
var clipboardData = await AvaUtils.GetClipboardData(this);
|
||||
if (ViewModel != null)
|
||||
if (clipboardData.IsNotEmpty() && ViewModel != null)
|
||||
{
|
||||
await ViewModel.AddServerViaClipboardAsync(clipboardData);
|
||||
}
|
||||
|
||||
@@ -109,13 +109,20 @@ namespace v2rayN.Desktop.Views
|
||||
|
||||
case EViewAction.SetClipboardData:
|
||||
if (obj is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
await AvaUtils.SetClipboardData(this, (string)obj);
|
||||
break;
|
||||
|
||||
case EViewAction.ImportRulesFromClipboard:
|
||||
var clipboardData = await AvaUtils.GetClipboardData(this);
|
||||
ViewModel?.ImportRulesFromClipboardAsync(clipboardData);
|
||||
if (clipboardData.IsNotEmpty())
|
||||
{
|
||||
ViewModel?.ImportRulesFromClipboardAsync(clipboardData);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -18,11 +18,11 @@ namespace v2rayN
|
||||
/// <returns></returns>
|
||||
public static string? GetClipboardData()
|
||||
{
|
||||
string? strData = string.Empty;
|
||||
var strData = string.Empty;
|
||||
try
|
||||
{
|
||||
IDataObject data = Clipboard.GetDataObject();
|
||||
if (data.GetDataPresent(DataFormats.UnicodeText))
|
||||
var data = Clipboard.GetDataObject();
|
||||
if (data?.GetDataPresent(DataFormats.UnicodeText) == true)
|
||||
{
|
||||
strData = data.GetData(DataFormats.UnicodeText)?.ToString();
|
||||
}
|
||||
|
||||
@@ -232,7 +232,10 @@ namespace v2rayN.Views
|
||||
|
||||
case EViewAction.AddServerViaClipboard:
|
||||
var clipboardData = WindowsUtils.GetClipboardData();
|
||||
ViewModel?.AddServerViaClipboardAsync(clipboardData);
|
||||
if (clipboardData.IsNotEmpty())
|
||||
{
|
||||
ViewModel?.AddServerViaClipboardAsync(clipboardData);
|
||||
}
|
||||
break;
|
||||
|
||||
case EViewAction.AdjustMainLvColWidth:
|
||||
@@ -284,11 +287,20 @@ namespace v2rayN.Views
|
||||
{
|
||||
case Key.V:
|
||||
if (Keyboard.FocusedElement is TextBox)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var clipboardData = WindowsUtils.GetClipboardData();
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null)
|
||||
_ = service.AddServerViaClipboardAsync(clipboardData);
|
||||
if (clipboardData.IsNotEmpty())
|
||||
{
|
||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
||||
if (service != null)
|
||||
{
|
||||
_ = service.AddServerViaClipboardAsync(clipboardData);
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Key.S:
|
||||
|
||||
@@ -110,7 +110,10 @@ namespace v2rayN.Views
|
||||
|
||||
case EViewAction.ImportRulesFromClipboard:
|
||||
var clipboardData = WindowsUtils.GetClipboardData();
|
||||
ViewModel?.ImportRulesFromClipboardAsync(clipboardData);
|
||||
if (clipboardData.IsNotEmpty())
|
||||
{
|
||||
ViewModel?.ImportRulesFromClipboardAsync(clipboardData);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
module github.com/2dust/AndroidLibXrayLite
|
||||
|
||||
go 1.24
|
||||
go 1.24.1
|
||||
|
||||
require (
|
||||
github.com/xtls/xray-core v1.8.25-0.20250306135015-2cba2c4d59e4
|
||||
golang.org/x/mobile v0.0.0-20250218173827-cd096645fcd3
|
||||
golang.org/x/mobile v0.0.0-20250305212854-3a7bc9f8a4de
|
||||
golang.org/x/sys v0.31.0
|
||||
)
|
||||
|
||||
@@ -16,18 +16,18 @@ require (
|
||||
github.com/ghodss/yaml v1.0.1-0.20220118164431-d8423dcdf344 // indirect
|
||||
github.com/go-task/slim-sprig/v3 v3.0.0 // indirect
|
||||
github.com/google/btree v1.1.3 // indirect
|
||||
github.com/google/pprof v0.0.0-20250208200701-d0013a598941 // indirect
|
||||
github.com/google/pprof v0.0.0-20250302191652-9094ed2288e7 // indirect
|
||||
github.com/gorilla/websocket v1.5.3 // indirect
|
||||
github.com/klauspost/compress v1.17.11 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 // indirect
|
||||
github.com/klauspost/compress v1.18.0 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
|
||||
github.com/onsi/ginkgo/v2 v2.23.0 // indirect
|
||||
github.com/pelletier/go-toml v1.9.5 // indirect
|
||||
github.com/pires/go-proxyproto v0.8.0 // indirect
|
||||
github.com/quic-go/qpack v0.5.1 // indirect
|
||||
github.com/quic-go/quic-go v0.50.0 // indirect
|
||||
github.com/refraction-networking/utls v1.6.7 // indirect
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 // indirect
|
||||
github.com/sagernet/sing v0.6.1 // indirect
|
||||
github.com/sagernet/sing v0.6.2 // indirect
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 // indirect
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 // indirect
|
||||
github.com/v2fly/ss-bloomring v0.0.0-20210312155135-28617310f63e // indirect
|
||||
@@ -37,16 +37,16 @@ require (
|
||||
go.uber.org/mock v0.5.0 // indirect
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba // indirect
|
||||
golang.org/x/crypto v0.36.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa // indirect
|
||||
golang.org/x/mod v0.23.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 // indirect
|
||||
golang.org/x/mod v0.24.0 // indirect
|
||||
golang.org/x/net v0.37.0 // indirect
|
||||
golang.org/x/sync v0.12.0 // indirect
|
||||
golang.org/x/text v0.23.0 // indirect
|
||||
golang.org/x/time v0.10.0 // indirect
|
||||
golang.org/x/tools v0.30.0 // indirect
|
||||
golang.org/x/time v0.11.0 // indirect
|
||||
golang.org/x/tools v0.31.0 // indirect
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/grpc v1.71.0 // indirect
|
||||
google.golang.org/protobuf v1.36.5 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0 h1:Wo41lDOevRJSGpevP+8Pk5bANX7fJacO2w04aqLiC5I=
|
||||
github.com/OmarTariq612/goech v0.0.0-20240405204721-8e2e1dafd3a0/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM=
|
||||
github.com/OmarTariq612/goech v0.0.1 h1:/0c918Bk1ik65GXDj2k7SOK78DyZr30Jmq9euy1/HXg=
|
||||
github.com/OmarTariq612/goech v0.0.1/go.mod h1:FVGavL/QEBQDcBpr3fAojoK17xX5k9bicBphrOpP7uM=
|
||||
github.com/andybalholm/brotli v1.1.1 h1:PR2pgnyFznKEugtsUo0xLdDop5SKXd5Qf5ysW+7XdTA=
|
||||
github.com/andybalholm/brotli v1.1.1/go.mod h1:05ib4cKhjx3OQYUY22hTVd34Bc8upXjOLL2rKwwZBoA=
|
||||
github.com/cloudflare/circl v1.6.0 h1:cr5JKic4HI+LkINy2lg3W2jF8sHCVTBncJr5gIIq7qk=
|
||||
@@ -26,20 +26,20 @@ github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
|
||||
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
|
||||
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
|
||||
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
|
||||
github.com/google/pprof v0.0.0-20250208200701-d0013a598941 h1:43XjGa6toxLpeksjcxs1jIoIyr+vUfOqY2c6HB4bpoc=
|
||||
github.com/google/pprof v0.0.0-20250208200701-d0013a598941/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/pprof v0.0.0-20250302191652-9094ed2288e7 h1:+J3r2e8+RsmN3vKfo75g0YSY61ms37qzPglu4p0sGro=
|
||||
github.com/google/pprof v0.0.0-20250302191652-9094ed2288e7/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
|
||||
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
|
||||
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
|
||||
github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=
|
||||
github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
|
||||
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
|
||||
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
|
||||
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
|
||||
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
|
||||
github.com/miekg/dns v1.1.63 h1:8M5aAw6OMZfFXTT7K5V0Eu5YiiL8l7nUAkyN6C9YwaY=
|
||||
github.com/miekg/dns v1.1.63/go.mod h1:6NGHfjhpmr5lt3XPLuyfDJi5AXbNIPM9PY6H6sF1Nfs=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2 h1:/3X8Panh8/WwhU/3Ssa6rCKqPLuAkVY2I0RoyDLySlU=
|
||||
github.com/onsi/ginkgo/v2 v2.22.2/go.mod h1:oeMosUL+8LtarXBHu/c0bx2D/K9zyQ6uX3cTyztHwsk=
|
||||
github.com/onsi/ginkgo/v2 v2.23.0 h1:FA1xjp8ieYDzlgS5ABTpdUDB7wtngggONc8a7ku2NqQ=
|
||||
github.com/onsi/ginkgo/v2 v2.23.0/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
|
||||
github.com/onsi/gomega v1.36.2 h1:koNYke6TVk6ZmnyHrCXba/T/MoLBXFjeC1PtvYgw0A8=
|
||||
github.com/onsi/gomega v1.36.2/go.mod h1:DdwyADRjrc825LhMEkD76cHR5+pUnjhUN8GlHlRPHzY=
|
||||
github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8=
|
||||
@@ -56,8 +56,8 @@ github.com/refraction-networking/utls v1.6.7 h1:zVJ7sP1dJx/WtVuITug3qYUq034cDq9B
|
||||
github.com/refraction-networking/utls v1.6.7/go.mod h1:BC3O4vQzye5hqpmDTWUqi4P5DDhzJfkV1tdqtawQIH0=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3 h1:f/FNXud6gA3MNr8meMVVGxhp+QBTqY91tM8HjEuMjGg=
|
||||
github.com/riobard/go-bloom v0.0.0-20200614022211-cdc8013cb5b3/go.mod h1:HgjTstvQsPGkxUsCd2KWxErBblirPizecHcpD3ffK+s=
|
||||
github.com/sagernet/sing v0.6.1 h1:mJ6e7Ir2wtCoGLbdnnXWBsNJu5YHtbXmv66inoE0zFA=
|
||||
github.com/sagernet/sing v0.6.1/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing v0.6.2 h1:TR9WeH0yDJMjSFThqgFYe/i2pdH69Gb0tDJzJLPuVec=
|
||||
github.com/sagernet/sing v0.6.2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7 h1:zaopR1tbHEw5Nk6FAkM05wCslV6ahVegEZaKMv9ipx8=
|
||||
github.com/sagernet/sing-shadowsocks v0.2.7/go.mod h1:0rIKJZBR65Qi0zwdKezt4s57y/Tl1ofkaq6NlkzVuyE=
|
||||
github.com/seiflotfy/cuckoofilter v0.0.0-20240715131351-a2f2c23f1771 h1:emzAzMZ1L9iaKCTxdy3Em8Wv4ChIAGnfiz18Cda70g4=
|
||||
@@ -97,12 +97,12 @@ go4.org/netipx v0.0.0-20231129151722-fdeea329fbba h1:0b9z3AuHCjxk0x/opv64kcgZLBs
|
||||
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba/go.mod h1:PLyyIXexvUFg3Owu6p/WfdlivPbZJsZdgWZlrGope/Y=
|
||||
golang.org/x/crypto v0.36.0 h1:AnAEvhDddvBdpY+uR+MyHmuZzzNqXSe/GvuDeob5L34=
|
||||
golang.org/x/crypto v0.36.0/go.mod h1:Y4J0ReaxCR1IMaabaSMugxJES1EpwhBHhv2bDHklZvc=
|
||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa h1:t2QcU6V556bFjYgu4L6C+6VrCPyJZ+eyRsABUPs1mz4=
|
||||
golang.org/x/exp v0.0.0-20250218142911-aa4b98e5adaa/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk=
|
||||
golang.org/x/mobile v0.0.0-20250218173827-cd096645fcd3 h1:0V/7Y1FEaFdAzb9DkVDh4QFp4vL4yYCiJ5cjk80lZyA=
|
||||
golang.org/x/mobile v0.0.0-20250218173827-cd096645fcd3/go.mod h1:j5VYNgQ6lZYZlzHFjdgS2UeqRSZunDk+/zXVTAIA3z4=
|
||||
golang.org/x/mod v0.23.0 h1:Zb7khfcRGKk+kqfxFaP5tZqCnDZMjC5VtUBs87Hr6QM=
|
||||
golang.org/x/mod v0.23.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394 h1:nDVHiLt8aIbd/VzvPWN6kSOPE7+F/fNFDSXLVYkE/Iw=
|
||||
golang.org/x/exp v0.0.0-20250305212735-054e65f0b394/go.mod h1:sIifuuw/Yco/y6yb6+bDNfyeQ/MdPUy/hKEMYQV17cM=
|
||||
golang.org/x/mobile v0.0.0-20250305212854-3a7bc9f8a4de h1:WuckfUoaRGJfaQTPZvlmcaQwg4Xj9oS2cvvh3dUqpDo=
|
||||
golang.org/x/mobile v0.0.0-20250305212854-3a7bc9f8a4de/go.mod h1:/IZuixag1ELW37+FftdmIt59/3esqpAWM/QqWtf7HUI=
|
||||
golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU=
|
||||
golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
|
||||
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
|
||||
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
|
||||
golang.org/x/sync v0.12.0 h1:MHc5BpPuC30uJk597Ri8TV3CNZcTLu6B6z4lJy+g6Jw=
|
||||
@@ -113,16 +113,16 @@ golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
|
||||
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||
golang.org/x/text v0.23.0 h1:D71I7dUrlY+VX0gQShAThNGHFxZ13dGLBHQLVl1mJlY=
|
||||
golang.org/x/text v0.23.0/go.mod h1:/BLNzu4aZCJ1+kcD0DNRotWKage4q2rGVAg4o22unh4=
|
||||
golang.org/x/time v0.10.0 h1:3usCWA8tQn0L8+hFJQNgzpWbd89begxN66o1Ojdn5L4=
|
||||
golang.org/x/time v0.10.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
|
||||
golang.org/x/tools v0.30.0 h1:BgcpHewrV5AUp2G9MebG4XPFI1E2W41zU1SaqVA9vJY=
|
||||
golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY=
|
||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||
golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU=
|
||||
golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg=
|
||||
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 h1:/jFs0duh4rdb8uIfPMv78iAJGcPKDeqAFnaLBropIC4=
|
||||
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173/go.mod h1:tkCQ4FQXmpAgYVh++1cq16/dH4QJtmvpRv19DWGAHSA=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a h1:51aaUVRocpvUOSQKM6Q7VuoaktNIaMCLuhZB6DKksq4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a/go.mod h1:uRxBH1mhmO8PGhU89cMcHaXKZqO+OfakD8QQO0oYwlQ=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:LuRYeWDFV6WOn90g357N17oMCaxpgCnbi/44qJvDn2I=
|
||||
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
|
||||
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
|
||||
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
|
||||
|
||||
@@ -12,7 +12,7 @@ android {
|
||||
applicationId = "com.v2ray.ang"
|
||||
minSdk = 21
|
||||
targetSdk = 35
|
||||
versionCode = 636
|
||||
versionCode = 638
|
||||
versionName = "1.9.39"
|
||||
multiDexEnabled = true
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ au.com.shiftyjelly.pocketcasts
|
||||
bbc.mobile.news.ww
|
||||
be.mygod.vpnhotspot
|
||||
ch.protonmail.android
|
||||
cm.aptoide.pt
|
||||
co.wanqu.android
|
||||
com.alphainventor.filemanager
|
||||
com.amazon.kindle
|
||||
@@ -34,7 +35,9 @@ com.chrome.canary
|
||||
com.chrome.dev
|
||||
com.cl.newt66y
|
||||
com.cradle.iitc_mobile
|
||||
org.exarhteam.iitc_mobile
|
||||
com.cygames.shadowverse
|
||||
com.dcard.freedom
|
||||
com.devhd.feedly
|
||||
com.devolver.reigns2
|
||||
com.discord
|
||||
@@ -108,6 +111,7 @@ com.ifttt.ifttt
|
||||
com.imgur.mobile
|
||||
com.innologica.inoreader
|
||||
com.instagram.android
|
||||
com.instagram.lite
|
||||
com.instapaper.android
|
||||
com.jarvanh.vpntether
|
||||
com.kapp.youtube.final
|
||||
@@ -115,6 +119,7 @@ com.klinker.android.twitter_l
|
||||
com.lastpass.lpandroid
|
||||
com.linecorp.linelite
|
||||
com.lingodeer
|
||||
com.ltnnews.news
|
||||
com.mediapods.tumbpods
|
||||
com.mgoogle.android.gms
|
||||
com.microsoft.emmx
|
||||
@@ -159,6 +164,7 @@ com.slack
|
||||
com.snaptube.premium
|
||||
com.sololearn
|
||||
com.sonelli.juicessh
|
||||
com.sparkslab.dcardreader
|
||||
com.spotify.music
|
||||
com.tencent.huatuo
|
||||
com.termux
|
||||
@@ -173,10 +179,13 @@ com.twitter.android
|
||||
com.u91porn
|
||||
com.u9porn
|
||||
com.ubisoft.dance.justdance2015companion
|
||||
com.udn.news
|
||||
com.utopia.pxview
|
||||
com.valvesoftware.android.steam.communimunity
|
||||
com.valvesoftware.android.steam.community
|
||||
com.vanced.manager
|
||||
com.vanced.android.youtube
|
||||
com.vanced.android.apps.youtube.music
|
||||
com.mgoogle.android.gms
|
||||
com.vimeo.android.videoapp
|
||||
com.vivaldi.browser
|
||||
com.vivaldi.browser.snapshot
|
||||
@@ -186,10 +195,12 @@ com.wire
|
||||
com.wuxiangai.refactor
|
||||
com.xda.labs
|
||||
com.xvideos.app
|
||||
com.yahoo.mobile.client.android.superapp
|
||||
com.yandex.browser
|
||||
com.yandex.browser.beta
|
||||
com.yandex.browser.alpha
|
||||
com.z28j.feel
|
||||
com.zhiliaoapp.musically
|
||||
con.medium.reader
|
||||
de.apkgrabber
|
||||
de.robv.android.xposed.installer
|
||||
@@ -210,6 +221,7 @@ jp.bokete.app.android
|
||||
jp.naver.line.android
|
||||
jp.pxv.android
|
||||
luo.speedometergpspro
|
||||
m.cna.com.tw.App
|
||||
mark.via.gp
|
||||
me.tshine.easymark
|
||||
net.teeha.android.url_shortener
|
||||
@@ -226,6 +238,7 @@ org.mozilla.firefox_beta
|
||||
org.mozilla.focus
|
||||
org.schabi.newpipe
|
||||
org.telegram.messenger
|
||||
org.telegram.messenger.web
|
||||
org.telegram.multi
|
||||
org.telegram.plus
|
||||
org.thunderdog.challegram
|
||||
@@ -239,3 +252,162 @@ tw.com.gamer.android.activecenter
|
||||
videodownloader.downloadvideo.downloader
|
||||
uk.co.bbc.learningenglish
|
||||
com.ted.android
|
||||
de.danoeh.antennapod
|
||||
com.kiwibrowser.browser
|
||||
nekox.messenger
|
||||
com.nextcloud.client
|
||||
com.aurora.store
|
||||
com.aurora.adroid
|
||||
chat.simplex.app
|
||||
im.vector.app
|
||||
network.loki.messenger
|
||||
eu.siacs.conversations
|
||||
xyz.nextalone.nagram
|
||||
net.programmierecke.radiodroid2
|
||||
im.fdx.v2ex
|
||||
ml.docilealligator.infinityforreddit
|
||||
com.bytemyth.ama
|
||||
app.vanadium.browser
|
||||
com.cakewallet.cake_wallet
|
||||
org.purplei2p.i2pd
|
||||
dk.tacit.android.foldersync.lite
|
||||
com.nononsenseapps.feeder
|
||||
com.m2049r.xmrwallet
|
||||
com.paypal.android.p2pmobile
|
||||
com.google.android.apps.googlevoice
|
||||
com.readdle.spark
|
||||
org.torproject.torbrowser
|
||||
com.deepl.mobiletranslator
|
||||
com.microsoft.bing
|
||||
com.keylesspalace.tusky
|
||||
com.ottplay.ottplay
|
||||
ru.iptvremote.android.iptv.pro
|
||||
jp.naver.line.android
|
||||
com.xmflsct.app.tooot
|
||||
com.forem.android
|
||||
app.revanced.android.youtube
|
||||
com.mgoogle.android.gms
|
||||
com.pionex.client
|
||||
vip.mytokenpocket
|
||||
im.token.app
|
||||
com.linekong.mars24
|
||||
com.feixiaohao
|
||||
com.aicoin.appandroid
|
||||
com.binance.dev
|
||||
com.kraken.trade
|
||||
com.okinc.okex.gp
|
||||
com.authy.authy
|
||||
air.com.rosettastone.mobile.CoursePlayer
|
||||
com.blizzard.bma
|
||||
com.amazon.kindle
|
||||
com.google.android.apps.fitness
|
||||
net.tsapps.appsales
|
||||
com.wemesh.android
|
||||
com.google.android.apps.googleassistant
|
||||
allen.town.focus.reader
|
||||
me.hyliu.fluent_reader_lite
|
||||
com.aljazeera.mobile
|
||||
com.ft.news
|
||||
de.marmaro.krt.ffupdater
|
||||
myradio.radio.fmradio.liveradio.radiostation
|
||||
com.google.earth
|
||||
eu.kanade.tachiyomi.j2k
|
||||
com.audials
|
||||
com.microsoft.skydrive
|
||||
com.mb.android.tg
|
||||
com.melodis.midomiMusicIdentifier.freemium
|
||||
com.foxnews.android
|
||||
ch.threema.app
|
||||
com.briarproject.briar.android
|
||||
foundation.e.apps
|
||||
com.valvesoftware.android.steam.friendsui
|
||||
com.imback.yeetalk
|
||||
so.onekey.app.wallet
|
||||
com.xc3fff0e.xmanager
|
||||
meditofoundation.medito
|
||||
com.picol.client
|
||||
com.streetwriters.notesnook
|
||||
shanghai.panewsApp.com
|
||||
org.coursera.android
|
||||
com.positron_it.zlib
|
||||
com.blizzard.messenger
|
||||
com.javdb.javrocket
|
||||
com.picacomic.fregata
|
||||
com.fxl.chacha
|
||||
me.proton.android.drive
|
||||
com.lastpass.lpandroid
|
||||
com.tradingview.tradingviewapp
|
||||
com.deviantart.android.damobile
|
||||
com.fusionmedia.investing
|
||||
com.ewa.ewaapp
|
||||
com.duolingo
|
||||
com.hellotalk
|
||||
io.github.huskydg.magisk
|
||||
com.jsy.xpgbox
|
||||
com.hostloc.app.hostloc
|
||||
com.dena.pokota
|
||||
com.vitorpamplona.amethyst
|
||||
com.zhiliaoapp.musically
|
||||
us.spotco.fennec_dos
|
||||
com.fongmi.android.tv
|
||||
com.pocketprep.android.itcybersecurity
|
||||
com.cloudtv
|
||||
com.glassdoor.app
|
||||
com.indeed.android.jobsearch
|
||||
com.linkedin.android
|
||||
com.github.tvbox.osc.bh
|
||||
com.example.douban
|
||||
com.sipnetic.app
|
||||
com.microsoft.rdc.androidx
|
||||
org.zwanoo.android.speedtest
|
||||
com.sonelli.juicessh
|
||||
com.scmp.newspulse
|
||||
org.lsposed.manager
|
||||
mnn.Android
|
||||
com.thomsonretuers.reuters
|
||||
com.guardian
|
||||
com.ttxapps.onesyncv2
|
||||
org.fcitx.fcitx5.android.updater
|
||||
com.tailscale.ipn
|
||||
tw.nekomimi.nekogram
|
||||
com.nexon.kartdrift
|
||||
io.syncapps.lemmy_sync
|
||||
com.seazon.feedme
|
||||
com.readwise
|
||||
de.spiritcroc.riotx
|
||||
com.openai.chatgpt
|
||||
io.changenow.changenow
|
||||
com.poe.android
|
||||
com.twingate
|
||||
com.blinkslabs.blinkist.android
|
||||
com.ichi2.anki
|
||||
md.obsidian
|
||||
com.musixmatch.android.lyrify
|
||||
com.cyber.turbo
|
||||
com.offsec.nethunter
|
||||
me.ghui.v2er
|
||||
com.samruston.twitter
|
||||
org.adaway
|
||||
org.swiftapps.swiftbackup
|
||||
com.zerotier.one
|
||||
com.quietmobile
|
||||
com.instagram.barcelona
|
||||
im.molly.app
|
||||
com.rvx.android.youtube
|
||||
com.deepl.mobiletranslator
|
||||
com.qingsong.yingmi
|
||||
com.lemurbrowser.exts
|
||||
com.silverdev.dnartdroid
|
||||
me.ash.reader
|
||||
de.tutao.tutanota
|
||||
dev.imranr.obtainium
|
||||
com.getsomeheadspace.android
|
||||
org.cromite.cromite
|
||||
com.nutomic.syncthingandroid
|
||||
com.bumble.app
|
||||
com.cnn.mobile.android.phone
|
||||
com.google.android.apps.authenticator2
|
||||
com.microsoft.copilot
|
||||
com.netflix.NGP.Storyteller
|
||||
com.Slack
|
||||
com.server.auditor.ssh.client
|
||||
@@ -1,8 +1,6 @@
|
||||
package com.v2ray.ang
|
||||
|
||||
import android.content.Context
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import androidx.multidex.MultiDexApplication
|
||||
import androidx.work.Configuration
|
||||
import androidx.work.WorkManager
|
||||
|
||||
@@ -8,8 +8,10 @@ import com.google.gson.JsonSerializer
|
||||
import com.google.gson.annotations.SerializedName
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean.OutSettingsBean.*
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean.OutSettingsBean.VnextBean.*
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean.OutSettingsBean.ServersBean
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean.OutSettingsBean.VnextBean
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean.OutSettingsBean.VnextBean.UsersBean
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean.OutSettingsBean.WireGuardBean
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.lang.reflect.Type
|
||||
|
||||
|
||||
@@ -4,7 +4,6 @@ import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.dto.V2rayConfig.OutboundBean
|
||||
import com.v2ray.ang.extension.isNotNullEmpty
|
||||
import kotlin.text.orEmpty
|
||||
|
||||
object HttpFmt : FmtBase() {
|
||||
fun toOutbound(profileItem: ProfileItem): OutboundBean? {
|
||||
|
||||
@@ -7,7 +7,6 @@ import com.v2ray.ang.extension.idnHost
|
||||
import com.v2ray.ang.extension.isNotNullEmpty
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.net.URI
|
||||
import kotlin.text.orEmpty
|
||||
|
||||
object SocksFmt : FmtBase() {
|
||||
fun parse(str: String): ProfileItem? {
|
||||
|
||||
@@ -9,7 +9,6 @@ import com.v2ray.ang.extension.idnHost
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.net.URI
|
||||
import kotlin.text.orEmpty
|
||||
|
||||
object TrojanFmt : FmtBase() {
|
||||
fun parse(str: String): ProfileItem? {
|
||||
|
||||
@@ -14,7 +14,6 @@ import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.JsonUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.net.URI
|
||||
import kotlin.text.orEmpty
|
||||
|
||||
object VmessFmt : FmtBase() {
|
||||
fun parse(str: String): ProfileItem? {
|
||||
|
||||
@@ -8,7 +8,6 @@ import com.v2ray.ang.dto.V2rayConfig.OutboundBean
|
||||
import com.v2ray.ang.extension.idnHost
|
||||
import com.v2ray.ang.util.Utils
|
||||
import java.net.URI
|
||||
import kotlin.text.orEmpty
|
||||
|
||||
object WireguardFmt : FmtBase() {
|
||||
fun parse(str: String): ProfileItem? {
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.v2ray.ang.fmt.TrojanFmt
|
||||
import com.v2ray.ang.fmt.VlessFmt
|
||||
import com.v2ray.ang.fmt.VmessFmt
|
||||
import com.v2ray.ang.fmt.WireguardFmt
|
||||
import com.v2ray.ang.util.HttpUtil
|
||||
import com.v2ray.ang.util.JsonUtil
|
||||
import com.v2ray.ang.util.QRCodeDecoder
|
||||
import com.v2ray.ang.util.Utils
|
||||
@@ -346,7 +347,7 @@ object AngConfigManager {
|
||||
if (!it.second.enabled) {
|
||||
return 0
|
||||
}
|
||||
val url = Utils.idnToASCII(it.second.url)
|
||||
val url = HttpUtil.idnToASCII(it.second.url)
|
||||
if (!Utils.isValidUrl(url)) {
|
||||
return 0
|
||||
}
|
||||
@@ -354,7 +355,7 @@ object AngConfigManager {
|
||||
|
||||
var configText = try {
|
||||
val httpPort = SettingsManager.getHttpPort()
|
||||
Utils.getUrlContentWithCustomUserAgent(url, 30000, httpPort)
|
||||
HttpUtil.getUrlContentWithUserAgent(url, 30000, httpPort)
|
||||
} catch (e: Exception) {
|
||||
Log.e(AppConfig.ANG_PACKAGE, "Update subscription: proxy not ready or other error, try……")
|
||||
//e.printStackTrace()
|
||||
@@ -362,7 +363,7 @@ object AngConfigManager {
|
||||
}
|
||||
if (configText.isEmpty()) {
|
||||
configText = try {
|
||||
Utils.getUrlContentWithCustomUserAgent(url)
|
||||
HttpUtil.getUrlContentWithUserAgent(url)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
""
|
||||
|
||||
@@ -22,7 +22,6 @@ import com.v2ray.ang.util.Utils.parseInt
|
||||
import java.io.File
|
||||
import java.io.FileOutputStream
|
||||
import java.util.Collections
|
||||
import kotlin.Int
|
||||
|
||||
object SettingsManager {
|
||||
|
||||
|
||||
-1
@@ -16,7 +16,6 @@
|
||||
package com.v2ray.ang.helper
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.animation.ValueAnimator.AnimatorUpdateListener
|
||||
import android.graphics.Canvas
|
||||
import android.view.animation.DecelerateInterpolator
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
|
||||
@@ -13,6 +13,6 @@ class BootReceiver : BroadcastReceiver() {
|
||||
//Check if flag is true and a server is selected
|
||||
if (!MmkvManager.decodeStartOnBoot() || MmkvManager.getSelectServer().isNullOrEmpty()) return
|
||||
//Start v2ray
|
||||
V2RayServiceManager.startV2Ray(context)
|
||||
V2RayServiceManager.startVService(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,9 +5,7 @@ import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.text.TextUtils
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.service.V2RayServiceManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
|
||||
class TaskerReceiver : BroadcastReceiver() {
|
||||
|
||||
@@ -22,13 +20,12 @@ class TaskerReceiver : BroadcastReceiver() {
|
||||
return
|
||||
} else if (switch) {
|
||||
if (guid == AppConfig.TASKER_DEFAULT_GUID) {
|
||||
Utils.startVServiceFromToggle(context)
|
||||
V2RayServiceManager.startVServiceFromToggle(context)
|
||||
} else {
|
||||
MmkvManager.setSelectServer(guid)
|
||||
V2RayServiceManager.startV2Ray(context)
|
||||
V2RayServiceManager.startVService(context, guid)
|
||||
}
|
||||
} else {
|
||||
Utils.stopVService(context)
|
||||
V2RayServiceManager.stopVService(context)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
|
||||
@@ -11,7 +11,6 @@ import android.widget.RemoteViews
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.service.V2RayServiceManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
|
||||
class WidgetProvider : AppWidgetProvider() {
|
||||
/**
|
||||
@@ -19,7 +18,7 @@ class WidgetProvider : AppWidgetProvider() {
|
||||
*/
|
||||
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds)
|
||||
updateWidgetBackground(context, appWidgetManager, appWidgetIds, V2RayServiceManager.v2rayPoint.isRunning)
|
||||
updateWidgetBackground(context, appWidgetManager, appWidgetIds, V2RayServiceManager.isRunning())
|
||||
}
|
||||
|
||||
|
||||
@@ -57,10 +56,10 @@ class WidgetProvider : AppWidgetProvider() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
super.onReceive(context, intent)
|
||||
if (AppConfig.BROADCAST_ACTION_WIDGET_CLICK == intent.action) {
|
||||
if (V2RayServiceManager.v2rayPoint.isRunning) {
|
||||
Utils.stopVService(context)
|
||||
if (V2RayServiceManager.isRunning()) {
|
||||
V2RayServiceManager.stopVService(context)
|
||||
} else {
|
||||
Utils.startVServiceFromToggle(context)
|
||||
V2RayServiceManager.startVServiceFromToggle(context)
|
||||
}
|
||||
} else if (AppConfig.BROADCAST_ACTION_ACTIVITY == intent.action) {
|
||||
AppWidgetManager.getInstance(context)?.let { manager ->
|
||||
|
||||
@@ -0,0 +1,214 @@
|
||||
package com.v2ray.ang.service
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||
import com.v2ray.ang.AppConfig.TAG_DIRECT
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.extension.toSpeedString
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.ui.MainActivity
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlin.math.min
|
||||
|
||||
object NotificationService {
|
||||
private const val NOTIFICATION_ID = 1
|
||||
private const val NOTIFICATION_PENDING_INTENT_CONTENT = 0
|
||||
private const val NOTIFICATION_PENDING_INTENT_STOP_V2RAY = 1
|
||||
private const val NOTIFICATION_PENDING_INTENT_RESTART_V2RAY = 2
|
||||
private const val NOTIFICATION_ICON_THRESHOLD = 3000
|
||||
|
||||
private var lastQueryTime = 0L
|
||||
private var mBuilder: NotificationCompat.Builder? = null
|
||||
private var speedNotificationJob: Job? = null
|
||||
private var mNotificationManager: NotificationManager? = null
|
||||
|
||||
|
||||
fun startSpeedNotification(currentConfig: ProfileItem?) {
|
||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_SPEED_ENABLED) != true) return
|
||||
if (speedNotificationJob != null || V2RayServiceManager.isRunning() == false) return
|
||||
|
||||
lastQueryTime = System.currentTimeMillis()
|
||||
var lastZeroSpeed = false
|
||||
val outboundTags = currentConfig?.getAllOutboundTags()
|
||||
outboundTags?.remove(TAG_DIRECT)
|
||||
|
||||
speedNotificationJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
while (isActive) {
|
||||
val queryTime = System.currentTimeMillis()
|
||||
val sinceLastQueryInSeconds = (queryTime - lastQueryTime) / 1000.0
|
||||
var proxyTotal = 0L
|
||||
val text = StringBuilder()
|
||||
outboundTags?.forEach {
|
||||
val up = V2RayServiceManager.queryStats(it, AppConfig.UPLINK)
|
||||
val down = V2RayServiceManager.queryStats(it, AppConfig.DOWNLINK)
|
||||
if (up + down > 0) {
|
||||
appendSpeedString(text, it, up / sinceLastQueryInSeconds, down / sinceLastQueryInSeconds)
|
||||
proxyTotal += up + down
|
||||
}
|
||||
}
|
||||
val directUplink = V2RayServiceManager.queryStats(TAG_DIRECT, AppConfig.UPLINK)
|
||||
val directDownlink = V2RayServiceManager.queryStats(TAG_DIRECT, AppConfig.DOWNLINK)
|
||||
val zeroSpeed = proxyTotal == 0L && directUplink == 0L && directDownlink == 0L
|
||||
if (!zeroSpeed || !lastZeroSpeed) {
|
||||
if (proxyTotal == 0L) {
|
||||
appendSpeedString(text, outboundTags?.firstOrNull(), 0.0, 0.0)
|
||||
}
|
||||
appendSpeedString(
|
||||
text, TAG_DIRECT, directUplink / sinceLastQueryInSeconds,
|
||||
directDownlink / sinceLastQueryInSeconds
|
||||
)
|
||||
updateNotification(text.toString(), proxyTotal, directDownlink + directUplink)
|
||||
}
|
||||
lastZeroSpeed = zeroSpeed
|
||||
lastQueryTime = queryTime
|
||||
delay(3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun showNotification(currentConfig: ProfileItem?) {
|
||||
val service = getService() ?: return
|
||||
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
|
||||
val startMainIntent = Intent(service, MainActivity::class.java)
|
||||
val contentPendingIntent = PendingIntent.getActivity(service, NOTIFICATION_PENDING_INTENT_CONTENT, startMainIntent, flags)
|
||||
|
||||
val stopV2RayIntent = Intent(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
stopV2RayIntent.`package` = ANG_PACKAGE
|
||||
stopV2RayIntent.putExtra("key", AppConfig.MSG_STATE_STOP)
|
||||
val stopV2RayPendingIntent = PendingIntent.getBroadcast(service, NOTIFICATION_PENDING_INTENT_STOP_V2RAY, stopV2RayIntent, flags)
|
||||
|
||||
val restartV2RayIntent = Intent(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
restartV2RayIntent.`package` = ANG_PACKAGE
|
||||
restartV2RayIntent.putExtra("key", AppConfig.MSG_STATE_RESTART)
|
||||
val restartV2RayPendingIntent = PendingIntent.getBroadcast(service, NOTIFICATION_PENDING_INTENT_RESTART_V2RAY, restartV2RayIntent, flags)
|
||||
|
||||
val channelId =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createNotificationChannel()
|
||||
} else {
|
||||
// If earlier version channel ID is not used
|
||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||
""
|
||||
}
|
||||
|
||||
mBuilder = NotificationCompat.Builder(service, channelId)
|
||||
.setSmallIcon(R.drawable.ic_stat_name)
|
||||
.setContentTitle(currentConfig?.remarks)
|
||||
.setPriority(NotificationCompat.PRIORITY_MIN)
|
||||
.setOngoing(true)
|
||||
.setShowWhen(false)
|
||||
.setOnlyAlertOnce(true)
|
||||
.setContentIntent(contentPendingIntent)
|
||||
.addAction(
|
||||
R.drawable.ic_delete_24dp,
|
||||
service.getString(R.string.notification_action_stop_v2ray),
|
||||
stopV2RayPendingIntent
|
||||
)
|
||||
.addAction(
|
||||
R.drawable.ic_delete_24dp,
|
||||
service.getString(R.string.title_service_restart),
|
||||
restartV2RayPendingIntent
|
||||
)
|
||||
//.build()
|
||||
|
||||
//mBuilder?.setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE) //取消震动,铃声其他都不好使
|
||||
|
||||
service.startForeground(NOTIFICATION_ID, mBuilder?.build())
|
||||
}
|
||||
|
||||
fun cancelNotification() {
|
||||
val service = getService() ?: return
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
service.stopForeground(Service.STOP_FOREGROUND_REMOVE)
|
||||
} else {
|
||||
service.stopForeground(true)
|
||||
}
|
||||
|
||||
mBuilder = null
|
||||
speedNotificationJob?.cancel()
|
||||
speedNotificationJob = null
|
||||
}
|
||||
|
||||
fun stopSpeedNotification(currentConfig: ProfileItem?) {
|
||||
speedNotificationJob?.let {
|
||||
it.cancel()
|
||||
speedNotificationJob = null
|
||||
updateNotification(currentConfig?.remarks, 0, 0)
|
||||
}
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun createNotificationChannel(): String {
|
||||
val channelId = AppConfig.RAY_NG_CHANNEL_ID
|
||||
val channelName = AppConfig.RAY_NG_CHANNEL_NAME
|
||||
val chan = NotificationChannel(
|
||||
channelId,
|
||||
channelName, NotificationManager.IMPORTANCE_HIGH
|
||||
)
|
||||
chan.lightColor = Color.DKGRAY
|
||||
chan.importance = NotificationManager.IMPORTANCE_NONE
|
||||
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
||||
getNotificationManager()?.createNotificationChannel(chan)
|
||||
return channelId
|
||||
}
|
||||
|
||||
private fun updateNotification(contentText: String?, proxyTraffic: Long, directTraffic: Long) {
|
||||
if (mBuilder != null) {
|
||||
if (proxyTraffic < NOTIFICATION_ICON_THRESHOLD && directTraffic < NOTIFICATION_ICON_THRESHOLD) {
|
||||
mBuilder?.setSmallIcon(R.drawable.ic_stat_name)
|
||||
} else if (proxyTraffic > directTraffic) {
|
||||
mBuilder?.setSmallIcon(R.drawable.ic_stat_proxy)
|
||||
} else {
|
||||
mBuilder?.setSmallIcon(R.drawable.ic_stat_direct)
|
||||
}
|
||||
mBuilder?.setStyle(NotificationCompat.BigTextStyle().bigText(contentText))
|
||||
mBuilder?.setContentText(contentText) // Emui4.1 need content text even if style is set as BigTextStyle
|
||||
getNotificationManager()?.notify(NOTIFICATION_ID, mBuilder?.build())
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNotificationManager(): NotificationManager? {
|
||||
if (mNotificationManager == null) {
|
||||
val service = getService() ?: return null
|
||||
mNotificationManager = service.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
}
|
||||
return mNotificationManager
|
||||
}
|
||||
|
||||
private fun appendSpeedString(text: StringBuilder, name: String?, up: Double, down: Double) {
|
||||
var n = name ?: "no tag"
|
||||
n = n.substring(0, min(n.length, 6))
|
||||
text.append(n)
|
||||
for (i in n.length..6 step 2) {
|
||||
text.append("\t")
|
||||
}
|
||||
text.append("• ${up.toLong().toSpeedString()}↑ ${down.toLong().toSpeedString()}↓\n")
|
||||
}
|
||||
|
||||
private fun getService(): Service? {
|
||||
return V2RayServiceManager.serviceControl?.get()?.getService()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -26,7 +26,7 @@ class QSTileService : TileService() {
|
||||
qsTile?.icon = Icon.createWithResource(applicationContext, R.drawable.ic_stat_name)
|
||||
} else if (state == Tile.STATE_ACTIVE) {
|
||||
qsTile?.state = Tile.STATE_ACTIVE
|
||||
qsTile?.label = V2RayServiceManager.currentConfig?.remarks
|
||||
qsTile?.label = V2RayServiceManager.getRunningServerName()
|
||||
qsTile?.icon = Icon.createWithResource(applicationContext, R.drawable.ic_stat_name)
|
||||
}
|
||||
|
||||
@@ -64,11 +64,11 @@ class QSTileService : TileService() {
|
||||
super.onClick()
|
||||
when (qsTile.state) {
|
||||
Tile.STATE_INACTIVE -> {
|
||||
Utils.startVServiceFromToggle(this)
|
||||
V2RayServiceManager.startVServiceFromToggle(this)
|
||||
}
|
||||
|
||||
Tile.STATE_ACTIVE -> {
|
||||
Utils.stopVService(this)
|
||||
V2RayServiceManager.stopVService(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,57 +1,38 @@
|
||||
package com.v2ray.ang.service
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.IntentFilter
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.annotation.RequiresApi
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.v2ray.ang.AppConfig
|
||||
import com.v2ray.ang.AppConfig.ANG_PACKAGE
|
||||
import com.v2ray.ang.AppConfig.TAG_DIRECT
|
||||
import com.v2ray.ang.AppConfig.VPN
|
||||
import com.v2ray.ang.R
|
||||
import com.v2ray.ang.dto.EConfigType
|
||||
import com.v2ray.ang.dto.ProfileItem
|
||||
import com.v2ray.ang.extension.toSpeedString
|
||||
import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.handler.V2rayConfigManager
|
||||
import com.v2ray.ang.ui.MainActivity
|
||||
import com.v2ray.ang.util.MessageUtil
|
||||
import com.v2ray.ang.util.PluginUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
import go.Seq
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
import kotlinx.coroutines.launch
|
||||
import libv2ray.Libv2ray
|
||||
import libv2ray.V2RayPoint
|
||||
import libv2ray.V2RayVPNServiceSupportsSet
|
||||
import java.lang.ref.SoftReference
|
||||
import kotlin.math.min
|
||||
|
||||
object V2RayServiceManager {
|
||||
private const val NOTIFICATION_ID = 1
|
||||
private const val NOTIFICATION_PENDING_INTENT_CONTENT = 0
|
||||
private const val NOTIFICATION_PENDING_INTENT_STOP_V2RAY = 1
|
||||
private const val NOTIFICATION_PENDING_INTENT_RESTART_V2RAY = 2
|
||||
private const val NOTIFICATION_ICON_THRESHOLD = 3000
|
||||
|
||||
val v2rayPoint: V2RayPoint = Libv2ray.newV2RayPoint(V2RayCallback(), Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1)
|
||||
private val v2rayPoint: V2RayPoint = Libv2ray.newV2RayPoint(V2RayCallback(), Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1)
|
||||
private val mMsgReceive = ReceiveMessageHandler()
|
||||
private var currentConfig: ProfileItem? = null
|
||||
|
||||
var serviceControl: SoftReference<ServiceControl>? = null
|
||||
set(value) {
|
||||
@@ -59,14 +40,33 @@ object V2RayServiceManager {
|
||||
Seq.setContext(value?.get()?.getService()?.applicationContext)
|
||||
Libv2ray.initV2Env(Utils.userAssetPath(value?.get()?.getService()), Utils.getDeviceIdForXUDPBaseKey())
|
||||
}
|
||||
var currentConfig: ProfileItem? = null
|
||||
|
||||
private var lastQueryTime = 0L
|
||||
private var mBuilder: NotificationCompat.Builder? = null
|
||||
private var speedNotificationJob: Job? = null
|
||||
private var mNotificationManager: NotificationManager? = null
|
||||
fun startVServiceFromToggle(context: Context): Boolean {
|
||||
if (MmkvManager.getSelectServer().isNullOrEmpty()) {
|
||||
context.toast(R.string.app_tile_first_use)
|
||||
return false
|
||||
}
|
||||
startContextService(context)
|
||||
return true
|
||||
}
|
||||
|
||||
fun startV2Ray(context: Context) {
|
||||
fun startVService(context: Context, guid: String? = null) {
|
||||
if (guid != null) {
|
||||
MmkvManager.setSelectServer(guid)
|
||||
}
|
||||
startContextService(context)
|
||||
}
|
||||
|
||||
fun stopVService(context: Context) {
|
||||
context.toast(R.string.toast_services_stop)
|
||||
MessageUtil.sendMsg2Service(context, AppConfig.MSG_STATE_STOP, "")
|
||||
}
|
||||
|
||||
fun isRunning() = v2rayPoint.isRunning
|
||||
|
||||
fun getRunningServerName() = currentConfig?.remarks.orEmpty()
|
||||
|
||||
private fun startContextService(context: Context) {
|
||||
if (v2rayPoint.isRunning) return
|
||||
val guid = MmkvManager.getSelectServer() ?: return
|
||||
val config = MmkvManager.decodeServerConfig(guid) ?: return
|
||||
@@ -82,7 +82,7 @@ object V2RayServiceManager {
|
||||
} else {
|
||||
context.toast(R.string.toast_services_start)
|
||||
}
|
||||
val intent = if ((MmkvManager.decodeSettingsString(AppConfig.PREF_MODE) ?: VPN) == VPN) {
|
||||
val intent = if ((MmkvManager.decodeSettingsString(AppConfig.PREF_MODE) ?: AppConfig.VPN) == AppConfig.VPN) {
|
||||
Intent(context.applicationContext, V2RayVpnService::class.java)
|
||||
} else {
|
||||
Intent(context.applicationContext, V2RayProxyOnlyService::class.java)
|
||||
@@ -94,6 +94,116 @@ object V2RayServiceManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refer to the official documentation for [registerReceiver](https://developer.android.com/reference/androidx/core/content/ContextCompat#registerReceiver(android.content.Context,android.content.BroadcastReceiver,android.content.IntentFilter,int):
|
||||
* `registerReceiver(Context, BroadcastReceiver, IntentFilter, int)`.
|
||||
*/
|
||||
|
||||
fun startV2rayPoint() {
|
||||
val service = getService() ?: return
|
||||
val guid = MmkvManager.getSelectServer() ?: return
|
||||
val config = MmkvManager.decodeServerConfig(guid) ?: return
|
||||
if (v2rayPoint.isRunning) {
|
||||
return
|
||||
}
|
||||
val result = V2rayConfigManager.getV2rayConfig(service, guid)
|
||||
if (!result.status)
|
||||
return
|
||||
|
||||
try {
|
||||
val mFilter = IntentFilter(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
mFilter.addAction(Intent.ACTION_SCREEN_ON)
|
||||
mFilter.addAction(Intent.ACTION_SCREEN_OFF)
|
||||
mFilter.addAction(Intent.ACTION_USER_PRESENT)
|
||||
ContextCompat.registerReceiver(service, mMsgReceive, mFilter, Utils.receiverFlags())
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
|
||||
v2rayPoint.configureFileContent = result.content
|
||||
v2rayPoint.domainName = result.domainPort
|
||||
currentConfig = config
|
||||
|
||||
try {
|
||||
v2rayPoint.runLoop(MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6))
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
|
||||
if (v2rayPoint.isRunning) {
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_STATE_START_SUCCESS, "")
|
||||
NotificationService.showNotification(currentConfig)
|
||||
|
||||
PluginUtil.runPlugin(service, config, result.domainPort)
|
||||
} else {
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_STATE_START_FAILURE, "")
|
||||
NotificationService.cancelNotification()
|
||||
}
|
||||
}
|
||||
|
||||
fun stopV2rayPoint() {
|
||||
val service = getService() ?: return
|
||||
|
||||
if (v2rayPoint.isRunning) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
v2rayPoint.stopLoop()
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_STATE_STOP_SUCCESS, "")
|
||||
NotificationService.cancelNotification()
|
||||
|
||||
try {
|
||||
service.unregisterReceiver(mMsgReceive)
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
PluginUtil.stopPlugin()
|
||||
}
|
||||
|
||||
fun queryStats(tag: String, link: String): Long {
|
||||
return v2rayPoint.queryStats(tag, link)
|
||||
}
|
||||
|
||||
private fun measureV2rayDelay() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val service = getService() ?: return@launch
|
||||
var time = -1L
|
||||
var errstr = ""
|
||||
if (v2rayPoint.isRunning) {
|
||||
try {
|
||||
time = v2rayPoint.measureDelay(Utils.getDelayTestUrl())
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, "measureV2rayDelay: $e")
|
||||
errstr = e.message?.substringAfter("\":") ?: "empty message"
|
||||
}
|
||||
if (time == -1L) {
|
||||
try {
|
||||
time = v2rayPoint.measureDelay(Utils.getDelayTestUrl(true))
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, "measureV2rayDelay: $e")
|
||||
errstr = e.message?.substringAfter("\":") ?: "empty message"
|
||||
}
|
||||
}
|
||||
}
|
||||
val result = if (time == -1L) {
|
||||
service.getString(R.string.connection_test_error, errstr)
|
||||
} else {
|
||||
service.getString(R.string.connection_test_available, time)
|
||||
}
|
||||
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_MEASURE_DELAY_SUCCESS, result)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getService(): Service? {
|
||||
return serviceControl?.get()?.getService()
|
||||
}
|
||||
|
||||
private class V2RayCallback : V2RayVPNServiceSupportsSet {
|
||||
override fun shutdown(): Long {
|
||||
val serviceControl = serviceControl?.get() ?: return -1
|
||||
@@ -124,8 +234,7 @@ object V2RayServiceManager {
|
||||
val serviceControl = serviceControl?.get() ?: return -1
|
||||
return try {
|
||||
serviceControl.startService()
|
||||
lastQueryTime = System.currentTimeMillis()
|
||||
startSpeedNotification()
|
||||
NotificationService.startSpeedNotification(currentConfig)
|
||||
0
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
@@ -134,77 +243,6 @@ object V2RayServiceManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Refer to the official documentation for [registerReceiver](https://developer.android.com/reference/androidx/core/content/ContextCompat#registerReceiver(android.content.Context,android.content.BroadcastReceiver,android.content.IntentFilter,int):
|
||||
* `registerReceiver(Context, BroadcastReceiver, IntentFilter, int)`.
|
||||
*/
|
||||
|
||||
fun startV2rayPoint() {
|
||||
val service = serviceControl?.get()?.getService() ?: return
|
||||
val guid = MmkvManager.getSelectServer() ?: return
|
||||
val config = MmkvManager.decodeServerConfig(guid) ?: return
|
||||
if (v2rayPoint.isRunning) {
|
||||
return
|
||||
}
|
||||
val result = V2rayConfigManager.getV2rayConfig(service, guid)
|
||||
if (!result.status)
|
||||
return
|
||||
|
||||
try {
|
||||
val mFilter = IntentFilter(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
mFilter.addAction(Intent.ACTION_SCREEN_ON)
|
||||
mFilter.addAction(Intent.ACTION_SCREEN_OFF)
|
||||
mFilter.addAction(Intent.ACTION_USER_PRESENT)
|
||||
ContextCompat.registerReceiver(service, mMsgReceive, mFilter, Utils.receiverFlags())
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
|
||||
v2rayPoint.configureFileContent = result.content
|
||||
v2rayPoint.domainName = result.domainPort
|
||||
currentConfig = config
|
||||
|
||||
try {
|
||||
v2rayPoint.runLoop(MmkvManager.decodeSettingsBool(AppConfig.PREF_PREFER_IPV6))
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
|
||||
if (v2rayPoint.isRunning) {
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_STATE_START_SUCCESS, "")
|
||||
showNotification()
|
||||
|
||||
PluginUtil.runPlugin(service, config, result.domainPort)
|
||||
} else {
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_STATE_START_FAILURE, "")
|
||||
cancelNotification()
|
||||
}
|
||||
}
|
||||
|
||||
fun stopV2rayPoint() {
|
||||
val service = serviceControl?.get()?.getService() ?: return
|
||||
|
||||
if (v2rayPoint.isRunning) {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
v2rayPoint.stopLoop()
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_STATE_STOP_SUCCESS, "")
|
||||
cancelNotification()
|
||||
|
||||
try {
|
||||
service.unregisterReceiver(mMsgReceive)
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, e.toString())
|
||||
}
|
||||
PluginUtil.stopPlugin()
|
||||
}
|
||||
|
||||
private class ReceiveMessageHandler : BroadcastReceiver() {
|
||||
override fun onReceive(ctx: Context?, intent: Intent?) {
|
||||
val serviceControl = serviceControl?.get() ?: return
|
||||
@@ -234,7 +272,7 @@ object V2RayServiceManager {
|
||||
Log.d(ANG_PACKAGE, "Restart Service")
|
||||
serviceControl.stopService()
|
||||
Thread.sleep(500L)
|
||||
startV2Ray(serviceControl.getService())
|
||||
startVService(serviceControl.getService())
|
||||
}
|
||||
|
||||
AppConfig.MSG_MEASURE_DELAY -> {
|
||||
@@ -245,213 +283,14 @@ object V2RayServiceManager {
|
||||
when (intent?.action) {
|
||||
Intent.ACTION_SCREEN_OFF -> {
|
||||
Log.d(ANG_PACKAGE, "SCREEN_OFF, stop querying stats")
|
||||
stopSpeedNotification()
|
||||
NotificationService.stopSpeedNotification(currentConfig)
|
||||
}
|
||||
|
||||
Intent.ACTION_SCREEN_ON -> {
|
||||
Log.d(ANG_PACKAGE, "SCREEN_ON, start querying stats")
|
||||
startSpeedNotification()
|
||||
NotificationService.startSpeedNotification(currentConfig)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun measureV2rayDelay() {
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
val service = serviceControl?.get()?.getService() ?: return@launch
|
||||
var time = -1L
|
||||
var errstr = ""
|
||||
if (v2rayPoint.isRunning) {
|
||||
try {
|
||||
time = v2rayPoint.measureDelay(Utils.getDelayTestUrl())
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, "measureV2rayDelay: $e")
|
||||
errstr = e.message?.substringAfter("\":") ?: "empty message"
|
||||
}
|
||||
if (time == -1L) {
|
||||
try {
|
||||
time = v2rayPoint.measureDelay(Utils.getDelayTestUrl(true))
|
||||
} catch (e: Exception) {
|
||||
Log.d(ANG_PACKAGE, "measureV2rayDelay: $e")
|
||||
errstr = e.message?.substringAfter("\":") ?: "empty message"
|
||||
}
|
||||
}
|
||||
}
|
||||
val result = if (time == -1L) {
|
||||
service.getString(R.string.connection_test_error, errstr)
|
||||
} else {
|
||||
service.getString(R.string.connection_test_available, time)
|
||||
}
|
||||
|
||||
MessageUtil.sendMsg2UI(service, AppConfig.MSG_MEASURE_DELAY_SUCCESS, result)
|
||||
}
|
||||
}
|
||||
|
||||
private fun showNotification() {
|
||||
val service = serviceControl?.get()?.getService() ?: return
|
||||
val flags = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
|
||||
} else {
|
||||
PendingIntent.FLAG_UPDATE_CURRENT
|
||||
}
|
||||
|
||||
val startMainIntent = Intent(service, MainActivity::class.java)
|
||||
val contentPendingIntent = PendingIntent.getActivity(service, NOTIFICATION_PENDING_INTENT_CONTENT, startMainIntent, flags)
|
||||
|
||||
val stopV2RayIntent = Intent(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
stopV2RayIntent.`package` = ANG_PACKAGE
|
||||
stopV2RayIntent.putExtra("key", AppConfig.MSG_STATE_STOP)
|
||||
val stopV2RayPendingIntent = PendingIntent.getBroadcast(service, NOTIFICATION_PENDING_INTENT_STOP_V2RAY, stopV2RayIntent, flags)
|
||||
|
||||
val restartV2RayIntent = Intent(AppConfig.BROADCAST_ACTION_SERVICE)
|
||||
restartV2RayIntent.`package` = ANG_PACKAGE
|
||||
restartV2RayIntent.putExtra("key", AppConfig.MSG_STATE_RESTART)
|
||||
val restartV2RayPendingIntent = PendingIntent.getBroadcast(service, NOTIFICATION_PENDING_INTENT_RESTART_V2RAY, restartV2RayIntent, flags)
|
||||
|
||||
val channelId =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
createNotificationChannel()
|
||||
} else {
|
||||
// If earlier version channel ID is not used
|
||||
// https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html#NotificationCompat.Builder(android.content.Context)
|
||||
""
|
||||
}
|
||||
|
||||
mBuilder = NotificationCompat.Builder(service, channelId)
|
||||
.setSmallIcon(R.drawable.ic_stat_name)
|
||||
.setContentTitle(currentConfig?.remarks)
|
||||
.setPriority(NotificationCompat.PRIORITY_MIN)
|
||||
.setOngoing(true)
|
||||
.setShowWhen(false)
|
||||
.setOnlyAlertOnce(true)
|
||||
.setContentIntent(contentPendingIntent)
|
||||
.addAction(
|
||||
R.drawable.ic_delete_24dp,
|
||||
service.getString(R.string.notification_action_stop_v2ray),
|
||||
stopV2RayPendingIntent
|
||||
)
|
||||
.addAction(
|
||||
R.drawable.ic_delete_24dp,
|
||||
service.getString(R.string.title_service_restart),
|
||||
restartV2RayPendingIntent
|
||||
)
|
||||
//.build()
|
||||
|
||||
//mBuilder?.setDefaults(NotificationCompat.FLAG_ONLY_ALERT_ONCE) //取消震动,铃声其他都不好使
|
||||
|
||||
service.startForeground(NOTIFICATION_ID, mBuilder?.build())
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.O)
|
||||
private fun createNotificationChannel(): String {
|
||||
val channelId = AppConfig.RAY_NG_CHANNEL_ID
|
||||
val channelName = AppConfig.RAY_NG_CHANNEL_NAME
|
||||
val chan = NotificationChannel(
|
||||
channelId,
|
||||
channelName, NotificationManager.IMPORTANCE_HIGH
|
||||
)
|
||||
chan.lightColor = Color.DKGRAY
|
||||
chan.importance = NotificationManager.IMPORTANCE_NONE
|
||||
chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
|
||||
getNotificationManager()?.createNotificationChannel(chan)
|
||||
return channelId
|
||||
}
|
||||
|
||||
fun cancelNotification() {
|
||||
val service = serviceControl?.get()?.getService() ?: return
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
service.stopForeground(Service.STOP_FOREGROUND_REMOVE)
|
||||
} else {
|
||||
service.stopForeground(true)
|
||||
}
|
||||
|
||||
mBuilder = null
|
||||
speedNotificationJob?.cancel()
|
||||
speedNotificationJob = null
|
||||
}
|
||||
|
||||
private fun updateNotification(contentText: String?, proxyTraffic: Long, directTraffic: Long) {
|
||||
if (mBuilder != null) {
|
||||
if (proxyTraffic < NOTIFICATION_ICON_THRESHOLD && directTraffic < NOTIFICATION_ICON_THRESHOLD) {
|
||||
mBuilder?.setSmallIcon(R.drawable.ic_stat_name)
|
||||
} else if (proxyTraffic > directTraffic) {
|
||||
mBuilder?.setSmallIcon(R.drawable.ic_stat_proxy)
|
||||
} else {
|
||||
mBuilder?.setSmallIcon(R.drawable.ic_stat_direct)
|
||||
}
|
||||
mBuilder?.setStyle(NotificationCompat.BigTextStyle().bigText(contentText))
|
||||
mBuilder?.setContentText(contentText) // Emui4.1 need content text even if style is set as BigTextStyle
|
||||
getNotificationManager()?.notify(NOTIFICATION_ID, mBuilder?.build())
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNotificationManager(): NotificationManager? {
|
||||
if (mNotificationManager == null) {
|
||||
val service = serviceControl?.get()?.getService() ?: return null
|
||||
mNotificationManager = service.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
|
||||
}
|
||||
return mNotificationManager
|
||||
}
|
||||
|
||||
private fun startSpeedNotification() {
|
||||
if (speedNotificationJob == null &&
|
||||
v2rayPoint.isRunning &&
|
||||
MmkvManager.decodeSettingsBool(AppConfig.PREF_SPEED_ENABLED) == true
|
||||
) {
|
||||
var lastZeroSpeed = false
|
||||
val outboundTags = currentConfig?.getAllOutboundTags()
|
||||
outboundTags?.remove(TAG_DIRECT)
|
||||
|
||||
speedNotificationJob = CoroutineScope(Dispatchers.IO).launch {
|
||||
while (isActive) {
|
||||
val queryTime = System.currentTimeMillis()
|
||||
val sinceLastQueryInSeconds = (queryTime - lastQueryTime) / 1000.0
|
||||
var proxyTotal = 0L
|
||||
val text = StringBuilder()
|
||||
outboundTags?.forEach {
|
||||
val up = v2rayPoint.queryStats(it, AppConfig.UPLINK)
|
||||
val down = v2rayPoint.queryStats(it, AppConfig.DOWNLINK)
|
||||
if (up + down > 0) {
|
||||
appendSpeedString(text, it, up / sinceLastQueryInSeconds, down / sinceLastQueryInSeconds)
|
||||
proxyTotal += up + down
|
||||
}
|
||||
}
|
||||
val directUplink = v2rayPoint.queryStats(TAG_DIRECT, AppConfig.UPLINK)
|
||||
val directDownlink = v2rayPoint.queryStats(TAG_DIRECT, AppConfig.DOWNLINK)
|
||||
val zeroSpeed = proxyTotal == 0L && directUplink == 0L && directDownlink == 0L
|
||||
if (!zeroSpeed || !lastZeroSpeed) {
|
||||
if (proxyTotal == 0L) {
|
||||
appendSpeedString(text, outboundTags?.firstOrNull(), 0.0, 0.0)
|
||||
}
|
||||
appendSpeedString(
|
||||
text, TAG_DIRECT, directUplink / sinceLastQueryInSeconds,
|
||||
directDownlink / sinceLastQueryInSeconds
|
||||
)
|
||||
updateNotification(text.toString(), proxyTotal, directDownlink + directUplink)
|
||||
}
|
||||
lastZeroSpeed = zeroSpeed
|
||||
lastQueryTime = queryTime
|
||||
delay(3000)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun appendSpeedString(text: StringBuilder, name: String?, up: Double, down: Double) {
|
||||
var n = name ?: "no tag"
|
||||
n = n.substring(0, min(n.length, 6))
|
||||
text.append(n)
|
||||
for (i in n.length..6 step 2) {
|
||||
text.append("\t")
|
||||
}
|
||||
text.append("• ${up.toLong().toSpeedString()}↑ ${down.toLong().toSpeedString()}↓\n")
|
||||
}
|
||||
|
||||
private fun stopSpeedNotification() {
|
||||
speedNotificationJob?.let {
|
||||
it.cancel()
|
||||
speedNotificationJob = null
|
||||
updateNotification(currentConfig?.remarks, 0, 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,7 +105,37 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
V2RayServiceManager.cancelNotification()
|
||||
NotificationService.cancelNotification()
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
V2RayServiceManager.startV2rayPoint()
|
||||
return START_STICKY
|
||||
//return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
override fun getService(): Service {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun startService() {
|
||||
setup()
|
||||
}
|
||||
|
||||
override fun stopService() {
|
||||
stopV2Ray(true)
|
||||
}
|
||||
|
||||
override fun vpnProtect(socket: Int): Boolean {
|
||||
return protect(socket)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun attachBaseContext(newBase: Context?) {
|
||||
val context = newBase?.let {
|
||||
MyContextWrapper.wrap(newBase, Utils.getLocale())
|
||||
}
|
||||
super.attachBaseContext(context)
|
||||
}
|
||||
|
||||
private fun setup() {
|
||||
@@ -114,6 +144,14 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
return
|
||||
}
|
||||
|
||||
if (setupVpnService() != true) {
|
||||
return
|
||||
}
|
||||
|
||||
runTun2socks()
|
||||
}
|
||||
|
||||
private fun setupVpnService(): Boolean {
|
||||
// If the old interface has exactly the same parameters, use it!
|
||||
// Configure a builder while parsing the parameters.
|
||||
val builder = Builder()
|
||||
@@ -152,7 +190,7 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
}
|
||||
// }
|
||||
|
||||
builder.setSession(V2RayServiceManager.currentConfig?.remarks.orEmpty())
|
||||
builder.setSession(V2RayServiceManager.getRunningServerName())
|
||||
|
||||
val selfPackageName = BuildConfig.APPLICATION_ID
|
||||
if (MmkvManager.decodeSettingsBool(AppConfig.PREF_PER_APP_PROXY)) {
|
||||
@@ -200,12 +238,13 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
try {
|
||||
mInterface = builder.establish()!!
|
||||
isRunning = true
|
||||
runTun2socks()
|
||||
return true
|
||||
} catch (e: Exception) {
|
||||
// non-nullable lateinit var
|
||||
e.printStackTrace()
|
||||
stopV2Ray()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun runTun2socks() {
|
||||
@@ -279,12 +318,6 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
}
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
V2RayServiceManager.startV2rayPoint()
|
||||
return START_STICKY
|
||||
//return super.onStartCommand(intent, flags, startId)
|
||||
}
|
||||
|
||||
private fun stopV2Ray(isForced: Boolean = true) {
|
||||
// val configName = defaultDPreference.getPrefString(PREF_CURR_CONFIG_GUID, "")
|
||||
// val emptyInfo = VpnNetworkInfo()
|
||||
@@ -324,27 +357,4 @@ class V2RayVpnService : VpnService(), ServiceControl {
|
||||
}
|
||||
}
|
||||
|
||||
override fun getService(): Service {
|
||||
return this
|
||||
}
|
||||
|
||||
override fun startService() {
|
||||
setup()
|
||||
}
|
||||
|
||||
override fun stopService() {
|
||||
stopV2Ray(true)
|
||||
}
|
||||
|
||||
override fun vpnProtect(socket: Int): Boolean {
|
||||
return protect(socket)
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
override fun attachBaseContext(newBase: Context?) {
|
||||
val context = newBase?.let {
|
||||
MyContextWrapper.wrap(newBase, Utils.getLocale())
|
||||
}
|
||||
super.attachBaseContext(context)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.content.FileProvider
|
||||
import com.tencent.mmkv.MMKV
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.v2ray.ang.ui
|
||||
|
||||
import android.Manifest
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.content.res.ColorStateList
|
||||
@@ -39,6 +38,7 @@ import com.v2ray.ang.handler.MigrateManager
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.helper.SimpleItemTouchHelperCallback
|
||||
import com.v2ray.ang.service.V2RayServiceManager
|
||||
import com.v2ray.ang.util.HttpUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
import com.v2ray.ang.viewmodel.MainViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -46,7 +46,6 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import me.drakeet.support.toast.ToastCompat
|
||||
import java.util.concurrent.TimeUnit
|
||||
|
||||
class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedListener {
|
||||
private val binding by lazy {
|
||||
@@ -141,7 +140,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
|
||||
binding.fab.setOnClickListener {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
Utils.stopVService(this)
|
||||
V2RayServiceManager.stopVService(this)
|
||||
} else if ((MmkvManager.decodeSettingsString(AppConfig.PREF_MODE) ?: VPN) == VPN) {
|
||||
val intent = VpnService.prepare(this)
|
||||
if (intent == null) {
|
||||
@@ -270,12 +269,12 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
toast(R.string.title_file_chooser)
|
||||
return
|
||||
}
|
||||
V2RayServiceManager.startV2Ray(this)
|
||||
V2RayServiceManager.startVService(this)
|
||||
}
|
||||
|
||||
fun restartV2Ray() {
|
||||
if (mainViewModel.isRunning.value == true) {
|
||||
Utils.stopVService(this)
|
||||
V2RayServiceManager.stopVService(this)
|
||||
}
|
||||
lifecycleScope.launch {
|
||||
delay(500)
|
||||
@@ -626,7 +625,7 @@ class MainActivity : BaseActivity(), NavigationView.OnNavigationItemSelectedList
|
||||
}
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val configText = try {
|
||||
Utils.getUrlContentWithCustomUserAgent(url)
|
||||
HttpUtil.getUrlContentWithUserAgent(url)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
""
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.v2ray.ang.service.V2RayServiceManager
|
||||
import com.v2ray.ang.util.Utils
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import java.util.*
|
||||
|
||||
class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<MainRecyclerAdapter.BaseViewHolder>(), ItemTouchHelperAdapter {
|
||||
companion object {
|
||||
@@ -165,11 +164,11 @@ class MainRecyclerAdapter(val activity: MainActivity) : RecyclerView.Adapter<Mai
|
||||
}
|
||||
notifyItemChanged(mActivity.mainViewModel.getPosition(guid))
|
||||
if (isRunning) {
|
||||
Utils.stopVService(mActivity)
|
||||
V2RayServiceManager.stopVService(mActivity)
|
||||
mActivity.lifecycleScope.launch {
|
||||
try {
|
||||
delay(500)
|
||||
V2RayServiceManager.startV2Ray(mActivity)
|
||||
V2RayServiceManager.startVService(mActivity)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.v2ray.ang.extension.toast
|
||||
import com.v2ray.ang.extension.v2RayApplication
|
||||
import com.v2ray.ang.handler.MmkvManager
|
||||
import com.v2ray.ang.util.AppManagerUtil
|
||||
import com.v2ray.ang.util.HttpUtil
|
||||
import com.v2ray.ang.util.Utils
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
@@ -154,7 +155,7 @@ class PerAppProxyActivity : BaseActivity() {
|
||||
toast(R.string.msg_downloading_content)
|
||||
val url = AppConfig.androidpackagenamelistUrl
|
||||
lifecycleScope.launch(Dispatchers.IO) {
|
||||
val content = Utils.getUrlContext(url, 5000)
|
||||
val content = HttpUtil.getUrlContent(url, 5000)
|
||||
launch(Dispatchers.Main) {
|
||||
Log.d(ANG_PACKAGE, content)
|
||||
selectProxyApp(content, true)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user