import (
"context"
"errors"
- "maps"
- "reflect"
+ "sync"
"sync/atomic"
-
- psync "github.com/qydysky/part/sync"
)
var (
- ErrNoLink = errors.New("ErrNoLink")
- ErrLinked = errors.New("ErrLinked")
- ErrNoExist = errors.New("ErrNoExist")
- ErrConflict = errors.New("ErrConflict")
- ErrWrongType = errors.New("ErrWrongType")
+ ErrStopRun = errors.New("ErrStopRun")
+ ErrSelfDel = errors.New("ErrSelfDel")
)
-type components struct {
- m psync.Map
- link map[string][]string
- loadLink atomic.Bool
+type Component[T any] struct {
+ del atomic.Bool
+ deal func(ctx context.Context, ptr T) error
}
-func NewComp() *components {
- return &components{link: make(map[string][]string)}
+func NewComp[T any](deal func(ctx context.Context, ptr T) error) *Component[T] {
+ return &Component[T]{atomic.Bool{}, deal}
}
-func (t *components) Put(Key string, Deal func(ctx context.Context, ptr any) error) error {
- _, loaded := t.m.LoadOrStore(Key, Deal)
- if loaded {
- return errors.Join(ErrConflict, errors.New(Key))
+func (t *Component[T]) Run(ctx context.Context, ptr T) error {
+ if t.del.Load() {
+ return nil
}
- return nil
+ return t.deal(ctx, ptr)
}
-func (t *components) Del(Key string) {
- t.m.Delete(Key)
+func (t *Component[T]) Del() {
+ t.del.Store(true)
}
-func (t *components) Run(key string, ctx context.Context, ptr any) error {
- if !t.loadLink.Load() {
- return ErrNoLink
- }
- links := t.link[key]
- if len(links) == 0 {
- return ErrNoExist
- }
- for i := 0; i < len(links); i++ {
- if deal, ok := t.m.LoadV(links[i]).(func(ctx context.Context, ptr any) error); ok {
- if e := deal(ctx, ptr); e != nil {
- return e
+type Components[T any] struct {
+ lock sync.RWMutex
+ comps []*Component[T]
+}
+
+func NewComps[T any](c ...*Component[T]) *Components[T] {
+ return &Components[T]{comps: c}
+}
+
+func (t *Components[T]) Put(c ...*Component[T]) {
+ t.lock.Lock()
+ t.comps = append(t.comps, c...)
+ t.lock.Unlock()
+}
+
+func (t *Components[T]) Del(c ...*Component[T]) {
+ t.lock.Lock()
+ for i := 0; i < len(t.comps); i++ {
+ for j := 0; j < len(c); j++ {
+ if t.comps[i] == c[j] {
+ copy(t.comps[i:], t.comps[i+1:])
+ t.comps = t.comps[:len(t.comps)-1]
+ copy(c[i:], c[i+1:])
+ c = c[:len(c)-1]
+ break
}
}
}
- return nil
+ t.lock.Unlock()
}
-func (t *components) Link(link map[string][]string) error {
- if t.loadLink.CompareAndSwap(false, true) {
- t.link = maps.Clone(link)
- return nil
- }
- return ErrLinked
+func (t *Components[T]) DelAll() {
+ t.lock.Lock()
+ clear(t.comps)
+ t.lock.Unlock()
}
-func Put[T any](key string, deal func(ctx context.Context, ptr *T) error) error {
- return Comp.Put(key, func(ctx context.Context, ptr any) error {
- if item, ok := ptr.(*T); ok {
- return deal(ctx, item)
+func (t *Components[T]) Run(ctx context.Context, ptr T) error {
+ var needDel bool
+
+ t.lock.RLock()
+ defer func() {
+ t.lock.RUnlock()
+ if needDel {
+ t.lock.Lock()
+ for i := 0; i < len(t.comps); i++ {
+ if t.comps[i].del.Load() {
+ copy(t.comps[i:], t.comps[i+1:])
+ t.comps = t.comps[:len(t.comps)-1]
+ }
+ }
+ t.lock.Unlock()
}
- return errors.Join(ErrWrongType, errors.New(key))
- })
-}
+ }()
-func Run[T any](key string, ctx context.Context, ptr *T) error {
- return Comp.Run(key, ctx, ptr)
-}
+ for i := 0; i < len(t.comps); i++ {
+ if t.comps[i].del.Load() {
+ continue
+ }
+ e := t.comps[i].deal(ctx, ptr)
+ if errors.Is(e, ErrSelfDel) {
+ t.comps[i].del.Store(true)
+ needDel = true
+ }
+ if errors.Is(e, ErrStopRun) {
+ return e
+ }
+ }
-func Link(link map[string][]string) error {
- return Comp.Link(link)
+ return nil
}
-func Sign[T any](exsign ...string) (sign string) {
- sign = reflect.TypeOf(*new(T)).PkgPath()
- for i := 0; i < len(exsign); i++ {
- sign += "." + exsign[i]
+func (t *Components[T]) Start(ctx context.Context, ptr T, concurrency ...int) error {
+ var needDel bool
+
+ t.lock.RLock()
+ defer func() {
+ t.lock.RUnlock()
+ if needDel {
+ t.lock.Lock()
+ for i := 0; i < len(t.comps); i++ {
+ if t.comps[i].del.Load() {
+ copy(t.comps[i:], t.comps[i+1:])
+ t.comps = t.comps[:len(t.comps)-1]
+ }
+ }
+ t.lock.Unlock()
+ }
+ }()
+
+ var (
+ wg sync.WaitGroup
+ con chan struct{}
+ err = make(chan error, len(t.comps))
+ )
+ if len(concurrency) > 0 {
+ con = make(chan struct{}, concurrency[0])
}
- return
-}
+ wg.Add(len(t.comps))
-var Comp *components = NewComp()
+ for i := 0; i < len(t.comps); i++ {
+ if con != nil {
+ con <- struct{}{}
+ }
+ go func(i int) {
+ e := t.comps[i].deal(ctx, ptr)
+ if errors.Is(e, ErrSelfDel) {
+ t.comps[i].del.Store(true)
+ }
+ err <- e
+ wg.Done()
+ if con != nil {
+ <-con
+ }
+ }(i)
+ }
+
+ wg.Wait()
+
+ return nil
+}
import (
"context"
- "errors"
- "strconv"
- "strings"
+ "fmt"
"testing"
)
-func Test1(t *testing.T) {
- Comp = NewComp()
- Put(`1`, func(ctx context.Context, ptr *int) error {
- if *ptr > 1 {
- return nil
- }
- return errors.New("1")
- })
+// func Test1(t *testing.T) {
+// Comp = NewComp()
+// Put(`1`, func(ctx context.Context, ptr *int) error {
+// if *ptr > 1 {
+// return nil
+// }
+// return errors.New("1")
+// })
- if e := Put(`1`, func(ctx context.Context, ptr *int) error {
- if *ptr > 1 {
- return nil
- }
- return errors.New("1")
- }); !errors.Is(e, ErrConflict) {
- t.Fatal(e)
- }
-
- Comp.Put(`1.2`, func(_ context.Context, ptr any) error {
- if sp, ok := ptr.(*int); ok && *sp >= 2 {
- return nil
- }
- return errors.New("1.2")
- })
+// if e := Put(`1`, func(ctx context.Context, ptr *int) error {
+// if *ptr > 1 {
+// return nil
+// }
+// return errors.New("1")
+// }); !errors.Is(e, ErrConflict) {
+// t.Fatal(e)
+// }
- Comp.Put(`1.2.1`, func(_ context.Context, ptr any) error {
- if sp, ok := ptr.(*int); ok && *sp >= 3 {
- return nil
- }
- return errors.New("1.2.1")
- })
+// Comp.Put(`1.2`, func(_ context.Context, ptr any) error {
+// if sp, ok := ptr.(*int); ok && *sp >= 2 {
+// return nil
+// }
+// return errors.New("1.2")
+// })
- if e := Comp.Link(map[string][]string{
- `1`: {`1`},
- }); e != nil {
- t.Fatal(e)
- }
+// Comp.Put(`1.2.1`, func(_ context.Context, ptr any) error {
+// if sp, ok := ptr.(*int); ok && *sp >= 3 {
+// return nil
+// }
+// return errors.New("1.2.1")
+// })
- var s = 3
- if e := Comp.Run(`1`, context.Background(), &s); e != nil {
- t.Fatal(e)
- }
+// if e := Comp.Link(map[string][]string{
+// `1`: {`1`},
+// }); e != nil {
+// t.Fatal(e)
+// }
- Comp.Del(`1.2`)
+// var s = 3
+// if e := Comp.Run(`1`, context.Background(), &s); e != nil {
+// t.Fatal(e)
+// }
- if e := Comp.Run(`1.2.1`, context.Background(), &s); e == nil {
- t.Fatal()
- }
+// Comp.Del(`1.2`)
- if e := Comp.Run(`1`, context.Background(), &s); e != nil {
- t.Fatal(e)
- }
-}
+// if e := Comp.Run(`1.2.1`, context.Background(), &s); e == nil {
+// t.Fatal()
+// }
-func TestDot(t *testing.T) {
- Comp = NewComp()
- Put[int](`1`, func(ctx context.Context, ptr *int) error {
- if *ptr == 1 {
- return nil
- } else {
- return errors.New("1")
- }
- })
- Put[int](`12`, func(ctx context.Context, ptr *int) error {
- return errors.New("12")
- })
- Put[int](`1.2`, func(ctx context.Context, ptr *int) error {
- return errors.New("1.2")
- })
- Link(map[string][]string{
- `1`: {`1.2`},
- })
- i := 1
- if e := Run(`1`, context.Background(), &i); !strings.Contains(e.Error(), "1.2") {
- t.Fatal(e)
- }
-}
+// if e := Comp.Run(`1`, context.Background(), &s); e != nil {
+// t.Fatal(e)
+// }
+// }
-func Test3(t *testing.T) {
- Comp = NewComp()
- sumup := func(ctx context.Context, ptr *int) error {
- return nil
- }
- if e := Put[int](`bili_danmu.Reply.wsmsg.preparing.sumup`, sumup); e != nil {
- panic(e)
- } else {
- println("bili_danmu.Reply.wsmsg.preparing.sumup")
- }
- Link(map[string][]string{
- `bili_danmu.Reply.wsmsg.preparing`: {`bili_danmu.Reply.wsmsg.preparing.sumup`},
- })
- i := 1
- if e := Run(`bili_danmu.Reply.wsmsg.preparing`, context.Background(), &i); e != nil {
- t.Fatal(e)
- }
-}
+// func TestDot(t *testing.T) {
+// Comp = NewComp()
+// Put[int](`1`, func(ctx context.Context, ptr *int) error {
+// if *ptr == 1 {
+// return nil
+// } else {
+// return errors.New("1")
+// }
+// })
+// Put[int](`12`, func(ctx context.Context, ptr *int) error {
+// return errors.New("12")
+// })
+// Put[int](`1.2`, func(ctx context.Context, ptr *int) error {
+// return errors.New("1.2")
+// })
+// Link(map[string][]string{
+// `1`: {`1.2`},
+// })
+// i := 1
+// if e := Run(`1`, context.Background(), &i); !strings.Contains(e.Error(), "1.2") {
+// t.Fatal(e)
+// }
+// }
-func Test4(t *testing.T) {
- type empty struct{}
- if pkg := Sign[empty](`1`, `2`); pkg != `github.com/qydysky/part/component.1.2` {
- t.Fatal(pkg)
- }
-}
+// func Test3(t *testing.T) {
+// Comp = NewComp()
+// sumup := func(ctx context.Context, ptr *int) error {
+// return nil
+// }
+// if e := Put[int](`bili_danmu.Reply.wsmsg.preparing.sumup`, sumup); e != nil {
+// panic(e)
+// } else {
+// println("bili_danmu.Reply.wsmsg.preparing.sumup")
+// }
+// Link(map[string][]string{
+// `bili_danmu.Reply.wsmsg.preparing`: {`bili_danmu.Reply.wsmsg.preparing.sumup`},
+// })
+// i := 1
+// if e := Run(`bili_danmu.Reply.wsmsg.preparing`, context.Background(), &i); e != nil {
+// t.Fatal(e)
+// }
+// }
+
+// func Test4(t *testing.T) {
+// type empty struct{}
+// if pkg := Sign[empty](`1`, `2`); pkg != `github.com/qydysky/part/component.1.2` {
+// t.Fatal(pkg)
+// }
+// }
+
+// func Test5(t *testing.T) {
+// t.Log(GetPkgSign())
+// }
+
+// func Benchmark2(b *testing.B) {
+// for i := 0; i < b.N; i++ {
+// Put[int](strconv.Itoa(i), func(ctx context.Context, ptr *int) error {
+// return nil
+// })
+// }
+// }
-func Benchmark2(b *testing.B) {
- for i := 0; i < b.N; i++ {
- Put[int](strconv.Itoa(i), func(ctx context.Context, ptr *int) error {
- return nil
- })
- }
+// func Benchmark1(b *testing.B) {
+// for i := 0; i < 1000; i++ {
+// Put[int](`1`, func(ctx context.Context, ptr *int) error {
+// return nil
+// })
+// }
+// Link(map[string][]string{
+// `1`: {`1`},
+// })
+// ctx := context.Background()
+// b.ResetTimer()
+// for i := 0; i < b.N; i++ {
+// if e := Run(`1`, ctx, &i); e != nil {
+// b.Fatal(e)
+// }
+// }
+// }
+
+func TestMain(t *testing.T) {
+ c1 := NewComp(func(ctx context.Context, ptr string) error {
+ fmt.Println(ptr)
+ return nil
+ })
+ c1.Run(context.Background(), "1")
}
-func Benchmark1(b *testing.B) {
- for i := 0; i < 1000; i++ {
- Put[int](`1`, func(ctx context.Context, ptr *int) error {
- return nil
- })
- }
- Link(map[string][]string{
- `1`: {`1`},
+func TestMain2(t *testing.T) {
+ c1 := NewComp(func(ctx context.Context, ptr string) error {
+ fmt.Println(ptr)
+ return ErrSelfDel
+ })
+ c2 := NewComp(func(ctx context.Context, ptr string) error {
+ fmt.Println(ptr + "s")
+ return nil
})
- ctx := context.Background()
- b.ResetTimer()
- for i := 0; i < b.N; i++ {
- if e := Run(`1`, ctx, &i); e != nil {
- b.Fatal(e)
- }
- }
+ cs1 := NewComps[string]()
+ cs1.Put(c1, c2)
+ cs1.Run(context.Background(), "1")
+ cs1.Start(context.Background(), "1")
}
require (
github.com/andybalholm/brotli v1.0.6
- github.com/gorilla/websocket v1.5.0
- github.com/klauspost/compress v1.17.2
- github.com/miekg/dns v1.1.56
+ github.com/gorilla/websocket v1.5.1
+ github.com/klauspost/compress v1.17.3
+ github.com/miekg/dns v1.1.57
github.com/shirou/gopsutil v3.21.11+incompatible
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
github.com/thedevsaddam/gojsonq/v2 v2.5.2
- golang.org/x/text v0.13.0
+ golang.org/x/text v0.14.0
)
require (
github.com/tklauser/go-sysconf v0.3.12 // indirect
github.com/tklauser/numcpus v0.6.1 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
- golang.org/x/mod v0.13.0 // indirect
- golang.org/x/tools v0.14.0 // indirect
+ golang.org/x/mod v0.14.0 // indirect
+ golang.org/x/tools v0.15.0 // indirect
lukechampine.com/uint128 v1.3.0 // indirect
modernc.org/cc/v3 v3.41.0 // indirect
modernc.org/ccgo/v3 v3.16.15 // indirect
- modernc.org/libc v1.29.0 // indirect
+ modernc.org/libc v1.34.4 // indirect
modernc.org/mathutil v1.6.0 // indirect
modernc.org/memory v1.7.2 // indirect
modernc.org/opt v0.1.3 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/lib/pq v1.10.9
github.com/stretchr/testify v1.8.4 // indirect
- golang.org/x/net v0.17.0 // indirect
- golang.org/x/sys v0.13.0 // indirect
- modernc.org/sqlite v1.26.0
+ golang.org/x/net v0.18.0 // indirect
+ golang.org/x/sys v0.14.0 // indirect
+ modernc.org/sqlite v1.27.0
)
//replace github.com/thedevsaddam/gojsonq v2.3.0+incompatible => github.com/thedevsaddam/gojsonq/v2 v2.5.2
github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4=
github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
-github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
+github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
+github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
-github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
-github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA=
+github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
-github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE=
-github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY=
+github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM=
+github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw=
github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
-golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY=
-golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
-golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
-golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
-golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
-golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
+golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0=
+golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
+golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
+golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=
+golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
+golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.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.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
-golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
-golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc=
-golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg=
+golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
+golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
+golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8=
+golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
-modernc.org/libc v1.29.0 h1:tTFRFq69YKCF2QyGNuRUQxKBm1uZZLubf6Cjh/pVHXs=
-modernc.org/libc v1.29.0/go.mod h1:DaG/4Q3LRRdqpiLyP0C2m1B8ZMGkQ+cCgOIjEtQlYhQ=
+modernc.org/libc v1.34.4 h1:r9+5s4wNeoCsB8CuJE67UB4N07ernbvrcry9O3MLWtQ=
+modernc.org/libc v1.34.4/go.mod h1:YAXkAZ8ktnkCKaN9sw/UDeUVkGYJ/YquGO4FTi5nmHE=
modernc.org/mathutil v1.6.0 h1:fRe9+AmYlaej+64JsEEhoWuAYBkOtQiMEU7n/XgfYi4=
modernc.org/mathutil v1.6.0/go.mod h1:Ui5Q9q1TR2gFm0AQRqQUaBWFLAhQpCwNcuhBOSedWPo=
modernc.org/memory v1.7.2 h1:Klh90S215mmH8c9gO98QxQFsY+W451E8AnzjoE2ee1E=
modernc.org/memory v1.7.2/go.mod h1:NO4NVCQy0N7ln+T9ngWqOQfi7ley4vpwvARR+Hjw95E=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
-modernc.org/sqlite v1.26.0 h1:SocQdLRSYlA8W99V8YH0NES75thx19d9sB/aFc4R8Lw=
-modernc.org/sqlite v1.26.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
+modernc.org/sqlite v1.27.0 h1:MpKAHoyYB7xqcwnUwkuD+npwEa0fojF0B5QRbN+auJ8=
+modernc.org/sqlite v1.27.0/go.mod h1:Qxpazz0zH8Z1xCFyi5GSL3FzbtZ3fvbjmywNogldEW0=
modernc.org/strutil v1.2.0 h1:agBi9dp1I+eOnxXeiZawM8F4LawKv4NzGWSaLfyeNZA=
modernc.org/strutil v1.2.0/go.mod h1:/mdcBmfOibveCTBxUl5B5l6W+TTH1FXPLHZE6bTosX0=
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=