diff --git a/.github/update.log b/.github/update.log index 095357167d..1a94a6bb1f 100644 --- a/.github/update.log +++ b/.github/update.log @@ -580,3 +580,4 @@ Update On Tue Mar 5 01:51:50 CET 2024 Update On Tue Mar 5 02:18:45 CET 2024 Update On Tue Mar 5 19:29:09 CET 2024 Update On Wed Mar 6 19:27:47 CET 2024 +Update On Thu Mar 7 19:24:38 CET 2024 diff --git a/clash-meta/adapter/outbound/dns.go b/clash-meta/adapter/outbound/dns.go index 405392a158..21a5b2b77f 100644 --- a/clash-meta/adapter/outbound/dns.go +++ b/clash-meta/adapter/outbound/dns.go @@ -2,10 +2,10 @@ package outbound import ( "context" - "fmt" "net" "time" + N "github.com/metacubex/mihomo/common/net" "github.com/metacubex/mihomo/common/pool" "github.com/metacubex/mihomo/component/dialer" "github.com/metacubex/mihomo/component/resolver" @@ -24,7 +24,9 @@ type DnsOption struct { // DialContext implements C.ProxyAdapter func (d *Dns) DialContext(ctx context.Context, metadata *C.Metadata, opts ...dialer.Option) (C.Conn, error) { - return nil, fmt.Errorf("dns outbound does not support tcp") + left, right := N.Pipe() + go resolver.RelayDnsConn(context.Background(), right, 0) + return NewConn(left, d), nil } // ListenPacketContext implements C.ProxyAdapter @@ -76,29 +78,44 @@ func (d *dnsPacketConn) ReadFrom(p []byte) (n int, addr net.Addr, err error) { } func (d *dnsPacketConn) WriteTo(p []byte, addr net.Addr) (n int, err error) { + select { + case <-d.ctx.Done(): + return 0, net.ErrClosed + default: + } + + if len(p) > resolver.SafeDnsPacketSize { + // wtf??? + return len(p), nil + } + ctx, cancel := context.WithTimeout(d.ctx, resolver.DefaultDnsRelayTimeout) defer cancel() buf := pool.Get(resolver.SafeDnsPacketSize) put := func() { _ = pool.Put(buf) } - buf, err = resolver.RelayDnsPacket(ctx, p, buf) - if err != nil { - put() - return 0, err - } + copy(buf, p) // avoid p be changed after WriteTo returned - packet := dnsPacket{ - data: buf, - put: put, - addr: addr, - } - select { - case d.response <- packet: - return len(p), nil - case <-d.ctx.Done(): - put() - return 0, net.ErrClosed - } + go func() { // don't block the WriteTo function + buf, err = resolver.RelayDnsPacket(ctx, buf[:len(p)], buf) + if err != nil { + put() + return + } + + packet := dnsPacket{ + data: buf, + put: put, + addr: addr, + } + select { + case d.response <- packet: + break + case <-d.ctx.Done(): + put() + } + }() + return len(p), nil } func (d *dnsPacketConn) Close() error { diff --git a/clash-meta/adapter/outboundgroup/fallback.go b/clash-meta/adapter/outboundgroup/fallback.go index 4c8a22474c..9387f7dee8 100644 --- a/clash-meta/adapter/outboundgroup/fallback.go +++ b/clash-meta/adapter/outboundgroup/fallback.go @@ -164,6 +164,8 @@ func NewFallback(option *GroupCommonOption, providers []provider.ProxyProvider) option.Filter, option.ExcludeFilter, option.ExcludeType, + option.TestTimeout, + option.MaxFailedTimes, providers, }), disableUDP: option.DisableUDP, diff --git a/clash-meta/adapter/outboundgroup/groupbase.go b/clash-meta/adapter/outboundgroup/groupbase.go index 0ea3685bec..b39ee3a659 100644 --- a/clash-meta/adapter/outboundgroup/groupbase.go +++ b/clash-meta/adapter/outboundgroup/groupbase.go @@ -31,14 +31,18 @@ type GroupBase struct { failedTesting atomic.Bool proxies [][]C.Proxy versions []atomic.Uint32 + TestTimeout int + maxFailedTimes int } type GroupBaseOption struct { outbound.BaseOption - filter string - excludeFilter string - excludeType string - providers []provider.ProxyProvider + filter string + excludeFilter string + excludeType string + TestTimeout int + maxFailedTimes int + providers []provider.ProxyProvider } func NewGroupBase(opt GroupBaseOption) *GroupBase { @@ -66,6 +70,15 @@ func NewGroupBase(opt GroupBaseOption) *GroupBase { excludeTypeArray: excludeTypeArray, providers: opt.providers, failedTesting: atomic.NewBool(false), + TestTimeout: opt.TestTimeout, + maxFailedTimes: opt.maxFailedTimes, + } + + if gb.TestTimeout == 0 { + gb.TestTimeout = 5000 + } + if gb.maxFailedTimes == 0 { + gb.maxFailedTimes = 5 } gb.proxies = make([][]C.Proxy, len(opt.providers)) @@ -240,13 +253,13 @@ func (gb *GroupBase) onDialFailed(adapterType C.AdapterType, err error) { log.Debugln("ProxyGroup: %s first failed", gb.Name()) gb.failedTime = time.Now() } else { - if time.Since(gb.failedTime) > gb.failedTimeoutInterval() { + if time.Since(gb.failedTime) > time.Duration(gb.TestTimeout)*time.Millisecond { gb.failedTimes = 0 return } log.Debugln("ProxyGroup: %s failed count: %d", gb.Name(), gb.failedTimes) - if gb.failedTimes >= gb.maxFailedTimes() { + if gb.failedTimes >= gb.maxFailedTimes { log.Warnln("because %s failed multiple times, active health check", gb.Name()) gb.healthCheck() } @@ -275,20 +288,8 @@ func (gb *GroupBase) healthCheck() { gb.failedTimes = 0 } -func (gb *GroupBase) failedIntervalTime() int64 { - return 5 * time.Second.Milliseconds() -} - func (gb *GroupBase) onDialSuccess() { if !gb.failedTesting.Load() { gb.failedTimes = 0 } } - -func (gb *GroupBase) maxFailedTimes() int { - return 5 -} - -func (gb *GroupBase) failedTimeoutInterval() time.Duration { - return 5 * time.Second -} diff --git a/clash-meta/adapter/outboundgroup/loadbalance.go b/clash-meta/adapter/outboundgroup/loadbalance.go index 976a2e89fa..4cb0db004f 100644 --- a/clash-meta/adapter/outboundgroup/loadbalance.go +++ b/clash-meta/adapter/outboundgroup/loadbalance.go @@ -266,6 +266,8 @@ func NewLoadBalance(option *GroupCommonOption, providers []provider.ProxyProvide option.Filter, option.ExcludeFilter, option.ExcludeType, + option.TestTimeout, + option.MaxFailedTimes, providers, }), strategyFn: strategyFn, diff --git a/clash-meta/adapter/outboundgroup/parser.go b/clash-meta/adapter/outboundgroup/parser.go index 96b23eb271..74947587f7 100644 --- a/clash-meta/adapter/outboundgroup/parser.go +++ b/clash-meta/adapter/outboundgroup/parser.go @@ -29,6 +29,7 @@ type GroupCommonOption struct { URL string `group:"url,omitempty"` Interval int `group:"interval,omitempty"` TestTimeout int `group:"timeout,omitempty"` + MaxFailedTimes int `group:"max-failed-times,omitempty"` Lazy bool `group:"lazy,omitempty"` DisableUDP bool `group:"disable-udp,omitempty"` Filter string `group:"filter,omitempty"` diff --git a/clash-meta/adapter/outboundgroup/relay.go b/clash-meta/adapter/outboundgroup/relay.go index 6a8e8bb1be..07fbcd9588 100644 --- a/clash-meta/adapter/outboundgroup/relay.go +++ b/clash-meta/adapter/outboundgroup/relay.go @@ -160,6 +160,8 @@ func NewRelay(option *GroupCommonOption, providers []provider.ProxyProvider) *Re "", "", "", + 5000, + 5, providers, }), Hidden: option.Hidden, diff --git a/clash-meta/adapter/outboundgroup/selector.go b/clash-meta/adapter/outboundgroup/selector.go index 3ac740f414..20eca70ffd 100644 --- a/clash-meta/adapter/outboundgroup/selector.go +++ b/clash-meta/adapter/outboundgroup/selector.go @@ -114,6 +114,8 @@ func NewSelector(option *GroupCommonOption, providers []provider.ProxyProvider) option.Filter, option.ExcludeFilter, option.ExcludeType, + option.TestTimeout, + option.MaxFailedTimes, providers, }), selected: "COMPATIBLE", diff --git a/clash-meta/adapter/outboundgroup/urltest.go b/clash-meta/adapter/outboundgroup/urltest.go index 8439772c51..5da44f3813 100644 --- a/clash-meta/adapter/outboundgroup/urltest.go +++ b/clash-meta/adapter/outboundgroup/urltest.go @@ -235,6 +235,8 @@ func NewURLTest(option *GroupCommonOption, providers []provider.ProxyProvider, o option.Filter, option.ExcludeFilter, option.ExcludeType, + option.TestTimeout, + option.MaxFailedTimes, providers, }), fastSingle: singledo.NewSingle[C.Proxy](time.Second * 10), diff --git a/clash-meta/common/net/deadline/conn.go b/clash-meta/common/net/deadline/conn.go index e8446ce2b9..fdf9334fd6 100644 --- a/clash-meta/common/net/deadline/conn.go +++ b/clash-meta/common/net/deadline/conn.go @@ -26,6 +26,11 @@ type Conn struct { resultCh chan *connReadResult } +func IsConn(conn any) bool { + _, ok := conn.(*Conn) + return ok +} + func NewConn(conn net.Conn) *Conn { c := &Conn{ ExtendedConn: bufio.NewExtendedConn(conn), diff --git a/clash-meta/common/net/deadline/pipe_sing.go b/clash-meta/common/net/deadline/pipe_sing.go index 20721fadbd..0f6d378da7 100644 --- a/clash-meta/common/net/deadline/pipe_sing.go +++ b/clash-meta/common/net/deadline/pipe_sing.go @@ -215,3 +215,8 @@ func (p *pipe) waitReadBuffer() (buffer *buf.Buffer, err error) { return nil, os.ErrDeadlineExceeded } } + +func IsPipe(conn any) bool { + _, ok := conn.(*pipe) + return ok +} diff --git a/clash-meta/common/net/sing.go b/clash-meta/common/net/sing.go index 3296ad5ba9..d726f4409d 100644 --- a/clash-meta/common/net/sing.go +++ b/clash-meta/common/net/sing.go @@ -23,6 +23,12 @@ type ExtendedReader = network.ExtendedReader var WriteBuffer = bufio.WriteBuffer func NewDeadlineConn(conn net.Conn) ExtendedConn { + if deadline.IsPipe(conn) || deadline.IsPipe(network.UnwrapReader(conn)) { + return NewExtendedConn(conn) // pipe always have correctly deadline implement + } + if deadline.IsConn(conn) || deadline.IsConn(network.UnwrapReader(conn)) { + return NewExtendedConn(conn) // was a *deadline.Conn + } return deadline.NewConn(conn) } diff --git a/clash-meta/component/resolver/relay.go b/clash-meta/component/resolver/relay.go index 3bc544456e..27b25af1d9 100644 --- a/clash-meta/component/resolver/relay.go +++ b/clash-meta/component/resolver/relay.go @@ -17,15 +17,15 @@ const DefaultDnsRelayTimeout = time.Second * 5 const SafeDnsPacketSize = 2 * 1024 // safe size which is 1232 from https://dnsflagday.net/2020/, so 2048 is enough -func RelayDnsConn(ctx context.Context, conn net.Conn) error { +func RelayDnsConn(ctx context.Context, conn net.Conn, readTimeout time.Duration) error { buff := pool.Get(pool.UDPBufferSize) defer func() { _ = pool.Put(buff) _ = conn.Close() }() for { - if conn.SetReadDeadline(time.Now().Add(DefaultDnsReadTimeout)) != nil { - break + if readTimeout > 0 { + _ = conn.SetReadDeadline(time.Now().Add(readTimeout)) } length := uint16(0) diff --git a/clash-meta/constant/rule.go b/clash-meta/constant/rule.go index 66fc18bb7f..9b03822198 100644 --- a/clash-meta/constant/rule.go +++ b/clash-meta/constant/rule.go @@ -5,6 +5,7 @@ const ( Domain RuleType = iota DomainSuffix DomainKeyword + DomainRegex GEOSITE GEOIP IPCIDR @@ -40,6 +41,8 @@ func (rt RuleType) String() string { return "DomainSuffix" case DomainKeyword: return "DomainKeyword" + case DomainRegex: + return "DomainRegex" case GEOSITE: return "GeoSite" case GEOIP: diff --git a/clash-meta/listener/sing_tun/dns.go b/clash-meta/listener/sing_tun/dns.go index 86237daa78..42926732f4 100644 --- a/clash-meta/listener/sing_tun/dns.go +++ b/clash-meta/listener/sing_tun/dns.go @@ -37,7 +37,7 @@ func (h *ListenerHandler) ShouldHijackDns(targetAddr netip.AddrPort) bool { func (h *ListenerHandler) NewConnection(ctx context.Context, conn net.Conn, metadata M.Metadata) error { if h.ShouldHijackDns(metadata.Destination.AddrPort()) { log.Debugln("[DNS] hijack tcp:%s", metadata.Destination.String()) - return resolver.RelayDnsConn(ctx, conn) + return resolver.RelayDnsConn(ctx, conn, resolver.DefaultDnsReadTimeout) } return h.ListenerHandler.NewConnection(ctx, conn, metadata) } diff --git a/clash-meta/main.go b/clash-meta/main.go index 748fa2e30c..4b2dff9c3d 100644 --- a/clash-meta/main.go +++ b/clash-meta/main.go @@ -4,6 +4,7 @@ import ( "flag" "fmt" "os" + "os/exec" "os/signal" "path/filepath" "runtime" @@ -48,6 +49,10 @@ func init() { } func main() { + if runtime.GOOS == "android" { + SetAndroidTZ() + } + _, _ = maxprocs.Set(maxprocs.Logger(func(string, ...any) {})) if version { fmt.Printf("Mihomo Meta %s %s %s with %s %s\n", @@ -176,3 +181,15 @@ func updateGeoDatabases() { executor.ApplyConfig(cfg, false) }() } + +func SetAndroidTZ() { + out, err := exec.Command("getprop", "persist.sys.timezone").Output() + if err != nil { + return + } + z, err := time.LoadLocation(strings.TrimSpace(string(out))) + if err != nil { + return + } + time.Local = z +} diff --git a/clash-meta/rules/common/domain_regex.go b/clash-meta/rules/common/domain_regex.go new file mode 100644 index 0000000000..f1eb87e6e2 --- /dev/null +++ b/clash-meta/rules/common/domain_regex.go @@ -0,0 +1,42 @@ +package common + +import ( + "regexp" + "strings" + + C "github.com/metacubex/mihomo/constant" +) + +type DomainRegex struct { + *Base + regex string + adapter string +} + +func (dr *DomainRegex) RuleType() C.RuleType { + return C.DomainRegex +} + +func (dr *DomainRegex) Match(metadata *C.Metadata) (bool, string) { + domain := metadata.RuleHost() + match, _ := regexp.MatchString(dr.regex, domain) + return match, dr.adapter +} + +func (dr *DomainRegex) Adapter() string { + return dr.adapter +} + +func (dr *DomainRegex) Payload() string { + return dr.regex +} + +func NewDomainRegex(regex string, adapter string) *DomainRegex { + return &DomainRegex{ + Base: &Base{}, + regex: strings.ToLower(regex), + adapter: adapter, + } +} + +//var _ C.Rule = (*DomainRegex)(nil) diff --git a/clash-meta/rules/parser.go b/clash-meta/rules/parser.go index 7a79b18bf4..23f781230b 100644 --- a/clash-meta/rules/parser.go +++ b/clash-meta/rules/parser.go @@ -2,7 +2,7 @@ package rules import ( "fmt" - + C "github.com/metacubex/mihomo/constant" RC "github.com/metacubex/mihomo/rules/common" "github.com/metacubex/mihomo/rules/logic" @@ -17,6 +17,8 @@ func ParseRule(tp, payload, target string, params []string, subRules map[string] parsed = RC.NewDomainSuffix(payload, target) case "DOMAIN-KEYWORD": parsed = RC.NewDomainKeyword(payload, target) + case "DOMAIN-REGEX": + parsed = RC.NewDomainRegex(payload, target) case "GEOSITE": parsed, parseErr = RC.NewGEOSITE(payload, target) case "GEOIP": diff --git a/clash-nyanpasu/backend/Cargo.lock b/clash-nyanpasu/backend/Cargo.lock index e24e1afa7b..57a35e9186 100644 --- a/clash-nyanpasu/backend/Cargo.lock +++ b/clash-nyanpasu/backend/Cargo.lock @@ -5149,9 +5149,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.30.6" +version = "0.30.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6746919caf9f2a85bff759535664c060109f21975c5ac2e8652e60102bd4d196" +checksum = "0c385888ef380a852a16209afc8cfad22795dd8873d69c9a14d2e2088f118d18" dependencies = [ "cfg-if", "core-foundation-sys", diff --git a/clash-nyanpasu/manifest/version.json b/clash-nyanpasu/manifest/version.json index 0fec17a1bc..983ca9f808 100644 --- a/clash-nyanpasu/manifest/version.json +++ b/clash-nyanpasu/manifest/version.json @@ -2,7 +2,7 @@ "manifest_version": 1, "latest": { "mihomo": "v1.18.1", - "mihomo_alpha": "alpha-974332c", + "mihomo_alpha": "alpha-0488676", "clash_rs": "v0.1.14", "clash_premium": "2023-09-05-gdcc8d87" }, @@ -36,5 +36,5 @@ "darwin-x64": "clash-darwin-amd64-n{}.gz" } }, - "updated_at": "2024-03-05T22:25:43.206Z" + "updated_at": "2024-03-06T22:24:15.572Z" } diff --git a/clash-nyanpasu/package.json b/clash-nyanpasu/package.json index a6b9eff8ed..8ded7d759e 100644 --- a/clash-nyanpasu/package.json +++ b/clash-nyanpasu/package.json @@ -86,7 +86,7 @@ "react-dom": "18.2.0", "react-error-boundary": "4.0.13", "react-hook-form": "7.51.0", - "react-i18next": "14.0.5", + "react-i18next": "14.1.0", "react-markdown": "9.0.1", "react-router-dom": "6.22.2", "react-transition-group": "4.4.5", @@ -102,9 +102,9 @@ "@types/fs-extra": "11.0.4", "@types/js-cookie": "3.0.6", "@types/lodash-es": "4.17.12", - "@types/node": "20.11.24", - "@types/react": "18.2.63", - "@types/react-dom": "18.2.20", + "@types/node": "20.11.25", + "@types/react": "18.2.64", + "@types/react-dom": "18.2.21", "@types/react-transition-group": "4.4.10", "@typescript-eslint/eslint-plugin": "7.1.1", "@typescript-eslint/parser": "7.1.1", @@ -150,7 +150,7 @@ "stylelint-scss": "6.2.1", "telegraf": "4.16.3", "tsx": "4.7.1", - "typescript": "5.3.3", + "typescript": "5.4.2", "vite": "5.1.5", "vite-plugin-monaco-editor": "1.1.0", "vite-plugin-svgr": "4.2.0" diff --git a/clash-nyanpasu/pnpm-lock.yaml b/clash-nyanpasu/pnpm-lock.yaml index 7cdfd97e10..7575448991 100644 --- a/clash-nyanpasu/pnpm-lock.yaml +++ b/clash-nyanpasu/pnpm-lock.yaml @@ -19,25 +19,25 @@ dependencies: version: 3.2.2(react@18.2.0) '@emotion/react': specifier: 11.11.4 - version: 11.11.4(@types/react@18.2.63)(react@18.2.0) + version: 11.11.4(@types/react@18.2.64)(react@18.2.0) '@emotion/styled': specifier: 11.11.0 - version: 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) + version: 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.64)(react@18.2.0) '@juggle/resize-observer': specifier: 3.4.0 version: 3.4.0 '@mui/icons-material': specifier: 5.15.12 - version: 5.15.12(@mui/material@5.15.12)(@types/react@18.2.63)(react@18.2.0) + version: 5.15.12(@mui/material@5.15.12)(@types/react@18.2.64)(react@18.2.0) '@mui/lab': specifier: 5.0.0-alpha.167 - version: 5.0.0-alpha.167(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) + version: 5.0.0-alpha.167(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) '@mui/material': specifier: 5.15.12 - version: 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) + version: 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) '@mui/x-data-grid': specifier: 6.19.6 - version: 6.19.6(@mui/material@5.15.12)(@mui/system@5.15.12)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) + version: 6.19.6(@mui/material@5.15.12)(@mui/system@5.15.12)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) '@tauri-apps/api': specifier: 1.5.3 version: 1.5.3 @@ -64,7 +64,7 @@ dependencies: version: 0.46.0 mui-color-input: specifier: 2.0.3 - version: 2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) + version: 2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -78,11 +78,11 @@ dependencies: specifier: 7.51.0 version: 7.51.0(react@18.2.0) react-i18next: - specifier: 14.0.5 - version: 14.0.5(i18next@23.10.0)(react-dom@18.2.0)(react@18.2.0) + specifier: 14.1.0 + version: 14.1.0(i18next@23.10.0)(react-dom@18.2.0)(react@18.2.0) react-markdown: specifier: 9.0.1 - version: 9.0.1(@types/react@18.2.63)(react@18.2.0) + version: 9.0.1(@types/react@18.2.64)(react@18.2.0) react-router-dom: specifier: 6.22.2 version: 6.22.2(react-dom@18.2.0)(react@18.2.0) @@ -105,7 +105,7 @@ devDependencies: version: 6.0.0 '@commitlint/cli': specifier: 19.0.3 - version: 19.0.3(@types/node@20.11.24)(typescript@5.3.3) + version: 19.0.3(@types/node@20.11.25)(typescript@5.4.2) '@commitlint/config-conventional': specifier: 19.0.3 version: 19.0.3 @@ -122,23 +122,23 @@ devDependencies: specifier: 4.17.12 version: 4.17.12 '@types/node': - specifier: 20.11.24 - version: 20.11.24 + specifier: 20.11.25 + version: 20.11.25 '@types/react': - specifier: 18.2.63 - version: 18.2.63 + specifier: 18.2.64 + version: 18.2.64 '@types/react-dom': - specifier: 18.2.20 - version: 18.2.20 + specifier: 18.2.21 + version: 18.2.21 '@types/react-transition-group': specifier: 4.4.10 version: 4.4.10 '@typescript-eslint/eslint-plugin': specifier: 7.1.1 - version: 7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.3.3) + version: 7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/parser': specifier: 7.1.1 - version: 7.1.1(eslint@8.57.0)(typescript@5.3.3) + version: 7.1.1(eslint@8.57.0)(typescript@5.4.2) '@vitejs/plugin-react': specifier: 4.2.1 version: 4.2.1(vite@5.1.5) @@ -240,7 +240,7 @@ devDependencies: version: 0.10.2 stylelint: specifier: 16.2.1 - version: 16.2.1(typescript@5.3.3) + version: 16.2.1(typescript@5.4.2) stylelint-config-html: specifier: 1.1.0 version: 1.1.0(postcss-html@1.6.0)(stylelint@16.2.1) @@ -266,17 +266,17 @@ devDependencies: specifier: 4.7.1 version: 4.7.1 typescript: - specifier: 5.3.3 - version: 5.3.3 + specifier: 5.4.2 + version: 5.4.2 vite: specifier: 5.1.5 - version: 5.1.5(@types/node@20.11.24)(sass@1.71.1) + version: 5.1.5(@types/node@20.11.25)(sass@1.71.1) vite-plugin-monaco-editor: specifier: npm:vite-plugin-monaco-editor-new@1.1.3 version: /vite-plugin-monaco-editor-new@1.1.3(monaco-editor@0.46.0) vite-plugin-svgr: specifier: 4.2.0 - version: 4.2.0(typescript@5.3.3)(vite@5.1.5) + version: 4.2.0(typescript@5.4.2)(vite@5.1.5) packages: @@ -533,14 +533,14 @@ packages: '@babel/helper-validator-identifier': 7.22.20 to-fast-properties: 2.0.0 - /@commitlint/cli@19.0.3(@types/node@20.11.24)(typescript@5.3.3): + /@commitlint/cli@19.0.3(@types/node@20.11.25)(typescript@5.4.2): resolution: {integrity: sha512-mGhh/aYPib4Vy4h+AGRloMY+CqkmtdeKPV9poMcZeImF5e3knQ5VYaSeAM0mEzps1dbKsHvABwaDpafLUuM96g==} engines: {node: '>=v18'} hasBin: true dependencies: '@commitlint/format': 19.0.3 '@commitlint/lint': 19.0.3 - '@commitlint/load': 19.0.3(@types/node@20.11.24)(typescript@5.3.3) + '@commitlint/load': 19.0.3(@types/node@20.11.25)(typescript@5.4.2) '@commitlint/read': 19.0.3 '@commitlint/types': 19.0.3 execa: 8.0.1 @@ -609,7 +609,7 @@ packages: '@commitlint/types': 19.0.3 dev: true - /@commitlint/load@19.0.3(@types/node@20.11.24)(typescript@5.3.3): + /@commitlint/load@19.0.3(@types/node@20.11.25)(typescript@5.4.2): resolution: {integrity: sha512-18Tk/ZcDFRKIoKfEcl7kC+bYkEQ055iyKmGsYDoYWpKf6FUvBrP9bIWapuy/MB+kYiltmP9ITiUx6UXtqC9IRw==} engines: {node: '>=v18'} dependencies: @@ -618,8 +618,8 @@ packages: '@commitlint/resolve-extends': 19.0.3 '@commitlint/types': 19.0.3 chalk: 5.3.0 - cosmiconfig: 8.3.6(typescript@5.3.3) - cosmiconfig-typescript-loader: 5.0.0(@types/node@20.11.24)(cosmiconfig@8.3.6)(typescript@5.3.3) + cosmiconfig: 8.3.6(typescript@5.4.2) + cosmiconfig-typescript-loader: 5.0.0(@types/node@20.11.25)(cosmiconfig@8.3.6)(typescript@5.4.2) lodash.isplainobject: 4.0.6 lodash.merge: 4.6.2 lodash.uniq: 4.5.0 @@ -831,7 +831,7 @@ packages: resolution: {integrity: sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA==} dev: false - /@emotion/react@11.11.4(@types/react@18.2.63)(react@18.2.0): + /@emotion/react@11.11.4(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-t8AjMlF0gHpvvxk5mAtCqR4vmxiGHCeJBaQO6gncUSdklELOgtwjerNY2yuJNfwnc6vi16U/+uMF+afIawJ9iw==} peerDependencies: '@types/react': '*' @@ -847,7 +847,7 @@ packages: '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 '@emotion/weak-memoize': 0.3.1 - '@types/react': 18.2.63 + '@types/react': 18.2.64 hoist-non-react-statics: 3.3.2 react: 18.2.0 dev: false @@ -866,7 +866,7 @@ packages: resolution: {integrity: sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA==} dev: false - /@emotion/styled@11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0): + /@emotion/styled@11.11.0(@emotion/react@11.11.4)(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==} peerDependencies: '@emotion/react': ^11.0.0-rc.0 @@ -879,11 +879,11 @@ packages: '@babel/runtime': 7.23.8 '@emotion/babel-plugin': 11.11.0 '@emotion/is-prop-valid': 1.2.1 - '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.64)(react@18.2.0) '@emotion/serialize': 1.1.3 '@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0) '@emotion/utils': 1.2.1 - '@types/react': 18.2.63 + '@types/react': 18.2.64 react: 18.2.0 dev: false @@ -1250,7 +1250,7 @@ packages: resolution: {integrity: sha512-dfLbk+PwWvFzSxwk3n5ySL0hfBog779o8h68wK/7/APo/7cgyWp5jcXockbxdk5kFRkbeXWm4Fbi9FrdN381sA==} dev: false - /@mui/base@5.0.0-beta.38(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0): + /@mui/base@5.0.0-beta.38(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-AsjD6Y1X5A1qndxz8xCcR8LDqv31aiwlgWMPxFAX/kCKiIGKlK65yMeVZ62iQr/6LBz+9hSKLiD1i4TZdAHKcQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1263,10 +1263,10 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@floating-ui/react-dom': 2.0.8(react-dom@18.2.0)(react@18.2.0) - '@mui/types': 7.2.13(@types/react@18.2.63) - '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.2.64) + '@mui/utils': 5.15.12(@types/react@18.2.64)(react@18.2.0) '@popperjs/core': 2.11.8 - '@types/react': 18.2.63 + '@types/react': 18.2.64 clsx: 2.1.0 prop-types: 15.8.1 react: 18.2.0 @@ -1277,7 +1277,7 @@ packages: resolution: {integrity: sha512-brRO+tMFLpGyjEYHrX97bzqeF6jZmKpqqe1rY0LyIHAwP6xRVzh++zSecOQorDOCaZJg4XkGT9xfD+RWOWxZBA==} dev: false - /@mui/icons-material@5.15.12(@mui/material@5.15.12)(@types/react@18.2.63)(react@18.2.0): + /@mui/icons-material@5.15.12(@mui/material@5.15.12)(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-3BXiDlOd3AexZoEXa/VqpIpVIvosCzjLHsdMWzKMXbZdnBiJjmb9ECdqfjn5SpTClO49qvkKLhkTqdBH3fSFGw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1289,12 +1289,12 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.63 + '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.64 react: 18.2.0 dev: false - /@mui/lab@5.0.0-alpha.167(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0): + /@mui/lab@5.0.0-alpha.167(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-BNQJ7fBBvL68WGVnzAhbtTmabSuJDXaILr9dz/3RNK4TgGXPgWCAr7qtJeUdc4p1t7c4Z1ifG8UwgqD+5hzMNg==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1313,21 +1313,21 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) - '@mui/base': 5.0.0-beta.38(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) - '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) - '@mui/system': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react@18.2.0) - '@mui/types': 7.2.13(@types/react@18.2.63) - '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) - '@types/react': 18.2.63 + '@emotion/react': 11.11.4(@types/react@18.2.64)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.64)(react@18.2.0) + '@mui/base': 5.0.0-beta.38(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) + '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.2.64) + '@mui/utils': 5.15.12(@types/react@18.2.64)(react@18.2.0) + '@types/react': 18.2.64 clsx: 2.1.0 prop-types: 15.8.1 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false - /@mui/material@5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0): + /@mui/material@5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-vXJGg6KNKucsvbW6l7w9zafnpOp0CWc0Wx4mDykuABTpQ5QQBnZxP7+oB4yAS1hDZQ1WobbeIl0CjxK4EEahkA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1345,14 +1345,14 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) - '@mui/base': 5.0.0-beta.38(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.64)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.64)(react@18.2.0) + '@mui/base': 5.0.0-beta.38(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) '@mui/core-downloads-tracker': 5.15.12 - '@mui/system': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react@18.2.0) - '@mui/types': 7.2.13(@types/react@18.2.63) - '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) - '@types/react': 18.2.63 + '@mui/system': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react@18.2.0) + '@mui/types': 7.2.13(@types/react@18.2.64) + '@mui/utils': 5.15.12(@types/react@18.2.64)(react@18.2.0) + '@types/react': 18.2.64 '@types/react-transition-group': 4.4.10 clsx: 2.1.0 csstype: 3.1.3 @@ -1363,7 +1363,7 @@ packages: react-transition-group: 4.4.5(react-dom@18.2.0)(react@18.2.0) dev: false - /@mui/private-theming@5.15.12(@types/react@18.2.63)(react@18.2.0): + /@mui/private-theming@5.15.12(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-cqoSo9sgA5HE+8vZClbLrq9EkyOnYysooepi5eKaKvJ41lReT2c5wOZAeDDM1+xknrMDos+0mT2zr3sZmUiRRA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1374,8 +1374,8 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) - '@types/react': 18.2.63 + '@mui/utils': 5.15.12(@types/react@18.2.64)(react@18.2.0) + '@types/react': 18.2.64 prop-types: 15.8.1 react: 18.2.0 dev: false @@ -1395,14 +1395,14 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@emotion/cache': 11.11.0 - '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.64)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.64)(react@18.2.0) csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/system@5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react@18.2.0): + /@mui/system@5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-/pq+GO6yN3X7r3hAwFTrzkAh7K1bTF5r8IzS79B9eyKJg7v6B/t4/zZYMR6OT9qEPtwf6rYN2Utg1e6Z7F1OgQ==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1419,20 +1419,20 @@ packages: optional: true dependencies: '@babel/runtime': 7.23.9 - '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) - '@mui/private-theming': 5.15.12(@types/react@18.2.63)(react@18.2.0) + '@emotion/react': 11.11.4(@types/react@18.2.64)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.64)(react@18.2.0) + '@mui/private-theming': 5.15.12(@types/react@18.2.64)(react@18.2.0) '@mui/styled-engine': 5.15.11(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(react@18.2.0) - '@mui/types': 7.2.13(@types/react@18.2.63) - '@mui/utils': 5.15.12(@types/react@18.2.63)(react@18.2.0) - '@types/react': 18.2.63 + '@mui/types': 7.2.13(@types/react@18.2.64) + '@mui/utils': 5.15.12(@types/react@18.2.64)(react@18.2.0) + '@types/react': 18.2.64 clsx: 2.1.0 csstype: 3.1.3 prop-types: 15.8.1 react: 18.2.0 dev: false - /@mui/types@7.2.13(@types/react@18.2.63): + /@mui/types@7.2.13(@types/react@18.2.64): resolution: {integrity: sha512-qP9OgacN62s+l8rdDhSFRe05HWtLLJ5TGclC9I1+tQngbssu0m2dmFZs+Px53AcOs9fD7TbYd4gc9AXzVqO/+g==} peerDependencies: '@types/react': ^17.0.0 || ^18.0.0 @@ -1440,10 +1440,10 @@ packages: '@types/react': optional: true dependencies: - '@types/react': 18.2.63 + '@types/react': 18.2.64 dev: false - /@mui/utils@5.15.11(@types/react@18.2.63)(react@18.2.0): + /@mui/utils@5.15.11(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-D6bwqprUa9Stf8ft0dcMqWyWDKEo7D+6pB1k8WajbqlYIRA8J8Kw9Ra7PSZKKePGBGWO+/xxrX1U8HpG/aXQCw==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1455,13 +1455,13 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@types/prop-types': 15.7.11 - '@types/react': 18.2.63 + '@types/react': 18.2.64 prop-types: 15.8.1 react: 18.2.0 react-is: 18.2.0 dev: false - /@mui/utils@5.15.12(@types/react@18.2.63)(react@18.2.0): + /@mui/utils@5.15.12(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-8SDGCnO2DY9Yy+5bGzu00NZowSDtuyHP4H8gunhHGQoIlhlY2Z3w64wBzAOLpYw/ZhJNzksDTnS/i8qdJvxuow==} engines: {node: '>=12.0.0'} peerDependencies: @@ -1473,13 +1473,13 @@ packages: dependencies: '@babel/runtime': 7.23.9 '@types/prop-types': 15.7.11 - '@types/react': 18.2.63 + '@types/react': 18.2.64 prop-types: 15.8.1 react: 18.2.0 react-is: 18.2.0 dev: false - /@mui/x-data-grid@6.19.6(@mui/material@5.15.12)(@mui/system@5.15.12)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0): + /@mui/x-data-grid@6.19.6(@mui/material@5.15.12)(@mui/system@5.15.12)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-jpZkX1Gnlo87gKcD10mKMY8YoAzUD8Cv3/IvedH3FINDKO3hnraMeOciKDeUk0tYSj8RUDB02kpTHCM8ojLVBA==} engines: {node: '>=14.0.0'} peerDependencies: @@ -1489,9 +1489,9 @@ packages: react-dom: ^17.0.0 || ^18.0.0 dependencies: '@babel/runtime': 7.23.9 - '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) - '@mui/system': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react@18.2.0) - '@mui/utils': 5.15.11(@types/react@18.2.63)(react@18.2.0) + '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) + '@mui/system': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react@18.2.0) + '@mui/utils': 5.15.11(@types/react@18.2.64)(react@18.2.0) clsx: 2.1.0 prop-types: 15.8.1 react: 18.2.0 @@ -1841,14 +1841,14 @@ packages: '@svgr/babel-plugin-transform-svg-component': 8.0.0(@babel/core@7.23.6) dev: true - /@svgr/core@8.1.0(typescript@5.3.3): + /@svgr/core@8.1.0(typescript@5.4.2): resolution: {integrity: sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==} engines: {node: '>=14'} dependencies: '@babel/core': 7.23.6 '@svgr/babel-preset': 8.1.0(@babel/core@7.23.6) camelcase: 6.3.0 - cosmiconfig: 8.3.6(typescript@5.3.3) + cosmiconfig: 8.3.6(typescript@5.4.2) snake-case: 3.0.4 transitivePeerDependencies: - supports-color @@ -1871,7 +1871,7 @@ packages: dependencies: '@babel/core': 7.23.6 '@svgr/babel-preset': 8.1.0(@babel/core@7.23.6) - '@svgr/core': 8.1.0(typescript@5.3.3) + '@svgr/core': 8.1.0(typescript@5.4.2) '@svgr/hast-util-to-babel-ast': 8.0.0 svg-parser: 2.0.4 transitivePeerDependencies: @@ -2040,7 +2040,7 @@ packages: /@types/conventional-commits-parser@5.0.0: resolution: {integrity: sha512-loB369iXNmAZglwWATL+WRe+CRMmmBPtpolYzIebFaX4YA3x+BEfLqhUAV9WanycKI3TG1IMr5bMJDajDKLlUQ==} dependencies: - '@types/node': 20.11.24 + '@types/node': 20.11.25 dev: true /@types/debug@4.1.12: @@ -2062,7 +2062,7 @@ packages: resolution: {integrity: sha512-yTbItCNreRooED33qjunPthRcSjERP1r4MqCZc7wv0u2sUkzTFp45tgUfS5+r7FrZPdmCCNflLhVSP/o+SemsQ==} dependencies: '@types/jsonfile': 6.1.4 - '@types/node': 20.11.24 + '@types/node': 20.11.25 dev: true /@types/hast@3.0.4: @@ -2086,7 +2086,7 @@ packages: /@types/jsonfile@6.1.4: resolution: {integrity: sha512-D5qGUYwjvnNNextdU59/+fI+spnwtTFmyQP0h+PfIOSkNfpU6AOICUOkm4i0OnSk+NyjdPJrxCDro0sJsWlRpQ==} dependencies: - '@types/node': 20.11.24 + '@types/node': 20.11.25 dev: true /@types/lodash-es@4.17.12: @@ -2109,8 +2109,8 @@ packages: resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==} dev: false - /@types/node@20.11.24: - resolution: {integrity: sha512-Kza43ewS3xoLgCEpQrsT+xRo/EJej1y0kVYGiLFE1NEODXGzTfwiC6tXTLMQskn1X4/Rjlh0MQUvx9W+L9long==} + /@types/node@20.11.25: + resolution: {integrity: sha512-TBHyJxk2b7HceLVGFcpAUjsa5zIdsPWlR6XHfyGzd0SFu+/NFgQgMAl96MSDZgQDvJAvV6BKsFOrt6zIL09JDw==} dependencies: undici-types: 5.26.5 dev: true @@ -2122,19 +2122,19 @@ packages: /@types/prop-types@15.7.11: resolution: {integrity: sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng==} - /@types/react-dom@18.2.20: - resolution: {integrity: sha512-HXN/biJY8nv20Cn9ZbCFq3liERd4CozVZmKbaiZ9KiKTrWqsP7eoGDO6OOGvJQwoVFuiXaiJ7nBBjiFFbRmQMQ==} + /@types/react-dom@18.2.21: + resolution: {integrity: sha512-gnvBA/21SA4xxqNXEwNiVcP0xSGHh/gi1VhWv9Bl46a0ItbTT5nFY+G9VSQpaG/8N/qdJpJ+vftQ4zflTtnjLw==} dependencies: - '@types/react': 18.2.63 + '@types/react': 18.2.64 dev: true /@types/react-transition-group@4.4.10: resolution: {integrity: sha512-hT/+s0VQs2ojCX823m60m5f0sL5idt9SO6Tj6Dg+rdphGPIeJbJ6CxvBYkgkGKrYeDjvIpKTR38UzmtHJOGW3Q==} dependencies: - '@types/react': 18.2.63 + '@types/react': 18.2.64 - /@types/react@18.2.63: - resolution: {integrity: sha512-ppaqODhs15PYL2nGUOaOu2RSCCB4Difu4UFrP4I3NHLloXC/ESQzQMi9nvjfT1+rudd0d2L3fQPJxRSey+rGlQ==} + /@types/react@18.2.64: + resolution: {integrity: sha512-MlmPvHgjj2p3vZaxbQgFUQFvD8QiZwACfGqEdDSWou5yISWxDQ4/74nCAwsUiX7UFLKZz3BbVSPj+YxeoGGCfg==} dependencies: '@types/prop-types': 15.7.11 '@types/scheduler': 0.16.2 @@ -2155,7 +2155,7 @@ packages: resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} dev: false - /@typescript-eslint/eslint-plugin@7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/eslint-plugin@7.1.1(@typescript-eslint/parser@7.1.1)(eslint@8.57.0)(typescript@5.4.2): resolution: {integrity: sha512-zioDz623d0RHNhvx0eesUmGfIjzrk18nSBC8xewepKXbBvN/7c1qImV7Hg8TI1URTxKax7/zxfxj3Uph8Chcuw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2167,10 +2167,10 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/scope-manager': 7.1.1 - '@typescript-eslint/type-utils': 7.1.1(eslint@8.57.0)(typescript@5.3.3) - '@typescript-eslint/utils': 7.1.1(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/type-utils': 7.1.1(eslint@8.57.0)(typescript@5.4.2) + '@typescript-eslint/utils': 7.1.1(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/visitor-keys': 7.1.1 debug: 4.3.4 eslint: 8.57.0 @@ -2178,13 +2178,13 @@ packages: ignore: 5.3.0 natural-compare: 1.4.0 semver: 7.6.0 - ts-api-utils: 1.0.3(typescript@5.3.3) - typescript: 5.3.3 + ts-api-utils: 1.0.3(typescript@5.4.2) + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/parser@7.1.1(eslint@8.57.0)(typescript@5.4.2): resolution: {integrity: sha512-ZWUFyL0z04R1nAEgr9e79YtV5LbafdOtN7yapNbn1ansMyaegl2D4bL7vHoJ4HPSc4CaLwuCVas8CVuneKzplQ==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2196,11 +2196,11 @@ packages: dependencies: '@typescript-eslint/scope-manager': 7.1.1 '@typescript-eslint/types': 7.1.1 - '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.4.2) '@typescript-eslint/visitor-keys': 7.1.1 debug: 4.3.4 eslint: 8.57.0 - typescript: 5.3.3 + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: true @@ -2213,7 +2213,7 @@ packages: '@typescript-eslint/visitor-keys': 7.1.1 dev: true - /@typescript-eslint/type-utils@7.1.1(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/type-utils@7.1.1(eslint@8.57.0)(typescript@5.4.2): resolution: {integrity: sha512-5r4RKze6XHEEhlZnJtR3GYeCh1IueUHdbrukV2KSlLXaTjuSfeVF8mZUVPLovidCuZfbVjfhi4c0DNSa/Rdg5g==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2223,12 +2223,12 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.3.3) - '@typescript-eslint/utils': 7.1.1(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.4.2) + '@typescript-eslint/utils': 7.1.1(eslint@8.57.0)(typescript@5.4.2) debug: 4.3.4 eslint: 8.57.0 - ts-api-utils: 1.0.3(typescript@5.3.3) - typescript: 5.3.3 + ts-api-utils: 1.0.3(typescript@5.4.2) + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: true @@ -2238,7 +2238,7 @@ packages: engines: {node: ^16.0.0 || >=18.0.0} dev: true - /@typescript-eslint/typescript-estree@7.1.1(typescript@5.3.3): + /@typescript-eslint/typescript-estree@7.1.1(typescript@5.4.2): resolution: {integrity: sha512-9ZOncVSfr+sMXVxxca2OJOPagRwT0u/UHikM2Rd6L/aB+kL/QAuTnsv6MeXtjzCJYb8PzrXarypSGIPx3Jemxw==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2254,13 +2254,13 @@ packages: is-glob: 4.0.3 minimatch: 9.0.3 semver: 7.6.0 - ts-api-utils: 1.0.3(typescript@5.3.3) - typescript: 5.3.3 + ts-api-utils: 1.0.3(typescript@5.4.2) + typescript: 5.4.2 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils@7.1.1(eslint@8.57.0)(typescript@5.3.3): + /@typescript-eslint/utils@7.1.1(eslint@8.57.0)(typescript@5.4.2): resolution: {integrity: sha512-thOXM89xA03xAE0lW7alstvnyoBUbBX38YtY+zAUcpRPcq9EIhXPuJ0YTv948MbzmKh6e1AUszn5cBFK49Umqg==} engines: {node: ^16.0.0 || >=18.0.0} peerDependencies: @@ -2271,7 +2271,7 @@ packages: '@types/semver': 7.5.6 '@typescript-eslint/scope-manager': 7.1.1 '@typescript-eslint/types': 7.1.1 - '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.3.3) + '@typescript-eslint/typescript-estree': 7.1.1(typescript@5.4.2) eslint: 8.57.0 semver: 7.6.0 transitivePeerDependencies: @@ -2301,7 +2301,7 @@ packages: '@babel/plugin-transform-react-jsx-source': 7.23.3(@babel/core@7.23.6) '@types/babel__core': 7.20.5 react-refresh: 0.14.0 - vite: 5.1.5(@types/node@20.11.24)(sass@1.71.1) + vite: 5.1.5(@types/node@20.11.25)(sass@1.71.1) transitivePeerDependencies: - supports-color dev: true @@ -2947,7 +2947,7 @@ packages: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} dev: true - /cosmiconfig-typescript-loader@5.0.0(@types/node@20.11.24)(cosmiconfig@8.3.6)(typescript@5.3.3): + /cosmiconfig-typescript-loader@5.0.0(@types/node@20.11.25)(cosmiconfig@8.3.6)(typescript@5.4.2): resolution: {integrity: sha512-+8cK7jRAReYkMwMiG+bxhcNKiHJDM6bR9FD/nGBXOWdMLuYawjF5cGrtLilJ+LGd3ZjCXnJjR5DkfWPoIVlqJA==} engines: {node: '>=v16'} peerDependencies: @@ -2955,10 +2955,10 @@ packages: cosmiconfig: '>=8.2' typescript: '>=4' dependencies: - '@types/node': 20.11.24 - cosmiconfig: 8.3.6(typescript@5.3.3) + '@types/node': 20.11.25 + cosmiconfig: 8.3.6(typescript@5.4.2) jiti: 1.21.0 - typescript: 5.3.3 + typescript: 5.4.2 dev: true /cosmiconfig@7.0.1: @@ -2972,7 +2972,7 @@ packages: yaml: 1.10.2 dev: false - /cosmiconfig@8.3.6(typescript@5.3.3): + /cosmiconfig@8.3.6(typescript@5.4.2): resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} engines: {node: '>=14'} peerDependencies: @@ -2985,10 +2985,10 @@ packages: js-yaml: 4.1.0 parse-json: 5.2.0 path-type: 4.0.0 - typescript: 5.3.3 + typescript: 5.4.2 dev: true - /cosmiconfig@9.0.0(typescript@5.3.3): + /cosmiconfig@9.0.0(typescript@5.4.2): resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} peerDependencies: @@ -3001,7 +3001,7 @@ packages: import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 - typescript: 5.3.3 + typescript: 5.4.2 dev: true /cross-env@7.0.3: @@ -3551,7 +3551,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.4.2) debug: 3.2.7 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 @@ -3588,7 +3588,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.3.3) + '@typescript-eslint/parser': 7.1.1(eslint@8.57.0)(typescript@5.4.2) array-includes: 3.1.7 array.prototype.findlastindex: 1.2.3 array.prototype.flat: 1.3.2 @@ -5444,7 +5444,7 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - /mui-color-input@2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0): + /mui-color-input@2.0.3(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@mui/material@5.15.12)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0): resolution: {integrity: sha512-rAd040qQ0Y+8dk4gE8kkCiJ/vCgA0j4vv1quJ43BfORTFE3uHarHj0xY1Vo9CPbojtx1f5vW+CjckYPRIZPIRg==} peerDependencies: '@emotion/react': ^11.5.0 @@ -5458,10 +5458,10 @@ packages: optional: true dependencies: '@ctrl/tinycolor': 4.0.3 - '@emotion/react': 11.11.4(@types/react@18.2.63)(react@18.2.0) - '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.63)(react@18.2.0) - '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.63)(react-dom@18.2.0)(react@18.2.0) - '@types/react': 18.2.63 + '@emotion/react': 11.11.4(@types/react@18.2.64)(react@18.2.0) + '@emotion/styled': 11.11.0(@emotion/react@11.11.4)(@types/react@18.2.64)(react@18.2.0) + '@mui/material': 5.15.12(@emotion/react@11.11.4)(@emotion/styled@11.11.0)(@types/react@18.2.64)(react-dom@18.2.0)(react@18.2.0) + '@types/react': 18.2.64 react: 18.2.0 react-dom: 18.2.0(react@18.2.0) dev: false @@ -5966,8 +5966,8 @@ packages: react: 18.2.0 dev: false - /react-i18next@14.0.5(i18next@23.10.0)(react-dom@18.2.0)(react@18.2.0): - resolution: {integrity: sha512-5+bQSeEtgJrMBABBL5lO7jPdSNAbeAZ+MlFWDw//7FnVacuVu3l9EeWFzBQvZsKy+cihkbThWOAThEdH8YjGEw==} + /react-i18next@14.1.0(i18next@23.10.0)(react-dom@18.2.0)(react@18.2.0): + resolution: {integrity: sha512-3KwX6LHpbvGQ+sBEntjV4sYW3Zovjjl3fpoHbUwSgFHf0uRBcbeCBLR5al6ikncI5+W0EFb71QXZmfop+J6NrQ==} peerDependencies: i18next: '>= 23.2.3' react: '>= 16.8.0' @@ -5993,14 +5993,14 @@ packages: resolution: {integrity: sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==} dev: false - /react-markdown@9.0.1(@types/react@18.2.63)(react@18.2.0): + /react-markdown@9.0.1(@types/react@18.2.64)(react@18.2.0): resolution: {integrity: sha512-186Gw/vF1uRkydbsOIkcGXw7aHq0sZOCRFFjGrr7b9+nVZg4UfA4enXCaxm4fUzecU38sWfrNDitGhshuU7rdg==} peerDependencies: '@types/react': '>=18' react: '>=18' dependencies: '@types/hast': 3.0.4 - '@types/react': 18.2.63 + '@types/react': 18.2.64 devlop: 1.1.0 hast-util-to-jsx-runtime: 2.3.0 html-url-attributes: 3.0.0 @@ -6633,7 +6633,7 @@ packages: stylelint: '>=14.0.0' dependencies: postcss-html: 1.6.0 - stylelint: 16.2.1(typescript@5.3.3) + stylelint: 16.2.1(typescript@5.4.2) dev: true /stylelint-config-recess-order@5.0.0(stylelint@16.2.1): @@ -6641,7 +6641,7 @@ packages: peerDependencies: stylelint: '>=16' dependencies: - stylelint: 16.2.1(typescript@5.3.3) + stylelint: 16.2.1(typescript@5.4.2) stylelint-order: 6.0.4(stylelint@16.2.1) dev: true @@ -6651,7 +6651,7 @@ packages: peerDependencies: stylelint: ^16.0.0 dependencies: - stylelint: 16.2.1(typescript@5.3.3) + stylelint: 16.2.1(typescript@5.4.2) dev: true /stylelint-config-standard@36.0.0(stylelint@16.2.1): @@ -6660,7 +6660,7 @@ packages: peerDependencies: stylelint: ^16.1.0 dependencies: - stylelint: 16.2.1(typescript@5.3.3) + stylelint: 16.2.1(typescript@5.4.2) stylelint-config-recommended: 14.0.0(stylelint@16.2.1) dev: true @@ -6670,7 +6670,7 @@ packages: peerDependencies: stylelint: ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 dependencies: - stylelint: 16.2.1(typescript@5.3.3) + stylelint: 16.2.1(typescript@5.4.2) dev: true /stylelint-order@6.0.4(stylelint@16.2.1): @@ -6680,7 +6680,7 @@ packages: dependencies: postcss: 8.4.35 postcss-sorting: 8.0.2(postcss@8.4.35) - stylelint: 16.2.1(typescript@5.3.3) + stylelint: 16.2.1(typescript@5.4.2) dev: true /stylelint-scss@6.2.1(stylelint@16.2.1): @@ -6694,10 +6694,10 @@ packages: postcss-resolve-nested-selector: 0.1.1 postcss-selector-parser: 6.0.15 postcss-value-parser: 4.2.0 - stylelint: 16.2.1(typescript@5.3.3) + stylelint: 16.2.1(typescript@5.4.2) dev: true - /stylelint@16.2.1(typescript@5.3.3): + /stylelint@16.2.1(typescript@5.4.2): resolution: {integrity: sha512-SfIMGFK+4n7XVAyv50CpVfcGYWG4v41y6xG7PqOgQSY8M/PgdK0SQbjWFblxjJZlN9jNq879mB4BCZHJRIJ1hA==} engines: {node: '>=18.12.0'} hasBin: true @@ -6708,7 +6708,7 @@ packages: '@csstools/selector-specificity': 3.0.1(postcss-selector-parser@6.0.15) balanced-match: 2.0.0 colord: 2.9.3 - cosmiconfig: 9.0.0(typescript@5.3.3) + cosmiconfig: 9.0.0(typescript@5.4.2) css-functions-list: 3.2.1 css-tree: 2.3.1 debug: 4.3.4 @@ -6870,13 +6870,13 @@ packages: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} dev: false - /ts-api-utils@1.0.3(typescript@5.3.3): + /ts-api-utils@1.0.3(typescript@5.4.2): resolution: {integrity: sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==} engines: {node: '>=16.13.0'} peerDependencies: typescript: '>=4.2.0' dependencies: - typescript: 5.3.3 + typescript: 5.4.2 dev: true /tsconfig-paths@3.15.0: @@ -7006,8 +7006,8 @@ packages: possible-typed-array-names: 1.0.0 dev: true - /typescript@5.3.3: - resolution: {integrity: sha512-pXWcraxM0uxAS+tN0AG/BF2TyqmHO014Z070UsJ+pFvYuRSq8KH8DmWpnbXe0pEPDHXZV3FcAbJkijJ5oNEnWw==} + /typescript@5.4.2: + resolution: {integrity: sha512-+2/g0Fds1ERlP6JsakQQDXjZdZMM+rqpamFZJEKh4kwTIn3iDkgKtby0CeNd5ATNZ4Ry1ax15TMx0W2V+miizQ==} engines: {node: '>=14.17'} hasBin: true dev: true @@ -7167,22 +7167,22 @@ packages: monaco-editor: 0.46.0 dev: true - /vite-plugin-svgr@4.2.0(typescript@5.3.3)(vite@5.1.5): + /vite-plugin-svgr@4.2.0(typescript@5.4.2)(vite@5.1.5): resolution: {integrity: sha512-SC7+FfVtNQk7So0XMjrrtLAbEC8qjFPifyD7+fs/E6aaNdVde6umlVVh0QuwDLdOMu7vp5RiGFsB70nj5yo0XA==} peerDependencies: vite: ^2.6.0 || 3 || 4 || 5 dependencies: '@rollup/pluginutils': 5.0.5 - '@svgr/core': 8.1.0(typescript@5.3.3) + '@svgr/core': 8.1.0(typescript@5.4.2) '@svgr/plugin-jsx': 8.1.0(@svgr/core@8.1.0) - vite: 5.1.5(@types/node@20.11.24)(sass@1.71.1) + vite: 5.1.5(@types/node@20.11.25)(sass@1.71.1) transitivePeerDependencies: - rollup - supports-color - typescript dev: true - /vite@5.1.5(@types/node@20.11.24)(sass@1.71.1): + /vite@5.1.5(@types/node@20.11.25)(sass@1.71.1): resolution: {integrity: sha512-BdN1xh0Of/oQafhU+FvopafUp6WaYenLU/NFoL5WyJL++GxkNfieKzBhM24H3HVsPQrlAqB7iJYTHabzaRed5Q==} engines: {node: ^18.0.0 || >=20.0.0} hasBin: true @@ -7210,7 +7210,7 @@ packages: terser: optional: true dependencies: - '@types/node': 20.11.24 + '@types/node': 20.11.25 esbuild: 0.19.10 postcss: 8.4.35 rollup: 4.9.0 diff --git a/echo/internal/cmgr/cmgr.go b/echo/internal/cmgr/cmgr.go index c343ca46c5..73e7a5e1d2 100644 --- a/echo/internal/cmgr/cmgr.go +++ b/echo/internal/cmgr/cmgr.go @@ -2,7 +2,6 @@ package cmgr import ( "context" - "net/http" "sort" "sync" "time" @@ -155,8 +154,8 @@ func (cm *cmgrImpl) countClosedConnection() int { } func (cm *cmgrImpl) Start(ctx context.Context, errCH chan error) { - cm.l.Info("start") - ticker := time.NewTicker(time.Second * time.Duration(cm.cfg.SyncDuration)) + cm.l.Infof("start sync interval=%d", cm.cfg.SyncInterval) + ticker := time.NewTicker(time.Second * time.Duration(cm.cfg.SyncInterval)) defer ticker.Stop() for { @@ -175,32 +174,3 @@ func (cm *cmgrImpl) Start(ctx context.Context, errCH chan error) { } } } - -type syncReq struct { - RelayLabel string `json:"relay_label"` - Stats conn.Stats `json:"stats"` -} - -func (cm *cmgrImpl) syncOnce() error { - cm.l.Infof("sync once total closed connections: %d", cm.countClosedConnection()) - // todo: opt lock - cm.lock.Lock() - - reqs := []syncReq{} - for label, conns := range cm.closedConnectionsMap { - for _, c := range conns { - reqs = append(reqs, syncReq{ - RelayLabel: label, - Stats: *c.GetStats(), - }) - } - } - cm.closedConnectionsMap = make(map[string][]conn.RelayConn) - cm.lock.Unlock() - if cm.cfg.NeedSync() { - return myhttp.PostJson(http.DefaultClient, cm.cfg.SyncURL, &reqs) - } else { - cm.l.Debugf("remove %d closed connections", len(reqs)) - } - return nil -} diff --git a/echo/internal/cmgr/config.go b/echo/internal/cmgr/config.go index 44592d2d02..aa96e985a8 100644 --- a/echo/internal/cmgr/config.go +++ b/echo/internal/cmgr/config.go @@ -4,7 +4,7 @@ var DummyConfig = &Config{} type Config struct { SyncURL string `json:"sync_url,omitempty"` - SyncDuration int `json:"sync_duration"` // in seconds + SyncInterval int `json:"sync_interval,omitempty"` // in seconds } func (c *Config) NeedSync() bool { @@ -12,7 +12,7 @@ func (c *Config) NeedSync() bool { } func (c *Config) Adjust() { - if c.SyncDuration <= 0 { - c.SyncDuration = 60 + if c.SyncInterval <= 0 { + c.SyncInterval = 60 } } diff --git a/echo/internal/cmgr/metric_sync.go b/echo/internal/cmgr/metric_sync.go new file mode 100644 index 0000000000..41dd4dd103 --- /dev/null +++ b/echo/internal/cmgr/metric_sync.go @@ -0,0 +1,53 @@ +package cmgr + +import ( + "net/http" + + "github.com/Ehco1996/ehco/internal/conn" + myhttp "github.com/Ehco1996/ehco/pkg/http" +) + +type StatsPerRule struct { + RelayLabel string `json:"relay_label"` + + Up int64 `json:"up_bytes"` + Down int64 `json:"down_bytes"` + ConnectionCnt int `json:"connection_count"` + HandShakeLatency int64 `json:"latency_in_ms"` +} + +type syncReq struct { + Stats []StatsPerRule `json:"stats"` +} + +func (cm *cmgrImpl) syncOnce() error { + cm.l.Infof("sync once total closed connections: %d", cm.countClosedConnection()) + // todo: opt lock + cm.lock.Lock() + + req := syncReq{Stats: []StatsPerRule{}} + for label, conns := range cm.closedConnectionsMap { + s := StatsPerRule{ + RelayLabel: label, + } + var totalLatency int64 + for _, c := range conns { + s.ConnectionCnt++ + s.Up += c.GetStats().Up + s.Down += c.GetStats().Down + totalLatency += c.GetStats().HandShakeLatency.Milliseconds() + } + if s.ConnectionCnt > 0 { + s.HandShakeLatency = totalLatency / int64(s.ConnectionCnt) + } + req.Stats = append(req.Stats, s) + } + cm.closedConnectionsMap = make(map[string][]conn.RelayConn) + cm.lock.Unlock() + if cm.cfg.NeedSync() { + return myhttp.PostJson(http.DefaultClient, cm.cfg.SyncURL, &req) + } else { + cm.l.Debugf("remove %d closed connections", len(req.Stats)) + } + return nil +} diff --git a/echo/internal/config/config.go b/echo/internal/config/config.go index 84e820341b..2124d6616a 100644 --- a/echo/internal/config/config.go +++ b/echo/internal/config/config.go @@ -29,7 +29,7 @@ type Config struct { RelayConfigs []*conf.Config `json:"relay_configs"` RelaySyncURL string `json:"relay_sync_url,omitempty"` - RelaySyncDuration int `json:"relay_sync_duration,omitempty"` + RelaySyncInterval int `json:"relay_sync_interval,omitempty"` SubConfigs []*SubConfig `json:"sub_configs,omitempty"` XRayConfig *xConf.Config `json:"xray_config,omitempty"` diff --git a/echo/internal/conn/conn.go b/echo/internal/conn/conn.go index 7789266e3f..770a9a3d85 100644 --- a/echo/internal/conn/conn.go +++ b/echo/internal/conn/conn.go @@ -18,8 +18,9 @@ var ( ) type Stats struct { - Up int64 `json:"up"` - Down int64 `json:"down"` + Up int64 + Down int64 + HandShakeLatency time.Duration } func (s *Stats) Record(up, down int64) { @@ -136,6 +137,8 @@ func copyConn(conn1, conn2 *innerConn) error { return err2 } +type RelayConnOption func(*relayConnImpl) + type RelayConn interface { // Transport transports data between the client and the remote server. // The remoteLabel is the label of the remote server. @@ -149,14 +152,18 @@ type RelayConn interface { Close() error } -func NewRelayConn(relayName string, clientConn, remoteConn net.Conn) RelayConn { - return &relayConnImpl{ +func NewRelayConn(relayName string, clientConn, remoteConn net.Conn, opts ...RelayConnOption) RelayConn { + rci := &relayConnImpl{ RelayLabel: relayName, - Stats: &Stats{Up: 0, Down: 0}, - clientConn: clientConn, remoteConn: remoteConn, } + for _, opt := range opts { + opt(rci) + } + s := &Stats{Up: 0, Down: 0, HandShakeLatency: rci.HandshakeDuration} + rci.Stats = s + return rci } type relayConnImpl struct { @@ -166,12 +173,19 @@ type relayConnImpl struct { StartTime time.Time `json:"start_time"` EndTime time.Time `json:"end_time,omitempty"` - Stats *Stats `json:"stats"` + Stats *Stats `json:"stats"` + HandshakeDuration time.Duration clientConn net.Conn remoteConn net.Conn } +func WithHandshakeDuration(duration time.Duration) RelayConnOption { + return func(rci *relayConnImpl) { + rci.HandshakeDuration = duration + } +} + func (rc *relayConnImpl) Transport(remoteLabel string) error { defer rc.Close() // nolint: errcheck name := rc.Name() diff --git a/echo/internal/relay/server.go b/echo/internal/relay/server.go index a300cdf148..cce7392694 100644 --- a/echo/internal/relay/server.go +++ b/echo/internal/relay/server.go @@ -31,7 +31,7 @@ func NewServer(cfg *config.Config) (*Server, error) { l := zap.S().Named("relay-server") cmgrCfg := &cmgr.Config{ SyncURL: cfg.RelaySyncURL, - SyncDuration: cfg.RelaySyncDuration, + SyncInterval: cfg.RelaySyncInterval, } cmgrCfg.Adjust() s := &Server{ diff --git a/echo/internal/transporter/mtcp.go b/echo/internal/transporter/mtcp.go index 9ac64e5667..c49ee39434 100644 --- a/echo/internal/transporter/mtcp.go +++ b/echo/internal/transporter/mtcp.go @@ -26,17 +26,20 @@ func (s *MTCP) dialRemote(remote *lb.Node) (net.Conn, error) { if err != nil { return nil, err } - metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(time.Since(t1).Milliseconds())) + latency := time.Since(t1) + metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(latency.Milliseconds())) + remote.HandShakeDuration = latency return mtcpc, nil } func (s *MTCP) HandleTCPConn(c net.Conn, remote *lb.Node) error { - mtcpc, err := s.dialRemote(remote) + clonedRemote := remote.Clone() + mtcpc, err := s.dialRemote(clonedRemote) if err != nil { return err } s.l.Infof("HandleTCPConn from:%s to:%s", c.LocalAddr(), remote.Address) - relayConn := conn.NewRelayConn(s.relayLabel, c, mtcpc) + relayConn := conn.NewRelayConn(s.relayLabel, c, mtcpc, conn.WithHandshakeDuration(clonedRemote.HandShakeDuration)) s.cmgr.AddConnection(relayConn) defer s.cmgr.RemoveConnection(relayConn) return relayConn.Transport(remote.Label) diff --git a/echo/internal/transporter/mwss.go b/echo/internal/transporter/mwss.go index d38fe6f801..f92adade3a 100644 --- a/echo/internal/transporter/mwss.go +++ b/echo/internal/transporter/mwss.go @@ -32,17 +32,21 @@ func (s *Mwss) dialRemote(remote *lb.Node) (net.Conn, error) { if err != nil { return nil, err } - metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(time.Since(t1).Milliseconds())) + + latency := time.Since(t1) + metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(latency.Milliseconds())) + remote.HandShakeDuration = latency return mwssc, nil } func (s *Mwss) HandleTCPConn(c net.Conn, remote *lb.Node) error { - mwsc, err := s.dialRemote(remote) + clonedRemote := remote.Clone() + mwsc, err := s.dialRemote(clonedRemote) if err != nil { return err } s.l.Infof("HandleTCPConn from:%s to:%s", c.LocalAddr(), remote.Address) - relayConn := conn.NewRelayConn(s.relayLabel, c, mwsc) + relayConn := conn.NewRelayConn(s.relayLabel, c, mwsc, conn.WithHandshakeDuration(clonedRemote.HandShakeDuration)) s.cmgr.AddConnection(relayConn) defer s.cmgr.RemoveConnection(relayConn) return relayConn.Transport(remote.Label) diff --git a/echo/internal/transporter/raw.go b/echo/internal/transporter/raw.go index 5980dd9006..0b5669c1bc 100644 --- a/echo/internal/transporter/raw.go +++ b/echo/internal/transporter/raw.go @@ -150,7 +150,9 @@ func (raw *Raw) dialRemote(remote *lb.Node) (net.Conn, error) { if err != nil { return nil, err } - metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(time.Since(t1).Milliseconds())) + latency := time.Since(t1) + metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(latency.Milliseconds())) + remote.HandShakeDuration = latency return rc, nil } @@ -159,12 +161,13 @@ func (raw *Raw) HandleTCPConn(c net.Conn, remote *lb.Node) error { metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Inc() defer metrics.CurConnectionCount.WithLabelValues(remote.Label, metrics.METRIC_CONN_TYPE_TCP).Dec() - rc, err := raw.dialRemote(remote) + clonedRemote := remote.Clone() + rc, err := raw.dialRemote(clonedRemote) if err != nil { return err } raw.l.Infof("HandleTCPConn from %s to %s", c.LocalAddr(), remote.Address) - relayConn := conn.NewRelayConn(raw.relayLabel, c, rc) + relayConn := conn.NewRelayConn(raw.relayLabel, c, rc, conn.WithHandshakeDuration(clonedRemote.HandShakeDuration)) raw.cmgr.AddConnection(relayConn) defer raw.cmgr.RemoveConnection(relayConn) return relayConn.Transport(remote.Label) diff --git a/echo/internal/transporter/ws.go b/echo/internal/transporter/ws.go index d266136c9c..074a608c2b 100644 --- a/echo/internal/transporter/ws.go +++ b/echo/internal/transporter/ws.go @@ -28,17 +28,22 @@ func (s *Ws) dialRemote(remote *lb.Node) (net.Conn, error) { if err != nil { return nil, err } - metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(time.Since(t1).Milliseconds())) + latency := time.Since(t1) + metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(latency.Milliseconds())) + remote.HandShakeDuration = latency return wsc, nil } func (s *Ws) HandleTCPConn(c net.Conn, remote *lb.Node) error { - wsc, err := s.dialRemote(remote) + clonedRemote := remote.Clone() + wsc, err := s.dialRemote(clonedRemote) if err != nil { return err } s.l.Infof("HandleTCPConn from %s to %s", c.LocalAddr(), remote.Address) - relayConn := conn.NewRelayConn(s.relayLabel, c, wsc) + relayConn := conn.NewRelayConn( + s.relayLabel, c, wsc, + conn.WithHandshakeDuration(clonedRemote.HandShakeDuration)) s.cmgr.AddConnection(relayConn) defer s.cmgr.RemoveConnection(relayConn) return relayConn.Transport(remote.Label) diff --git a/echo/internal/transporter/wss.go b/echo/internal/transporter/wss.go index 317ac0c357..5e7f286c93 100644 --- a/echo/internal/transporter/wss.go +++ b/echo/internal/transporter/wss.go @@ -30,18 +30,21 @@ func (s *Wss) dialRemote(remote *lb.Node) (net.Conn, error) { if err != nil { return nil, err } - metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(time.Since(t1).Milliseconds())) + latency := time.Since(t1) + metrics.HandShakeDuration.WithLabelValues(remote.Label).Observe(float64(latency.Milliseconds())) + remote.HandShakeDuration = latency return wssc, nil } func (s *Wss) HandleTCPConn(c net.Conn, remote *lb.Node) error { - wssc, err := s.dialRemote(remote) + clonedRemote := remote.Clone() + wssc, err := s.dialRemote(clonedRemote) if err != nil { return err } s.l.Infof("HandleTCPConn from %s to %s", c.RemoteAddr(), remote.Address) - relayConn := conn.NewRelayConn(s.relayLabel, c, wssc) + relayConn := conn.NewRelayConn(s.relayLabel, c, wssc, conn.WithHandshakeDuration(clonedRemote.HandShakeDuration)) s.cmgr.AddConnection(relayConn) defer s.cmgr.RemoveConnection(relayConn) return relayConn.Transport(remote.Label) diff --git a/echo/pkg/lb/round_robin.go b/echo/pkg/lb/round_robin.go index 3885440005..136426abca 100644 --- a/echo/pkg/lb/round_robin.go +++ b/echo/pkg/lb/round_robin.go @@ -1,12 +1,24 @@ package lb import ( + "time" + "go.uber.org/atomic" ) +// todo: move to internal/lb type Node struct { - Address string - Label string + Address string + Label string + HandShakeDuration time.Duration +} + +func (n *Node) Clone() *Node { + return &Node{ + Address: n.Address, + Label: n.Label, + HandShakeDuration: n.HandShakeDuration, + } } // RoundRobin is an interface for representing round-robin balancing. diff --git a/filebrowser/cmd/utils.go b/filebrowser/cmd/utils.go index 2bd9e7602d..d4ccbacc8f 100644 --- a/filebrowser/cmd/utils.go +++ b/filebrowser/cmd/utils.go @@ -87,16 +87,23 @@ func python(fn pythonFunc, cfg pythonConfig) cobraFunc { data := pythonData{hadDB: true} path := getParam(cmd.Flags(), "database") + absPath, err := filepath.Abs(path) + if err != nil { + panic(err) + } exists, err := dbExists(path) if err != nil { panic(err) } else if exists && cfg.noDB { - log.Fatal(path + " already exists") + log.Fatal(absPath + " already exists") } else if !exists && !cfg.noDB && !cfg.allowNoDB { - log.Fatal(path + " does not exist. Please run 'filebrowser config init' first.") + log.Fatal(absPath + " does not exist. Please run 'filebrowser config init' first.") + } else if !exists && !cfg.noDB { + log.Println("Warning: filebrowser.db can't be found. Initialing in " + strings.TrimSuffix(absPath, "filebrowser.db")) } + log.Println("Using database: " + absPath) data.hadDB = exists db, err := storm.Open(path) checkErr(err) diff --git a/filebrowser/frontend/src/components/prompts/Delete.vue b/filebrowser/frontend/src/components/prompts/Delete.vue index f65e69b72e..2527c855db 100644 --- a/filebrowser/frontend/src/components/prompts/Delete.vue +++ b/filebrowser/frontend/src/components/prompts/Delete.vue @@ -45,6 +45,7 @@ export default { submit: async function () { buttons.loading("delete"); + window.sessionStorage.setItem("modified", "true"); try { if (!this.isListing) { await api.remove(this.$route.path); diff --git a/filebrowser/frontend/src/components/prompts/Rename.vue b/filebrowser/frontend/src/components/prompts/Rename.vue index b6fb38ed58..f3a96c2ef9 100644 --- a/filebrowser/frontend/src/components/prompts/Rename.vue +++ b/filebrowser/frontend/src/components/prompts/Rename.vue @@ -88,6 +88,7 @@ export default { newLink = url.removeLastDir(oldLink) + "/" + encodeURIComponent(this.name); + window.sessionStorage.setItem("modified", "true"); try { await api.move([{ from: oldLink, to: newLink }]); if (!this.isListing) { diff --git a/filebrowser/frontend/src/css/mobile.css b/filebrowser/frontend/src/css/mobile.css index 3779d6e761..8047a5b674 100644 --- a/filebrowser/frontend/src/css/mobile.css +++ b/filebrowser/frontend/src/css/mobile.css @@ -2,10 +2,6 @@ nav { width: 10em } - /* Mobile Only fix div hidden by bottom navigation bar of mobile browser when using height: 100vh */ - #previewer .preview { - height: calc(100% - 4em) !important; - } } @media (max-width: 1024px) { diff --git a/filebrowser/frontend/src/css/styles.css b/filebrowser/frontend/src/css/styles.css index f38f6b63b9..bac14c6d37 100644 --- a/filebrowser/frontend/src/css/styles.css +++ b/filebrowser/frontend/src/css/styles.css @@ -153,7 +153,6 @@ main .spinner .bounce2 { #previewer { background-color: rgba(0, 0, 0, 0.99); - padding-top: 4em; position: fixed; top: 0; left: 0; @@ -166,15 +165,25 @@ main .spinner .bounce2 { #previewer header { background: none; color: #fff; + border-bottom: 0px; + box-shadow: 0px 0px 0px; + z-index: 19999; } #previewer header > .action i { color: #fff; + text-shadow: 1px 1px 1px #000000; +} + +#previewer header > title { + white-space: nowrap; + text-shadow: 1px 1px 1px #000000; } @media (min-width: 738px) { #previewer header #dropdown .action i { color: #fff; + text-shadow: 1px 1px 1px #000000; } } @@ -188,7 +197,7 @@ main .spinner .bounce2 { #previewer .preview { text-align: center; - height: calc(100vh - 4em); + height: 100%; } #previewer .preview pre { @@ -203,6 +212,12 @@ main .spinner .bounce2 { margin: 0; } +#previewer .preview audio { + width: 95%; + height: 88%; +} + + #previewer .preview video { height: 100%; } @@ -247,7 +262,7 @@ main .spinner .bounce2 { #previewer > button { margin: 0; position: fixed; - top: calc(50% + 1.85em); + top: 50%; transform: translateY(-50%); background-color: rgba(80, 80, 80, 0.5); color: white; diff --git a/filebrowser/frontend/src/views/Files.vue b/filebrowser/frontend/src/views/Files.vue index 2d67fdd792..29a7afd976 100644 --- a/filebrowser/frontend/src/views/Files.vue +++ b/filebrowser/frontend/src/views/Files.vue @@ -54,8 +54,7 @@ export default { currentView() { if (this.req.type == undefined || this.req.isDir) { return null; - } - else if ( + } else if ( this.req.type === "text" || this.req.type === "textImmutable" ) { @@ -72,11 +71,11 @@ export default { $route: function (to, from) { if (from.path.endsWith("/")) { if (to.path.endsWith("/")) { - window.sessionStorage.setItem('listFrozen', "false"); + window.sessionStorage.setItem("listFrozen", "false"); this.fetchData(); return; } else { - window.sessionStorage.setItem('listFrozen', "true"); + window.sessionStorage.setItem("listFrozen", "true"); this.fetchData(); return; } @@ -117,7 +116,7 @@ export default { this.$store.commit("closeHovers"); // Set loading to true and reset the error. - if (window.sessionStorage.getItem('listFrozen') !=="true"){ + if (window.sessionStorage.getItem("listFrozen") !=="true" && window.sessionStorage.getItem("modified") !=="true"){ this.setLoading(true); } this.error = null; diff --git a/filebrowser/frontend/src/views/files/Editor.vue b/filebrowser/frontend/src/views/files/Editor.vue index bf0d47e2df..f48716158a 100644 --- a/filebrowser/frontend/src/views/files/Editor.vue +++ b/filebrowser/frontend/src/views/files/Editor.vue @@ -1,5 +1,9 @@