From 6c49957be85d31ba1f476fed2bcbb54b59787058 Mon Sep 17 00:00:00 2001 From: tsosunchia <59512455+tsosunchia@users.noreply.github.com> Date: Sun, 5 Jan 2025 12:24:58 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=BD=91=E7=BB=9C?= =?UTF-8?q?=E4=B8=8D=E9=80=9A=E6=97=B6=E7=9A=84=E5=8D=A1=E6=AD=BB=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pow/pow.go | 42 +++++++++++++++++++++++++++++------------- util/latency.go | 13 ++++++++++--- 2 files changed, 39 insertions(+), 16 deletions(-) diff --git a/pow/pow.go b/pow/pow.go index 0b823fd8..7f372f19 100644 --- a/pow/pow.go +++ b/pow/pow.go @@ -6,6 +6,9 @@ import ( "github.com/tsosunchia/powclient" "net/url" "os" + "os/signal" + "syscall" + "time" ) const ( @@ -13,6 +16,9 @@ const ( ) func GetToken(fastIp string, host string, port string) (string, error) { + // 捕获中断信号 + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt, syscall.SIGTERM) getTokenParams := powclient.NewGetTokenParams() u := url.URL{Scheme: "https", Host: fastIp + ":" + port, Path: baseURL} getTokenParams.BaseUrl = u.String() @@ -26,20 +32,30 @@ func GetToken(fastIp string, host string, port string) (string, error) { var ( token string err error + done = make(chan bool) ) - // 尝试三次RetToken,如果都失败了,异常退出 - for i := 0; i < 3; i++ { - token, err = powclient.RetToken(getTokenParams) - if err != nil { - continue + // 在 goroutine 中处理阻塞调用 + go func() { + for i := 0; i < 3; i++ { + token, err = powclient.RetToken(getTokenParams) + if err != nil { + continue // 如果失败则重试 + } + done <- true // 成功后通知主线程 + return } - //fmt.Println("GetToken success", token, getTokenParams.UserAgent) - return token, nil - } - if err != nil { - fmt.Println(err) + done <- false // 失败后通知主线程 + }() + + select { + case <-sigChan: // 监听中断信号 + return "", fmt.Errorf("Program interrupted by user ") // 添加返回值 + case success := <-done: // 等待 goroutine 完成 + if success { + return token, nil + } + return "", fmt.Errorf("RetToken failed 3 times, please try again later") + case <-time.After(10 * time.Second): // 超时处理 + return "", fmt.Errorf("RetToken timed out(10s), please check your network") // 添加返回值 } - fmt.Println("RetToken failed 3 times, please try again after a while, exit") - os.Exit(1) - return "", err } diff --git a/util/latency.go b/util/latency.go index e6c41459..51aae074 100644 --- a/util/latency.go +++ b/util/latency.go @@ -7,6 +7,8 @@ import ( "log" "net" "net/http" + "os" + "os/signal" "strings" "time" @@ -57,12 +59,17 @@ func GetFastIP(domain string, port string, enableOutput bool) string { var result ResponseInfo + sigChan := make(chan os.Signal, 1) + signal.Notify(sigChan, os.Interrupt) + select { case result = <-results: - //等待5s没有结果 视为连不上API了 + // 正常返回结果 case <-time.After(timeout): - log.Println("IP connection has been timeout, please check your network") - + log.Println("IP connection has been timeout(5s), please check your network") + case <-sigChan: // 响应中断信号 + log.Println("Program interrupted by user") + os.Exit(0) } //if len(ips) > 0 { From 69588b0d14187ee00f48aa04e5617256148c3ecf Mon Sep 17 00:00:00 2001 From: tsosunchia <59512455+tsosunchia@users.noreply.github.com> Date: Sat, 11 Jan 2025 23:09:27 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E6=9B=B4=E6=96=B0Golang=E5=88=B0v1.23,?= =?UTF-8?q?=E6=AD=A4=E5=A4=84=E9=9C=80=E6=B3=A8=E6=84=8F=E4=B9=8B=E5=90=8E?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E7=BC=96=E8=AF=91=E6=97=B6=E9=9C=80=E8=A6=81?= =?UTF-8?q?=E5=8A=A0"-ldflags=3D-checklinkname=3D0"=E5=8F=82=E6=95=B0=20?= =?UTF-8?q?=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20.cross=5Fcompile.s?= =?UTF-8?q?h=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20.github/workfl?= =?UTF-8?q?ows/build.yml=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20.g?= =?UTF-8?q?ithub/workflows/test.yml=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20?= =?UTF-8?q?=20=20=20README.md=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20?= =?UTF-8?q?=20README=5Fzh=5FCN.md=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20?= =?UTF-8?q?=20=20=20go.mod=20=09=E4=BF=AE=E6=94=B9=EF=BC=9A=20=20=20=20=20?= =?UTF-8?q?go.sum?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cross_compile.sh | 8 ++++---- .github/workflows/build.yml | 4 ++-- .github/workflows/test.yml | 6 +++--- README.md | 15 --------------- README_zh_CN.md | 17 ----------------- go.mod | 14 +++++++------- go.sum | 26 ++++++++++++-------------- 7 files changed, 28 insertions(+), 62 deletions(-) diff --git a/.cross_compile.sh b/.cross_compile.sh index c16bb306..f187cf75 100644 --- a/.cross_compile.sh +++ b/.cross_compile.sh @@ -29,13 +29,13 @@ for pl in ${PLATFORMS}; do -ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \ -X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \ -X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\ - -w -s" + -w -s -checklinkname=0" else go build -trimpath -o ${TARGET} \ -ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \ -X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \ -X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\ - -w -s" + -w -s -checklinkname=0" fi done export CGO_ENABLED=0 @@ -49,13 +49,13 @@ done -ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \ -X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \ -X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\ - -w -s" + -w -s -checklinkname=0" else go build -trimpath -o ${TARGET} \ -ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \ -X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \ -X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\ - -w -s" + -w -s -checklinkname=0" fi diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 86581b15..e2f48ecb 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -135,7 +135,7 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' - name: Get project dependencies run: go mod download - name: Build @@ -144,7 +144,7 @@ jobs: -ldflags "-X 'github.com/nxtrace/NTrace-core/config.Version=${BUILD_VERSION}' \ -X 'github.com/nxtrace/NTrace-core/config.BuildDate=${BUILD_DATE}' \ -X 'github.com/nxtrace/NTrace-core/config.CommitID=${COMMIT_SHA1}'\ - -w -s" + -checklinkname=0 -w -s" - name: Upload files to Artifacts uses: actions/upload-artifact@v4 with: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b312ac3e..aff6b958 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -31,12 +31,12 @@ jobs: - name: Set up Go uses: actions/setup-go@v5 with: - go-version: '1.22' + go-version: '1.23' - name: Checkout codebase uses: actions/checkout@v4 - name: Test with unix if: ${{ matrix.os != 'windows-latest' }} - run: sudo go test -v -coverprofile='coverage.out' -covermode=count ./... + run: sudo go test -v -ldflags=-checklinkname=0 -coverprofile='coverage.out' -covermode=count ./... - name: Test with windows if: ${{ matrix.os == 'windows-latest' }} - run: go test -v -coverprofile='coverage.out' -covermode=count ./... + run: go test -v -ldflags=-checklinkname=0 -coverprofile='coverage.out' -covermode=count ./... diff --git a/README.md b/README.md index f70a1f84..17729c2b 100644 --- a/README.md +++ b/README.md @@ -128,21 +128,6 @@ Please note, the repositories for all of the above installation methods are main * `Release` provides compiled binary executables for many systems and different architectures. If none are available, you can compile it yourself. * Some essential dependencies of this project are not fully implemented on `Windows` by `Golang`, so currently, `NextTrace` is in an experimental support phase on the `Windows` platform. -* Install from source - - After installing Go >= 1.20 yourself, you can use the following command to install - - ```shell - go install github.com/nxtrace/NTrace-core@latest - ``` - *because of the version constraints conflict, you can not install `NTrace-V1` by this* - After installation, the executable is in the `$GOPATH/bin` directory. If you have not set `GOPATH`, it is in the `$HOME/go/bin` directory. - The binary file name is consistent with the project name. You need to replace the `nexttrace` command below with `NTrace-core`. - If you want to be consistent with the commands below, you can rename the binary after executing the `go install` command - ```shell - mv $GOPATH/bin/NTrace-core $GOPATH/bin/nexttrace - ``` - ### Get Started `NextTrace` uses the `ICMP` protocol to perform TraceRoute requests by default, which supports both `IPv4` and `IPv6` diff --git a/README_zh_CN.md b/README_zh_CN.md index b35e8c25..7fdfbbec 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -138,23 +138,6 @@ Document Language: [English](README.md) | 简体中文 * `Release`里面为很多系统以及不同架构提供了编译好的二进制可执行文件,如果没有可以自行编译。 * 一些本项目的必要依赖在`Windows`上`Golang`底层实现不完全,所以目前`NextTrace`在`Windows`平台出于实验性支持阶段。 -* 从源码安装 - - 您可在自行安装Go >= 1.20后,使用以下命令安装 - - ```shell - go install github.com/nxtrace/NTrace-core@latest - ``` - *由于go.mod文件声明和文件目录冲突的问题,你不能用go install命令安装 `NTrace-V1` 版本* - 安装后可执行文件在`$GOPATH/bin`目录下,如果您没有设置`GOPATH`,则在`$HOME/go/bin`目录下。 - 安装后二进制文件名称与项目名称保持一致,你需要将下文中的 `nexttrace` 命令替换为 `NTrace-core` 使用 - 如果你希望与下文命令保持一致,可以在执行 `go install` 命令后重命名二进制文件 - - ```shell - mv $GOPATH/bin/NTrace-core $GOPATH/bin/nexttrace - ``` - - ### Get Started `NextTrace` 默认使用`ICMP`协议发起`TraceRoute`请求,该协议同时支持`IPv4`和`IPv6` diff --git a/go.mod b/go.mod index 294d2665..6b834a77 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/nxtrace/NTrace-core -go 1.22.10 +go 1.23.4 require ( github.com/akamensky/argparse v1.4.0 @@ -10,7 +10,7 @@ require ( github.com/stretchr/testify v1.10.0 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 github.com/tsosunchia/powclient v0.1.5 - golang.org/x/net v0.33.0 + golang.org/x/net v0.34.0 golang.org/x/sync v0.10.0 ) @@ -19,20 +19,20 @@ require ( github.com/fsnotify/fsnotify v1.8.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/magiconair/properties v1.8.9 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.2.3 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/sagikazarmark/locafero v0.6.0 // indirect + github.com/sagikazarmark/locafero v0.7.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect - github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/afero v1.12.0 // indirect github.com/spf13/cast v1.7.1 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect + golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect golang.org/x/text v0.21.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect ) @@ -45,6 +45,6 @@ require ( github.com/tidwall/gjson v1.18.0 github.com/tidwall/match v1.1.1 // indirect github.com/tidwall/pretty v1.2.1 // indirect - golang.org/x/sys v0.28.0 // indirect + golang.org/x/sys v0.29.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index b9298cbf..f3e8b79d 100644 --- a/go.sum +++ b/go.sum @@ -26,9 +26,8 @@ github.com/lionsoul2014/ip2region v2.11.2+incompatible h1:+VRsGcrHz8ewXI/2UzTptJ github.com/lionsoul2014/ip2region v2.11.2+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI= github.com/magiconair/properties v1.8.9 h1:nWcCbLq1N2v/cpNsy5WvQ37Fb+YElfq20WJ/a8RkpQM= github.com/magiconair/properties v1.8.9/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= 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-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= @@ -48,14 +47,14 @@ github.com/rodaine/table v1.3.0 h1:4/3S3SVkHnVZX91EHFvAMV7K42AnJ0XuymRR2C5HlGE= github.com/rodaine/table v1.3.0/go.mod h1:47zRsHar4zw0jgxGxL9YtFfs7EGN6B/TaS+/Dmk4WxU= github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= -github.com/sagikazarmark/locafero v0.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk= -github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0= +github.com/sagikazarmark/locafero v0.7.0 h1:5MqpDsTGNDhY8sGp0Aowyf0qKsPrhewaLSsFaodPcyo= +github.com/sagikazarmark/locafero v0.7.0/go.mod h1:2za3Cg5rMaTMoG/2Ulr9AwtFaIppKXTRYnozin4aB5k= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ= github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo= github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= -github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= -github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/afero v1.12.0 h1:UcOPyRBYczmFn6yvphxkn9ZEOY65cpwGKb5mL36mrqs= +github.com/spf13/afero v1.12.0/go.mod h1:ZTlWwG4/ahT8W7T0WQ5uYmjI9duaLQGy3Q2OAl4sk/4= github.com/spf13/cast v1.7.1 h1:cuNEagBQEHWN1FnbGEjCXL2szYEXqfJPbP2HNUaca9Y= github.com/spf13/cast v1.7.1/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -89,23 +88,22 @@ go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo= -golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 h1:yqrTHse8TCMW1M1ZCP+VAR/l0kKxwaAIqN/il7x4voA= +golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= +golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= +golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ=