Update On Mon Jun 17 20:31:37 CEST 2024

This commit is contained in:
github-action[bot]
2024-06-17 20:31:38 +02:00
parent 8154b3f7d4
commit 42fe6da925
253 changed files with 5362 additions and 1716 deletions
+1
View File
@@ -675,3 +675,4 @@ Update On Thu Jun 13 20:31:26 CEST 2024
Update On Fri Jun 14 20:32:58 CEST 2024
Update On Sat Jun 15 20:30:01 CEST 2024
Update On Sun Jun 16 20:31:07 CEST 2024
Update On Mon Jun 17 20:31:27 CEST 2024
+50
View File
@@ -0,0 +1,50 @@
package utils
import (
"io"
"sync"
list "github.com/bahlo/generic-list-go"
)
type Callback[T any] struct {
list list.List[func(T)]
mutex sync.RWMutex
}
func NewCallback[T any]() *Callback[T] {
return &Callback[T]{}
}
func (c *Callback[T]) Register(item func(T)) io.Closer {
c.mutex.RLock()
defer c.mutex.RUnlock()
element := c.list.PushBack(item)
return &callbackCloser[T]{
element: element,
callback: c,
}
}
func (c *Callback[T]) Emit(item T) {
c.mutex.RLock()
defer c.mutex.RUnlock()
for element := c.list.Front(); element != nil; element = element.Next() {
go element.Value(item)
}
}
type callbackCloser[T any] struct {
element *list.Element[func(T)]
callback *Callback[T]
once sync.Once
}
func (c *callbackCloser[T]) Close() error {
c.once.Do(func() {
c.callback.mutex.Lock()
defer c.callback.mutex.Unlock()
c.callback.list.Remove(c.element)
})
return nil
}
+5 -3
View File
@@ -43,12 +43,12 @@ func (set *IpCidrSet) IsContainForString(ipString string) bool {
}
func (set *IpCidrSet) IsContain(ip netip.Addr) bool {
return set.toIPSet().Contains(ip.WithZone(""))
return set.ToIPSet().Contains(ip.WithZone(""))
}
func (set *IpCidrSet) Merge() error {
var b netipx.IPSetBuilder
b.AddSet(set.toIPSet())
b.AddSet(set.ToIPSet())
i, err := b.IPSet()
if err != nil {
return err
@@ -57,7 +57,9 @@ func (set *IpCidrSet) Merge() error {
return nil
}
func (set *IpCidrSet) toIPSet() *netipx.IPSet {
// ToIPSet not safe convert to *netipx.IPSet
// be careful, must be used after Merge
func (set *IpCidrSet) ToIPSet() *netipx.IPSet {
return (*netipx.IPSet)(unsafe.Pointer(set))
}
+6 -4
View File
@@ -11,8 +11,9 @@ import (
type Interface struct {
Index int
MTU int
Name string
Addrs []netip.Prefix
Addresses []netip.Prefix
HardwareAddr net.HardwareAddr
}
@@ -61,8 +62,9 @@ func Interfaces() (map[string]*Interface, error) {
r[iface.Name] = &Interface{
Index: iface.Index,
MTU: iface.MTU,
Name: iface.Name,
Addrs: ipNets,
Addresses: ipNets,
HardwareAddr: iface.HardwareAddr,
}
}
@@ -92,7 +94,7 @@ func IsLocalIp(ip netip.Addr) (bool, error) {
return false, err
}
for _, iface := range ifaces {
for _, addr := range iface.Addrs {
for _, addr := range iface.Addresses {
if addr.Contains(ip) {
return true, nil
}
@@ -120,7 +122,7 @@ func (iface *Interface) PickIPv6Addr(destination netip.Addr) (netip.Prefix, erro
func (iface *Interface) pickIPAddr(destination netip.Addr, accept func(addr netip.Prefix) bool) (netip.Prefix, error) {
var fallback netip.Prefix
for _, addr := range iface.Addrs {
for _, addr := range iface.Addresses {
if !accept(addr) {
continue
}
+64 -43
View File
@@ -246,31 +246,39 @@ type RawTun struct {
DNSHijack []string `yaml:"dns-hijack" json:"dns-hijack"`
AutoRoute bool `yaml:"auto-route" json:"auto-route"`
AutoDetectInterface bool `yaml:"auto-detect-interface"`
RedirectToTun []string `yaml:"-" json:"-"`
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
GSO bool `yaml:"gso" json:"gso,omitempty"`
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
//Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4_address,omitempty"`
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6_address,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"`
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6_address,omitempty"`
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
AutoRedirect bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict_route,omitempty"`
RouteAddress []netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
RouteAddressSet []string `yaml:"route-address-set" json:"route_address_set,omitempty"`
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"`
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4_route_address,omitempty"`
Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6_route_address,omitempty"`
Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4_route_exclude_address,omitempty"`
Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6_route_exclude_address,omitempty"`
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include_uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include_uid_range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude_uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude_uid_range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include_android_user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include_package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude_package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp_timeout,omitempty"`
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
TableIndex int `yaml:"table-index" json:"table-index"`
}
type RawTuicServer struct {
@@ -564,13 +572,13 @@ func ParseRawConfig(rawCfg *RawConfig) (*Config, error) {
}
config.RuleProviders = ruleProviders
subRules, err := parseSubRules(rawCfg, proxies)
subRules, err := parseSubRules(rawCfg, proxies, ruleProviders)
if err != nil {
return nil, err
}
config.SubRules = subRules
rules, err := parseRules(rawCfg.Rule, proxies, subRules, "rules")
rules, err := parseRules(rawCfg.Rule, proxies, ruleProviders, subRules, "rules")
if err != nil {
return nil, err
}
@@ -666,7 +674,6 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
updater.ExternalUIURL = cfg.ExternalUIURL
}
cfg.Tun.RedirectToTun = cfg.EBpf.RedirectToTun
return &General{
Inbound: Inbound{
Port: cfg.Port,
@@ -845,6 +852,7 @@ func parseListeners(cfg *RawConfig) (listeners map[string]C.InboundListener, err
}
func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes.RuleProvider, err error) {
RP.SetTunnel(T.Tunnel)
ruleProviders = map[string]providerTypes.RuleProvider{}
// parse rule provider
for name, mapping := range cfg.RuleProvider {
@@ -854,12 +862,11 @@ func parseRuleProviders(cfg *RawConfig) (ruleProviders map[string]providerTypes.
}
ruleProviders[name] = rp
RP.SetRuleProvider(rp)
}
return
}
func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy) (subRules map[string][]C.Rule, err error) {
func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider) (subRules map[string][]C.Rule, err error) {
subRules = map[string][]C.Rule{}
for name := range cfg.SubRules {
subRules[name] = make([]C.Rule, 0)
@@ -869,7 +876,7 @@ func parseSubRules(cfg *RawConfig, proxies map[string]C.Proxy) (subRules map[str
return nil, fmt.Errorf("sub-rule name is empty")
}
var rules []C.Rule
rules, err = parseRules(rawRules, proxies, subRules, fmt.Sprintf("sub-rules[%s]", name))
rules, err = parseRules(rawRules, proxies, ruleProviders, subRules, fmt.Sprintf("sub-rules[%s]", name))
if err != nil {
return nil, err
}
@@ -922,7 +929,7 @@ func verifySubRuleCircularReferences(n string, subRules map[string][]C.Rule, arr
return nil
}
func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[string][]C.Rule, format string) ([]C.Rule, error) {
func parseRules(rulesConfig []string, proxies map[string]C.Proxy, ruleProviders map[string]providerTypes.RuleProvider, subRules map[string][]C.Rule, format string) ([]C.Rule, error) {
var rules []C.Rule
// parse rules
@@ -971,6 +978,12 @@ func parseRules(rulesConfig []string, proxies map[string]C.Proxy, subRules map[s
return nil, fmt.Errorf("%s[%d] [%s] error: %s", format, idx, line, parseErr.Error())
}
for _, name := range parsed.ProviderNames() {
if _, ok := ruleProviders[name]; !ok {
return nil, fmt.Errorf("%s[%d] [%s] error: rule set [%s] not found", format, idx, line, name)
}
}
rules = append(rules, parsed)
}
@@ -1455,31 +1468,39 @@ func parseTun(rawTun RawTun, general *General) error {
DNSHijack: rawTun.DNSHijack,
AutoRoute: rawTun.AutoRoute,
AutoDetectInterface: rawTun.AutoDetectInterface,
RedirectToTun: rawTun.RedirectToTun,
MTU: rawTun.MTU,
GSO: rawTun.GSO,
GSOMaxSize: rawTun.GSOMaxSize,
Inet4Address: []netip.Prefix{tunAddressPrefix},
Inet6Address: rawTun.Inet6Address,
StrictRoute: rawTun.StrictRoute,
MTU: rawTun.MTU,
GSO: rawTun.GSO,
GSOMaxSize: rawTun.GSOMaxSize,
Inet4Address: []netip.Prefix{tunAddressPrefix},
Inet6Address: rawTun.Inet6Address,
IPRoute2TableIndex: rawTun.IPRoute2TableIndex,
IPRoute2RuleIndex: rawTun.IPRoute2RuleIndex,
AutoRedirect: rawTun.AutoRedirect,
AutoRedirectInputMark: rawTun.AutoRedirectInputMark,
AutoRedirectOutputMark: rawTun.AutoRedirectOutputMark,
StrictRoute: rawTun.StrictRoute,
RouteAddress: rawTun.RouteAddress,
RouteAddressSet: rawTun.RouteAddressSet,
RouteExcludeAddress: rawTun.RouteExcludeAddress,
RouteExcludeAddressSet: rawTun.RouteExcludeAddressSet,
IncludeInterface: rawTun.IncludeInterface,
ExcludeInterface: rawTun.ExcludeInterface,
IncludeUID: rawTun.IncludeUID,
IncludeUIDRange: rawTun.IncludeUIDRange,
ExcludeUID: rawTun.ExcludeUID,
ExcludeUIDRange: rawTun.ExcludeUIDRange,
IncludeAndroidUser: rawTun.IncludeAndroidUser,
IncludePackage: rawTun.IncludePackage,
ExcludePackage: rawTun.ExcludePackage,
EndpointIndependentNat: rawTun.EndpointIndependentNat,
UDPTimeout: rawTun.UDPTimeout,
FileDescriptor: rawTun.FileDescriptor,
Inet4RouteAddress: rawTun.Inet4RouteAddress,
Inet6RouteAddress: rawTun.Inet6RouteAddress,
Inet4RouteExcludeAddress: rawTun.Inet4RouteExcludeAddress,
Inet6RouteExcludeAddress: rawTun.Inet6RouteExcludeAddress,
IncludeInterface: rawTun.IncludeInterface,
ExcludeInterface: rawTun.ExcludeInterface,
IncludeUID: rawTun.IncludeUID,
IncludeUIDRange: rawTun.IncludeUIDRange,
ExcludeUID: rawTun.ExcludeUID,
ExcludeUIDRange: rawTun.ExcludeUIDRange,
IncludeAndroidUser: rawTun.IncludeAndroidUser,
IncludePackage: rawTun.IncludePackage,
ExcludePackage: rawTun.ExcludePackage,
EndpointIndependentNat: rawTun.EndpointIndependentNat,
UDPTimeout: rawTun.UDPTimeout,
FileDescriptor: rawTun.FileDescriptor,
TableIndex: rawTun.TableIndex,
}
return nil
+7 -1
View File
@@ -84,7 +84,7 @@ type RuleProvider interface {
Match(*constant.Metadata) bool
ShouldResolveIP() bool
ShouldFindProcess() bool
AsRule(adaptor string) constant.Rule
Strategy() any
}
// Rule Behavior
@@ -127,3 +127,9 @@ func (rf RuleFormat) String() string {
return "Unknown"
}
}
type Tunnel interface {
Providers() map[string]ProxyProvider
RuleProviders() map[string]RuleProvider
RuleUpdateCallback() *utils.Callback[RuleProvider]
}
+1
View File
@@ -116,4 +116,5 @@ type Rule interface {
Payload() string
ShouldResolveIP() bool
ShouldFindProcess() bool
ProviderNames() []string
}
+8 -5
View File
@@ -37,14 +37,17 @@ func (p geositePolicy) Match(domain string) []dnsClient {
}
type domainSetPolicy struct {
domainSetProvider provider.RuleProvider
dnsClients []dnsClient
tunnel provider.Tunnel
name string
dnsClients []dnsClient
}
func (p domainSetPolicy) Match(domain string) []dnsClient {
metadata := &C.Metadata{Host: domain}
if ok := p.domainSetProvider.Match(metadata); ok {
return p.dnsClients
if ruleProvider, ok := p.tunnel.RuleProviders()[p.name]; ok {
metadata := &C.Metadata{Host: domain}
if ok := ruleProvider.Match(metadata); ok {
return p.dnsClients
}
}
return nil
}
+5 -4
View File
@@ -414,7 +414,7 @@ type Config struct {
Pool *fakeip.Pool
Hosts *trie.DomainTrie[resolver.HostValue]
Policy *orderedmap.OrderedMap[string, []NameServer]
RuleProviders map[string]provider.RuleProvider
Tunnel provider.Tunnel
CacheAlgorithm string
}
@@ -502,11 +502,12 @@ func NewResolver(config Config) *Resolver {
key := temp[1]
switch prefix {
case "rule-set":
if p, ok := config.RuleProviders[key]; ok {
if _, ok := config.Tunnel.RuleProviders()[key]; ok {
log.Debugln("Adding rule-set policy: %s ", key)
insertPolicy(domainSetPolicy{
domainSetProvider: p,
dnsClients: cacheTransform(nameserver),
tunnel: config.Tunnel,
name: key,
dnsClients: cacheTransform(nameserver),
})
continue
} else {
+14 -2
View File
@@ -116,13 +116,25 @@ tun:
# mtu: 9000 # 最大传输单元
# gso: false # 启用通用分段卸载,仅支持 Linux
# gso-max-size: 65536 # 通用分段卸载包的最大大小
auto-redirect: false # 自动配置 iptables 以重定向 TCP 连接。仅支持 Linux。带有 auto-redirect 的 auto-route 现在可以在路由器上按预期工作,无需干预。
# strict-route: true # 将所有连接路由到 tun 来防止泄漏,但你的设备将无法其他设备被访问
inet4-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由
route-address-set: # 将指定规则集中的目标 IP CIDR 规则添加到防火墙, 不匹配的流量将绕过路由, 仅支持 Linux,且需要 nftables`auto-route` 和 `auto-redirect` 已启用。
- ruleset-1
- ruleset-2
route-exclude-address-set: # 将指定规则集中的目标 IP CIDR 规则添加到防火墙, 匹配的流量将绕过路由, 仅支持 Linux,且需要 nftables`auto-route` 和 `auto-redirect` 已启用。
- ruleset-3
- ruleset-4
route-address: # 启用 auto-route 时使用自定义路由而不是默认路由
- 0.0.0.0/1
- 128.0.0.0/1
inet6-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由
- "::/1"
- "8000::/1"
# inet4-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由(旧写法)
# - 0.0.0.0/1
# - 128.0.0.0/1
# inet6-route-address: # 启用 auto-route 时使用自定义路由而不是默认路由(旧写法)
# - "::/1"
# - "8000::/1"
# endpoint-independent-nat: false # 启用独立于端点的 NAT
# include-interface: # 限制被路由的接口。默认不限制,与 `exclude-interface` 冲突
# - "lan0"
+13 -12
View File
@@ -24,7 +24,7 @@ require (
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72
github.com/metacubex/sing-shadowsocks v0.2.6
github.com/metacubex/sing-shadowsocks2 v0.2.0
github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414
github.com/metacubex/sing-tun v0.2.7-0.20240617013029-d05cf9df9cfe
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f
github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63
github.com/metacubex/tfo-go v0.0.0-20240228025757-be1269474a66
@@ -35,8 +35,8 @@ require (
github.com/oschwald/maxminddb-golang v1.12.0
github.com/puzpuzpuz/xsync/v3 v3.1.0
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97
github.com/sagernet/sing v0.3.8
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a
github.com/sagernet/sing v0.5.0-alpha.10
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6
github.com/sagernet/sing-shadowtls v0.1.4
github.com/sagernet/wireguard-go v0.0.0-20231209092712-9a439356a62e
@@ -47,11 +47,11 @@ require (
github.com/wk8/go-ordered-map/v2 v2.1.8
go.uber.org/automaxprocs v1.5.3
go4.org/netipx v0.0.0-20231129151722-fdeea329fbba
golang.org/x/crypto v0.23.0
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842
golang.org/x/net v0.25.0
golang.org/x/crypto v0.24.0
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8
golang.org/x/net v0.26.0
golang.org/x/sync v0.7.0
golang.org/x/sys v0.20.0
golang.org/x/sys v0.21.0
google.golang.org/protobuf v1.34.1
gopkg.in/yaml.v3 v3.0.1
lukechampine.com/blake3 v1.3.0
@@ -92,6 +92,7 @@ require (
github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect
github.com/quic-go/qpack v0.4.0 // indirect
github.com/quic-go/qtls-go1-20 v0.4.1 // indirect
github.com/sagernet/nftables v0.3.0-beta.4 // indirect
github.com/sagernet/smux v0.0.0-20231208180855-7041f6ea79e7 // indirect
github.com/shoenig/go-m1cpu v0.1.6 // indirect
github.com/sina-ghaderi/poly1305 v0.0.0-20220724002748-c5926b03988b // indirect
@@ -100,14 +101,14 @@ require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923 // indirect
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 // indirect
github.com/vishvananda/netns v0.0.4 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
gitlab.com/yawning/bsaes.git v0.0.0-20190805113838-0a714cd429ec // indirect
go.uber.org/mock v0.4.0 // indirect
golang.org/x/mod v0.17.0 // indirect
golang.org/x/text v0.15.0 // indirect
golang.org/x/mod v0.18.0 // indirect
golang.org/x/text v0.16.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.21.0 // indirect
golang.org/x/tools v0.22.0 // indirect
)
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1
replace github.com/sagernet/sing => github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2
+25 -24
View File
@@ -108,16 +108,16 @@ github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e h1:bLYn3GuRvW
github.com/metacubex/quic-go v0.45.1-0.20240610004319-163fee60637e/go.mod h1:Yza2H7Ax1rxWPUcJx0vW+oAt9EsPuSiyQFhFabUPzwU=
github.com/metacubex/randv2 v0.2.0 h1:uP38uBvV2SxYfLj53kuvAjbND4RUDfFJjwr4UigMiLs=
github.com/metacubex/randv2 v0.2.0/go.mod h1:kFi2SzrQ5WuneuoLLCMkABtiBu6VRrMrWFqSPyj2cxY=
github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1 h1:7hDHLTmjgtRoAp59STwPQpe5Pinwi4cWex+FB3Ohvco=
github.com/metacubex/sing v0.0.0-20240518125217-e63d65a914d1/go.mod h1:+60H3Cm91RnL9dpVGWDPHt0zTQImO9Vfqt9a4rSambI=
github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2 h1:N5tidgg/FRmkgPw/AjRwhLUinKDx/ODCSbvv9xqRoLM=
github.com/metacubex/sing v0.0.0-20240617013425-3e3bd9dab6a2/go.mod h1:ARkL0gM13/Iv5VCZmci/NuoOlePoIsW0m7BWfln/Hak=
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72 h1:Wr4g1HCb5Z/QIFwFiVNjO2qL+dRu25+Mdn9xtAZZ+ew=
github.com/metacubex/sing-quic v0.0.0-20240518034124-7696d3f7da72/go.mod h1:g7Mxj7b7zm7YVqD975mk/hSmrb0A0G4bVvIMr2MMzn8=
github.com/metacubex/sing-shadowsocks v0.2.6 h1:6oEB3QcsFYnNiFeoevcXrCwJ3sAablwVSgtE9R3QeFQ=
github.com/metacubex/sing-shadowsocks v0.2.6/go.mod h1:zIkMeSnb8Mbf4hdqhw0pjzkn1d99YJ3JQm/VBg5WMTg=
github.com/metacubex/sing-shadowsocks2 v0.2.0 h1:hqwT/AfI5d5UdPefIzR6onGHJfDXs5zgOM5QSgaM/9A=
github.com/metacubex/sing-shadowsocks2 v0.2.0/go.mod h1:LCKF6j1P94zN8ZS+LXRK1gmYTVGB3squivBSXAFnOg8=
github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414 h1:IPxTZgQV6fVUBS8tozLMSFPHV3imYc/NbuGfp0bLQq0=
github.com/metacubex/sing-tun v0.2.7-0.20240521155100-e8316a45a414/go.mod h1:4VsMwZH1IlgPGFK1ZbBomZ/B2MYkTgs2+gnBAr5GOIo=
github.com/metacubex/sing-tun v0.2.7-0.20240617013029-d05cf9df9cfe h1:NrWjVEkRmEkdREVSpohMgEBoznS0PrRfJDr6iCV4348=
github.com/metacubex/sing-tun v0.2.7-0.20240617013029-d05cf9df9cfe/go.mod h1:WwJGbCx7bQcBzuQXiDOJvZH27R0kIjKNNlISIWsL6kM=
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f h1:QjXrHKbTMBip/C+R79bvbfr42xH1gZl3uFb0RELdZiQ=
github.com/metacubex/sing-vmess v0.1.9-0.20231207122118-72303677451f/go.mod h1:olVkD4FChQ5gKMHG4ZzuD7+fMkJY1G8vwOKpRehjrmY=
github.com/metacubex/sing-wireguard v0.0.0-20240321042214-224f96122a63 h1:AGyIB55UfQm/0ZH0HtQO9u3l//yjtHUpjeRjjPGfGRI=
@@ -159,8 +159,10 @@ github.com/quic-go/qtls-go1-20 v0.4.1/go.mod h1:X9Nh97ZL80Z+bX/gUXMbipO6OxdiDi58
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a h1:+NkI2670SQpQWvkkD2QgdTuzQG263YZ+2emfpeyGqW0=
github.com/sagernet/bbolt v0.0.0-20231014093535-ea5cb2fe9f0a/go.mod h1:63s7jpZqcDAIpj8oI/1v4Izok+npJOHACFCU6+huCkM=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97 h1:iL5gZI3uFp0X6EslacyapiRz7LLSJyr4RajF/BhMVyE=
github.com/sagernet/netlink v0.0.0-20220905062125-8043b4a9aa97/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a h1:ObwtHN2VpqE0ZNjr6sGeT00J8uU7JF4cNUdb44/Duis=
github.com/sagernet/netlink v0.0.0-20240612041022-b9a21c07ac6a/go.mod h1:xLnfdiJbSp8rNqYEdIW/6eDO4mVoogml14Bh2hSiFpM=
github.com/sagernet/nftables v0.3.0-beta.4 h1:kbULlAwAC3jvdGAC1P5Fa3GSxVwQJibNenDW2zaXr8I=
github.com/sagernet/nftables v0.3.0-beta.4/go.mod h1:OQXAjvjNGGFxaTgVCSTRIhYB5/llyVDeapVoENYBDS8=
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6 h1:5bCAkvDDzSMITiHFjolBwpdqYsvycdTu71FsMEFXQ14=
github.com/sagernet/sing-mux v0.2.1-0.20240124034317-9bfb33698bb6/go.mod h1:khzr9AOPocLa+g53dBplwNDz4gdsyx/YM3swtAhlkHQ=
github.com/sagernet/sing-shadowtls v0.1.4 h1:aTgBSJEgnumzFenPvc+kbD9/W0PywzWevnVpEx6Tw3k=
@@ -206,8 +208,8 @@ github.com/u-root/uio v0.0.0-20230220225925-ffce2a382923/go.mod h1:eLL9Nub3yfAho
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=
github.com/vishvananda/netns v0.0.4 h1:Oeaw1EM2JMxD51g9uhtC0D7erkIjgmj8+JZc26m1YX8=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
github.com/wk8/go-ordered-map/v2 v2.1.8 h1:5h/BUHu93oj4gIdvHHHGsScSTMijfx5PeYkE/fJgbpc=
github.com/wk8/go-ordered-map/v2 v2.1.8/go.mod h1:5nJHM5DyteebpVlHnWMV0rPz6Zp7+xBAnxjb1X5vnTw=
github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo0=
@@ -222,18 +224,18 @@ 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.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI=
golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8 h1:yixxcjnhBmY0nkL253HFVIm0JsFHwrHdT3Yh6szTnfY=
golang.org/x/exp v0.0.0-20240613232115-7f521ea00fb8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA=
golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
@@ -252,19 +254,18 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk=
golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw=
golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg=
+5 -7
View File
@@ -97,7 +97,7 @@ func ApplyConfig(cfg *config.Config, force bool) {
updateHosts(cfg.Hosts)
updateGeneral(cfg.General)
updateNTP(cfg.NTP)
updateDNS(cfg.DNS, cfg.RuleProviders, cfg.General.IPv6)
updateDNS(cfg.DNS, cfg.General.IPv6)
updateListeners(cfg.General, cfg.Listeners, force)
updateIPTables(cfg)
updateTun(cfg.General)
@@ -211,7 +211,7 @@ func updateNTP(c *config.NTP) {
}
}
func updateDNS(c *config.DNS, ruleProvider map[string]provider.RuleProvider, generalIPv6 bool) {
func updateDNS(c *config.DNS, generalIPv6 bool) {
if !c.Enable {
resolver.DefaultResolver = nil
resolver.DefaultHostMapper = nil
@@ -237,7 +237,7 @@ func updateDNS(c *config.DNS, ruleProvider map[string]provider.RuleProvider, gen
Default: c.DefaultNameserver,
Policy: c.NameServerPolicy,
ProxyServer: c.ProxyServerNameserver,
RuleProviders: ruleProvider,
Tunnel: tunnel.Tunnel,
CacheAlgorithm: c.CacheAlgorithm,
}
@@ -355,7 +355,7 @@ func updateTun(general *config.General) {
return
}
listener.ReCreateTun(general.Tun, tunnel.Tunnel)
listener.ReCreateRedirToTun(general.Tun.RedirectToTun)
listener.ReCreateRedirToTun(general.EBpf.RedirectToTun)
}
func updateSniffer(sniffer *config.Sniffer) {
@@ -507,9 +507,7 @@ func updateIPTables(cfg *config.Config) {
inboundInterface = iptables.InboundInterface
}
if dialer.DefaultRoutingMark.Load() == 0 {
dialer.DefaultRoutingMark.Store(2158)
}
dialer.DefaultRoutingMark.CompareAndSwap(0, 2158)
err = tproxy.SetTProxyIPTables(inboundInterface, bypass, uint16(tProxyPort), DnsRedirect, dnsPort.Port())
if err != nil {
+54 -18
View File
@@ -68,25 +68,34 @@ type tunSchema struct {
GSO *bool `yaml:"gso" json:"gso,omitempty"`
GSOMaxSize *uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
//Inet4Address *[]netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address *[]netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"`
Inet6Address *[]netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
IPRoute2TableIndex *int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
IPRoute2RuleIndex *int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
AutoRedirect *bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
AutoRedirectInputMark *uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
AutoRedirectOutputMark *uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
StrictRoute *bool `yaml:"strict-route" json:"strict-route,omitempty"`
RouteAddress *[]netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
RouteAddressSet *[]string `yaml:"route-address-set" json:"route_address_set,omitempty"`
RouteExcludeAddress *[]netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
RouteExcludeAddressSet *[]string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
IncludeInterface *[]string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface *[]string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"`
IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"`
ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
FileDescriptor *int `yaml:"file-descriptor" json:"file-descriptor"`
Inet4RouteAddress *[]netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
Inet6RouteAddress *[]netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"`
Inet4RouteExcludeAddress *[]netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4-route-exclude-address,omitempty"`
Inet6RouteExcludeAddress *[]netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6-route-exclude-address,omitempty"`
IncludeInterface *[]string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface *[]string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID *[]uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
IncludeUIDRange *[]string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
ExcludeUID *[]uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
ExcludeUIDRange *[]string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
IncludeAndroidUser *[]int `yaml:"include-android-user" json:"include-android-user,omitempty"`
IncludePackage *[]string `yaml:"include-package" json:"include-package,omitempty"`
ExcludePackage *[]string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat *bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout *int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
FileDescriptor *int `yaml:"file-descriptor" json:"file-descriptor"`
TableIndex *int `yaml:"table-index" json:"table-index"`
}
type tuicServerSchema struct {
@@ -157,6 +166,36 @@ func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun {
if p.Inet6Address != nil {
def.Inet6Address = *p.Inet6Address
}
if p.IPRoute2TableIndex != nil {
def.IPRoute2TableIndex = *p.IPRoute2TableIndex
}
if p.IPRoute2RuleIndex != nil {
def.IPRoute2RuleIndex = *p.IPRoute2RuleIndex
}
if p.AutoRedirect != nil {
def.AutoRedirect = *p.AutoRedirect
}
if p.AutoRedirectInputMark != nil {
def.AutoRedirectInputMark = *p.AutoRedirectInputMark
}
if p.AutoRedirectOutputMark != nil {
def.AutoRedirectOutputMark = *p.AutoRedirectOutputMark
}
if p.StrictRoute != nil {
def.StrictRoute = *p.StrictRoute
}
if p.RouteAddress != nil {
def.RouteAddress = *p.RouteAddress
}
if p.RouteAddressSet != nil {
def.RouteAddressSet = *p.RouteAddressSet
}
if p.RouteExcludeAddress != nil {
def.RouteExcludeAddress = *p.RouteExcludeAddress
}
if p.RouteExcludeAddressSet != nil {
def.RouteExcludeAddressSet = *p.RouteExcludeAddressSet
}
if p.Inet4RouteAddress != nil {
def.Inet4RouteAddress = *p.Inet4RouteAddress
}
@@ -205,9 +244,6 @@ func pointerOrDefaultTun(p *tunSchema, def LC.Tun) LC.Tun {
if p.FileDescriptor != nil {
def.FileDescriptor = *p.FileDescriptor
}
if p.TableIndex != nil {
def.TableIndex = *p.TableIndex
}
}
return def
}
+28 -19
View File
@@ -27,27 +27,36 @@ type Tun struct {
AutoDetectInterface bool `yaml:"auto-detect-interface" json:"auto-detect-interface"`
RedirectToTun []string `yaml:"-" json:"-"`
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
GSO bool `yaml:"gso" json:"gso,omitempty"`
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
MTU uint32 `yaml:"mtu" json:"mtu,omitempty"`
GSO bool `yaml:"gso" json:"gso,omitempty"`
GSOMaxSize uint32 `yaml:"gso-max-size" json:"gso-max-size,omitempty"`
Inet4Address []netip.Prefix `yaml:"inet4-address" json:"inet4-address,omitempty"`
Inet6Address []netip.Prefix `yaml:"inet6-address" json:"inet6-address,omitempty"`
IPRoute2TableIndex int `yaml:"iproute2-table-index" json:"iproute2_table_index,omitempty"`
IPRoute2RuleIndex int `yaml:"iproute2-rule-index" json:"iproute2_rule_index,omitempty"`
AutoRedirect bool `yaml:"auto-redirect" json:"auto_redirect,omitempty"`
AutoRedirectInputMark uint32 `yaml:"auto-redirect-input-mark" json:"auto_redirect_input_mark,omitempty"`
AutoRedirectOutputMark uint32 `yaml:"auto-redirect-output-mark" json:"auto_redirect_output_mark,omitempty"`
StrictRoute bool `yaml:"strict-route" json:"strict-route,omitempty"`
RouteAddress []netip.Prefix `yaml:"route-address" json:"route_address,omitempty"`
RouteAddressSet []string `yaml:"route-address-set" json:"route_address_set,omitempty"`
RouteExcludeAddress []netip.Prefix `yaml:"route-exclude-address" json:"route_exclude_address,omitempty"`
RouteExcludeAddressSet []string `yaml:"route-exclude-address-set" json:"route_exclude_address_set,omitempty"`
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
Inet4RouteAddress []netip.Prefix `yaml:"inet4-route-address" json:"inet4-route-address,omitempty"`
Inet6RouteAddress []netip.Prefix `yaml:"inet6-route-address" json:"inet6-route-address,omitempty"`
Inet4RouteExcludeAddress []netip.Prefix `yaml:"inet4-route-exclude-address" json:"inet4-route-exclude-address,omitempty"`
Inet6RouteExcludeAddress []netip.Prefix `yaml:"inet6-route-exclude-address" json:"inet6-route-exclude-address,omitempty"`
IncludeInterface []string `yaml:"include-interface" json:"include-interface,omitempty"`
ExcludeInterface []string `yaml:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID []uint32 `yaml:"include-uid" json:"include-uid,omitempty"`
IncludeUIDRange []string `yaml:"include-uid-range" json:"include-uid-range,omitempty"`
ExcludeUID []uint32 `yaml:"exclude-uid" json:"exclude-uid,omitempty"`
ExcludeUIDRange []string `yaml:"exclude-uid-range" json:"exclude-uid-range,omitempty"`
IncludeAndroidUser []int `yaml:"include-android-user" json:"include-android-user,omitempty"`
IncludePackage []string `yaml:"include-package" json:"include-package,omitempty"`
ExcludePackage []string `yaml:"exclude-package" json:"exclude-package,omitempty"`
EndpointIndependentNat bool `yaml:"endpoint-independent-nat" json:"endpoint-independent-nat,omitempty"`
UDPTimeout int64 `yaml:"udp-timeout" json:"udp-timeout,omitempty"`
FileDescriptor int `yaml:"file-descriptor" json:"file-descriptor"`
TableIndex int `yaml:"table-index" json:"table-index"`
}
+72 -44
View File
@@ -18,29 +18,38 @@ type TunOption struct {
AutoRoute bool `inbound:"auto-route,omitempty"`
AutoDetectInterface bool `inbound:"auto-detect-interface,omitempty"`
MTU uint32 `inbound:"mtu,omitempty"`
GSO bool `inbound:"gso,omitempty"`
GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"`
Inet4Address []string `inbound:"inet4_address,omitempty"`
Inet6Address []string `inbound:"inet6_address,omitempty"`
StrictRoute bool `inbound:"strict_route,omitempty"`
MTU uint32 `inbound:"mtu,omitempty"`
GSO bool `inbound:"gso,omitempty"`
GSOMaxSize uint32 `inbound:"gso-max-size,omitempty"`
Inet4Address []string `inbound:"inet4_address,omitempty"`
Inet6Address []string `inbound:"inet6_address,omitempty"`
IPRoute2TableIndex int `inbound:"iproute2-table-index"`
IPRoute2RuleIndex int `inbound:"iproute2-rule-index"`
AutoRedirect bool `inbound:"auto-redirect"`
AutoRedirectInputMark uint32 `inbound:"auto-redirect-input-mark"`
AutoRedirectOutputMark uint32 `inbound:"auto-redirect-output-mark"`
StrictRoute bool `inbound:"strict_route,omitempty"`
RouteAddress []string `inbound:"route-address"`
RouteAddressSet []string `inbound:"route-address-set"`
RouteExcludeAddress []string `inbound:"route-exclude-address"`
RouteExcludeAddressSet []string `inbound:"route-exclude-address-set"`
IncludeInterface []string `inbound:"include-interface,omitempty"`
ExcludeInterface []string `inbound:"exclude-interface"`
IncludeUID []uint32 `inbound:"include_uid,omitempty"`
IncludeUIDRange []string `inbound:"include_uid_range,omitempty"`
ExcludeUID []uint32 `inbound:"exclude_uid,omitempty"`
ExcludeUIDRange []string `inbound:"exclude_uid_range,omitempty"`
IncludeAndroidUser []int `inbound:"include_android_user,omitempty"`
IncludePackage []string `inbound:"include_package,omitempty"`
ExcludePackage []string `inbound:"exclude_package,omitempty"`
EndpointIndependentNat bool `inbound:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `inbound:"udp_timeout,omitempty"`
FileDescriptor int `inbound:"file-descriptor,omitempty"`
Inet4RouteAddress []string `inbound:"inet4_route_address,omitempty"`
Inet6RouteAddress []string `inbound:"inet6_route_address,omitempty"`
Inet4RouteExcludeAddress []string `inbound:"inet4_route_exclude_address,omitempty"`
Inet6RouteExcludeAddress []string `inbound:"inet6_route_exclude_address,omitempty"`
IncludeInterface []string `inbound:"include-interface,omitempty"`
ExcludeInterface []string `inbound:"exclude-interface" json:"exclude-interface,omitempty"`
IncludeUID []uint32 `inbound:"include_uid,omitempty"`
IncludeUIDRange []string `inbound:"include_uid_range,omitempty"`
ExcludeUID []uint32 `inbound:"exclude_uid,omitempty"`
ExcludeUIDRange []string `inbound:"exclude_uid_range,omitempty"`
IncludeAndroidUser []int `inbound:"include_android_user,omitempty"`
IncludePackage []string `inbound:"include_package,omitempty"`
ExcludePackage []string `inbound:"exclude_package,omitempty"`
EndpointIndependentNat bool `inbound:"endpoint_independent_nat,omitempty"`
UDPTimeout int64 `inbound:"udp_timeout,omitempty"`
FileDescriptor int `inbound:"file-descriptor,omitempty"`
TableIndex int `inbound:"table-index,omitempty"`
}
func (o TunOption) Equal(config C.InboundConfig) bool {
@@ -63,6 +72,16 @@ func NewTun(options *TunOption) (*Tun, error) {
if !exist {
return nil, errors.New("invalid tun stack")
}
routeAddress, err := LC.StringSliceToNetipPrefixSlice(options.RouteAddress)
if err != nil {
return nil, err
}
routeExcludeAddress, err := LC.StringSliceToNetipPrefixSlice(options.RouteExcludeAddress)
if err != nil {
return nil, err
}
inet4Address, err := LC.StringSliceToNetipPrefixSlice(options.Inet4Address)
if err != nil {
return nil, err
@@ -91,35 +110,44 @@ func NewTun(options *TunOption) (*Tun, error) {
Base: base,
config: options,
tun: LC.Tun{
Enable: true,
Device: options.Device,
Stack: stack,
DNSHijack: options.DNSHijack,
AutoRoute: options.AutoRoute,
AutoDetectInterface: options.AutoDetectInterface,
MTU: options.MTU,
GSO: options.GSO,
GSOMaxSize: options.GSOMaxSize,
Inet4Address: inet4Address,
Inet6Address: inet6Address,
StrictRoute: options.StrictRoute,
Enable: true,
Device: options.Device,
Stack: stack,
DNSHijack: options.DNSHijack,
AutoRoute: options.AutoRoute,
AutoDetectInterface: options.AutoDetectInterface,
MTU: options.MTU,
GSO: options.GSO,
GSOMaxSize: options.GSOMaxSize,
Inet4Address: inet4Address,
Inet6Address: inet6Address,
IPRoute2TableIndex: options.IPRoute2TableIndex,
IPRoute2RuleIndex: options.IPRoute2RuleIndex,
AutoRedirect: options.AutoRedirect,
AutoRedirectInputMark: options.AutoRedirectInputMark,
AutoRedirectOutputMark: options.AutoRedirectOutputMark,
StrictRoute: options.StrictRoute,
RouteAddress: routeAddress,
RouteAddressSet: options.RouteAddressSet,
RouteExcludeAddress: routeExcludeAddress,
RouteExcludeAddressSet: options.RouteExcludeAddressSet,
IncludeInterface: options.IncludeInterface,
ExcludeInterface: options.ExcludeInterface,
IncludeUID: options.IncludeUID,
IncludeUIDRange: options.IncludeUIDRange,
ExcludeUID: options.ExcludeUID,
ExcludeUIDRange: options.ExcludeUIDRange,
IncludeAndroidUser: options.IncludeAndroidUser,
IncludePackage: options.IncludePackage,
ExcludePackage: options.ExcludePackage,
EndpointIndependentNat: options.EndpointIndependentNat,
UDPTimeout: options.UDPTimeout,
FileDescriptor: options.FileDescriptor,
Inet4RouteAddress: inet4RouteAddress,
Inet6RouteAddress: inet6RouteAddress,
Inet4RouteExcludeAddress: inet4RouteExcludeAddress,
Inet6RouteExcludeAddress: inet6RouteExcludeAddress,
IncludeInterface: options.IncludeInterface,
ExcludeInterface: options.ExcludeInterface,
IncludeUID: options.IncludeUID,
IncludeUIDRange: options.IncludeUIDRange,
ExcludeUID: options.ExcludeUID,
ExcludeUIDRange: options.ExcludeUIDRange,
IncludeAndroidUser: options.IncludeAndroidUser,
IncludePackage: options.IncludePackage,
ExcludePackage: options.ExcludePackage,
EndpointIndependentNat: options.EndpointIndependentNat,
UDPTimeout: options.UDPTimeout,
FileDescriptor: options.FileDescriptor,
TableIndex: options.TableIndex,
},
}, nil
}
+26 -2
View File
@@ -820,11 +820,15 @@ func hasTunConfigChange(tunConf *LC.Tun) bool {
LastTunConf.MTU != tunConf.MTU ||
LastTunConf.GSO != tunConf.GSO ||
LastTunConf.GSOMaxSize != tunConf.GSOMaxSize ||
LastTunConf.IPRoute2TableIndex != tunConf.IPRoute2TableIndex ||
LastTunConf.IPRoute2RuleIndex != tunConf.IPRoute2RuleIndex ||
LastTunConf.AutoRedirect != tunConf.AutoRedirect ||
LastTunConf.AutoRedirectInputMark != tunConf.AutoRedirectInputMark ||
LastTunConf.AutoRedirectOutputMark != tunConf.AutoRedirectOutputMark ||
LastTunConf.StrictRoute != tunConf.StrictRoute ||
LastTunConf.EndpointIndependentNat != tunConf.EndpointIndependentNat ||
LastTunConf.UDPTimeout != tunConf.UDPTimeout ||
LastTunConf.FileDescriptor != tunConf.FileDescriptor ||
LastTunConf.TableIndex != tunConf.TableIndex {
LastTunConf.FileDescriptor != tunConf.FileDescriptor {
return true
}
@@ -836,6 +840,22 @@ func hasTunConfigChange(tunConf *LC.Tun) bool {
return tunConf.DNSHijack[i] < tunConf.DNSHijack[j]
})
sort.Slice(tunConf.RouteAddress, func(i, j int) bool {
return tunConf.RouteAddress[i].String() < tunConf.RouteAddress[j].String()
})
sort.Slice(tunConf.RouteAddressSet, func(i, j int) bool {
return tunConf.RouteAddressSet[i] < tunConf.RouteAddressSet[j]
})
sort.Slice(tunConf.RouteExcludeAddress, func(i, j int) bool {
return tunConf.RouteExcludeAddress[i].String() < tunConf.RouteExcludeAddress[j].String()
})
sort.Slice(tunConf.RouteExcludeAddressSet, func(i, j int) bool {
return tunConf.RouteExcludeAddressSet[i] < tunConf.RouteExcludeAddressSet[j]
})
sort.Slice(tunConf.Inet4Address, func(i, j int) bool {
return tunConf.Inet4Address[i].String() < tunConf.Inet4Address[j].String()
})
@@ -897,6 +917,10 @@ func hasTunConfigChange(tunConf *LC.Tun) bool {
})
if !slices.Equal(tunConf.DNSHijack, LastTunConf.DNSHijack) ||
!slices.Equal(tunConf.RouteAddress, LastTunConf.RouteAddress) ||
!slices.Equal(tunConf.RouteAddressSet, LastTunConf.RouteAddressSet) ||
!slices.Equal(tunConf.RouteExcludeAddress, LastTunConf.RouteExcludeAddress) ||
!slices.Equal(tunConf.RouteExcludeAddressSet, LastTunConf.RouteExcludeAddressSet) ||
!slices.Equal(tunConf.Inet4Address, LastTunConf.Inet4Address) ||
!slices.Equal(tunConf.Inet6Address, LastTunConf.Inet6Address) ||
!slices.Equal(tunConf.Inet4RouteAddress, LastTunConf.Inet4RouteAddress) ||
+6
View File
@@ -198,6 +198,12 @@ func (h *ListenerHandler) NewError(ctx context.Context, err error) {
log.Warnln("%s listener get error: %+v", h.Type.String(), err)
}
func (h *ListenerHandler) TypeMutation(typ C.Type) *ListenerHandler {
handler := *h
handler.Type = typ
return &handler
}
func ShouldIgnorePacketError(err error) bool {
// ignore simple error
if E.IsTimeout(err) || E.IsClosed(err) || E.IsCanceled(err) {
+7
View File
@@ -8,6 +8,7 @@ import (
"time"
"github.com/metacubex/mihomo/component/resolver"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/listener/sing"
"github.com/metacubex/mihomo/log"
@@ -124,3 +125,9 @@ func (h *ListenerHandler) NewPacketConnection(ctx context.Context, conn network.
}
return h.ListenerHandler.NewPacketConnection(ctx, conn, metadata)
}
func (h *ListenerHandler) TypeMutation(typ C.Type) *ListenerHandler {
handle := *h
handle.ListenerHandler = h.ListenerHandler.TypeMutation(typ)
return &handle
}
+70
View File
@@ -0,0 +1,70 @@
package sing_tun
import (
"errors"
"net/netip"
"github.com/metacubex/mihomo/component/iface"
"github.com/sagernet/sing/common/control"
)
type defaultInterfaceFinder struct{}
var DefaultInterfaceFinder control.InterfaceFinder = (*defaultInterfaceFinder)(nil)
func (f *defaultInterfaceFinder) Interfaces() []control.Interface {
ifaces, err := iface.Interfaces()
if err != nil {
return nil
}
interfaces := make([]control.Interface, 0, len(ifaces))
for _, _interface := range ifaces {
interfaces = append(interfaces, control.Interface(*_interface))
}
return interfaces
}
var errNoSuchInterface = errors.New("no such network interface")
func (f *defaultInterfaceFinder) InterfaceIndexByName(name string) (int, error) {
ifaces, err := iface.Interfaces()
if err != nil {
return 0, err
}
for _, netInterface := range ifaces {
if netInterface.Name == name {
return netInterface.Index, nil
}
}
return 0, errNoSuchInterface
}
func (f *defaultInterfaceFinder) InterfaceNameByIndex(index int) (string, error) {
ifaces, err := iface.Interfaces()
if err != nil {
return "", err
}
for _, netInterface := range ifaces {
if netInterface.Index == index {
return netInterface.Name, nil
}
}
return "", errNoSuchInterface
}
func (f *defaultInterfaceFinder) InterfaceByAddr(addr netip.Addr) (*control.Interface, error) {
ifaces, err := iface.Interfaces()
if err != nil {
return nil, err
}
for _, netInterface := range ifaces {
for _, prefix := range netInterface.Addresses {
if prefix.Contains(addr) {
return (*control.Interface)(netInterface), nil
}
}
}
return nil, errNoSuchInterface
}
+197 -14
View File
@@ -3,27 +3,33 @@ package sing_tun
import (
"context"
"fmt"
"io"
"net"
"net/netip"
"os"
"runtime"
"strconv"
"strings"
"sync"
"github.com/metacubex/mihomo/adapter/inbound"
"github.com/metacubex/mihomo/component/dialer"
"github.com/metacubex/mihomo/component/iface"
"github.com/metacubex/mihomo/component/resolver"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/constant/provider"
LC "github.com/metacubex/mihomo/listener/config"
"github.com/metacubex/mihomo/listener/sing"
"github.com/metacubex/mihomo/log"
tun "github.com/metacubex/sing-tun"
"github.com/sagernet/sing/common"
"github.com/sagernet/sing/common/control"
E "github.com/sagernet/sing/common/exceptions"
F "github.com/sagernet/sing/common/format"
"github.com/sagernet/sing/common/ranges"
"go4.org/netipx"
"golang.org/x/exp/maps"
"golang.org/x/exp/slices"
)
@@ -43,10 +49,21 @@ type Listener struct {
networkUpdateMonitor tun.NetworkUpdateMonitor
defaultInterfaceMonitor tun.DefaultInterfaceMonitor
packageManager tun.PackageManager
autoRedirect tun.AutoRedirect
autoRedirectOutputMark int32
ruleUpdateCallbackCloser io.Closer
ruleUpdateMutex sync.Mutex
routeAddressMap map[string]*netipx.IPSet
routeExcludeAddressMap map[string]*netipx.IPSet
routeAddressSet []*netipx.IPSet
routeExcludeAddressSet []*netipx.IPSet
dnsServerIp []string
}
var emptyAddressSet = []*netipx.IPSet{{}}
func CalculateInterfaceName(name string) (tunName string) {
if runtime.GOOS == "darwin" {
tunName = "utun"
@@ -110,14 +127,45 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
inbound.WithSpecialRules(""),
}
}
ctx := context.TODO()
rpTunnel := tunnel.(provider.Tunnel)
if options.GSOMaxSize == 0 {
options.GSOMaxSize = 65536
}
if runtime.GOOS != "linux" {
options.AutoRedirect = false
}
tunName := options.Device
if tunName == "" || !checkTunName(tunName) {
tunName = CalculateInterfaceName(InterfaceName)
options.Device = tunName
}
routeAddress := options.RouteAddress
if len(options.Inet4RouteAddress) > 0 {
routeAddress = append(routeAddress, options.Inet4RouteAddress...)
}
if len(options.Inet6RouteAddress) > 0 {
routeAddress = append(routeAddress, options.Inet6RouteAddress...)
}
inet4RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
return it.Addr().Is4()
})
inet6RouteAddress := common.Filter(routeAddress, func(it netip.Prefix) bool {
return it.Addr().Is6()
})
routeExcludeAddress := options.RouteExcludeAddress
if len(options.Inet4RouteExcludeAddress) > 0 {
routeExcludeAddress = append(routeExcludeAddress, options.Inet4RouteExcludeAddress...)
}
if len(options.Inet6RouteExcludeAddress) > 0 {
routeExcludeAddress = append(routeExcludeAddress, options.Inet6RouteExcludeAddress...)
}
inet4RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
return it.Addr().Is4()
})
inet6RouteExcludeAddress := common.Filter(routeExcludeAddress, func(it netip.Prefix) bool {
return it.Addr().Is6()
})
tunMTU := options.MTU
if tunMTU == 0 {
tunMTU = 9000
@@ -128,9 +176,21 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
} else {
udpTimeout = int64(sing.UDPTimeout.Seconds())
}
tableIndex := options.TableIndex
tableIndex := options.IPRoute2TableIndex
if tableIndex == 0 {
tableIndex = 2022
tableIndex = tun.DefaultIPRoute2TableIndex
}
ruleIndex := options.IPRoute2RuleIndex
if ruleIndex == 0 {
ruleIndex = tun.DefaultIPRoute2RuleIndex
}
inputMark := options.AutoRedirectInputMark
if inputMark == 0 {
inputMark = tun.DefaultAutoRedirectInputMark
}
outputMark := options.AutoRedirectOutputMark
if outputMark == 0 {
outputMark = tun.DefaultAutoRedirectOutputMark
}
includeUID := uidToRange(options.IncludeUID)
if len(options.IncludeUIDRange) > 0 {
@@ -202,6 +262,8 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
}
}()
interfaceFinder := DefaultInterfaceFinder
networkUpdateMonitor, err := tun.NewNetworkUpdateMonitor(log.SingLogger)
if err != nil {
err = E.Cause(err, "create NetworkUpdateMonitor")
@@ -236,11 +298,15 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
Inet4Address: options.Inet4Address,
Inet6Address: options.Inet6Address,
AutoRoute: options.AutoRoute,
IPRoute2TableIndex: tableIndex,
IPRoute2RuleIndex: ruleIndex,
AutoRedirectInputMark: inputMark,
AutoRedirectOutputMark: outputMark,
StrictRoute: options.StrictRoute,
Inet4RouteAddress: options.Inet4RouteAddress,
Inet6RouteAddress: options.Inet6RouteAddress,
Inet4RouteExcludeAddress: options.Inet4RouteExcludeAddress,
Inet6RouteExcludeAddress: options.Inet6RouteExcludeAddress,
Inet4RouteAddress: inet4RouteAddress,
Inet6RouteAddress: inet6RouteAddress,
Inet4RouteExcludeAddress: inet4RouteExcludeAddress,
Inet6RouteExcludeAddress: inet6RouteExcludeAddress,
IncludeInterface: options.IncludeInterface,
ExcludeInterface: options.ExcludeInterface,
IncludeUID: includeUID,
@@ -250,7 +316,56 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
ExcludePackage: options.ExcludePackage,
FileDescriptor: options.FileDescriptor,
InterfaceMonitor: defaultInterfaceMonitor,
TableIndex: tableIndex,
}
if options.AutoRedirect {
l.routeAddressMap = make(map[string]*netipx.IPSet)
l.routeExcludeAddressMap = make(map[string]*netipx.IPSet)
if !options.AutoRoute {
return nil, E.New("`auto-route` is required by `auto-redirect`")
}
disableNFTables, dErr := strconv.ParseBool(os.Getenv("DISABLE_NFTABLES"))
l.autoRedirect, err = tun.NewAutoRedirect(tun.AutoRedirectOptions{
TunOptions: &tunOptions,
Context: ctx,
Handler: handler.TypeMutation(C.REDIR),
Logger: log.SingLogger,
NetworkMonitor: networkUpdateMonitor,
InterfaceFinder: interfaceFinder,
TableName: "mihomo",
DisableNFTables: dErr == nil && disableNFTables,
RouteAddressSet: &l.routeAddressSet,
RouteExcludeAddressSet: &l.routeExcludeAddressSet,
})
if err != nil {
err = E.Cause(err, "initialize auto redirect")
return
}
var markMode bool
for _, routeAddressSet := range options.RouteAddressSet {
rp, loaded := rpTunnel.RuleProviders()[routeAddressSet]
if !loaded {
err = E.New("parse route-address-set: rule-set not found: ", routeAddressSet)
return
}
l.updateRule(rp, false, false)
markMode = true
}
for _, routeExcludeAddressSet := range options.RouteExcludeAddressSet {
rp, loaded := rpTunnel.RuleProviders()[routeExcludeAddressSet]
if !loaded {
err = E.New("parse route-exclude_address-set: rule-set not found: ", routeExcludeAddressSet)
return
}
l.updateRule(rp, true, false)
markMode = true
}
if markMode {
tunOptions.AutoRedirectMarkMode = true
}
}
err = l.buildAndroidRules(&tunOptions)
@@ -269,14 +384,14 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
resolver.AddSystemDnsBlacklist(dnsServerIp...)
stackOptions := tun.StackOptions{
Context: context.TODO(),
Context: ctx,
Tun: tunIf,
TunOptions: tunOptions,
EndpointIndependentNat: options.EndpointIndependentNat,
UDPTimeout: udpTimeout,
Handler: handler,
Logger: log.SingLogger,
InterfaceFinder: control.DefaultInterfaceFinder(),
InterfaceFinder: interfaceFinder,
EnforceBindInterface: EnforceBindInterface,
}
@@ -299,13 +414,76 @@ func New(options LC.Tun, tunnel C.Tunnel, additions ...inbound.Addition) (l *Lis
}
l.tunStack = tunStack
if l.autoRedirect != nil {
if len(l.options.RouteAddressSet) > 0 && len(l.routeAddressSet) == 0 {
l.routeAddressSet = emptyAddressSet // without this we can't call UpdateRouteAddressSet after Start
}
if len(l.options.RouteExcludeAddressSet) > 0 && len(l.routeExcludeAddressSet) == 0 {
l.routeExcludeAddressSet = emptyAddressSet // without this we can't call UpdateRouteAddressSet after Start
}
err = l.autoRedirect.Start()
if err != nil {
err = E.Cause(err, "auto redirect")
return
}
if tunOptions.AutoRedirectMarkMode {
l.autoRedirectOutputMark = int32(outputMark)
dialer.DefaultRoutingMark.Store(l.autoRedirectOutputMark)
l.autoRedirect.UpdateRouteAddressSet()
l.ruleUpdateCallbackCloser = rpTunnel.RuleUpdateCallback().Register(l.ruleUpdateCallback)
}
}
//l.openAndroidHotspot(tunOptions)
l.addrStr = fmt.Sprintf("%s(%s,%s), mtu: %d, auto route: %v, ip stack: %s",
tunName, tunOptions.Inet4Address, tunOptions.Inet6Address, tunMTU, options.AutoRoute, options.Stack)
l.addrStr = fmt.Sprintf("%s(%s,%s), mtu: %d, auto route: %v, auto redir: %v, ip stack: %s",
tunName, tunOptions.Inet4Address, tunOptions.Inet6Address, tunMTU, options.AutoRoute, options.AutoRedirect, options.Stack)
return
}
func (l *Listener) ruleUpdateCallback(ruleProvider provider.RuleProvider) {
name := ruleProvider.Name()
if slices.Contains(l.options.RouteAddressSet, name) {
l.updateRule(ruleProvider, false, true)
return
}
if slices.Contains(l.options.RouteExcludeAddressSet, name) {
l.updateRule(ruleProvider, true, true)
return
}
}
func (l *Listener) updateRule(ruleProvider provider.RuleProvider, exclude bool, update bool) {
l.ruleUpdateMutex.Lock()
defer l.ruleUpdateMutex.Unlock()
name := ruleProvider.Name()
switch rp := ruleProvider.Strategy().(type) {
case interface{ ToIpCidr() *netipx.IPSet }:
if !exclude {
ipCidr := rp.ToIpCidr()
if ipCidr != nil {
l.routeAddressMap[name] = ipCidr
} else {
delete(l.routeAddressMap, name)
}
l.routeAddressSet = maps.Values(l.routeAddressMap)
} else {
ipCidr := rp.ToIpCidr()
if ipCidr != nil {
l.routeExcludeAddressMap[name] = ipCidr
} else {
delete(l.routeExcludeAddressMap, name)
}
l.routeExcludeAddressSet = maps.Values(l.routeExcludeAddressMap)
}
default:
return
}
if update && l.autoRedirect != nil {
l.autoRedirect.UpdateRouteAddressSet()
}
}
func (l *Listener) FlushDefaultInterface() {
if l.options.AutoDetectInterface {
for _, destination := range []netip.Addr{netip.IPv4Unspecified(), netip.IPv6Unspecified(), netip.MustParseAddr("1.1.1.1")} {
@@ -347,11 +525,11 @@ func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.
}
var start, end uint64
var err error
start, err = strconv.ParseUint(uidRange[:subIndex], 10, 32)
start, err = strconv.ParseUint(uidRange[:subIndex], 0, 32)
if err != nil {
return nil, E.Cause(err, "parse range start")
}
end, err = strconv.ParseUint(uidRange[subIndex+1:], 10, 32)
end, err = strconv.ParseUint(uidRange[subIndex+1:], 0, 32)
if err != nil {
return nil, E.Cause(err, "parse range end")
}
@@ -363,9 +541,14 @@ func parseRange(uidRanges []ranges.Range[uint32], rangeList []string) ([]ranges.
func (l *Listener) Close() error {
l.closed = true
resolver.RemoveSystemDnsBlacklist(l.dnsServerIp...)
if l.autoRedirectOutputMark != 0 {
dialer.DefaultRoutingMark.CompareAndSwap(l.autoRedirectOutputMark, 0)
}
return common.Close(
l.ruleUpdateCallbackCloser,
l.tunStack,
l.tunIf,
l.autoRedirect,
l.defaultInterfaceMonitor,
l.networkUpdateMonitor,
l.packageManager,
@@ -119,9 +119,7 @@ func CleanupTProxyIPTables() {
log.Warnln("Cleanup tproxy linux iptables")
if int(dialer.DefaultRoutingMark.Load()) == 2158 {
dialer.DefaultRoutingMark.Store(0)
}
dialer.DefaultRoutingMark.CompareAndSwap(2158, 0)
if _, err := cmd.ExecCmd("iptables -t mangle -L mihomo_divert"); err != nil {
return
+2
View File
@@ -20,6 +20,8 @@ func (b *Base) ShouldResolveIP() bool {
return false
}
func (b *Base) ProviderNames() []string { return nil }
func HasNoResolve(params []string) bool {
for _, p := range params {
if p == noResolve {
+7
View File
@@ -298,3 +298,10 @@ func (logic *Logic) ShouldResolveIP() bool {
func (logic *Logic) ShouldFindProcess() bool {
return logic.needProcess
}
func (logic *Logic) ProviderNames() (names []string) {
for _, rule := range logic.rules {
names = append(names, rule.ProviderNames()...)
}
return
}
@@ -4,6 +4,8 @@ import (
"github.com/metacubex/mihomo/component/cidr"
C "github.com/metacubex/mihomo/constant"
"github.com/metacubex/mihomo/log"
"go4.org/netipx"
)
type ipcidrStrategy struct {
@@ -52,6 +54,10 @@ func (i *ipcidrStrategy) FinishInsert() {
i.cidrSet.Merge()
}
func (i *ipcidrStrategy) ToIpCidr() *netipx.IPSet {
return i.cidrSet.ToIPSet()
}
func NewIPCidrStrategy() *ipcidrStrategy {
return &ipcidrStrategy{}
}
+2 -2
View File
@@ -12,8 +12,8 @@ type UpdatableProvider interface {
UpdatedAt() time.Time
}
func (f *ruleSetProvider) UpdatedAt() time.Time {
return f.Fetcher.UpdatedAt
func (rp *ruleSetProvider) UpdatedAt() time.Time {
return rp.Fetcher.UpdatedAt
}
func (rp *ruleSetProvider) Close() error {
+14 -20
View File
@@ -15,12 +15,14 @@ import (
P "github.com/metacubex/mihomo/constant/provider"
)
var (
ruleProviders = map[string]P.RuleProvider{}
)
var tunnel P.Tunnel
func SetTunnel(t P.Tunnel) {
tunnel = t
}
type ruleSetProvider struct {
*resource.Fetcher[any]
*resource.Fetcher[ruleStrategy]
behavior P.RuleBehavior
format P.RuleFormat
strategy ruleStrategy
@@ -49,16 +51,6 @@ type ruleStrategy interface {
FinishInsert()
}
func RuleProviders() map[string]P.RuleProvider {
return ruleProviders
}
func SetRuleProvider(ruleProvider P.RuleProvider) {
if ruleProvider != nil {
ruleProviders[(ruleProvider).Name()] = ruleProvider
}
}
func (rp *ruleSetProvider) Type() P.ProviderType {
return P.Rule
}
@@ -99,8 +91,8 @@ func (rp *ruleSetProvider) ShouldFindProcess() bool {
return rp.strategy.ShouldFindProcess()
}
func (rp *ruleSetProvider) AsRule(adaptor string) C.Rule {
panic("implement me")
func (rp *ruleSetProvider) Strategy() any {
return rp.strategy
}
func (rp *ruleSetProvider) MarshalJSON() ([]byte, error) {
@@ -123,13 +115,15 @@ func NewRuleSetProvider(name string, behavior P.RuleBehavior, format P.RuleForma
format: format,
}
onUpdate := func(elm interface{}) {
strategy := elm.(ruleStrategy)
onUpdate := func(strategy ruleStrategy) {
rp.strategy = strategy
tunnel.RuleUpdateCallback().Emit(rp)
}
rp.strategy = newStrategy(behavior, parse)
rp.Fetcher = resource.NewFetcher(name, interval, vehicle, func(bytes []byte) (any, error) { return rulesParse(bytes, newStrategy(behavior, parse), format) }, onUpdate)
rp.Fetcher = resource.NewFetcher(name, interval, vehicle, func(bytes []byte) (ruleStrategy, error) {
return rulesParse(bytes, newStrategy(behavior, parse), format)
}, onUpdate)
wrapper := &RuleSetProvider{
rp,
@@ -158,7 +152,7 @@ func newStrategy(behavior P.RuleBehavior, parse func(tp, payload, target string,
var ErrNoPayload = errors.New("file must have a `payload` field")
func rulesParse(buf []byte, strategy ruleStrategy, format P.RuleFormat) (any, error) {
func rulesParse(buf []byte, strategy ruleStrategy, format P.RuleFormat) (ruleStrategy, error) {
strategy.Reset()
schema := &RulePayload{}
+32 -19
View File
@@ -1,7 +1,6 @@
package provider
import (
"fmt"
C "github.com/metacubex/mihomo/constant"
P "github.com/metacubex/mihomo/constant/provider"
"github.com/metacubex/mihomo/rules/common"
@@ -11,13 +10,18 @@ type RuleSet struct {
*common.Base
ruleProviderName string
adapter string
ruleProvider P.RuleProvider
noResolveIP bool
shouldFindProcess bool
}
func (rs *RuleSet) ShouldFindProcess() bool {
return rs.shouldFindProcess || rs.getProviders().ShouldFindProcess()
if rs.shouldFindProcess {
return true
}
if provider, ok := rs.getProvider(); ok {
return provider.ShouldFindProcess()
}
return false
}
func (rs *RuleSet) RuleType() C.RuleType {
@@ -25,7 +29,10 @@ func (rs *RuleSet) RuleType() C.RuleType {
}
func (rs *RuleSet) Match(metadata *C.Metadata) (bool, string) {
return rs.getProviders().Match(metadata), rs.adapter
if provider, ok := rs.getProvider(); ok {
return provider.Match(metadata), rs.adapter
}
return false, ""
}
func (rs *RuleSet) Adapter() string {
@@ -33,31 +40,37 @@ func (rs *RuleSet) Adapter() string {
}
func (rs *RuleSet) Payload() string {
return rs.getProviders().Name()
if provider, ok := rs.getProvider(); ok {
return provider.Name()
}
return ""
}
func (rs *RuleSet) ShouldResolveIP() bool {
return !rs.noResolveIP && rs.getProviders().ShouldResolveIP()
}
func (rs *RuleSet) getProviders() P.RuleProvider {
if rs.ruleProvider == nil {
rp := RuleProviders()[rs.ruleProviderName]
rs.ruleProvider = rp
if rs.noResolveIP {
return false
}
if provider, ok := rs.getProvider(); ok {
return provider.ShouldResolveIP()
}
return false
}
return rs.ruleProvider
func (rs *RuleSet) ProviderNames() []string {
return []string{rs.ruleProviderName}
}
func (rs *RuleSet) getProvider() (P.RuleProvider, bool) {
pp, ok := tunnel.RuleProviders()[rs.ruleProviderName]
return pp, ok
}
func NewRuleSet(ruleProviderName string, adapter string, noResolveIP bool) (*RuleSet, error) {
rp, ok := RuleProviders()[ruleProviderName]
if !ok {
return nil, fmt.Errorf("rule set %s not found", ruleProviderName)
}
return &RuleSet{
rs := &RuleSet{
Base: &common.Base{},
ruleProviderName: ruleProviderName,
adapter: adapter,
ruleProvider: rp,
noResolveIP: noResolveIP,
}, nil
}
return rs, nil
}
+18 -1
View File
@@ -13,6 +13,7 @@ import (
"time"
N "github.com/metacubex/mihomo/common/net"
"github.com/metacubex/mihomo/common/utils"
"github.com/metacubex/mihomo/component/loopback"
"github.com/metacubex/mihomo/component/nat"
P "github.com/metacubex/mihomo/component/process"
@@ -50,11 +51,15 @@ var (
findProcessMode P.FindProcessMode
fakeIPRange netip.Prefix
ruleUpdateCallback = utils.NewCallback[provider.RuleProvider]()
)
type tunnel struct{}
var Tunnel C.Tunnel = tunnel{}
var Tunnel = tunnel{}
var _ C.Tunnel = Tunnel
var _ provider.Tunnel = Tunnel
func (t tunnel) HandleTCPConn(conn net.Conn, metadata *C.Metadata) {
connCtx := icontext.NewConnContext(conn, metadata)
@@ -73,6 +78,18 @@ func (t tunnel) NatTable() C.NatTable {
return natTable
}
func (t tunnel) Providers() map[string]provider.ProxyProvider {
return providers
}
func (t tunnel) RuleProviders() map[string]provider.RuleProvider {
return ruleProviders
}
func (t tunnel) RuleUpdateCallback() *utils.Callback[provider.RuleProvider] {
return ruleUpdateCallback
}
func OnSuspend() {
status.Store(Suspend)
}
@@ -120,7 +120,7 @@ pub fn create_window(app_handle: &AppHandle) {
let mut builder = tauri::window::WindowBuilder::new(
app_handle,
"main".to_string(),
tauri::WindowUrl::App("/proxies".into()),
tauri::WindowUrl::App("/dashboard".into()),
)
.title("Clash Nyanpasu")
.fullscreen(false)
@@ -22,6 +22,8 @@ export const useClashWS = () => {
return {
connections: resolveUrl("connections"),
logs: resolveUrl("logs"),
traffic: resolveUrl("traffic"),
memory: resolveUrl("memory"),
};
}
}, [getClashInfo.data]);
@@ -30,8 +32,14 @@ export const useClashWS = () => {
const logs = useWebSocket(url?.logs ?? "");
const traffic = useWebSocket(url?.traffic ?? "");
const memory = useWebSocket(url?.memory ?? "");
return {
connections,
logs,
traffic,
memory,
};
};
@@ -189,3 +189,13 @@ export interface ProviderItem {
updatedAt: string;
vehicleType: string;
}
export interface Traffic {
up: number;
down: number;
}
export interface Memory {
inuse: number;
oslimit: number;
}
@@ -56,9 +56,10 @@
"@typescript-eslint/eslint-plugin": "7.13.0",
"@typescript-eslint/parser": "7.13.0",
"@vitejs/plugin-react": "4.3.1",
"@vitejs/plugin-react-swc": "^3.7.0",
"@vitejs/plugin-react-swc": "3.7.0",
"sass": "1.77.5",
"shiki": "1.6.5",
"shiki": "1.7.0",
"tailwindcss-textshadow": "2.1.3",
"vite": "5.3.1",
"vite-plugin-monaco-editor": "1.1.3",
"vite-plugin-sass-dts": "1.3.22",
@@ -34,13 +34,29 @@ export const AppDrawer = ({ isDrawer }: { isDrawer?: boolean }) => {
data-windrag
>
<div
className="w-full h-full max-w-32 max-h-32 ml-auto mr-auto"
data-windrag
className={classNames(
"flex items-center justify-center gap-4 ",
isDrawer && "mx-2",
)}
>
<AnimatedLogo className="w-full h-full" data-windrag />
<div
className={classNames(
isDrawer && "w-10 h-10",
"w-full h-full max-w-32 max-h-32 ml-auto mr-auto",
)}
data-windrag
>
<AnimatedLogo className="w-full h-full" data-windrag />
</div>
{isDrawer && (
<div className="text-lg text-nowrap font-bold mt-1" data-windrag>
Clash Nyanpasu
</div>
)}
</div>
<div className="flex flex-col gap-2">
<div className="flex flex-col gap-2 overflow-y-auto scrollbar-hidden">
{Object.entries(routes).map(([name, { path, icon }]) => {
return (
<RouteListItem key={name} name={name} path={path} icon={icon} />
@@ -23,7 +23,7 @@ export const RouteListItem = ({
return (
<ListItemButton
className="!pr-12 !rounded-full"
className="!pr-14 !rounded-full"
sx={{
backgroundColor: match ? alpha(palette.primary.main, 0.3) : undefined,
@@ -42,7 +42,7 @@ export const RouteListItem = ({
</ListItemIcon>
<div
className="pt-1 pb-1"
className="pt-1 pb-1 w-full text-center text-nowrap"
style={{ color: match ? palette.primary.main : undefined }}
>
{t(`label_${name}`)}
@@ -45,9 +45,14 @@ export const ConnectionsTable = () => {
? connection.upload - previousConnection.upload
: 0;
const host = String(
connection.metadata.host || connection.metadata.destinationIP,
);
updatedConnections.push({
...connection,
...connection.metadata,
host,
downloadSpeed,
uploadSpeed,
});
@@ -0,0 +1,134 @@
import Dataline, { DatalineProps } from "@/components/dashboard/dataline";
import {
Connection,
Memory,
Traffic,
useClashWS,
useNyanpasu,
} from "@nyanpasu/interface";
import { useInterval } from "ahooks";
import { useState } from "react";
import {
ArrowDownward,
ArrowUpward,
MemoryOutlined,
SettingsEthernet,
} from "@mui/icons-material";
import Grid from "@mui/material/Unstable_Grid2";
import { useTranslation } from "react-i18next";
export const DataPanel = () => {
const { t } = useTranslation();
const [traffic, setTraffice] = useState<Traffic[]>(
new Array(16).fill({ up: 0, down: 0 }),
);
const [memory, setMemory] = useState<Memory[]>(
new Array(16).fill({ inuse: 0 }),
);
const [connection, setConnection] = useState<
{
downloadTotal: number;
uploadTotal: number;
connections: number;
}[]
>(
new Array(16).fill({
downloadTotal: 0,
uploadTotal: 0,
connections: 0,
}),
);
const {
traffic: { latestMessage: latestTraffic },
memory: { latestMessage: latestMemory },
connections: { latestMessage: latestConnections },
} = useClashWS();
useInterval(() => {
const trafficData = latestTraffic?.data
? (JSON.parse(latestTraffic.data) as Traffic)
: { up: 0, down: 0 };
setTraffice((prevData) => [...prevData.slice(1), trafficData]);
const meomryData = latestMemory?.data
? (JSON.parse(latestMemory.data) as Memory)
: { inuse: 0, oslimit: 0 };
setMemory((prevData) => [...prevData.slice(1), meomryData]);
const connectionsData = latestConnections?.data
? (JSON.parse(latestConnections.data) as Connection.Response)
: {
downloadTotal: 0,
uploadTotal: 0,
};
setConnection((prevData) => [
...prevData.slice(1),
{
downloadTotal: connectionsData.downloadTotal,
uploadTotal: connectionsData.uploadTotal,
connections: connectionsData.connections?.length ?? 0,
},
]);
}, 1000);
const { nyanpasuConfig } = useNyanpasu();
const supportMemory =
nyanpasuConfig?.clash_core &&
["mihomo", "mihomo-alpha"].includes(nyanpasuConfig?.clash_core);
const Datalines: DatalineProps[] = [
{
data: traffic.map((item) => item.up),
icon: ArrowUpward,
title: t("Upload Traffic"),
total: connection.at(-1)?.uploadTotal,
type: "speed",
},
{
data: traffic.map((item) => item.down),
icon: ArrowDownward,
title: t("Download Traffic"),
total: connection.at(-1)?.downloadTotal,
type: "speed",
},
{
data: connection.map((item) => item.connections),
icon: SettingsEthernet,
title: t("Active Connections"),
type: "raw",
},
];
if (supportMemory) {
Datalines.splice(2, 0, {
data: memory.map((item) => item.inuse),
icon: MemoryOutlined,
title: t("Memory"),
});
}
const gridLayout = {
sm: 12,
md: 6,
lg: supportMemory ? 3 : 4,
xl: supportMemory ? 3 : 4,
};
return Datalines.map((props, index) => {
return (
<Grid key={`data-${index}`} {...gridLayout} className="w-full">
<Dataline {...props} className="min-h-48 max-h-1/8" />
</Grid>
);
});
};
export default DataPanel;
@@ -0,0 +1,53 @@
import parseTraffic from "@/utils/parse-traffic";
import { SvgIconComponent } from "@mui/icons-material";
import { Paper } from "@mui/material";
import { Sparkline } from "@nyanpasu/ui";
import { FC, cloneElement } from "react";
import { useTranslation } from "react-i18next";
export interface DatalineProps {
data: number[];
icon: SvgIconComponent;
title: string;
total?: number;
type?: "speed" | "raw";
}
export const Dataline: FC<DatalineProps> = ({
data,
icon,
title,
total,
type,
}) => {
const { t } = useTranslation();
return (
<Paper className="!rounded-3xl relative">
<Sparkline data={data} className="rounded-3xl" />
<div className="absolute top-0 p-4 h-full flex flex-col gap-4 justify-between">
<div className="flex items-center gap-2">
{cloneElement(icon)}
<div className="font-bold">{title}</div>
</div>
<div className="font-bold text-2xl text-shadow-md">
{type === "raw" ? data.at(-1) : parseTraffic(data.at(-1)).join(" ")}
{type === "speed" && "/s"}
</div>
<div className=" h-5">
{total && (
<span className="text-shadow-sm">
{t("Total")}: {parseTraffic(total).join(" ")}
</span>
)}
</div>
</div>
</Paper>
);
};
export default Dataline;
@@ -1,4 +1,5 @@
{
"label_dashboard": "Dashboard",
"label_proxies": "Proxies",
"label_profiles": "Profiles",
"label_connections": "Connections",
@@ -7,8 +8,10 @@
"label_settings": "Settings",
"label_providers": "Providers",
"Connections": "Connections",
"Upload Total": "Upload Total",
"Download Total": "Download Total",
"Upload Traffic": "Upload",
"Download Traffic": "Download",
"Total": "Total",
"Memory": "Memory",
"Active Connections": "Active Connections",
"Logs": "Logs",
"Clear": "Clear",
@@ -18,6 +21,7 @@
"global": "global",
"direct": "direct",
"script": "script",
"Dashboard": "Dashboard",
"Profiles": "Profiles",
"Profile URL": "Profile URL",
"Import": "Import",
@@ -116,7 +120,6 @@
"Retain 30 Days": "Retain 30 Days",
"Retain 90 Days": "Retain 90 Days",
"Max Log Files": "Max Log Files",
"Collect Logs": "Collect Logs",
"Back": "Back",
"Save": "Save",
@@ -1,4 +1,5 @@
{
"label_dashboard": "概 览",
"label_proxies": "代 理",
"label_profiles": "配 置",
"label_connections": "连 接",
@@ -6,10 +7,13 @@
"label_rules": "规 则",
"label_settings": "设 置",
"label_providers": "资 源",
"Connections": "连接",
"Upload Total": "上传总量",
"Download Total": "下载总量",
"Upload Traffic": "上传流量",
"Download Traffic": "下载流量",
"Total": "总量",
"Memory": "内存占用",
"Active Connections": "活动连接",
"Logs": "日志",
"Clear": "清除",
@@ -19,7 +23,7 @@
"global": "全局",
"direct": "直连",
"script": "脚本",
"Dashboard": "概览",
"Profiles": "配置",
"Profile URL": "配置文件链接",
"Import": "导入",
@@ -42,7 +46,6 @@
"Update All Profiles": "更新所有配置",
"View Runtime Config": "查看运行时配置",
"Reactivate Profiles": "重新激活配置",
"Location": "当前节点",
"Delay check": "延迟测试",
"Sort by default": "默认排序",
@@ -53,7 +56,6 @@
"Filter": "过滤节点",
"Filter conditions": "过滤条件",
"Refresh profiles": "刷新配置",
"Type": "类型",
"Name": "名称",
"Descriptions": "描述",
@@ -61,7 +63,6 @@
"Update Interval": "更新间隔",
"Use System Proxy": "使用系统代理更新",
"Use Clash Proxy": "使用Clash代理更新",
"Settings": "设置",
"Clash Setting": "Clash 设置",
"System Setting": "系统设置",
@@ -113,7 +114,6 @@
"ReadOnly": "只读",
"Check Updates": "检查更新",
"Restart": "重启内核",
"Tasks": "定期任务",
"Auto Log Clean": "自动清理日志",
"Never Clean": "不清理",
@@ -122,16 +122,13 @@
"Retain 30 Days": "保留30天",
"Retain 90 Days": "保留90天",
"Max Log Files": "最大日志文件数",
"Collect Logs": "收集日志",
"Back": "返回",
"Save": "保存",
"Cancel": "取消",
"Default": "默认",
"Download Speed": "下载速度",
"Upload Speed": "上传速度",
"open_or_close_dashboard": "打开/关闭面板",
"clash_mode_rule": "规则模式",
"clash_mode_global": "全局模式",
@@ -143,26 +140,21 @@
"toggle_tun_mode": "切换Tun模式",
"enable_tun_mode": "开启Tun模式",
"disable_tun_mode": "关闭Tun模式",
"App Log Level": "App日志等级",
"Auto Close Connections": "自动关闭连接",
"Enable Clash Fields Filter": "开启Clash字段过滤",
"Enable Builtin Enhanced": "开启内建增强功能",
"Proxy Layout Column": "代理页布局列数",
"Default Latency Test": "默认测试链接",
"Error": "错误",
"Success": "成功",
"Providers": "资源",
"Rules Providers": "规则集",
"Update Rules Providers All": "全部更新",
"Rule Set rules": "{{rule}} 条规则",
"Last Update": "{{fromNow}}更新",
"Update Rules Providers Success": "更新规则集成功",
"Portable Update Error": "便携版无法自动更新,请到 Github 下载最新版本",
"Enable Tray Proxies Selector": "开启托盘代理选择",
"Proxy Set proxies": "{{rule}} 个节点",
"Update Proxies Providers All": "全部更新",
@@ -0,0 +1,18 @@
import { BasePage } from "@nyanpasu/ui";
import Grid from "@mui/material/Unstable_Grid2";
import DataPanel from "@/components/dashboard/data-panel";
import { useTranslation } from "react-i18next";
export const Dashboard = () => {
const { t } = useTranslation();
return (
<BasePage title={t("Dashboard")}>
<Grid container spacing={2} sx={{ width: "calc(100% + 24px)" }}>
<DataPanel />
</Grid>
</BasePage>
);
};
export default Dashboard;
+12 -9
View File
@@ -1,23 +1,26 @@
// Generouted, changes to this file will be overriden
/* eslint-disable */
import { components, hooks, utils } from '@generouted/react-router/client'
import { components, hooks, utils } from "@generouted/react-router/client";
export type Path =
| `/connections`
| `/dashboard`
| `/logs`
| `/profiles`
| `/providers`
| `/proxies`
| `/rules`
| `/settings`
| `/settings`;
export type Params = {
}
export type Params = {};
export type ModalPath = never
export type ModalPath = never;
export const { Link, Navigate } = components<Path, Params>()
export const { useModals, useNavigate, useParams } = hooks<Path, Params, ModalPath>()
export const { redirect } = utils<Path, Params>()
export const { Link, Navigate } = components<Path, Params>();
export const { useModals, useNavigate, useParams } = hooks<
Path,
Params,
ModalPath
>();
export const { redirect } = utils<Path, Params>();
@@ -1,5 +1,6 @@
import {
Apps,
Dashboard,
DesignServices,
GridView,
Public,
@@ -10,6 +11,7 @@ import {
} from "@mui/icons-material";
const routes: { [key: string]: SvgIconComponent } = {
dashboard: Dashboard,
proxies: Public,
profiles: GridView,
connections: SettingsEthernet,
@@ -1,8 +1,24 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const plugin = require("tailwindcss/plugin");
/** @type {import('tailwindcss').Config} */
export default {
content: ["./src/**/*.{tsx,ts}"],
theme: {
extend: {},
extend: {
maxHeight: {
"1/8": "calc(100vh / 8)",
},
},
},
plugins: [],
plugins: [
require("tailwindcss-textshadow"),
plugin(({ addBase }) => {
addBase({
".scrollbar-hidden::-webkit-scrollbar": {
width: "0px",
},
});
}),
],
};
@@ -20,6 +20,7 @@
"@/*": ["src/*"],
"~/*": ["./*"],
},
"jsxImportSource": "@emotion/react",
},
"include": ["./src"],
"references": [{ "path": "../interface/tsconfig.json" }],
@@ -46,7 +46,6 @@ export default defineConfig(({ command }) => {
tsconfigPaths(),
svgr(),
react({
jsxImportSource: "@emotion/react",
// babel: {
// plugins: ["@emotion/babel-plugin"],
// },
@@ -57,12 +56,7 @@ export default defineConfig(({ command }) => {
isDev && devtools(),
],
optimizeDeps: {
include: [
"@emotion/react",
"@emotion/styled",
"@mui/lab/*",
"@mui/material/*",
],
include: ["@emotion/styled", "@mui/lab/*", "@mui/material/*"],
},
esbuild: {
drop: isDev ? undefined : ["console", "debugger"],
@@ -0,0 +1 @@
export * from "./sparkline";
@@ -0,0 +1,100 @@
import { CSSProperties, FC, useEffect, useRef } from "react";
import * as d3 from "d3";
import { alpha, useTheme } from "@mui/material";
interface SparklineProps {
data: number[];
className?: string;
style?: CSSProperties;
}
export const Sparkline: FC<SparklineProps> = ({ data, className, style }) => {
const { palette } = useTheme();
const svgRef = useRef<SVGSVGElement | null>(null);
useEffect(() => {
if (!svgRef.current) return;
const svg = d3.select(svgRef.current);
const { width, height } = svg.node()?.getBoundingClientRect() ?? {
width: 0,
height: 0,
};
const maxHeight = () => {
const dataRange = d3.max(data)! - d3.min(data)!;
if (dataRange / d3.max(data)! < 0.1) {
return height * 0.65;
}
if (d3.max(data)) {
return height * 0.35;
} else {
return height;
}
};
const xScale = d3
.scaleLinear()
.domain([0, data.length - 1])
.range([0, width]);
const yScale = d3
.scaleLinear()
.domain([0, d3.max(data) ?? 0])
.range([height, maxHeight()]);
const line = d3
.line<number>()
.x((d, i) => xScale(i))
.y((d) => yScale(d))
.curve(d3.curveCatmullRom.alpha(0.5));
const area = d3
.area<number>()
.x((d, i) => xScale(i))
.y0(height)
.y1((d) => yScale(d))
.curve(d3.curveCatmullRom.alpha(0.5));
svg.selectAll("*").remove();
svg
.append("path")
.datum(data)
.attr("class", "area")
.attr("fill", alpha(palette.primary.main, 0.1))
.attr("d", area);
svg
.append("path")
.datum(data)
.attr("class", "line")
.attr("fill", "none")
.attr("stroke", alpha(palette.primary.main, 0.7))
.attr("stroke-width", 2)
.attr("d", line);
const updateChart = () => {
xScale.domain([0, data.length - 1]);
yScale.domain([0, d3.max(data) ?? 0]);
svg.select(".area").datum(data).attr("d", area);
svg.select(".line").datum(data).attr("d", line);
};
updateChart();
}, [data]);
return (
<svg
className={className}
ref={svgRef}
style={{ width: "100%", height: "100%", ...style }}
></svg>
);
};
@@ -1,5 +1,6 @@
import { useTheme } from "@mui/material";
import { useSetState } from "ahooks";
import { appWindow } from "@tauri-apps/api/window";
import { useDebounceFn, useSetState } from "ahooks";
import { useEffect, useCallback, useMemo } from "react";
export const useBreakpoint = (
@@ -23,7 +24,13 @@ export const useBreakpoint = (
}, [breakpoints.values]);
const getBreakpoint = useCallback(
(width: number) => {
async (width: number) => {
const isMinimized = await appWindow.isMinimized();
if (isMinimized) {
return;
}
for (const [key, value] of breakpointsValues) {
if (value >= width) {
if (key !== breakpoint.key) {
@@ -46,21 +53,25 @@ export const useBreakpoint = (
[breakpointsValues, columnMapping, breakpoint.key, setBreakpoint],
);
useEffect(() => {
const observer = new ResizeObserver((entries) => {
if (!Array.isArray(entries) || !entries.length) return;
const { width } = entries[0].contentRect;
const { run: triggerBreakpoint } = useDebounceFn(
() => {
const width = document.body.clientWidth;
getBreakpoint(width);
});
},
{
wait: 100,
},
);
useEffect(() => {
const observer = new ResizeObserver(triggerBreakpoint);
observer.observe(document.body);
return () => {
observer.disconnect();
};
}, [getBreakpoint]);
}, [triggerBreakpoint]);
return breakpoint;
};
+1
View File
@@ -1,2 +1,3 @@
export * from "./materialYou";
export * from "./hooks";
export * from "./chart";
+3
View File
@@ -8,8 +8,11 @@
"@mui/icons-material": "5.15.20",
"@mui/lab": "5.0.0-alpha.170",
"@mui/material": "5.15.20",
"@tauri-apps/api": "1.5.6",
"@types/d3": "7.4.3",
"@types/react": "18.3.3",
"ahooks": "3.8.0",
"d3": "7.9.0",
"framer-motion": "11.2.10",
"react": "18.3.1",
"react-error-boundary": "4.0.13",
+2 -2
View File
@@ -2,7 +2,7 @@
"manifest_version": 1,
"latest": {
"mihomo": "v1.18.5",
"mihomo_alpha": "alpha-40f40f6",
"mihomo_alpha": "alpha-0738e18",
"clash_rs": "v0.1.18",
"clash_premium": "2023-09-05-gdcc8d87"
},
@@ -36,5 +36,5 @@
"darwin-x64": "clash-darwin-amd64-n{}.gz"
}
},
"updated_at": "2024-06-15T22:19:49.581Z"
"updated_at": "2024-06-16T22:20:26.121Z"
}
+1 -1
View File
@@ -106,7 +106,7 @@
"stylelint-order": "6.0.4",
"stylelint-scss": "6.3.1",
"tailwindcss": "3.4.4",
"tsx": "4.15.5",
"tsx": "4.15.6",
"typescript": "5.4.5"
},
"packageManager": "pnpm@9.3.0",
+1050 -249
View File
File diff suppressed because it is too large Load Diff
+5 -5
View File
@@ -24,10 +24,10 @@
"@emotion/react": "^11.11.4",
"@emotion/styled": "^11.11.5",
"@juggle/resize-observer": "^3.4.0",
"@mui/icons-material": "^5.15.19",
"@mui/icons-material": "^5.15.20",
"@mui/lab": "5.0.0-alpha.149",
"@mui/material": "^5.15.19",
"@mui/x-data-grid": "^6.20.1",
"@mui/material": "^5.15.20",
"@mui/x-data-grid": "^7.7.0",
"@tauri-apps/api": "^1.5.6",
"@types/json-schema": "^7.0.15",
"ahooks": "^3.8.0",
@@ -43,7 +43,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-error-boundary": "^3.1.4",
"react-hook-form": "^7.51.5",
"react-hook-form": "^7.52.0",
"react-i18next": "^13.5.0",
"react-markdown": "^9.0.1",
"react-router-dom": "^6.23.1",
@@ -76,7 +76,7 @@
"sass": "^1.77.5",
"terser": "^5.31.1",
"typescript": "^5.4.5",
"vite": "^5.2.13",
"vite": "^5.3.1",
"vite-plugin-monaco-editor": "^1.1.0",
"vite-plugin-svgr": "^4.2.0"
},
+180 -179
View File
@@ -26,17 +26,17 @@ importers:
specifier: ^3.4.0
version: 3.4.0
"@mui/icons-material":
specifier: ^5.15.19
version: 5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
specifier: ^5.15.20
version: 5.15.20(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/lab":
specifier: 5.0.0-alpha.149
version: 5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
version: 5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/material":
specifier: ^5.15.19
version: 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
specifier: ^5.15.20
version: 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/x-data-grid":
specifier: ^6.20.1
version: 6.20.1(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
specifier: ^7.7.0
version: 7.7.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@tauri-apps/api":
specifier: ^1.5.6
version: 1.5.6
@@ -83,8 +83,8 @@ importers:
specifier: ^3.1.4
version: 3.1.4(react@18.3.1)
react-hook-form:
specifier: ^7.51.5
version: 7.51.5(react@18.3.1)
specifier: ^7.52.0
version: 7.52.0(react@18.3.1)
react-i18next:
specifier: ^13.5.0
version: 13.5.0(i18next@23.11.5)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
@@ -139,10 +139,10 @@ importers:
version: 4.4.10
"@vitejs/plugin-legacy":
specifier: ^5.4.1
version: 5.4.1(terser@5.31.1)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
version: 5.4.1(terser@5.31.1)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
"@vitejs/plugin-react":
specifier: ^4.3.1
version: 4.3.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
version: 4.3.1(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
adm-zip:
specifier: ^0.5.14
version: 0.5.14
@@ -177,14 +177,14 @@ importers:
specifier: ^5.4.5
version: 5.4.5
vite:
specifier: ^5.2.13
version: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
specifier: ^5.3.1
version: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
vite-plugin-monaco-editor:
specifier: ^1.1.0
version: 1.1.0(monaco-editor@0.49.0)
vite-plugin-svgr:
specifier: ^4.2.0
version: 4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
version: 4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))
packages:
"@actions/github@5.1.1":
@@ -1251,208 +1251,208 @@ packages:
integrity: sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww==,
}
"@esbuild/aix-ppc64@0.20.2":
"@esbuild/aix-ppc64@0.21.5":
resolution:
{
integrity: sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==,
integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==,
}
engines: { node: ">=12" }
cpu: [ppc64]
os: [aix]
"@esbuild/android-arm64@0.20.2":
"@esbuild/android-arm64@0.21.5":
resolution:
{
integrity: sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==,
integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==,
}
engines: { node: ">=12" }
cpu: [arm64]
os: [android]
"@esbuild/android-arm@0.20.2":
"@esbuild/android-arm@0.21.5":
resolution:
{
integrity: sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==,
integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==,
}
engines: { node: ">=12" }
cpu: [arm]
os: [android]
"@esbuild/android-x64@0.20.2":
"@esbuild/android-x64@0.21.5":
resolution:
{
integrity: sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==,
integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==,
}
engines: { node: ">=12" }
cpu: [x64]
os: [android]
"@esbuild/darwin-arm64@0.20.2":
"@esbuild/darwin-arm64@0.21.5":
resolution:
{
integrity: sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==,
integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==,
}
engines: { node: ">=12" }
cpu: [arm64]
os: [darwin]
"@esbuild/darwin-x64@0.20.2":
"@esbuild/darwin-x64@0.21.5":
resolution:
{
integrity: sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==,
integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==,
}
engines: { node: ">=12" }
cpu: [x64]
os: [darwin]
"@esbuild/freebsd-arm64@0.20.2":
"@esbuild/freebsd-arm64@0.21.5":
resolution:
{
integrity: sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==,
integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==,
}
engines: { node: ">=12" }
cpu: [arm64]
os: [freebsd]
"@esbuild/freebsd-x64@0.20.2":
"@esbuild/freebsd-x64@0.21.5":
resolution:
{
integrity: sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==,
integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==,
}
engines: { node: ">=12" }
cpu: [x64]
os: [freebsd]
"@esbuild/linux-arm64@0.20.2":
"@esbuild/linux-arm64@0.21.5":
resolution:
{
integrity: sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==,
integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==,
}
engines: { node: ">=12" }
cpu: [arm64]
os: [linux]
"@esbuild/linux-arm@0.20.2":
"@esbuild/linux-arm@0.21.5":
resolution:
{
integrity: sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==,
integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==,
}
engines: { node: ">=12" }
cpu: [arm]
os: [linux]
"@esbuild/linux-ia32@0.20.2":
"@esbuild/linux-ia32@0.21.5":
resolution:
{
integrity: sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==,
integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==,
}
engines: { node: ">=12" }
cpu: [ia32]
os: [linux]
"@esbuild/linux-loong64@0.20.2":
"@esbuild/linux-loong64@0.21.5":
resolution:
{
integrity: sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==,
integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==,
}
engines: { node: ">=12" }
cpu: [loong64]
os: [linux]
"@esbuild/linux-mips64el@0.20.2":
"@esbuild/linux-mips64el@0.21.5":
resolution:
{
integrity: sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==,
integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==,
}
engines: { node: ">=12" }
cpu: [mips64el]
os: [linux]
"@esbuild/linux-ppc64@0.20.2":
"@esbuild/linux-ppc64@0.21.5":
resolution:
{
integrity: sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==,
integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==,
}
engines: { node: ">=12" }
cpu: [ppc64]
os: [linux]
"@esbuild/linux-riscv64@0.20.2":
"@esbuild/linux-riscv64@0.21.5":
resolution:
{
integrity: sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==,
integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==,
}
engines: { node: ">=12" }
cpu: [riscv64]
os: [linux]
"@esbuild/linux-s390x@0.20.2":
"@esbuild/linux-s390x@0.21.5":
resolution:
{
integrity: sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==,
integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==,
}
engines: { node: ">=12" }
cpu: [s390x]
os: [linux]
"@esbuild/linux-x64@0.20.2":
"@esbuild/linux-x64@0.21.5":
resolution:
{
integrity: sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==,
integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==,
}
engines: { node: ">=12" }
cpu: [x64]
os: [linux]
"@esbuild/netbsd-x64@0.20.2":
"@esbuild/netbsd-x64@0.21.5":
resolution:
{
integrity: sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==,
integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==,
}
engines: { node: ">=12" }
cpu: [x64]
os: [netbsd]
"@esbuild/openbsd-x64@0.20.2":
"@esbuild/openbsd-x64@0.21.5":
resolution:
{
integrity: sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==,
integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==,
}
engines: { node: ">=12" }
cpu: [x64]
os: [openbsd]
"@esbuild/sunos-x64@0.20.2":
"@esbuild/sunos-x64@0.21.5":
resolution:
{
integrity: sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==,
integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==,
}
engines: { node: ">=12" }
cpu: [x64]
os: [sunos]
"@esbuild/win32-arm64@0.20.2":
"@esbuild/win32-arm64@0.21.5":
resolution:
{
integrity: sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==,
integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==,
}
engines: { node: ">=12" }
cpu: [arm64]
os: [win32]
"@esbuild/win32-ia32@0.20.2":
"@esbuild/win32-ia32@0.21.5":
resolution:
{
integrity: sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==,
integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==,
}
engines: { node: ">=12" }
cpu: [ia32]
os: [win32]
"@esbuild/win32-x64@0.20.2":
"@esbuild/win32-x64@0.21.5":
resolution:
{
integrity: sha512-N49X4lJX27+l9jbLKSqZ6bKNjzQvHaT8IIFUy+YIqmXQdjYCToGWwOItDrfby14c78aDd5NHQl29xingXfCdLQ==,
integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==,
}
engines: { node: ">=12" }
cpu: [x64]
@@ -1565,16 +1565,16 @@ packages:
"@types/react":
optional: true
"@mui/core-downloads-tracker@5.15.19":
"@mui/core-downloads-tracker@5.15.20":
resolution:
{
integrity: sha512-tCHSi/Tomez9ERynFhZRvFO6n9ATyrPs+2N80DMDzp6xDVirbBjEwhPcE+x7Lj+nwYw0SqFkOxyvMP0irnm55w==,
integrity: sha512-DoL2ppgldL16utL8nNyj/P12f8mCNdx/Hb/AJnX9rLY4b52hCMIx1kH83pbXQ6uMy6n54M3StmEbvSGoj2OFuA==,
}
"@mui/icons-material@5.15.19":
"@mui/icons-material@5.15.20":
resolution:
{
integrity: sha512-RsEiRxA5azN9b8gI7JRqekkgvxQUlitoBOtZglflb8cUDyP12/cP4gRwhb44Ea1/zwwGGjAj66ZJpGHhKfibNA==,
integrity: sha512-oGcKmCuHaYbAAoLN67WKSXtHmEgyWcJToT1uRtmPyxMj9N5uqwc/mRtEnst4Wj/eGr+zYH2FiZQ79v9k7kSk1Q==,
}
engines: { node: ">=12.0.0" }
peerDependencies:
@@ -1606,10 +1606,10 @@ packages:
"@types/react":
optional: true
"@mui/material@5.15.19":
"@mui/material@5.15.20":
resolution:
{
integrity: sha512-lp5xQBbcRuxNtjpWU0BWZgIrv2XLUz4RJ0RqFXBdESIsKoGCQZ6P3wwU5ZPuj5TjssNiKv9AlM+vHopRxZhvVQ==,
integrity: sha512-tVq3l4qoXx/NxUgIx/x3lZiPn/5xDbdTE8VrLczNpfblLYZzlrbxA7kb9mI8NoBF6+w9WE9IrxWnKK5KlPI2bg==,
}
engines: { node: ">=12.0.0" }
peerDependencies:
@@ -1626,10 +1626,10 @@ packages:
"@types/react":
optional: true
"@mui/private-theming@5.15.14":
"@mui/private-theming@5.15.20":
resolution:
{
integrity: sha512-UH0EiZckOWcxiXLX3Jbb0K7rC8mxTr9L9l6QhOZxYc4r8FHUkefltV9VDGLrzCaWh30SQiJvAEd7djX3XXY6Xw==,
integrity: sha512-BK8F94AIqSrnaPYXf2KAOjGZJgWfvqAVQ2gVR3EryvQFtuBnG6RwodxrCvd3B48VuMy6Wsk897+lQMUxJyk+6g==,
}
engines: { node: ">=12.0.0" }
peerDependencies:
@@ -1655,10 +1655,10 @@ packages:
"@emotion/styled":
optional: true
"@mui/system@5.15.15":
"@mui/system@5.15.20":
resolution:
{
integrity: sha512-aulox6N1dnu5PABsfxVGOZffDVmlxPOVgj56HrUnJE8MCSh8lOvvkd47cebIVQQYAjpwieXQXiDPj5pwM40jTQ==,
integrity: sha512-LoMq4IlAAhxzL2VNUDBTQxAb4chnBe8JvRINVNDiMtHE2PiPOoHlhOPutSxEbaL5mkECPVWSv6p8JEV+uykwIA==,
}
engines: { node: ">=12.0.0" }
peerDependencies:
@@ -1685,10 +1685,10 @@ packages:
"@types/react":
optional: true
"@mui/utils@5.15.14":
"@mui/utils@5.15.20":
resolution:
{
integrity: sha512-0lF/7Hh/ezDv5X7Pry6enMsbYyGKjADzvHyo3Qrc/SSlTsQ1VkbDMbH0m2t3OR5iIVLwMoxwM7yGd+6FCMtTFA==,
integrity: sha512-mAbYx0sovrnpAu1zHc3MDIhPqL8RPVC5W5xcO1b7PiSCJPtckIZmBkp8hefamAvUiAV8gpfMOM6Zb+eSisbI2A==,
}
engines: { node: ">=12.0.0" }
peerDependencies:
@@ -1698,15 +1698,14 @@ packages:
"@types/react":
optional: true
"@mui/x-data-grid@6.20.1":
"@mui/x-data-grid@7.7.0":
resolution:
{
integrity: sha512-x1muWWIG9otkk4FuvoTxH3I4foyA1caFu8ZC9TvMQ+7NSBKcfy/JeLQfKkZk8ACUUosvENdrRIkhqU2xdIqIVg==,
integrity: sha512-s3Oii9EKcYPnL7M4g5evNley/J0slLL6xWRi0VwYqTHPGntBAMntUktMZ63bD/xko99f5ZcFoRBYTc55+mJ+AQ==,
}
engines: { node: ">=14.0.0" }
peerDependencies:
"@mui/material": ^5.4.1
"@mui/system": ^5.4.1
"@mui/material": ^5.15.14
react: ^17.0.0 || ^18.0.0
react-dom: ^17.0.0 || ^18.0.0
@@ -2314,10 +2313,10 @@ packages:
peerDependencies:
vite: ^4.2.0 || ^5.0.0
acorn@8.11.3:
acorn@8.12.0:
resolution:
{
integrity: sha512-Y9rRfJG5jcKOE0CLisYbojUjIrIEE7AGMzA/Sm4BslANhbS+cDMpgBdcPT91oJ7OuJ9hYJBx59RjbhxVnrF8Xg==,
integrity: sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==,
}
engines: { node: ">=0.4.0" }
hasBin: true
@@ -2472,10 +2471,10 @@ packages:
}
engines: { node: ">=10" }
caniuse-lite@1.0.30001632:
caniuse-lite@1.0.30001636:
resolution:
{
integrity: sha512-udx3o7yHJfUxMLkGohMlVHCvFvWmirKh9JAH/d7WOLPetlH+LTL5cocMZ0t7oZx/mdlOWXti97xLZWc8uURRHg==,
integrity: sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==,
}
ccount@2.0.1:
@@ -2706,10 +2705,10 @@ packages:
integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==,
}
electron-to-chromium@1.4.799:
electron-to-chromium@1.4.803:
resolution:
{
integrity: sha512-3D3DwWkRTzrdEpntY0hMLYwj7SeBk1138CkPE8sBDSj3WzrzOiG2rHm3luw8jucpf+WiyLBCZyU9lMHyQI9M9Q==,
integrity: sha512-61H9mLzGOCLLVsnLiRzCbc63uldP0AniRYPV3hbGVtONA1pI7qSGILdbofR7A8TMbOypDocEAjH/e+9k1QIe3g==,
}
end-of-stream@1.4.4:
@@ -2731,10 +2730,10 @@ packages:
integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==,
}
esbuild@0.20.2:
esbuild@0.21.5:
resolution:
{
integrity: sha512-WdOOppmUNU+IbZ0PaDiTst80zjnrOkyJNHoKupIcVyU8Lvla3Ugx94VzkQ32Ijqd7UhHJy75gNWDMUekcrSJ6g==,
integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==,
}
engines: { node: ">=12" }
hasBin: true
@@ -3785,14 +3784,14 @@ packages:
integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==,
}
react-hook-form@7.51.5:
react-hook-form@7.52.0:
resolution:
{
integrity: sha512-J2ILT5gWx1XUIJRETiA7M19iXHlG74+6O3KApzvqB/w8S5NQR7AbU8HVZrMALdmDgWpRPYiZJl0zx8Z4L2mP6Q==,
integrity: sha512-mJX506Xc6mirzLsmXUJyqlAI3Kj9Ph2RhplYhUVffeOQSnubK2uVqBFOBJmvKikvbFV91pxVXmDiR+QMF19x6A==,
}
engines: { node: ">=12.22.0" }
peerDependencies:
react: ^16.8.0 || ^17 || ^18
react: ^16.8.0 || ^17 || ^18 || ^19
react-i18next@13.5.0:
resolution:
@@ -4348,10 +4347,10 @@ packages:
peerDependencies:
vite: ^2.6.0 || 3 || 4 || 5
vite@5.2.13:
vite@5.3.1:
resolution:
{
integrity: sha512-SSq1noJfY9pR3I1TUENL3rQYDQCFqgD+lM6fTRAM8Nv6Lsg5hDLaXkjETVeBt+7vZBCMoibD+6IWnT2mJ+Zb/A==,
integrity: sha512-XBmSKRLXLxiaPYamLv3/hnP/KXDai1NDexN0FpkTaZXTfycHvkRHoenpgl/fvuK/kPbB6xAgoyiryAhQNxYmAQ==,
}
engines: { node: ^18.0.0 || >=20.0.0 }
hasBin: true
@@ -5389,73 +5388,73 @@ snapshots:
"@emotion/weak-memoize@0.3.1": {}
"@esbuild/aix-ppc64@0.20.2":
"@esbuild/aix-ppc64@0.21.5":
optional: true
"@esbuild/android-arm64@0.20.2":
"@esbuild/android-arm64@0.21.5":
optional: true
"@esbuild/android-arm@0.20.2":
"@esbuild/android-arm@0.21.5":
optional: true
"@esbuild/android-x64@0.20.2":
"@esbuild/android-x64@0.21.5":
optional: true
"@esbuild/darwin-arm64@0.20.2":
"@esbuild/darwin-arm64@0.21.5":
optional: true
"@esbuild/darwin-x64@0.20.2":
"@esbuild/darwin-x64@0.21.5":
optional: true
"@esbuild/freebsd-arm64@0.20.2":
"@esbuild/freebsd-arm64@0.21.5":
optional: true
"@esbuild/freebsd-x64@0.20.2":
"@esbuild/freebsd-x64@0.21.5":
optional: true
"@esbuild/linux-arm64@0.20.2":
"@esbuild/linux-arm64@0.21.5":
optional: true
"@esbuild/linux-arm@0.20.2":
"@esbuild/linux-arm@0.21.5":
optional: true
"@esbuild/linux-ia32@0.20.2":
"@esbuild/linux-ia32@0.21.5":
optional: true
"@esbuild/linux-loong64@0.20.2":
"@esbuild/linux-loong64@0.21.5":
optional: true
"@esbuild/linux-mips64el@0.20.2":
"@esbuild/linux-mips64el@0.21.5":
optional: true
"@esbuild/linux-ppc64@0.20.2":
"@esbuild/linux-ppc64@0.21.5":
optional: true
"@esbuild/linux-riscv64@0.20.2":
"@esbuild/linux-riscv64@0.21.5":
optional: true
"@esbuild/linux-s390x@0.20.2":
"@esbuild/linux-s390x@0.21.5":
optional: true
"@esbuild/linux-x64@0.20.2":
"@esbuild/linux-x64@0.21.5":
optional: true
"@esbuild/netbsd-x64@0.20.2":
"@esbuild/netbsd-x64@0.21.5":
optional: true
"@esbuild/openbsd-x64@0.20.2":
"@esbuild/openbsd-x64@0.21.5":
optional: true
"@esbuild/sunos-x64@0.20.2":
"@esbuild/sunos-x64@0.21.5":
optional: true
"@esbuild/win32-arm64@0.20.2":
"@esbuild/win32-arm64@0.21.5":
optional: true
"@esbuild/win32-ia32@0.20.2":
"@esbuild/win32-ia32@0.21.5":
optional: true
"@esbuild/win32-x64@0.20.2":
"@esbuild/win32-x64@0.21.5":
optional: true
"@fastify/busboy@2.1.1": {}
@@ -5506,7 +5505,7 @@ snapshots:
"@babel/runtime": 7.24.7
"@floating-ui/react-dom": 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/types": 7.2.14(@types/react@18.3.3)
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
"@popperjs/core": 2.11.8
clsx: 2.1.1
prop-types: 15.8.1
@@ -5520,7 +5519,7 @@ snapshots:
"@babel/runtime": 7.24.7
"@floating-ui/react-dom": 2.1.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/types": 7.2.14(@types/react@18.3.3)
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
"@popperjs/core": 2.11.8
clsx: 2.1.1
prop-types: 15.8.1
@@ -5529,25 +5528,25 @@ snapshots:
optionalDependencies:
"@types/react": 18.3.3
"@mui/core-downloads-tracker@5.15.19": {}
"@mui/core-downloads-tracker@5.15.20": {}
"@mui/icons-material@5.15.19(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
"@mui/icons-material@5.15.20(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
react: 18.3.1
optionalDependencies:
"@types/react": 18.3.3
"@mui/lab@5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
"@mui/lab@5.0.0-alpha.149(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@mui/base": 5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/types": 7.2.14(@types/react@18.3.3)
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/x-tree-view": 6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
"@mui/x-tree-view": 6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
clsx: 2.1.1
prop-types: 15.8.1
react: 18.3.1
@@ -5557,14 +5556,14 @@ snapshots:
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@types/react": 18.3.3
"@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
"@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@mui/base": 5.0.0-beta.40(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/core-downloads-tracker": 5.15.19
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/core-downloads-tracker": 5.15.20
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/types": 7.2.14(@types/react@18.3.3)
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
"@types/react-transition-group": 4.4.10
clsx: 2.1.1
csstype: 3.1.3
@@ -5578,10 +5577,10 @@ snapshots:
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@types/react": 18.3.3
"@mui/private-theming@5.15.14(@types/react@18.3.3)(react@18.3.1)":
"@mui/private-theming@5.15.20(@types/react@18.3.3)(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
prop-types: 15.8.1
react: 18.3.1
optionalDependencies:
@@ -5598,13 +5597,13 @@ snapshots:
"@emotion/react": 11.11.4(@types/react@18.3.3)(react@18.3.1)
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
"@mui/system@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@mui/private-theming": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/private-theming": 5.15.20(@types/react@18.3.3)(react@18.3.1)
"@mui/styled-engine": 5.15.14(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(react@18.3.1)
"@mui/types": 7.2.14(@types/react@18.3.3)
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
clsx: 2.1.1
csstype: 3.1.3
prop-types: 15.8.1
@@ -5618,7 +5617,7 @@ snapshots:
optionalDependencies:
"@types/react": 18.3.3
"@mui/utils@5.15.14(@types/react@18.3.3)(react@18.3.1)":
"@mui/utils@5.15.20(@types/react@18.3.3)(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@types/prop-types": 15.7.12
@@ -5628,29 +5627,31 @@ snapshots:
optionalDependencies:
"@types/react": 18.3.3
"@mui/x-data-grid@6.20.1(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
"@mui/x-data-grid@7.7.0(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
clsx: 2.1.1
prop-types: 15.8.1
react: 18.3.1
react-dom: 18.3.1(react@18.3.1)
reselect: 4.1.8
transitivePeerDependencies:
- "@emotion/react"
- "@emotion/styled"
- "@types/react"
"@mui/x-tree-view@6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
"@mui/x-tree-view@6.0.0-alpha.1(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@mui/base@5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/material@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@mui/system@5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)":
dependencies:
"@babel/runtime": 7.24.7
"@emotion/react": 11.11.4(@types/react@18.3.3)(react@18.3.1)
"@emotion/styled": 11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/base": 5.0.0-beta.20(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/material": 5.15.19(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/system": 5.15.15(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.14(@types/react@18.3.3)(react@18.3.1)
"@mui/material": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
"@mui/system": 5.15.20(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@emotion/styled@11.11.5(@emotion/react@11.11.4(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1))(@types/react@18.3.3)(react@18.3.1)
"@mui/utils": 5.15.20(@types/react@18.3.3)(react@18.3.1)
"@types/react-transition-group": 4.4.10
clsx: 2.1.1
prop-types: 15.8.1
@@ -5981,7 +5982,7 @@ snapshots:
"@ungap/structured-clone@1.2.0": {}
"@vitejs/plugin-legacy@5.4.1(terser@5.31.1)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
"@vitejs/plugin-legacy@5.4.1(terser@5.31.1)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
dependencies:
"@babel/core": 7.24.7
"@babel/preset-env": 7.24.7(@babel/core@7.24.7)
@@ -5992,22 +5993,22 @@ snapshots:
regenerator-runtime: 0.14.1
systemjs: 6.15.1
terser: 5.31.1
vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
vite: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
transitivePeerDependencies:
- supports-color
"@vitejs/plugin-react@4.3.1(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
"@vitejs/plugin-react@4.3.1(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1))":
dependencies:
"@babel/core": 7.24.7
"@babel/plugin-transform-react-jsx-self": 7.24.7(@babel/core@7.24.7)
"@babel/plugin-transform-react-jsx-source": 7.24.7(@babel/core@7.24.7)
"@types/babel__core": 7.20.5
react-refresh: 0.14.2
vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
vite: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
transitivePeerDependencies:
- supports-color
acorn@8.11.3: {}
acorn@8.12.0: {}
adm-zip@0.5.14: {}
@@ -6098,8 +6099,8 @@ snapshots:
browserslist@4.23.1:
dependencies:
caniuse-lite: 1.0.30001632
electron-to-chromium: 1.4.799
caniuse-lite: 1.0.30001636
electron-to-chromium: 1.4.803
node-releases: 2.0.14
update-browserslist-db: 1.0.16(browserslist@4.23.1)
@@ -6109,7 +6110,7 @@ snapshots:
camelcase@6.3.0: {}
caniuse-lite@1.0.30001632: {}
caniuse-lite@1.0.30001636: {}
ccount@2.0.1: {}
@@ -6230,7 +6231,7 @@ snapshots:
no-case: 3.0.4
tslib: 2.6.3
electron-to-chromium@1.4.799: {}
electron-to-chromium@1.4.803: {}
end-of-stream@1.4.4:
dependencies:
@@ -6242,31 +6243,31 @@ snapshots:
dependencies:
is-arrayish: 0.2.1
esbuild@0.20.2:
esbuild@0.21.5:
optionalDependencies:
"@esbuild/aix-ppc64": 0.20.2
"@esbuild/android-arm": 0.20.2
"@esbuild/android-arm64": 0.20.2
"@esbuild/android-x64": 0.20.2
"@esbuild/darwin-arm64": 0.20.2
"@esbuild/darwin-x64": 0.20.2
"@esbuild/freebsd-arm64": 0.20.2
"@esbuild/freebsd-x64": 0.20.2
"@esbuild/linux-arm": 0.20.2
"@esbuild/linux-arm64": 0.20.2
"@esbuild/linux-ia32": 0.20.2
"@esbuild/linux-loong64": 0.20.2
"@esbuild/linux-mips64el": 0.20.2
"@esbuild/linux-ppc64": 0.20.2
"@esbuild/linux-riscv64": 0.20.2
"@esbuild/linux-s390x": 0.20.2
"@esbuild/linux-x64": 0.20.2
"@esbuild/netbsd-x64": 0.20.2
"@esbuild/openbsd-x64": 0.20.2
"@esbuild/sunos-x64": 0.20.2
"@esbuild/win32-arm64": 0.20.2
"@esbuild/win32-ia32": 0.20.2
"@esbuild/win32-x64": 0.20.2
"@esbuild/aix-ppc64": 0.21.5
"@esbuild/android-arm": 0.21.5
"@esbuild/android-arm64": 0.21.5
"@esbuild/android-x64": 0.21.5
"@esbuild/darwin-arm64": 0.21.5
"@esbuild/darwin-x64": 0.21.5
"@esbuild/freebsd-arm64": 0.21.5
"@esbuild/freebsd-x64": 0.21.5
"@esbuild/linux-arm": 0.21.5
"@esbuild/linux-arm64": 0.21.5
"@esbuild/linux-ia32": 0.21.5
"@esbuild/linux-loong64": 0.21.5
"@esbuild/linux-mips64el": 0.21.5
"@esbuild/linux-ppc64": 0.21.5
"@esbuild/linux-riscv64": 0.21.5
"@esbuild/linux-s390x": 0.21.5
"@esbuild/linux-x64": 0.21.5
"@esbuild/netbsd-x64": 0.21.5
"@esbuild/openbsd-x64": 0.21.5
"@esbuild/sunos-x64": 0.21.5
"@esbuild/win32-arm64": 0.21.5
"@esbuild/win32-ia32": 0.21.5
"@esbuild/win32-x64": 0.21.5
escalade@3.1.2: {}
@@ -6938,7 +6939,7 @@ snapshots:
react-fast-compare@3.2.2: {}
react-hook-form@7.51.5(react@18.3.1):
react-hook-form@7.52.0(react@18.3.1):
dependencies:
react: 18.3.1
@@ -7169,7 +7170,7 @@ snapshots:
terser@5.31.1:
dependencies:
"@jridgewell/source-map": 0.3.6
acorn: 8.11.3
acorn: 8.12.0
commander: 2.20.3
source-map-support: 0.5.21
@@ -7277,20 +7278,20 @@ snapshots:
dependencies:
monaco-editor: 0.49.0
vite-plugin-svgr@4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)):
vite-plugin-svgr@4.2.0(rollup@4.18.0)(typescript@5.4.5)(vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)):
dependencies:
"@rollup/pluginutils": 5.1.0(rollup@4.18.0)
"@svgr/core": 8.1.0(typescript@5.4.5)
"@svgr/plugin-jsx": 8.1.0(@svgr/core@8.1.0(typescript@5.4.5))
vite: 5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
vite: 5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1)
transitivePeerDependencies:
- rollup
- supports-color
- typescript
vite@5.2.13(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1):
vite@5.3.1(@types/node@20.14.2)(sass@1.77.5)(terser@5.31.1):
dependencies:
esbuild: 0.20.2
esbuild: 0.21.5
postcss: 8.4.38
rollup: 4.18.0
optionalDependencies:
@@ -1,10 +1,6 @@
import dayjs from "dayjs";
import { useMemo, useState } from "react";
import {
DataGrid,
GridColDef,
GridValueFormatterParams,
} from "@mui/x-data-grid";
import { DataGrid, GridColDef } from "@mui/x-data-grid";
import { truncateStr } from "@/utils/truncate-str";
import parseTraffic from "@/utils/parse-traffic";
import { t } from "i18next";
@@ -21,7 +17,7 @@ export const ConnectionTable = (props: Props) => {
Partial<Record<keyof IConnectionsItem, boolean>>
>({});
const columns: GridColDef[] = [
const [columns] = useState<GridColDef[]>([
{ field: "host", headerName: t("Host"), flex: 220, minWidth: 220 },
{
field: "download",
@@ -29,8 +25,7 @@ export const ConnectionTable = (props: Props) => {
width: 88,
align: "right",
headerAlign: "right",
valueFormatter: (params: GridValueFormatterParams<number>) =>
parseTraffic(params.value).join(" "),
valueFormatter: (value: number) => parseTraffic(value).join(" "),
},
{
field: "upload",
@@ -38,8 +33,7 @@ export const ConnectionTable = (props: Props) => {
width: 88,
align: "right",
headerAlign: "right",
valueFormatter: (params: GridValueFormatterParams<number>) =>
parseTraffic(params.value).join(" "),
valueFormatter: (value: number) => parseTraffic(value).join(" "),
},
{
field: "dlSpeed",
@@ -47,8 +41,7 @@ export const ConnectionTable = (props: Props) => {
width: 88,
align: "right",
headerAlign: "right",
valueFormatter: (params: GridValueFormatterParams<number>) =>
parseTraffic(params.value).join(" ") + "/s",
valueFormatter: (value: number) => parseTraffic(value).join(" ") + "/s",
},
{
field: "ulSpeed",
@@ -56,8 +49,7 @@ export const ConnectionTable = (props: Props) => {
width: 88,
align: "right",
headerAlign: "right",
valueFormatter: (params: GridValueFormatterParams<number>) =>
parseTraffic(params.value).join(" ") + "/s",
valueFormatter: (value: number) => parseTraffic(value).join(" ") + "/s",
},
{ field: "chains", headerName: t("Chains"), flex: 360, minWidth: 360 },
{ field: "rule", headerName: t("Rule"), flex: 300, minWidth: 250 },
@@ -69,11 +61,9 @@ export const ConnectionTable = (props: Props) => {
minWidth: 100,
align: "right",
headerAlign: "right",
sortComparator: (v1, v2) => {
return new Date(v2).getTime() - new Date(v1).getTime();
},
valueFormatter: (params: GridValueFormatterParams<string>) =>
dayjs(params.value).fromNow(),
sortComparator: (v1: string, v2: string) =>
new Date(v2).getTime() - new Date(v1).getTime(),
valueFormatter: (value: number) => dayjs(value).fromNow(),
},
{ field: "source", headerName: t("Source"), flex: 200, minWidth: 130 },
{
@@ -83,7 +73,7 @@ export const ConnectionTable = (props: Props) => {
minWidth: 130,
},
{ field: "type", headerName: t("Type"), flex: 160, minWidth: 100 },
];
]);
const connRows = useMemo(() => {
return connections.map((each) => {
@@ -8,7 +8,7 @@ import {
import { useClashInfo } from "@/hooks/use-clash";
import { useVerge } from "@/hooks/use-verge";
import { TrafficGraph, type TrafficRef } from "./traffic-graph";
import { useLogSetup } from "./use-log-setup";
import { useLogData } from "@/hooks/use-log-data";
import { useVisibility } from "@/hooks/use-visibility";
import parseTraffic from "@/utils/parse-traffic";
import useSWRSubscription from "swr/subscription";
@@ -30,8 +30,10 @@ export const LayoutTraffic = () => {
const trafficRef = useRef<TrafficRef>(null);
const pageVisible = useVisibility();
// setup log ws during layout
useLogSetup();
// https://swr.vercel.app/docs/subscription#deduplication
// useSWRSubscription auto deduplicates to one subscription per key per entire app
// So we can simply invoke it here acting as preconnect
useLogData();
const { data: traffic = { up: 0, down: 0 } } = useSWRSubscription<
ITrafficItem,
@@ -1,38 +0,0 @@
import dayjs from "dayjs";
import { useEffect } from "react";
import { getClashLogs } from "@/services/cmds";
import { useClashInfo } from "@/hooks/use-clash";
import { useEnableLog, useSetLogData } from "@/services/states";
import { useWebsocket } from "@/hooks/use-websocket";
const MAX_LOG_NUM = 1000;
// setup the log websocket
export const useLogSetup = () => {
const { clashInfo } = useClashInfo();
const [enableLog] = useEnableLog();
const setLogData = useSetLogData();
const { connect, disconnect } = useWebsocket((event) => {
const data = JSON.parse(event.data) as ILogItem;
const time = dayjs().format("MM-DD HH:mm:ss");
setLogData((l) => {
if (l.length >= MAX_LOG_NUM) l.shift();
return [...l, { ...data, time }];
});
});
useEffect(() => {
if (!enableLog || !clashInfo) return;
getClashLogs().then(setLogData);
const { server = "", secret = "" } = clashInfo;
connect(`ws://${server}/logs?token=${encodeURIComponent(secret)}`);
return () => {
disconnect();
};
}, [clashInfo, enableLog]);
};
@@ -32,7 +32,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
/^((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\*|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+|localhost|<local>)(;((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\d{1,3}\.\*|\d{1,3}\.\*|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+|localhost|<local>))*;?$/;
} else {
validReg =
/^((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>)(;((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>))*;?$/;
/^((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>)(,((\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|(\d{1,3}\.){1,3}\d{1,3}(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|\d{1,3}\.\*(\/\d{1,2}|\/3[0-2])?|([a-fA-F0-9:]+:+)+[a-fA-F0-9]+(\/\d{1,3})?|localhost|<local>))*,?$/;
}
const [open, setOpen] = useState(false);
+57
View File
@@ -0,0 +1,57 @@
import useSWRSubscription from "swr/subscription";
import { useEnableLog } from "../services/states";
import { createSockette } from "../utils/websocket";
import { useClashInfo } from "./use-clash";
import dayjs from "dayjs";
import { getClashLogs } from "../services/cmds";
const MAX_LOG_NUM = 1000;
export const useLogData = () => {
const { clashInfo } = useClashInfo();
const [enableLog] = useEnableLog();
!enableLog || !clashInfo;
return useSWRSubscription<ILogItem[], any, "getClashLog" | null>(
enableLog && clashInfo ? "getClashLog" : null,
(_key, { next }) => {
const { server = "", secret = "" } = clashInfo!;
// populate the initial logs
getClashLogs().then(
(logs) => next(null, logs),
(err) => next(err)
);
const s = createSockette(
`ws://${server}/logs?token=${encodeURIComponent(secret)}`,
{
onmessage(event) {
const data = JSON.parse(event.data) as ILogItem;
// append new log item on socket message
next(null, (l = []) => {
const time = dayjs().format("MM-DD HH:mm:ss");
if (l.length >= MAX_LOG_NUM) l.shift();
return [...l, { ...data, time }];
});
},
onerror(event) {
this.close();
next(event);
},
}
);
return () => {
s.close();
};
},
{
fallbackData: { up: 0, down: 0 },
keepPreviousData: true,
}
);
};
@@ -1,60 +0,0 @@
import { useRef } from "react";
export type WsMsgFn = (event: MessageEvent<any>) => void;
export interface WsOptions {
errorCount?: number; // default is 5
retryInterval?: number; // default is 2500
onError?: (event: Event) => void;
onClose?: (event: CloseEvent) => void;
}
export const useWebsocket = (onMessage: WsMsgFn, options?: WsOptions) => {
const wsRef = useRef<WebSocket | null>(null);
const timerRef = useRef<any>(null);
const disconnect = () => {
if (wsRef.current) {
wsRef.current.close();
wsRef.current = null;
}
if (timerRef.current) {
clearTimeout(timerRef.current);
}
};
const connect = (url: string) => {
let errorCount = options?.errorCount ?? 5;
if (!url) return;
const connectHelper = () => {
disconnect();
const ws = new WebSocket(url);
wsRef.current = ws;
ws.addEventListener("message", (event) => {
errorCount = 0; // reset counter
onMessage(event);
});
ws.addEventListener("error", (event) => {
errorCount -= 1;
if (errorCount >= 0) {
timerRef.current = setTimeout(connectHelper, 2500);
} else {
disconnect();
options?.onError?.(event);
}
});
ws.addEventListener("close", (event) => {
options?.onClose?.(event);
});
};
connectHelper();
};
return { connect, disconnect };
};
-2
View File
@@ -16,7 +16,6 @@ import Layout from "./pages/_layout";
import "./services/i18n";
import {
LoadingCacheProvider,
LogDataProvider,
ThemeModeProvider,
UpdateStateProvider,
} from "./services/states";
@@ -45,7 +44,6 @@ document.addEventListener("keydown", (event) => {
const contexts = [
<ThemeModeProvider />,
<LogDataProvider />,
<LoadingCacheProvider />,
<UpdateStateProvider />,
];
+66 -53
View File
@@ -1,4 +1,4 @@
import { useEffect, useMemo, useRef, useState } from "react";
import { useMemo, useRef, useState } from "react";
import { useLockFn } from "ahooks";
import { Box, Button, IconButton, MenuItem } from "@mui/material";
import { Virtuoso } from "react-virtuoso";
@@ -8,7 +8,6 @@ import { closeAllConnections } from "@/services/api";
import { useConnectionSetting } from "@/services/states";
import { useClashInfo } from "@/hooks/use-clash";
import { BaseEmpty, BasePage } from "@/components/base";
import { useWebsocket } from "@/hooks/use-websocket";
import { ConnectionItem } from "@/components/connection/connection-item";
import { ConnectionTable } from "@/components/connection/connection-table";
import {
@@ -19,8 +18,14 @@ import parseTraffic from "@/utils/parse-traffic";
import { useCustomTheme } from "@/components/layout/use-custom-theme";
import { BaseSearchBox } from "@/components/base/base-search-box";
import { BaseStyledSelect } from "@/components/base/base-styled-select";
import useSWRSubscription from "swr/subscription";
import { createSockette } from "@/utils/websocket";
const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
const initConn: IConnections = {
uploadTotal: 0,
downloadTotal: 0,
connections: [],
};
type OrderFunc = (list: IConnectionsItem[]) => IConnectionsItem[];
@@ -31,7 +36,6 @@ const ConnectionsPage = () => {
const isDark = theme.palette.mode === "dark";
const [match, setMatch] = useState(() => (_: string) => true);
const [curOrderOpt, setOrderOpt] = useState("Default");
const [connData, setConnData] = useState<IConnections>(initConn);
const [setting, setSetting] = useConnectionSetting();
@@ -49,6 +53,63 @@ const ConnectionsPage = () => {
list.sort((a, b) => b.curDownload! - a.curDownload!),
};
const { data: connData = initConn } = useSWRSubscription<
IConnections,
any,
"getClashConnections" | null
>(clashInfo ? "getClashConnections" : null, (_key, { next }) => {
const { server = "", secret = "" } = clashInfo!;
const s = createSockette(
`ws://${server}/connections?token=${encodeURIComponent(secret)}`,
{
onmessage(event) {
// meta v1.15.0 出现 data.connections 为 null 的情况
const data = JSON.parse(event.data) as IConnections;
// 尽量与前一次 connections 的展示顺序保持一致
next(null, (old = initConn) => {
const oldConn = old.connections;
const maxLen = data.connections?.length;
const connections: IConnectionsItem[] = [];
const rest = (data.connections || []).filter((each) => {
const index = oldConn.findIndex((o) => o.id === each.id);
if (index >= 0 && index < maxLen) {
const old = oldConn[index];
each.curUpload = each.upload - old.upload;
each.curDownload = each.download - old.download;
connections[index] = each;
return false;
}
return true;
});
for (let i = 0; i < maxLen; ++i) {
if (!connections[i] && rest.length > 0) {
connections[i] = rest.shift()!;
connections[i].curUpload = 0;
connections[i].curDownload = 0;
}
}
return { ...data, connections };
});
},
onerror(event) {
next(event);
},
},
3
);
return () => {
s.close();
};
});
const [filterConn, download, upload] = useMemo(() => {
const orderFunc = orderOpts[curOrderOpt];
let connections = connData.connections.filter((conn) =>
@@ -56,6 +117,7 @@ const ConnectionsPage = () => {
);
if (orderFunc) connections = orderFunc(connections);
let download = 0;
let upload = 0;
connections.forEach((x) => {
@@ -65,55 +127,6 @@ const ConnectionsPage = () => {
return [connections, download, upload];
}, [connData, match, curOrderOpt]);
const { connect, disconnect } = useWebsocket(
(event) => {
// meta v1.15.0 出现data.connections为null的情况
const data = JSON.parse(event.data) as IConnections;
// 尽量与前一次connections的展示顺序保持一致
setConnData((old) => {
const oldConn = old.connections;
const maxLen = data.connections?.length;
const connections: typeof oldConn = [];
const rest = (data.connections || []).filter((each) => {
const index = oldConn.findIndex((o) => o.id === each.id);
if (index >= 0 && index < maxLen) {
const old = oldConn[index];
each.curUpload = each.upload - old.upload;
each.curDownload = each.download - old.download;
connections[index] = each;
return false;
}
return true;
});
for (let i = 0; i < maxLen; ++i) {
if (!connections[i] && rest.length > 0) {
connections[i] = rest.shift()!;
connections[i].curUpload = 0;
connections[i].curDownload = 0;
}
}
return { ...data, connections };
});
},
{ errorCount: 3, retryInterval: 1000 }
);
useEffect(() => {
if (!clashInfo) return;
const { server = "", secret = "" } = clashInfo;
connect(`ws://${server}/connections?token=${encodeURIComponent(secret)}`);
return () => {
disconnect();
};
}, [clashInfo]);
const onCloseAll = useLockFn(closeAllConnections);
const detailRef = useRef<ConnectionDetailRef>(null!);
+7 -4
View File
@@ -6,17 +6,18 @@ import {
PlayCircleOutlineRounded,
PauseCircleOutlineRounded,
} from "@mui/icons-material";
import { useEnableLog, useLogData, useSetLogData } from "@/services/states";
import { useLogData } from "@/hooks/use-log-data";
import { useEnableLog } from "@/services/states";
import { BaseEmpty, BasePage } from "@/components/base";
import LogItem from "@/components/log/log-item";
import { useCustomTheme } from "@/components/layout/use-custom-theme";
import { BaseSearchBox } from "@/components/base/base-search-box";
import { BaseStyledSelect } from "@/components/base/base-styled-select";
import { mutate } from "swr";
const LogPage = () => {
const { t } = useTranslation();
const logData = useLogData();
const setLogData = useSetLogData();
const { data: logData = [] } = useLogData();
const [enableLog, setEnableLog] = useEnableLog();
const { theme } = useCustomTheme();
const isDark = theme.palette.mode === "dark";
@@ -54,7 +55,9 @@ const LogPage = () => {
<Button
size="small"
variant="contained"
onClick={() => setLogData([])}
// useSWRSubscription adds a prefix "$sub$" to the cache key
// https://github.com/vercel/swr/blob/1585a3e37d90ad0df8097b099db38f1afb43c95d/src/subscription/index.ts#L37
onClick={() => mutate("$sub$getClashLog", [])}
>
{t("Clear")}
</Button>
-7
View File
@@ -5,10 +5,6 @@ const [ThemeModeProvider, useThemeMode, useSetThemeMode] = createContextState<
"light" | "dark"
>("light");
const [LogDataProvider, useLogData, useSetLogData] = createContextState<
ILogItem[]
>([]);
export const useEnableLog = () => useLocalStorage("enable-log", true);
interface IConnectionSetting {
@@ -39,9 +35,6 @@ export {
ThemeModeProvider,
useThemeMode,
useSetThemeMode,
LogDataProvider,
useLogData,
useSetLogData,
LoadingCacheProvider,
useLoadingCache,
useSetLoadingCache,
+1 -1
View File
@@ -6,7 +6,7 @@ var (
// allow change in test
IdleTimeOut = 10 * time.Second
Version = "1.1.4-dev"
Version = "1.1.4"
GitBranch string
GitRevision string
BuildTime string
+2 -2
View File
@@ -1,2 +1,2 @@
LINUX_VERSION-5.10 = .218
LINUX_KERNEL_HASH-5.10.218 = 9c36b243e8c3ec1d5963366618f336710b84340bf95be2037b26c452392cb2d6
LINUX_VERSION-5.10 = .219
LINUX_KERNEL_HASH-5.10.219 = 93b73f15cc376463e6422cce09ccd9d0a20fb113921ffebddf3352c44d84cd30
+2 -2
View File
@@ -1,2 +1,2 @@
LINUX_VERSION-5.4 = .277
LINUX_KERNEL_HASH-5.4.277 = 7e1f5b28588e49ddfd18e7772476e4e8b52bdc9c3e19beafcbb7c103e6c01f51
LINUX_VERSION-5.4 = .278
LINUX_KERNEL_HASH-5.4.278 = e5a00606115545f444ef2766af5652f5539e3c96f46a9778bede89b98ffb8588
+2 -2
View File
@@ -1,2 +1,2 @@
LINUX_VERSION-6.1 = .92
LINUX_KERNEL_HASH-6.1.92 = 9019f427bfdc9ced5bc954d760d37ac08c0cdffb45ad28087fc45a73e64336c9
LINUX_VERSION-6.1 = .94
LINUX_KERNEL_HASH-6.1.94 = 38ea71ad22ae0187fd8ee5ff879b33b0d9bd58161ac9a3e868ae0b4c66b95369
+1 -1
View File
@@ -43,7 +43,7 @@ endef
define Package/nss-firmware-ipq8074
$(Package/nss-firmware-default)
TITLE:=NSS firmware for IPQ8074 devices
NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.12.0.0/BIN-NSS.FW.12.0.r1-002-HK.R.tar.bz2
NSS_ARCHIVE:=$(VERSION_PATH)/IPQ8074.ATH.12.0.0/BIN-NSS.FW.12.1-022-HK.R.tar.bz2
endef
define Build/Compile
@@ -1,47 +0,0 @@
From 648c906a27d3713f589717f4be36583fc64f2ba1 Mon Sep 17 00:00:00 2001
From: Steve Glendinning <steve.glendinning@smsc.com>
Date: Thu, 19 Feb 2015 18:47:12 +0000
Subject: [PATCH] smsx95xx: fix crimes against truesize
smsc95xx is adjusting truesize when it shouldn't, and following a recent patch from Eric this is now triggering warnings.
This patch stops smsc95xx from changing truesize.
Signed-off-by: Steve Glendinning <steve.glendinning@smsc.com>
---
drivers/net/usb/smsc95xx.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -79,6 +79,10 @@ static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+static bool truesize_mode = false;
+module_param(truesize_mode, bool, 0644);
+MODULE_PARM_DESC(truesize_mode, "Report larger truesize value");
+
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data)
{
@@ -1870,7 +1874,8 @@ static int smsc95xx_rx_fixup(struct usbn
if (dev->net->features & NETIF_F_RXCSUM)
smsc95xx_rx_csum_offload(skb);
skb_trim(skb, skb->len - 4); /* remove fcs */
- skb->truesize = size + sizeof(struct sk_buff);
+ if (truesize_mode)
+ skb->truesize = size + sizeof(struct sk_buff);
return 1;
}
@@ -1888,7 +1893,8 @@ static int smsc95xx_rx_fixup(struct usbn
if (dev->net->features & NETIF_F_RXCSUM)
smsc95xx_rx_csum_offload(ax_skb);
skb_trim(ax_skb, ax_skb->len - 4); /* remove fcs */
- ax_skb->truesize = size + sizeof(struct sk_buff);
+ if (truesize_mode)
+ ax_skb->truesize = size + sizeof(struct sk_buff);
usbnet_skb_return(dev, ax_skb);
}
@@ -11,9 +11,9 @@ See: http://forum.kodi.tv/showthread.php?tid=285288
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -83,6 +83,10 @@ static bool truesize_mode = false;
module_param(truesize_mode, bool, 0644);
MODULE_PARM_DESC(truesize_mode, "Report larger truesize value");
@@ -79,6 +79,10 @@ static bool turbo_mode = true;
module_param(turbo_mode, bool, 0644);
MODULE_PARM_DESC(turbo_mode, "Enable multiple frames per Rx transaction");
+static int packetsize = 2560;
+module_param(packetsize, int, 0644);
@@ -22,7 +22,7 @@ See: http://forum.kodi.tv/showthread.php?tid=285288
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data)
{
@@ -936,13 +940,13 @@ static int smsc95xx_reset(struct usbnet
@@ -932,13 +936,13 @@ static int smsc95xx_reset(struct usbnet
if (!turbo_mode) {
burst_cap = 0;
@@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -87,6 +87,10 @@ static int packetsize = 2560;
@@ -83,6 +83,10 @@ static int packetsize = 2560;
module_param(packetsize, int, 0644);
MODULE_PARM_DESC(packetsize, "Override the RX URB packet size");
@@ -33,7 +33,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
static int __must_check smsc95xx_read_reg(struct usbnet *dev, u32 index,
u32 *data)
{
@@ -809,6 +813,52 @@ static int smsc95xx_ioctl(struct net_dev
@@ -805,6 +809,52 @@ static int smsc95xx_ioctl(struct net_dev
return phy_mii_ioctl(netdev->phydev, rq, cmd);
}
@@ -86,7 +86,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
static void smsc95xx_init_mac_address(struct usbnet *dev)
{
u8 addr[ETH_ALEN];
@@ -832,6 +882,10 @@ static void smsc95xx_init_mac_address(st
@@ -828,6 +878,10 @@ static void smsc95xx_init_mac_address(st
}
}
@@ -27,7 +27,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -32,6 +32,8 @@ struct rpi_firmware {
@@ -33,6 +33,8 @@ struct rpi_firmware {
struct kref consumers;
};
@@ -36,7 +36,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
static DEFINE_MUTEX(transaction_lock);
static void response_callback(struct mbox_client *cl, void *msg)
@@ -280,6 +282,7 @@ static int rpi_firmware_probe(struct pla
@@ -281,6 +283,7 @@ static int rpi_firmware_probe(struct pla
kref_init(&fw->consumers);
platform_set_drvdata(pdev, fw);
@@ -44,7 +44,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
rpi_firmware_print_firmware_revision(fw);
rpi_register_hwmon_driver(dev, fw);
@@ -308,6 +311,7 @@ static int rpi_firmware_remove(struct pl
@@ -309,6 +312,7 @@ static int rpi_firmware_remove(struct pl
rpi_clk = NULL;
rpi_firmware_put(fw);
@@ -52,7 +52,7 @@ Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
return 0;
}
@@ -382,7 +386,18 @@ static struct platform_driver rpi_firmwa
@@ -383,7 +387,18 @@ static struct platform_driver rpi_firmwa
.shutdown = rpi_firmware_shutdown,
.remove = rpi_firmware_remove,
};
@@ -156,7 +156,7 @@ See: https://github.com/raspberrypi/linux/issues/1064
+MODULE_LICENSE("GPL");
--- a/include/linux/leds.h
+++ b/include/linux/leds.h
@@ -85,6 +85,9 @@ struct led_classdev {
@@ -95,6 +95,9 @@ struct led_classdev {
#define LED_BRIGHT_HW_CHANGED BIT(21)
#define LED_RETAIN_AT_SHUTDOWN BIT(22)
#define LED_INIT_DEFAULT_TRIGGER BIT(23)
@@ -13,7 +13,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -12,6 +12,7 @@
@@ -13,6 +13,7 @@
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
@@ -21,7 +21,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
#include <linux/slab.h>
#include <soc/bcm2835/raspberrypi-firmware.h>
@@ -179,6 +180,26 @@ int rpi_firmware_property(struct rpi_fir
@@ -180,6 +181,26 @@ int rpi_firmware_property(struct rpi_fir
}
EXPORT_SYMBOL_GPL(rpi_firmware_property);
@@ -48,7 +48,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.org>
static void
rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
{
@@ -387,15 +408,32 @@ static struct platform_driver rpi_firmwa
@@ -388,15 +409,32 @@ static struct platform_driver rpi_firmwa
.remove = rpi_firmware_remove,
};
@@ -16,7 +16,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -31,6 +31,7 @@ struct rpi_firmware {
@@ -32,6 +32,7 @@ struct rpi_firmware {
u32 enabled;
struct kref consumers;
@@ -24,7 +24,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
};
static struct platform_device *g_pdev;
@@ -176,6 +177,12 @@ int rpi_firmware_property(struct rpi_fir
@@ -177,6 +178,12 @@ int rpi_firmware_property(struct rpi_fir
kfree(data);
@@ -37,7 +37,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
return ret;
}
EXPORT_SYMBOL_GPL(rpi_firmware_property);
@@ -200,6 +207,27 @@ static int rpi_firmware_notify_reboot(st
@@ -201,6 +208,27 @@ static int rpi_firmware_notify_reboot(st
return 0;
}
@@ -65,7 +65,7 @@ Signed-off-by: Stefan Wahren <stefan.wahren@i2se.com>
static void
rpi_firmware_print_firmware_revision(struct rpi_firmware *fw)
{
@@ -229,6 +257,11 @@ rpi_register_hwmon_driver(struct device
@@ -230,6 +258,11 @@ rpi_register_hwmon_driver(struct device
rpi_hwmon = platform_device_register_data(dev, "raspberrypi-hwmon",
-1, NULL, 0);
@@ -26,7 +26,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -233,6 +233,15 @@ rpi_firmware_print_firmware_revision(str
@@ -234,6 +234,15 @@ rpi_firmware_print_firmware_revision(str
{
time64_t date_and_time;
u32 packet;
@@ -42,7 +42,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
int ret = rpi_firmware_property(fw,
RPI_FIRMWARE_GET_FIRMWARE_REVISION,
&packet, sizeof(packet));
@@ -242,7 +251,35 @@ rpi_firmware_print_firmware_revision(str
@@ -243,7 +252,35 @@ rpi_firmware_print_firmware_revision(str
/* This is not compatible with y2038 */
date_and_time = packet;
@@ -79,7 +79,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.org>
}
static void
@@ -339,6 +376,7 @@ static int rpi_firmware_probe(struct pla
@@ -340,6 +377,7 @@ static int rpi_firmware_probe(struct pla
g_pdev = pdev;
rpi_firmware_print_firmware_revision(fw);
@@ -36,7 +36,7 @@ Co-authored-by: Phil Elwell <phil@raspberrypi.org>
MODULE_DESCRIPTION("BCM2835 clock driver");
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -499,7 +499,7 @@ out2:
@@ -500,7 +500,7 @@ out2:
out1:
return ret;
}
@@ -32,7 +32,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -3690,6 +3690,7 @@ static int spi_set_cs_timing(struct spi_
@@ -3694,6 +3694,7 @@ static int spi_set_cs_timing(struct spi_
*/
int spi_setup(struct spi_device *spi)
{
@@ -40,7 +40,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
unsigned bad_bits, ugly_bits;
int status = 0;
@@ -3710,6 +3711,14 @@ int spi_setup(struct spi_device *spi)
@@ -3714,6 +3715,14 @@ int spi_setup(struct spi_device *spi)
(SPI_TX_DUAL | SPI_TX_QUAD | SPI_TX_OCTAL |
SPI_RX_DUAL | SPI_RX_QUAD | SPI_RX_OCTAL)))
return -EINVAL;
@@ -19,7 +19,7 @@ mechanism to be implemented for OS upgrades.
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -193,6 +193,7 @@ static int rpi_firmware_notify_reboot(st
@@ -194,6 +194,7 @@ static int rpi_firmware_notify_reboot(st
{
struct rpi_firmware *fw;
struct platform_device *pdev = g_pdev;
@@ -27,7 +27,7 @@ mechanism to be implemented for OS upgrades.
if (!pdev)
return 0;
@@ -201,8 +202,28 @@ static int rpi_firmware_notify_reboot(st
@@ -202,8 +203,28 @@ static int rpi_firmware_notify_reboot(st
if (!fw)
return 0;
@@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3193,6 +3193,31 @@ static const struct panel_desc qishenglo
@@ -3196,6 +3196,31 @@ static const struct panel_desc qishenglo
.connector_type = DRM_MODE_CONNECTOR_DPI,
};
@@ -47,7 +47,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
static const struct display_timing rocktech_rk070er9427_timing = {
.pixelclock = { 26400000, 33300000, 46800000 },
.hactive = { 800, 800, 800 },
@@ -4226,6 +4251,9 @@ static const struct of_device_id platfor
@@ -4229,6 +4254,9 @@ static const struct of_device_id platfor
.compatible = "qishenglong,gopher2b-lcd",
.data = &qishenglong_gopher2b_lcd,
}, {
@@ -46,7 +46,7 @@ Acked-by: Maxime Ripard <maxime@cerno.tech>
static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
.clock = 9000,
.hdisplay = 480,
@@ -4110,6 +4136,9 @@ static const struct of_device_id platfor
@@ -4113,6 +4139,9 @@ static const struct of_device_id platfor
.compatible = "friendlyarm,hd702e",
.data = &friendlyarm_hd702e,
}, {
@@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -429,6 +429,18 @@ static int rpi_firmware_remove(struct pl
@@ -430,6 +430,18 @@ static int rpi_firmware_remove(struct pl
return 0;
}
@@ -38,7 +38,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
/**
* rpi_firmware_get - Get pointer to rpi_firmware structure.
* @firmware_node: Pointer to the firmware Device Tree node.
@@ -484,12 +496,6 @@ struct rpi_firmware *devm_rpi_firmware_g
@@ -485,12 +497,6 @@ struct rpi_firmware *devm_rpi_firmware_g
}
EXPORT_SYMBOL_GPL(devm_rpi_firmware_get);
@@ -19,7 +19,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
--- a/drivers/firmware/raspberrypi.c
+++ b/drivers/firmware/raspberrypi.c
@@ -342,6 +342,26 @@ static void rpi_register_clk_driver(stru
@@ -343,6 +343,26 @@ static void rpi_register_clk_driver(stru
-1, NULL, 0);
}
@@ -36,7 +36,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
#include <sound/dmaengine_pcm.h>
#include <sound/hdmi-codec.h>
#include <sound/pcm_drm_eld.h>
@@ -3695,7 +3696,7 @@ static int vc4_hdmi_bind(struct device *
@@ -3697,7 +3698,7 @@ static int vc4_hdmi_bind(struct device *
if (variant->max_pixel_clock == 600000000) {
struct vc4_dev *vc4 = to_vc4_dev(drm);
@@ -91,7 +91,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
return MODE_CLOCK_HIGH;
if (info->max_tmds_clock && clock > (info->max_tmds_clock * 1000))
@@ -3694,14 +3695,6 @@ static int vc4_hdmi_bind(struct device *
@@ -3696,14 +3697,6 @@ static int vc4_hdmi_bind(struct device *
vc4_hdmi->disable_wifi_frequencies =
of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
@@ -165,7 +165,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
static const struct drm_display_mode innolux_at070tn92_mode = {
.clock = 33333,
.hdisplay = 800,
@@ -4146,6 +4178,9 @@ static const struct of_device_id platfor
@@ -4149,6 +4181,9 @@ static const struct of_device_id platfor
.compatible = "innolux,at043tn24",
.data = &innolux_at043tn24,
}, {
@@ -8,8 +8,8 @@ Slave addresses for DMA are meant to be supplied as physical addresses
Signed-off-by: Phil Elwell <phil@raspberrypi.com>
---
drivers/gpu/drm/vc4/vc4_hdmi.c | 13 ++++---------
1 file changed, 4 insertions(+), 9 deletions(-)
drivers/gpu/drm/vc4/vc4_hdmi.c | 15 ++++-----------
1 file changed, 4 insertions(+), 11 deletions(-)
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -22,7 +22,7 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
int index, len;
int ret;
@@ -2755,20 +2755,15 @@ static int vc4_hdmi_audio_init(struct vc
@@ -2755,22 +2755,15 @@ static int vc4_hdmi_audio_init(struct vc
}
/*
@@ -40,6 +40,8 @@ Signed-off-by: Phil Elwell <phil@raspberrypi.com>
+ iomem = platform_get_resource(vc4_hdmi->pdev, IORESOURCE_MEM, index);
- addr = of_get_address(dev->of_node, index, NULL, NULL);
- if (!addr)
- return -EINVAL;
-
- vc4_hdmi->audio.dma_data.addr = be32_to_cpup(addr) + mai_data->offset;
+ vc4_hdmi->audio.dma_data.addr = iomem->start + mai_data->offset;
@@ -43,7 +43,7 @@ Signed-off-by: Lukas Wunner <lukas@wunner.de>
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -814,49 +814,18 @@ static int smsc95xx_ioctl(struct net_dev
@@ -810,49 +810,18 @@ static int smsc95xx_ioctl(struct net_dev
}
/* Check the macaddr module parameter for a MAC address */
@@ -103,7 +103,7 @@ Signed-off-by: Lukas Wunner <lukas@wunner.de>
}
static void smsc95xx_init_mac_address(struct usbnet *dev)
@@ -883,8 +852,12 @@ static void smsc95xx_init_mac_address(st
@@ -879,8 +848,12 @@ static void smsc95xx_init_mac_address(st
}
/* Check module parameters */
@@ -50,7 +50,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
};
/*****************************************************************************\
@@ -4605,6 +4615,15 @@ int sdhci_setup_host(struct sdhci_host *
@@ -4611,6 +4621,15 @@ int sdhci_setup_host(struct sdhci_host *
!(host->quirks2 & SDHCI_QUIRK2_BROKEN_DDR50))
mmc->caps |= MMC_CAP_UHS_DDR50;
@@ -68,7 +68,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
host->flags |= SDHCI_SDR50_NEEDS_TUNING;
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -481,6 +481,11 @@ struct sdhci_host {
@@ -482,6 +482,11 @@ struct sdhci_host {
/* Issue CMD and DATA reset together */
#define SDHCI_QUIRK2_ISSUE_CMD_DAT_RESET_TOGETHER (1<<19)
@@ -80,7 +80,7 @@ sdhci: remove PYA0_INTR_BUG quirk. Add quirks to disable some of the higher SDR
int irq; /* Device IRQ */
void __iomem *ioaddr; /* Mapped address */
phys_addr_t mapbase; /* physical address base */
@@ -663,6 +668,7 @@ struct sdhci_ops {
@@ -664,6 +669,7 @@ struct sdhci_ops {
void (*request_done)(struct sdhci_host *host,
struct mmc_request *mrq);
void (*dump_vendor_regs)(struct sdhci_host *host);
@@ -18,7 +18,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -3625,6 +3625,7 @@ static int vc4_hdmi_runtime_suspend(stru
@@ -3627,6 +3627,7 @@ static int vc4_hdmi_runtime_suspend(stru
{
struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
@@ -26,7 +26,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
clk_disable_unprepare(vc4_hdmi->hsm_rpm_clock);
return 0;
@@ -3666,6 +3667,10 @@ static int vc4_hdmi_runtime_resume(struc
@@ -3668,6 +3669,10 @@ static int vc4_hdmi_runtime_resume(struc
goto err_disable_clk;
}
@@ -73,7 +73,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
VC4_HD_VID_CTL_ENABLE |
VC4_HD_VID_CTL_CLRRGB |
VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
@@ -3796,7 +3808,9 @@ static int vc4_hdmi_bind(struct device *
@@ -3798,7 +3810,9 @@ static int vc4_hdmi_bind(struct device *
return ret;
if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") ||
@@ -84,7 +84,7 @@ Signed-off-by: Maxime Ripard <maxime@cerno.tech>
HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) {
clk_prepare_enable(vc4_hdmi->pixel_clock);
clk_prepare_enable(vc4_hdmi->hsm_clock);
@@ -3931,10 +3945,66 @@ static const struct vc4_hdmi_variant bcm
@@ -3933,10 +3947,66 @@ static const struct vc4_hdmi_variant bcm
.hp_detect = vc5_hdmi_hp_detect,
};
@@ -15,7 +15,7 @@ Signed-off-by: Dave Stevenson <dave.stevenson@raspberrypi.com>
--- a/drivers/gpu/drm/panel/panel-simple.c
+++ b/drivers/gpu/drm/panel/panel-simple.c
@@ -3241,11 +3241,11 @@ static const struct panel_desc qishenglo
@@ -3244,11 +3244,11 @@ static const struct panel_desc qishenglo
};
static const struct drm_display_mode raspberrypi_7inch_mode = {
@@ -74,7 +74,7 @@ Signed-off-by: Dom Cobley <popcornmix@gmail.com>
},
--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
+++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
@@ -3958,7 +3958,7 @@ static const struct vc4_hdmi_variant bcm
@@ -3960,7 +3960,7 @@ static const struct vc4_hdmi_variant bcm
PHY_LANE_2,
PHY_LANE_CK,
},
@@ -83,7 +83,7 @@ Signed-off-by: Dom Cobley <popcornmix@gmail.com>
.external_irq_controller = true,
.init_resources = vc5_hdmi_init_resources,
@@ -3985,7 +3985,7 @@ static const struct vc4_hdmi_variant bcm
@@ -3987,7 +3987,7 @@ static const struct vc4_hdmi_variant bcm
PHY_LANE_2,
PHY_LANE_CK,
},
@@ -50,7 +50,7 @@ Signed-off-by: Jonathan Bell <jonathan@raspberrypi.com>
if (!mmc_op_tuning(host->cmd->opcode))
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -486,6 +486,9 @@ struct sdhci_host {
@@ -487,6 +487,9 @@ struct sdhci_host {
#define SDHCI_QUIRK2_NO_SDR50 (1<<20)
#define SDHCI_QUIRK2_NO_SDR104 (1<<21)
@@ -23,7 +23,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
/**
* struct panel_desc - Describes a simple panel.
@@ -4662,6 +4663,9 @@ static const struct panel_desc_dsi osd10
@@ -4665,6 +4666,9 @@ static const struct panel_desc_dsi osd10
.lanes = 4,
};
@@ -33,7 +33,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
static const struct of_device_id dsi_of_match[] = {
{
.compatible = "auo,b080uan01",
@@ -4685,14 +4689,118 @@ static const struct of_device_id dsi_of_
@@ -4688,14 +4692,118 @@ static const struct of_device_id dsi_of_
.compatible = "osddisplays,osd101t2045-53ts",
.data = &osd101t2045_53ts
}, {
@@ -152,7 +152,7 @@ Signed-off-by: Timon Skerutsch <kernel@diodes-delight.com>
const struct of_device_id *id;
int err;
@@ -4700,7 +4808,20 @@ static int panel_simple_dsi_probe(struct
@@ -4703,7 +4811,20 @@ static int panel_simple_dsi_probe(struct
if (!id)
return -ENODEV;
@@ -1815,7 +1815,7 @@ Signed-off-by: David S. Miller <davem@davemloft.net>
}
--- a/drivers/net/usb/smsc95xx.c
+++ b/drivers/net/usb/smsc95xx.c
@@ -901,11 +901,12 @@ static int smsc95xx_ioctl(struct net_dev
@@ -903,11 +903,12 @@ static int smsc95xx_ioctl(struct net_dev
static void smsc95xx_init_mac_address(struct usbnet *dev)
{
@@ -17,7 +17,7 @@ Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -953,8 +953,8 @@ static int mtd_otp_nvmem_add(struct mtd_
@@ -955,8 +955,8 @@ static int mtd_otp_nvmem_add(struct mtd_
nvmem = mtd_otp_nvmem_register(mtd, "user-otp", size,
mtd_nvmem_user_otp_reg_read);
if (IS_ERR(nvmem)) {
@@ -28,7 +28,7 @@ Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
}
mtd->otp_user_nvmem = nvmem;
}
@@ -971,7 +971,6 @@ static int mtd_otp_nvmem_add(struct mtd_
@@ -973,7 +973,6 @@ static int mtd_otp_nvmem_add(struct mtd_
nvmem = mtd_otp_nvmem_register(mtd, "factory-otp", size,
mtd_nvmem_fact_otp_reg_read);
if (IS_ERR(nvmem)) {
@@ -36,7 +36,7 @@ Link: https://lore.kernel.org/linux-mtd/20230308082021.870459-4-michael@walle.cc
err = PTR_ERR(nvmem);
goto err;
}
@@ -983,7 +982,7 @@ static int mtd_otp_nvmem_add(struct mtd_
@@ -985,7 +984,7 @@ static int mtd_otp_nvmem_add(struct mtd_
err:
nvmem_unregister(mtd->otp_user_nvmem);

Some files were not shown because too many files have changed in this diff Show More