]> 127.0.0.1 Git - bili_danmu/.git/commitdiff
Fix 在切片时决定是否移除旧录像
authorqydysky <qydysky@foxmail.com>
Wed, 13 Sep 2023 21:59:20 +0000 (05:59 +0800)
committerqydysky <qydysky@foxmail.com>
Wed, 13 Sep 2023 21:59:20 +0000 (05:59 +0800)
Reply/F/reSetMp4TimeStamp/reSetMp4TimeStamp.go
Reply/stream.go
cmd/cmd.go
go.mod
go.sum

index 1f23f67ac3508b1dc8ecaebe8802f7a62257efbb..07e16c8d7906f80d609f05292b590cbbfb4c79ea 100644 (file)
@@ -1,7 +1,6 @@
 package reSetMp4TimeStamp
 
 import (
-       "bytes"
        "context"
        "errors"
        "fmt"
@@ -39,14 +38,14 @@ func resetTS(ctx context.Context, ptr *string) error {
                return nil
        }
        defer f.Close()
-       var tfdtBuf = make([]byte, 16)
-       var tfhdBuf = make([]byte, 12)
-       var boxBuf = make([]byte, 4)
-       var trackBuf = make([]byte, 4)
-       var mdhdBuf = make([]byte, 4)
-       var timescale = make(map[int32]int64)
-       var opTs = make(map[int32]int64)
-       var cuTs = make(map[int32]int64)
+
+       var (
+               byte4     = make([]byte, 4)
+               byte16    = make([]byte, 16)
+               bgdts     = make(map[int32]int64)
+               eddts     = make(map[int32]int64)
+               timescale = make(map[int32]int64)
+       )
 
        for {
                if e := f.SeekUntil([]byte("tkhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
@@ -58,43 +57,18 @@ func resetTS(ctx context.Context, ptr *string) error {
                        }
                        return e
                }
-               if _, e := f.Read(boxBuf); e != nil {
-                       return e
-               } else if !bytes.Equal(boxBuf, []byte("tkhd")) {
-                       return fmt.Errorf("wrong box:%v", string(boxBuf))
-               }
-               _ = f.SeekIndex(12, file.AtCurrent)
-               if _, e := f.Read(trackBuf); e != nil {
-                       return e
-               }
-               trackId := btoi32(trackBuf, 0)
-
-               if e := f.SeekUntil([]byte("mdhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
-                       if errors.Is(e, file.ErrMaxReadSizeReach) {
-                               break
-                       }
-                       if errors.Is(e, io.EOF) {
-                               break
-                       }
-                       return e
-               }
-               if _, e := f.Read(boxBuf); e != nil {
-                       return e
-               } else if !bytes.Equal(boxBuf, []byte("mdhd")) {
-                       return fmt.Errorf("wrong box:%v", string(boxBuf))
-               }
-               _ = f.SeekIndex(12, file.AtCurrent)
-               if _, e := f.Read(mdhdBuf); e != nil {
+               _ = f.SeekIndex(16, file.AtCurrent)
+               if _, e := f.Read(byte4); e != nil {
                        return e
                }
+               trackId := btoi32(byte4, 0)
 
-               opTs[trackId] = -1
-               cuTs[trackId] = 0
-               timescale[trackId] = int64(btoi32(mdhdBuf, 0))
+               bgdts[trackId] = -1
+               eddts[trackId] = 0
        }
 
+       // rewrite dts
        _ = f.SeekIndex(0, file.AtOrigin)
-
        for {
                if e := f.SeekUntil([]byte("tfhd"), file.AtCurrent, 1<<17, 1<<20); e != nil {
                        if errors.Is(e, file.ErrMaxReadSizeReach) {
@@ -105,11 +79,11 @@ func resetTS(ctx context.Context, ptr *string) error {
                        }
                        return e
                }
-               if _, e := f.Read(tfhdBuf); e != nil {
+               _ = f.SeekIndex(8, file.AtCurrent)
+               if _, e := f.Read(byte4); e != nil {
                        return e
                }
-
-               trackID := btoi32(tfhdBuf, 8)
+               trackID := btoi32(byte4, 0)
 
                if e := f.SeekUntil([]byte("tfdt"), file.AtCurrent, 1<<17, 1<<20); e != nil {
                        if errors.Is(e, file.ErrMaxReadSizeReach) {
@@ -120,57 +94,94 @@ func resetTS(ctx context.Context, ptr *string) error {
                        }
                        return e
                }
-               if _, e := f.Read(tfdtBuf); e != nil {
+               if _, e := f.Read(byte16); e != nil {
                        return e
                }
-               switch tfdtBuf[4] {
+               switch byte16[4] {
                case 0:
-                       ts := int64(btoi32(tfdtBuf, 12))
-                       cuTs[trackID] = ts
+                       ts := int64(btoi32(byte16, 12))
+                       eddts[trackID] = ts
                        if e := f.SeekIndex(-4, file.AtCurrent); e != nil {
                                return e
                        }
-                       if opTs[trackID] == -1 {
-                               opTs[trackID] = ts
+                       if bgdts[trackID] == -1 {
+                               bgdts[trackID] = ts
                        }
-                       if _, e := f.Write(itob32(int32(ts-opTs[trackID])), false); e != nil {
+                       if _, e := f.Write(itob32(int32(ts-bgdts[trackID])), false); e != nil {
                                return e
                        }
                case 1:
-                       ts := btoi64(tfdtBuf, 8)
-                       cuTs[trackID] = ts
+                       ts := btoi64(byte16, 8)
+                       eddts[trackID] = ts
                        if e := f.SeekIndex(-8, file.AtCurrent); e != nil {
                                return e
                        }
-                       if opTs[trackID] == -1 {
-                               opTs[trackID] = ts
+                       if bgdts[trackID] == -1 {
+                               bgdts[trackID] = ts
                        }
-                       if _, e := f.Write(itob64(ts-opTs[trackID]), false); e != nil {
+                       if _, e := f.Write(itob64(ts-bgdts[trackID]), false); e != nil {
                                return e
                        }
                default:
-                       return fmt.Errorf("unknow tfdt version %x", tfdtBuf[8])
+                       return fmt.Errorf("unknow tfdt version %x", byte16[8])
                }
        }
 
-       for k, v := range opTs {
-               fmt.Printf("track %v opTs:%v cuTS:%v\n", k, v, cuTs[k])
+       _ = f.SeekIndex(0, file.AtOrigin)
+       for {
+               if e := f.SeekUntil([]byte("tkhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
+                       if errors.Is(e, file.ErrMaxReadSizeReach) {
+                               break
+                       }
+                       if errors.Is(e, io.EOF) {
+                               break
+                       }
+                       return e
+               }
+               _ = f.SeekIndex(16, file.AtCurrent)
+               if _, e := f.Read(byte4); e != nil {
+                       return e
+               }
+               trackId := btoi32(byte4, 0)
+
+               if e := f.SeekUntil([]byte("mdhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
+                       if errors.Is(e, file.ErrMaxReadSizeReach) {
+                               break
+                       }
+                       if errors.Is(e, io.EOF) {
+                               break
+                       }
+                       return e
+               }
+               _ = f.SeekIndex(16, file.AtCurrent)
+               if _, e := f.Read(byte4); e != nil {
+                       return e
+               }
+
+               timescale[trackId] = int64(btoi32(byte4, 0))
        }
 
-       // reset timestamp
-       // write mvhd
+       var duration int32
+       for k, v := range bgdts {
+               fmt.Println(eddts[k], v)
+               duration = int32((eddts[k] - v) / timescale[k])
+               break
+       }
+
+       _ = f.SeekIndex(0, file.AtOrigin)
        {
-               var duration int32
-               for k, v := range opTs {
-                       duration = int32((cuTs[k] - v) / timescale[k])
-                       break
+               if e := f.SeekUntil([]byte("moov"), file.AtCurrent, 1<<17, 1<<22); e != nil {
+                       return e
                }
-               _ = f.SeekIndex(0, file.AtOrigin)
+       }
+
+       // write mvhd
+       _ = f.SeekIndex(0, file.AtOrigin)
+       {
                if e := f.SeekUntil([]byte("mvhd"), file.AtCurrent, 1<<17, 1<<22); e != nil {
                        return e
                }
                _ = f.SeekIndex(20, file.AtCurrent)
-               fmt.Printf("mvhd %v \n", duration)
                if _, e := f.Write(itob32(duration), false); e != nil {
                        return e
                }
@@ -178,24 +189,18 @@ func resetTS(ctx context.Context, ptr *string) error {
 
        // write tkhd mdhd
        _ = f.SeekIndex(0, file.AtOrigin)
-       for i := 0; i < len(opTs); i++ {
+       for {
                if e := f.SeekUntil([]byte("tkhd"), file.AtCurrent, 1<<17, 1<<20); e != nil {
                        if errors.Is(e, file.ErrMaxReadSizeReach) {
-                               continue
+                               break
                        }
                        if errors.Is(e, io.EOF) {
                                break
                        }
                        return e
                }
-               _ = f.SeekIndex(16, file.AtCurrent)
-               if _, e := f.Read(trackBuf); e != nil {
-                       return e
-               }
-               trackID := btoi32(trackBuf, 0)
-               _ = f.SeekIndex(4, file.AtCurrent)
-               fmt.Printf("tkhd %v %v \n", trackID, int32((cuTs[trackID]-opTs[trackID])/timescale[trackID]))
-               if _, e := f.Write(itob32(int32((cuTs[trackID]-opTs[trackID])/timescale[trackID])), false); e != nil {
+               _ = f.SeekIndex(24, file.AtCurrent)
+               if _, e := f.Write(itob32(duration), false); e != nil {
                        return e
                }
 
@@ -208,17 +213,11 @@ func resetTS(ctx context.Context, ptr *string) error {
                        }
                        return e
                }
-               if _, e := f.Read(boxBuf); e != nil {
-                       return e
-               } else if !bytes.Equal(boxBuf, []byte("mdhd")) {
-                       return fmt.Errorf("wrong box:%v", string(boxBuf))
-               }
-               _ = f.SeekIndex(16, file.AtCurrent)
-               if _, e := f.Write(itob32(0), false); e != nil {
+               _ = f.SeekIndex(20, file.AtCurrent)
+               if _, e := f.Write(itob32(duration), false); e != nil {
                        return e
                }
        }
-
        return nil
 }
 
index 97200dbb38550c3372281047b127f16695d76639..453db77ccf43ab061e709a1e7ff3345be4d79c24 100644 (file)
@@ -594,11 +594,6 @@ func (t *M4SStream) saveStream() (e error) {
                }
        }
 
-       // 移除历史流
-       if err := t.removeStream(); err != nil {
-               t.log.L(`W: `, err)
-       }
-
        // 保存到文件
        if t.config.save_to_file {
                // 确保能接收到第一个帧才开始录制
@@ -1269,6 +1264,11 @@ func (t *M4SStream) Start() bool {
                                        }
                                        ms.getSavepath()
 
+                                       // 移除历史流
+                                       if err := ms.removeStream(); err != nil {
+                                               l.L(`W: `, err)
+                                       }
+
                                        var (
                                                cp = ms.Current_save_path
                                                st = ms.stream_type
index d2328753f0f0b5c04932d5a08a6b6f05ee4c0fae..b16dd69dd420702b4142b8679d5a81b4e83af886 100644 (file)
@@ -48,6 +48,7 @@ func Cmd() {
                        fmt.Println("搜索主播->输入' sea关键词'回车")
                        fmt.Println("房间信息->输入' room'回车")
                        fmt.Println("开始结束录制->输入' rec'回车")
+                       fmt.Println("录播切片->输入' cut'回车")
                        fmt.Println("退出当前房间->输入' exit'回车")
                        fmt.Println("其他输出隔断不影响")
                        fmt.Print("\n")
@@ -55,6 +56,15 @@ func Cmd() {
                        cmdlog.L(`W: `, "不支持功能键")
                } else if inputs[0] == 32 { // 开头
                        cmdlog.L(`T: `, "指令("+inputs+")")
+                       //录播切片
+                       if strings.Contains(inputs, ` cut`) {
+                               if c.C.Roomid != 0 && reply.StreamOStatus(c.C.Roomid) {
+                                       reply.StreamOCut(c.C.Roomid)
+                                       continue
+                               }
+                               cmdlog.L(`W: `, "输入错误", inputs)
+                               continue
+                       }
                        //录制切换
                        if strings.Contains(inputs, ` rec`) {
                                if len(inputs) > 4 {
diff --git a/go.mod b/go.mod
index 7070274a7f18f8806dadcc01270d5086efff4ea0..702ae11d5d7aed500561118027a9f2610e8612ac 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -8,12 +8,12 @@ require (
        github.com/qydysky/part v0.28.1-0.20230906125703-9c3051ab7a3c
        github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
        github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
-       golang.org/x/text v0.12.0
+       golang.org/x/text v0.13.0
 )
 
 require (
-       github.com/google/uuid v1.3.0
-       golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b
+       github.com/google/uuid v1.3.1
+       golang.org/x/exp v0.0.0-20230905200255-921286631fa9
 )
 
 require (
@@ -22,12 +22,12 @@ require (
        github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
        lukechampine.com/uint128 v1.3.0 // indirect
        modernc.org/cc/v3 v3.41.0 // indirect
-       modernc.org/ccgo/v3 v3.16.14 // indirect
+       modernc.org/ccgo/v3 v3.16.15 // indirect
        modernc.org/libc v1.24.1 // indirect
        modernc.org/mathutil v1.6.0 // indirect
-       modernc.org/memory v1.6.0 // indirect
+       modernc.org/memory v1.7.1 // indirect
        modernc.org/opt v0.1.3 // indirect
-       modernc.org/strutil v1.1.3 // indirect
+       modernc.org/strutil v1.2.0 // indirect
        modernc.org/token v1.1.0 // indirect
 )
 
@@ -35,24 +35,24 @@ require (
        github.com/andybalholm/brotli v1.0.5
        github.com/davecgh/go-spew v1.1.1 // indirect
        github.com/dustin/go-humanize v1.0.1
-       github.com/go-ole/go-ole v1.2.6 // indirect
+       github.com/go-ole/go-ole v1.3.0 // indirect
        github.com/go-sql-driver/mysql v1.7.1
        github.com/gorilla/websocket v1.5.0 // indirect
        github.com/klauspost/compress v1.16.7 // indirect
        github.com/lib/pq v1.10.9
-       github.com/miekg/dns v1.1.55 // indirect
+       github.com/miekg/dns v1.1.56 // indirect
        github.com/shirou/gopsutil v3.21.11+incompatible // indirect
        github.com/thedevsaddam/gojsonq/v2 v2.5.2 // indirect
        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.12.0 // indirect
-       golang.org/x/net v0.14.0 // indirect
-       golang.org/x/sys v0.11.0 // indirect
-       golang.org/x/tools v0.12.0 // indirect
+       golang.org/x/net v0.15.0 // indirect
+       golang.org/x/sys v0.12.0 // indirect
+       golang.org/x/tools v0.13.0 // indirect
        gopkg.in/yaml.v3 v3.0.1 // indirect
        modernc.org/sqlite v1.25.0
        rsc.io/qr v0.2.0 // indirect
 )
 
-// replace github.com/qydysky/part => ../part
+replace github.com/qydysky/part => ../part
diff --git a/go.sum b/go.sum
index 76affc031167ed39254af0490246fb7d0982f057..139d4aff72ffe1844965241d3eede881493c85d7 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -4,16 +4,17 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
 github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
-github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
 github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
+github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
+github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
 github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
 github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
 github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
 github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
 github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
 github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
-github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
-github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
+github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4=
+github.com/google/uuid v1.3.1/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/gotk3/gotk3 v0.6.2 h1:sx/PjaKfKULJPTPq8p2kn2ZbcNFxpOJqi4VLzMbEOO8=
@@ -30,12 +31,10 @@ github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwp
 github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
 github.com/mdp/qrterminal/v3 v3.1.1 h1:cIPwg3QU0OIm9+ce/lRfWXhPwEjOSKwk3HBwL3HBTyc=
 github.com/mdp/qrterminal/v3 v3.1.1/go.mod h1:5lJlXe7Jdr8wlPDdcsJttv1/knsRgzXASyr4dcGZqNU=
-github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo=
-github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY=
+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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/qydysky/part v0.28.1-0.20230906125703-9c3051ab7a3c h1:tqawXKX9YOPKEKrnWBZ91wnCe3tgqfAtrp5U6KKFPHA=
-github.com/qydysky/part v0.28.1-0.20230906125703-9c3051ab7a3c/go.mod h1:iOK6EzUOqdqTyQZm+pf1qxYpKvLmdK+YHZehNN/2J3U=
 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
 github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
 github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
@@ -54,23 +53,25 @@ github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+F
 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/exp v0.0.0-20230801115018-d63ba01acd4b h1:r+vk0EmXNmekl0S0BascoeeoHk/L7wmaW2QF90K+kYI=
-golang.org/x/exp v0.0.0-20230801115018-d63ba01acd4b/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9 h1:GoHiUyI/Tp2nVkLI2mCxVkOjsbSXD66ic0XW0js0R9g=
+golang.org/x/exp v0.0.0-20230905200255-921286631fa9/go.mod h1:S2oDrQGGwySpoQPVqRShND87VCbxmc6bL1Yd2oYrm6k=
 golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
 golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
-golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
-golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
+golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
 golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
 golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 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 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
 golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
-golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
-golang.org/x/tools v0.12.0 h1:YW6HUoUmYBpwSgyaGaZq1fHjrBjX1rlpZ54T6mu2kss=
-golang.org/x/tools v0.12.0/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
+golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
+golang.org/x/sys v0.12.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.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
@@ -78,8 +79,8 @@ lukechampine.com/uint128 v1.3.0 h1:cDdUVfRwDUDovz610ABgFD17nXD4/uDgVHl2sC3+sbo=
 lukechampine.com/uint128 v1.3.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
 modernc.org/cc/v3 v3.41.0 h1:QoR1Sn3YWlmA1T4vLaKZfawdVtSiGx8H+cEojbC7v1Q=
 modernc.org/cc/v3 v3.41.0/go.mod h1:Ni4zjJYJ04CDOhG7dn640WGfwBzfE0ecX8TyMB0Fv0Y=
-modernc.org/ccgo/v3 v3.16.14 h1:af6KNtFgsVmnDYrWk3PQCS9XT6BXe7o3ZFJKkIKvXNQ=
-modernc.org/ccgo/v3 v3.16.14/go.mod h1:mPDSujUIaTNWQSG4eqKw+atqLOEbma6Ncsa94WbC9zo=
+modernc.org/ccgo/v3 v3.16.15 h1:KbDR3ZAVU+wiLyMESPtbtE/Add4elztFyfsWoNTgxS0=
+modernc.org/ccgo/v3 v3.16.15/go.mod h1:yT7B+/E2m43tmMOT51GMoM98/MtHIcQQSleGnddkUNI=
 modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
 modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
 modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
@@ -88,14 +89,14 @@ modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
 modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
 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.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
-modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
+modernc.org/memory v1.7.1 h1:9J+2/GKTlV503mk3yv8QJ6oEpRCUrRy0ad8TXEPoV8M=
+modernc.org/memory v1.7.1/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.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA=
 modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
-modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
-modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
+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=
 modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
 modernc.org/token v1.1.0 h1:Xl7Ap9dKaEs5kLoOQeQmPWevfnk/DM5qcLcYlA8ys6Y=