mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-26 06:50:36 -05:00
Compare commits
7 Commits
groupware
...
bump-web-5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d0335c382 | ||
|
|
0d3fe86873 | ||
|
|
e372ae0ccf | ||
|
|
056039b624 | ||
|
|
6455052fa6 | ||
|
|
c43ac9974e | ||
|
|
22443cf0ad |
@@ -1,4 +1,4 @@
|
||||
# The test runner source for UI tests
|
||||
WEB_COMMITID=3120ea384c7a9d1f1ea0c328965951fc06d66900
|
||||
WEB_COMMITID=d5f9ddb7878c20ca6db54b6f097e611c996de728
|
||||
WEB_BRANCH=main
|
||||
|
||||
|
||||
14
go.mod
14
go.mod
@@ -34,7 +34,7 @@ require (
|
||||
github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
|
||||
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0
|
||||
github.com/go-playground/validator/v10 v10.30.1
|
||||
github.com/go-resty/resty/v2 v2.7.0
|
||||
github.com/go-resty/resty/v2 v2.17.1
|
||||
github.com/golang-jwt/jwt/v5 v5.3.0
|
||||
github.com/golang/protobuf v1.5.4
|
||||
github.com/google/go-cmp v0.7.0
|
||||
@@ -42,7 +42,7 @@ require (
|
||||
github.com/google/uuid v1.6.0
|
||||
github.com/gookit/config/v2 v2.2.7
|
||||
github.com/gorilla/mux v1.8.1
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5
|
||||
github.com/invopop/validation v0.8.0
|
||||
github.com/jellydator/ttlcache/v2 v2.11.1
|
||||
github.com/jellydator/ttlcache/v3 v3.4.0
|
||||
@@ -58,7 +58,7 @@ require (
|
||||
github.com/nats-io/nats-server/v2 v2.12.3
|
||||
github.com/nats-io/nats.go v1.48.0
|
||||
github.com/oklog/run v1.2.0
|
||||
github.com/olekukonko/tablewriter v1.1.2
|
||||
github.com/olekukonko/tablewriter v1.1.3
|
||||
github.com/onsi/ginkgo v1.16.5
|
||||
github.com/onsi/ginkgo/v2 v2.27.5
|
||||
github.com/onsi/gomega v1.39.0
|
||||
@@ -111,7 +111,7 @@ require (
|
||||
golang.org/x/sync v0.19.0
|
||||
golang.org/x/term v0.39.0
|
||||
golang.org/x/text v0.33.0
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516
|
||||
google.golang.org/grpc v1.78.0
|
||||
google.golang.org/protobuf v1.36.11
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
@@ -166,7 +166,7 @@ require (
|
||||
github.com/ceph/go-ceph v0.37.0 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||
github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.6.0 // indirect
|
||||
github.com/clipperhouse/displaywidth v0.6.2 // indirect
|
||||
github.com/clipperhouse/stringish v0.1.1 // indirect
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 // indirect
|
||||
github.com/cloudflare/circl v1.6.1 // indirect
|
||||
@@ -313,7 +313,7 @@ require (
|
||||
github.com/nxadm/tail v1.4.8 // indirect
|
||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 // indirect
|
||||
github.com/olekukonko/errors v1.1.0 // indirect
|
||||
github.com/olekukonko/ll v0.1.3 // indirect
|
||||
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 // indirect
|
||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
@@ -396,7 +396,7 @@ require (
|
||||
golang.org/x/time v0.14.0 // indirect
|
||||
golang.org/x/tools v0.40.0 // indirect
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b // indirect
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 // indirect
|
||||
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
|
||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||
|
||||
29
go.sum
29
go.sum
@@ -223,8 +223,8 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
|
||||
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
|
||||
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
github.com/clipperhouse/displaywidth v0.6.0 h1:k32vueaksef9WIKCNcoqRNyKbyvkvkysNYnAWz2fN4s=
|
||||
github.com/clipperhouse/displaywidth v0.6.0/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||
github.com/clipperhouse/displaywidth v0.6.2 h1:ZDpTkFfpHOKte4RG5O/BOyf3ysnvFswpyYrV7z2uAKo=
|
||||
github.com/clipperhouse/displaywidth v0.6.2/go.mod h1:R+kHuzaYWFkTm7xoMmK1lFydbci4X2CicfbGstSGg0o=
|
||||
github.com/clipperhouse/stringish v0.1.1 h1:+NSqMOr3GR6k1FdRhhnXrLfztGzuG+VuFDfatpWHKCs=
|
||||
github.com/clipperhouse/stringish v0.1.1/go.mod h1:v/WhFtE1q0ovMta2+m+UbpZ+2/HEXNWYXQgCt4hdOzA=
|
||||
github.com/clipperhouse/uax29/v2 v2.3.0 h1:SNdx9DVUqMoBuBoW3iLOj4FQv3dN5mDtuqwuhIGpJy4=
|
||||
@@ -461,8 +461,8 @@ github.com/go-playground/validator/v10 v10.30.1/go.mod h1:oSuBIQzuJxL//3MelwSLD5
|
||||
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
|
||||
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
|
||||
github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
|
||||
github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY=
|
||||
github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I=
|
||||
github.com/go-resty/resty/v2 v2.17.1 h1:x3aMpHK1YM9e4va/TMDRlusDDoZiQ+ViDu/WpA6xTM4=
|
||||
github.com/go-resty/resty/v2 v2.17.1/go.mod h1:kCKZ3wWmwJaNc7S29BRtUhJwy7iqmn+2mLtQrOyQlVA=
|
||||
github.com/go-sql-driver/mysql v1.9.3 h1:U/N249h2WzJ3Ukj8SowVFjdtZKfu9vlLZxjPXV1aweo=
|
||||
github.com/go-sql-driver/mysql v1.9.3/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
@@ -624,8 +624,8 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vb
|
||||
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.8.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4 h1:kEISI/Gx67NzH3nJxAmY/dGac80kKZgZt134u7Y/k1s=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4/go.mod h1:6Nz966r3vQYCqIzWsuEl9d7cf7mRhtDmm++sOxlnfxI=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5 h1:jP1RStw811EvUDzsUQ9oESqw2e4RqCjSAD9qIL8eMns=
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5/go.mod h1:WXNBZ64q3+ZUemCMXD9kYnr56H7CgZxDBHCVwstfl3s=
|
||||
github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
@@ -942,11 +942,11 @@ github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6 h1:zrbMGy9YXpIeTnGj
|
||||
github.com/olekukonko/cat v0.0.0-20250911104152-50322a0618f6/go.mod h1:rEKTHC9roVVicUIfZK7DYrdIoM0EOr8mK1Hj5s3JjH0=
|
||||
github.com/olekukonko/errors v1.1.0 h1:RNuGIh15QdDenh+hNvKrJkmxxjV4hcS50Db478Ou5sM=
|
||||
github.com/olekukonko/errors v1.1.0/go.mod h1:ppzxA5jBKcO1vIpCXQ9ZqgDh8iwODz6OXIGKU8r5m4Y=
|
||||
github.com/olekukonko/ll v0.1.3 h1:sV2jrhQGq5B3W0nENUISCR6azIPf7UBUpVq0x/y70Fg=
|
||||
github.com/olekukonko/ll v0.1.3/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
|
||||
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0 h1:jrYnow5+hy3WRDCBypUFvVKNSPPCdqgSXIE9eJDD8LM=
|
||||
github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0/go.mod h1:b52bVQRRPObe+yyBl0TxNfhesL0nedD4Cht0/zx55Ew=
|
||||
github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY=
|
||||
github.com/olekukonko/tablewriter v1.1.2 h1:L2kI1Y5tZBct/O/TyZK1zIE9GlBj/TVs+AY5tZDCDSc=
|
||||
github.com/olekukonko/tablewriter v1.1.2/go.mod h1:z7SYPugVqGVavWoA2sGsFIoOVNmEHxUAAMrhXONtfkg=
|
||||
github.com/olekukonko/tablewriter v1.1.3 h1:VSHhghXxrP0JHl+0NnKid7WoEmd9/urKRJLysb70nnA=
|
||||
github.com/olekukonko/tablewriter v1.1.3/go.mod h1:9VU0knjhmMkXjnMKrZ3+L2JhhtsQ/L38BbL3CRNE8tM=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
|
||||
@@ -1464,7 +1464,6 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
@@ -1746,10 +1745,10 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
|
||||
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
|
||||
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b h1:uA40e2M6fYRBf0+8uN5mLlqUtV192iiksiICIBkYJ1E=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:Xa7le7qx2vmqB/SzWUBa7KdMjpdpAHlh5QCSnjessQk=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b h1:Mv8VFug0MP9e5vUxfBcE3vUkV6CImK3cMNMIDFjmzxU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516 h1:vmC/ws+pLzWjj/gzApyoZuSVrDtF1aod4u/+bbj8hgM=
|
||||
google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:p3MLuOwURrGBRoEyFHBT3GjUwaCQVKeNqqWxlcISGdw=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516 h1:sNrWoksmOyF5bvJUcnmbeAmQi8baNhqg5IWaI3llQqU=
|
||||
google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516/go.mod h1:j9x/tPzZkyxcgEFkiKEEGxfvyumM01BEtsW8xzOahRQ=
|
||||
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
|
||||
@@ -34,7 +34,7 @@ var (
|
||||
// LatestTag is the latest released version plus the dev meta version.
|
||||
// Will be overwritten by the release pipeline
|
||||
// Needs a manual change for every tagged release
|
||||
LatestTag = "4.1.0+dev"
|
||||
LatestTag = "5.0.0+dev"
|
||||
|
||||
// Date indicates the build date.
|
||||
// This has been removed, it looks like you can only replace static strings with recent go versions
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-06 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-26 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Quan Tran, 2025\n"
|
||||
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
|
||||
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-06 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-26 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Quan Tran, 2025\n"
|
||||
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-03 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-23 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-03 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-23 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
|
||||
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"
|
||||
|
||||
@@ -11,7 +11,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: EMAIL\n"
|
||||
"POT-Creation-Date: 2026-01-05 00:06+0000\n"
|
||||
"POT-Creation-Date: 2026-01-25 00:11+0000\n"
|
||||
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
|
||||
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
|
||||
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
SHELL := bash
|
||||
NAME := web
|
||||
WEB_ASSETS_VERSION = v4.3.0
|
||||
WEB_ASSETS_VERSION = v5.0.0
|
||||
WEB_ASSETS_BRANCH = main
|
||||
|
||||
ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI
|
||||
|
||||
10
vendor/github.com/clipperhouse/displaywidth/CHANGELOG.md
generated
vendored
10
vendor/github.com/clipperhouse/displaywidth/CHANGELOG.md
generated
vendored
@@ -1,5 +1,15 @@
|
||||
# Changelog
|
||||
|
||||
## [0.6.1]
|
||||
|
||||
[Compare](https://github.com/clipperhouse/displaywidth/compare/v0.6.0...v0.6.1)
|
||||
|
||||
### Changed
|
||||
- Perf improvements: replaced the ASCII lookup table with a simple
|
||||
function. A bit more cache-friendly. More inlining.
|
||||
- Bug fix: single regional indicators are now treated as width 2, since that
|
||||
is what actual terminals do.
|
||||
|
||||
## [0.6.0]
|
||||
|
||||
[Compare](https://github.com/clipperhouse/displaywidth/compare/v0.5.0...v0.6.0)
|
||||
|
||||
114
vendor/github.com/clipperhouse/displaywidth/README.md
generated
vendored
114
vendor/github.com/clipperhouse/displaywidth/README.md
generated
vendored
@@ -33,42 +33,82 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
For most purposes, you should use the `String` or `Bytes` methods.
|
||||
For most purposes, you should use the `String` or `Bytes` methods. They sum
|
||||
the widths of grapheme clusters in the string or byte slice.
|
||||
|
||||
> Note: in your application, iterating over runes to measure width is likely incorrect;
|
||||
the smallest unit of display is a grapheme, not a rune.
|
||||
|
||||
### Iterating over graphemes
|
||||
|
||||
If you need the individual graphemes:
|
||||
|
||||
```go
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/clipperhouse/displaywidth"
|
||||
)
|
||||
|
||||
func main() {
|
||||
g := displaywidth.StringGraphemes("Hello, 世界!")
|
||||
for g.Next() {
|
||||
width := g.Width()
|
||||
value := g.Value()
|
||||
// do something with the width or value
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
You can specify East Asian Width settings. When false (default),
|
||||
[East Asian Ambiguous characters](https://www.unicode.org/reports/tr11/#Ambiguous)
|
||||
are treated as width 1. When true, East Asian Ambiguous characters are treated
|
||||
as width 2.
|
||||
There is one option, `displaywidth.Options.EastAsianWidth`, which defines
|
||||
how [East Asian Ambiguous characters](https://www.unicode.org/reports/tr11/#Ambiguous)
|
||||
are treated.
|
||||
|
||||
When `false` (default), East Asian Ambiguous characters are treated as width 1.
|
||||
When `true`, they are treated as width 2.
|
||||
|
||||
You may wish to configure this based on environment variables or locale.
|
||||
`go-runewidth`, for example, does so
|
||||
[during package initialization](https://github.com/mattn/go-runewidth/blob/master/runewidth.go#L26C1-L45C2).
|
||||
|
||||
`displaywidth` does not do this automatically, we prefer to leave it to you.
|
||||
You might do something like:
|
||||
|
||||
```go
|
||||
myOptions := displaywidth.Options{
|
||||
EastAsianWidth: true,
|
||||
var width displaywidth.Options // zero value is default
|
||||
|
||||
func init() {
|
||||
if os.Getenv("EAST_ASIAN_WIDTH") == "true" {
|
||||
width = displaywidth.Options{EastAsianWidth: true}
|
||||
}
|
||||
// or check locale, or any other logic you want
|
||||
}
|
||||
|
||||
width := myOptions.String("Hello, 世界!")
|
||||
fmt.Println(width)
|
||||
// use it in your logic
|
||||
func myApp() {
|
||||
fmt.Println(width.String("Hello, 世界!"))
|
||||
}
|
||||
```
|
||||
|
||||
## Technical details
|
||||
## Technical standards and compatibility
|
||||
|
||||
This package implements the Unicode East Asian Width standard
|
||||
([UAX #11](https://www.unicode.org/reports/tr11/)), and handles
|
||||
([UAX #11](https://www.unicode.org/reports/tr11/tr11-43.html)), and handles
|
||||
[version selectors](https://en.wikipedia.org/wiki/Variation_Selectors_(Unicode_block)),
|
||||
and [regional indicator pairs](https://en.wikipedia.org/wiki/Regional_indicator_symbol)
|
||||
(flags). We implement [Unicode TR51](https://unicode.org/reports/tr51/).
|
||||
(flags). We implement [Unicode TR51](https://www.unicode.org/reports/tr51/tr51-27.html). We are keeping
|
||||
an eye on [emerging standards](https://www.jeffquast.com/post/state-of-terminal-emulation-2025/).
|
||||
|
||||
|
||||
`clipperhouse/displaywidth`, `mattn/go-runewidth`, and `rivo/uniseg` will
|
||||
give the same outputs for most real-world text. See extensive details in the
|
||||
give the same outputs for most real-world text. Extensive details are in the
|
||||
[compatibility analysis](comparison/COMPATIBILITY_ANALYSIS.md).
|
||||
|
||||
If you wish to investigate the core logic, see the `lookupProperties` and `width`
|
||||
functions in [width.go](width.go#L135). The essential trie generation logic is in
|
||||
`buildPropertyBitmap` in [unicode.go](internal/gen/unicode.go#L317).
|
||||
functions in [width.go](width.go#L139). The essential trie generation logic is in
|
||||
`buildPropertyBitmap` in [unicode.go](internal/gen/unicode.go#L316).
|
||||
|
||||
I (@clipperhouse) am keeping an eye on [emerging standards and test suites](https://www.jeffquast.com/post/state-of-terminal-emulation-2025/).
|
||||
|
||||
## Prior Art
|
||||
|
||||
@@ -93,31 +133,33 @@ goarch: arm64
|
||||
pkg: github.com/clipperhouse/displaywidth/comparison
|
||||
cpu: Apple M2
|
||||
|
||||
BenchmarkString_Mixed/clipperhouse/displaywidth-8 10469 ns/op 161.15 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/mattn/go-runewidth-8 14250 ns/op 118.39 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/rivo/uniseg-8 19258 ns/op 87.60 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/clipperhouse/displaywidth-8 10326 ns/op 163.37 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/mattn/go-runewidth-8 14415 ns/op 117.03 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Mixed/rivo/uniseg-8 19343 ns/op 87.21 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkString_EastAsian/clipperhouse/displaywidth-8 10518 ns/op 160.39 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/mattn/go-runewidth-8 23827 ns/op 70.80 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/rivo/uniseg-8 19537 ns/op 86.35 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/clipperhouse/displaywidth-8 10561 ns/op 159.74 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/mattn/go-runewidth-8 23790 ns/op 70.91 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_EastAsian/rivo/uniseg-8 19322 ns/op 87.31 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkString_ASCII/clipperhouse/displaywidth-8 1027 ns/op 124.61 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/mattn/go-runewidth-8 1166 ns/op 109.78 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/rivo/uniseg-8 1551 ns/op 82.52 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/clipperhouse/displaywidth-8 1033 ns/op 123.88 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/mattn/go-runewidth-8 1168 ns/op 109.59 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_ASCII/rivo/uniseg-8 1585 ns/op 80.74 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkString_Emoji/clipperhouse/displaywidth-8 3164 ns/op 228.84 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/mattn/go-runewidth-8 4728 ns/op 153.13 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/rivo/uniseg-8 6489 ns/op 111.57 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/clipperhouse/displaywidth-8 3034 ns/op 238.61 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/mattn/go-runewidth-8 4797 ns/op 150.94 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkString_Emoji/rivo/uniseg-8 6612 ns/op 109.50 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_Mixed/clipperhouse/displaywidth-8 3429 ns/op 491.96 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Mixed/mattn/go-runewidth-8 5308 ns/op 317.81 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Mixed/clipperhouse/displaywidth-8 3343 ns/op 504.67 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Mixed/mattn/go-runewidth-8 5414 ns/op 311.62 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_EastAsian/clipperhouse/displaywidth-8 3419 ns/op 493.49 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_EastAsian/mattn/go-runewidth-8 15321 ns/op 110.11 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_EastAsian/clipperhouse/displaywidth-8 3393 ns/op 497.17 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_EastAsian/mattn/go-runewidth-8 15312 ns/op 110.17 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_ASCII/clipperhouse/displaywidth-8 254.4 ns/op 503.19 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_ASCII/mattn/go-runewidth-8 264.3 ns/op 484.31 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_ASCII/clipperhouse/displaywidth-8 256.9 ns/op 498.32 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_ASCII/mattn/go-runewidth-8 265.7 ns/op 481.75 MB/s 0 B/op 0 allocs/op
|
||||
|
||||
BenchmarkRune_Emoji/clipperhouse/displaywidth-8 1374 ns/op 527.02 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Emoji/mattn/go-runewidth-8 2210 ns/op 327.66 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Emoji/clipperhouse/displaywidth-8 1336 ns/op 541.96 MB/s 0 B/op 0 allocs/op
|
||||
BenchmarkRune_Emoji/mattn/go-runewidth-8 2304 ns/op 314.23 MB/s 0 B/op 0 allocs/op
|
||||
```
|
||||
|
||||
Here are some notes on [how to make Unicode things fast](https://clipperhouse.com/go-unicode/).
|
||||
|
||||
91
vendor/github.com/clipperhouse/displaywidth/tables.go
generated
vendored
91
vendor/github.com/clipperhouse/displaywidth/tables.go
generated
vendored
@@ -1,91 +0,0 @@
|
||||
package displaywidth
|
||||
|
||||
// propertyWidths is a jump table of sorts, instead of a switch
|
||||
var propertyWidths = [5]int{
|
||||
_Default: 1,
|
||||
_Zero_Width: 0,
|
||||
_East_Asian_Wide: 2,
|
||||
_East_Asian_Ambiguous: 1,
|
||||
_Emoji: 2,
|
||||
}
|
||||
|
||||
// asciiWidths is a lookup table for single-byte character widths. Printable
|
||||
// ASCII characters have width 1, control characters have width 0.
|
||||
//
|
||||
// It is intended for valid single-byte UTF-8, which means <128.
|
||||
//
|
||||
// If you look up an index >= 128, that is either:
|
||||
// - invalid UTF-8, or
|
||||
// - a multi-byte UTF-8 sequence, in which case you should be operating on
|
||||
// the grapheme cluster, and not using this table
|
||||
//
|
||||
// We will return a default value of 1 in those cases, so as not to panic.
|
||||
var asciiWidths = [256]int8{
|
||||
// Control characters (0x00-0x1F): width 0
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
// Printable ASCII (0x20-0x7E): width 1
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
// DEL (0x7F): width 0
|
||||
0,
|
||||
// >= 128
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
}
|
||||
|
||||
// asciiProperties is a lookup table for single-byte character properties.
|
||||
// It is intended for valid single-byte UTF-8, which means <128.
|
||||
//
|
||||
// If you look up an index >= 128, that is either:
|
||||
// - invalid UTF-8, or
|
||||
// - a multi-byte UTF-8 sequence, in which case you should be operating on
|
||||
// the grapheme cluster, and not using this table
|
||||
//
|
||||
// We will return a default value of _Default in those cases, so as not to
|
||||
// panic.
|
||||
var asciiProperties = [256]property{
|
||||
// Control characters (0x00-0x1F): _Zero_Width
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
_Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width, _Zero_Width,
|
||||
// Printable ASCII (0x20-0x7E): _Default
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
// DEL (0x7F): _Zero_Width
|
||||
_Zero_Width,
|
||||
// >= 128
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
_Default, _Default, _Default, _Default, _Default, _Default, _Default, _Default,
|
||||
}
|
||||
502
vendor/github.com/clipperhouse/displaywidth/trie.go
generated
vendored
502
vendor/github.com/clipperhouse/displaywidth/trie.go
generated
vendored
@@ -10,12 +10,10 @@ type property uint8
|
||||
const (
|
||||
// Always 0 width, includes combining marks, control characters, non-printable, etc
|
||||
_Zero_Width property = iota + 1
|
||||
// Always 2 wide (East Asian Wide F/W)
|
||||
_East_Asian_Wide
|
||||
// Always 2 wide (East Asian Wide F/W, Emoji, Regional Indicator)
|
||||
_Wide
|
||||
// Width depends on EastAsianWidth option
|
||||
_East_Asian_Ambiguous
|
||||
// Extended_Pictographic + Emoji_Presentation
|
||||
_Emoji
|
||||
)
|
||||
|
||||
// lookup returns the trie value for the first UTF-8 encoding in s and
|
||||
@@ -81,7 +79,7 @@ func lookup[T stringish.Interface](s T) (v uint8, sz int) {
|
||||
return 0, 1
|
||||
}
|
||||
|
||||
// stringWidthTrie. Total size: 17728 bytes (17.31 KiB). Checksum: b4b51ae347944fdb.
|
||||
// stringWidthTrie. Total size: 17664 bytes (17.25 KiB). Checksum: c77d82ff2d69f0d2.
|
||||
// type stringWidthTrie struct { }
|
||||
|
||||
// func newStringWidthTrie(i int) *stringWidthTrie {
|
||||
@@ -96,9 +94,9 @@ func lookupValue(n uint32, b byte) uint8 {
|
||||
}
|
||||
}
|
||||
|
||||
// stringWidthValues: 247 blocks, 15808 entries, 15808 bytes
|
||||
// stringWidthValues: 246 blocks, 15744 entries, 15744 bytes
|
||||
// The third block is the zero block.
|
||||
var stringWidthValues = [15808]uint8{
|
||||
var stringWidthValues = [15744]uint8{
|
||||
// Block 0x0, offset 0x0
|
||||
// Block 0x1, offset 0x40
|
||||
// Block 0x2, offset 0x80
|
||||
@@ -577,13 +575,13 @@ var stringWidthValues = [15808]uint8{
|
||||
0x167f: 0x0003,
|
||||
// Block 0x5a, offset 0x1680
|
||||
0x1692: 0x0003,
|
||||
0x169a: 0x0004, 0x169b: 0x0004,
|
||||
0x169a: 0x0002, 0x169b: 0x0002,
|
||||
0x16a9: 0x0002,
|
||||
0x16aa: 0x0002,
|
||||
// Block 0x5b, offset 0x16c0
|
||||
0x16e9: 0x0004,
|
||||
0x16ea: 0x0004, 0x16eb: 0x0004, 0x16ec: 0x0004,
|
||||
0x16f0: 0x0004, 0x16f3: 0x0004,
|
||||
0x16e9: 0x0002,
|
||||
0x16ea: 0x0002, 0x16eb: 0x0002, 0x16ec: 0x0002,
|
||||
0x16f0: 0x0002, 0x16f3: 0x0002,
|
||||
// Block 0x5c, offset 0x1700
|
||||
0x1720: 0x0003, 0x1721: 0x0003, 0x1722: 0x0003, 0x1723: 0x0003,
|
||||
0x1724: 0x0003, 0x1725: 0x0003, 0x1726: 0x0003, 0x1727: 0x0003, 0x1728: 0x0003, 0x1729: 0x0003,
|
||||
@@ -642,63 +640,63 @@ var stringWidthValues = [15808]uint8{
|
||||
0x1862: 0x0003, 0x1863: 0x0003,
|
||||
0x1864: 0x0003, 0x1865: 0x0003,
|
||||
0x186f: 0x0003,
|
||||
0x187d: 0x0004, 0x187e: 0x0004,
|
||||
0x187d: 0x0002, 0x187e: 0x0002,
|
||||
// Block 0x62, offset 0x1880
|
||||
0x1885: 0x0003,
|
||||
0x1886: 0x0003, 0x1889: 0x0003,
|
||||
0x188e: 0x0003, 0x188f: 0x0003,
|
||||
0x1894: 0x0004, 0x1895: 0x0004,
|
||||
0x1894: 0x0002, 0x1895: 0x0002,
|
||||
0x189c: 0x0003,
|
||||
0x189e: 0x0003,
|
||||
0x18b0: 0x0002, 0x18b1: 0x0002, 0x18b2: 0x0002, 0x18b3: 0x0002, 0x18b4: 0x0002, 0x18b5: 0x0002,
|
||||
0x18b6: 0x0002, 0x18b7: 0x0002,
|
||||
// Block 0x63, offset 0x18c0
|
||||
0x18c0: 0x0003, 0x18c2: 0x0003,
|
||||
0x18c8: 0x0004, 0x18c9: 0x0004, 0x18ca: 0x0004, 0x18cb: 0x0004,
|
||||
0x18cc: 0x0004, 0x18cd: 0x0004, 0x18ce: 0x0004, 0x18cf: 0x0004, 0x18d0: 0x0004, 0x18d1: 0x0004,
|
||||
0x18d2: 0x0004, 0x18d3: 0x0004,
|
||||
0x18c8: 0x0002, 0x18c9: 0x0002, 0x18ca: 0x0002, 0x18cb: 0x0002,
|
||||
0x18cc: 0x0002, 0x18cd: 0x0002, 0x18ce: 0x0002, 0x18cf: 0x0002, 0x18d0: 0x0002, 0x18d1: 0x0002,
|
||||
0x18d2: 0x0002, 0x18d3: 0x0002,
|
||||
0x18e0: 0x0003, 0x18e1: 0x0003, 0x18e3: 0x0003,
|
||||
0x18e4: 0x0003, 0x18e5: 0x0003, 0x18e7: 0x0003, 0x18e8: 0x0003, 0x18e9: 0x0003,
|
||||
0x18ea: 0x0003, 0x18ec: 0x0003, 0x18ed: 0x0003, 0x18ef: 0x0003,
|
||||
0x18ff: 0x0004,
|
||||
0x18ff: 0x0002,
|
||||
// Block 0x64, offset 0x1900
|
||||
0x190a: 0x0002, 0x190b: 0x0002,
|
||||
0x190c: 0x0002, 0x190d: 0x0002, 0x190e: 0x0002, 0x190f: 0x0002,
|
||||
0x1913: 0x0004,
|
||||
0x191e: 0x0003, 0x191f: 0x0003, 0x1921: 0x0004,
|
||||
0x192a: 0x0004, 0x192b: 0x0004,
|
||||
0x193d: 0x0004, 0x193e: 0x0004, 0x193f: 0x0003,
|
||||
0x1913: 0x0002,
|
||||
0x191e: 0x0003, 0x191f: 0x0003, 0x1921: 0x0002,
|
||||
0x192a: 0x0002, 0x192b: 0x0002,
|
||||
0x193d: 0x0002, 0x193e: 0x0002, 0x193f: 0x0003,
|
||||
// Block 0x65, offset 0x1940
|
||||
0x1944: 0x0004, 0x1945: 0x0004,
|
||||
0x1944: 0x0002, 0x1945: 0x0002,
|
||||
0x1946: 0x0003, 0x1947: 0x0003, 0x1948: 0x0003, 0x1949: 0x0003, 0x194a: 0x0003, 0x194b: 0x0003,
|
||||
0x194c: 0x0003, 0x194d: 0x0003, 0x194e: 0x0004, 0x194f: 0x0003, 0x1950: 0x0003, 0x1951: 0x0003,
|
||||
0x1952: 0x0003, 0x1953: 0x0003, 0x1954: 0x0004, 0x1955: 0x0003, 0x1956: 0x0003, 0x1957: 0x0003,
|
||||
0x194c: 0x0003, 0x194d: 0x0003, 0x194e: 0x0002, 0x194f: 0x0003, 0x1950: 0x0003, 0x1951: 0x0003,
|
||||
0x1952: 0x0003, 0x1953: 0x0003, 0x1954: 0x0002, 0x1955: 0x0003, 0x1956: 0x0003, 0x1957: 0x0003,
|
||||
0x1958: 0x0003, 0x1959: 0x0003, 0x195a: 0x0003, 0x195b: 0x0003, 0x195c: 0x0003, 0x195d: 0x0003,
|
||||
0x195e: 0x0003, 0x195f: 0x0003, 0x1960: 0x0003, 0x1961: 0x0003, 0x1963: 0x0003,
|
||||
0x1968: 0x0003, 0x1969: 0x0003,
|
||||
0x196a: 0x0004, 0x196b: 0x0003, 0x196c: 0x0003, 0x196d: 0x0003, 0x196e: 0x0003, 0x196f: 0x0003,
|
||||
0x1970: 0x0003, 0x1971: 0x0003, 0x1972: 0x0004, 0x1973: 0x0004, 0x1974: 0x0003, 0x1975: 0x0004,
|
||||
0x1976: 0x0003, 0x1977: 0x0003, 0x1978: 0x0003, 0x1979: 0x0003, 0x197a: 0x0004, 0x197b: 0x0003,
|
||||
0x197c: 0x0003, 0x197d: 0x0004, 0x197e: 0x0003, 0x197f: 0x0003,
|
||||
0x196a: 0x0002, 0x196b: 0x0003, 0x196c: 0x0003, 0x196d: 0x0003, 0x196e: 0x0003, 0x196f: 0x0003,
|
||||
0x1970: 0x0003, 0x1971: 0x0003, 0x1972: 0x0002, 0x1973: 0x0002, 0x1974: 0x0003, 0x1975: 0x0002,
|
||||
0x1976: 0x0003, 0x1977: 0x0003, 0x1978: 0x0003, 0x1979: 0x0003, 0x197a: 0x0002, 0x197b: 0x0003,
|
||||
0x197c: 0x0003, 0x197d: 0x0002, 0x197e: 0x0003, 0x197f: 0x0003,
|
||||
// Block 0x66, offset 0x1980
|
||||
0x1985: 0x0004,
|
||||
0x198a: 0x0004, 0x198b: 0x0004,
|
||||
0x19a8: 0x0004,
|
||||
0x1985: 0x0002,
|
||||
0x198a: 0x0002, 0x198b: 0x0002,
|
||||
0x19a8: 0x0002,
|
||||
0x19bd: 0x0003,
|
||||
// Block 0x67, offset 0x19c0
|
||||
0x19cc: 0x0004, 0x19ce: 0x0004,
|
||||
0x19d3: 0x0004, 0x19d4: 0x0004, 0x19d5: 0x0004, 0x19d7: 0x0004,
|
||||
0x19cc: 0x0002, 0x19ce: 0x0002,
|
||||
0x19d3: 0x0002, 0x19d4: 0x0002, 0x19d5: 0x0002, 0x19d7: 0x0002,
|
||||
0x19f6: 0x0003, 0x19f7: 0x0003, 0x19f8: 0x0003, 0x19f9: 0x0003, 0x19fa: 0x0003, 0x19fb: 0x0003,
|
||||
0x19fc: 0x0003, 0x19fd: 0x0003, 0x19fe: 0x0003, 0x19ff: 0x0003,
|
||||
// Block 0x68, offset 0x1a00
|
||||
0x1a15: 0x0004, 0x1a16: 0x0004, 0x1a17: 0x0004,
|
||||
0x1a30: 0x0004,
|
||||
0x1a3f: 0x0004,
|
||||
0x1a15: 0x0002, 0x1a16: 0x0002, 0x1a17: 0x0002,
|
||||
0x1a30: 0x0002,
|
||||
0x1a3f: 0x0002,
|
||||
// Block 0x69, offset 0x1a40
|
||||
0x1a5b: 0x0004, 0x1a5c: 0x0004,
|
||||
0x1a5b: 0x0002, 0x1a5c: 0x0002,
|
||||
// Block 0x6a, offset 0x1a80
|
||||
0x1a90: 0x0004,
|
||||
0x1a95: 0x0004, 0x1a96: 0x0003, 0x1a97: 0x0003,
|
||||
0x1a90: 0x0002,
|
||||
0x1a95: 0x0002, 0x1a96: 0x0003, 0x1a97: 0x0003,
|
||||
0x1a98: 0x0003, 0x1a99: 0x0003,
|
||||
// Block 0x6b, offset 0x1ac0
|
||||
0x1aef: 0x0001,
|
||||
@@ -1273,9 +1271,9 @@ var stringWidthValues = [15808]uint8{
|
||||
0x3604: 0x0001, 0x3605: 0x0001,
|
||||
0x3606: 0x0001, 0x3607: 0x0001, 0x3608: 0x0001, 0x3609: 0x0001, 0x360a: 0x0001,
|
||||
// Block 0xd9, offset 0x3640
|
||||
0x3644: 0x0004,
|
||||
0x3644: 0x0002,
|
||||
// Block 0xda, offset 0x3680
|
||||
0x368f: 0x0004,
|
||||
0x368f: 0x0002,
|
||||
// Block 0xdb, offset 0x36c0
|
||||
0x36c0: 0x0003, 0x36c1: 0x0003, 0x36c2: 0x0003, 0x36c3: 0x0003, 0x36c4: 0x0003, 0x36c5: 0x0003,
|
||||
0x36c6: 0x0003, 0x36c7: 0x0003, 0x36c8: 0x0003, 0x36c9: 0x0003, 0x36ca: 0x0003,
|
||||
@@ -1302,246 +1300,228 @@ var stringWidthValues = [15808]uint8{
|
||||
// Block 0xdd, offset 0x3740
|
||||
0x3740: 0x0003, 0x3741: 0x0003, 0x3742: 0x0003, 0x3743: 0x0003, 0x3744: 0x0003, 0x3745: 0x0003,
|
||||
0x3746: 0x0003, 0x3747: 0x0003, 0x3748: 0x0003, 0x3749: 0x0003, 0x374a: 0x0003, 0x374b: 0x0003,
|
||||
0x374c: 0x0003, 0x374d: 0x0003, 0x374e: 0x0004, 0x374f: 0x0003, 0x3750: 0x0003, 0x3751: 0x0004,
|
||||
0x3752: 0x0004, 0x3753: 0x0004, 0x3754: 0x0004, 0x3755: 0x0004, 0x3756: 0x0004, 0x3757: 0x0004,
|
||||
0x3758: 0x0004, 0x3759: 0x0004, 0x375a: 0x0004, 0x375b: 0x0003, 0x375c: 0x0003, 0x375d: 0x0003,
|
||||
0x374c: 0x0003, 0x374d: 0x0003, 0x374e: 0x0002, 0x374f: 0x0003, 0x3750: 0x0003, 0x3751: 0x0002,
|
||||
0x3752: 0x0002, 0x3753: 0x0002, 0x3754: 0x0002, 0x3755: 0x0002, 0x3756: 0x0002, 0x3757: 0x0002,
|
||||
0x3758: 0x0002, 0x3759: 0x0002, 0x375a: 0x0002, 0x375b: 0x0003, 0x375c: 0x0003, 0x375d: 0x0003,
|
||||
0x375e: 0x0003, 0x375f: 0x0003, 0x3760: 0x0003, 0x3761: 0x0003, 0x3762: 0x0003, 0x3763: 0x0003,
|
||||
0x3764: 0x0003, 0x3765: 0x0003, 0x3766: 0x0003, 0x3767: 0x0003, 0x3768: 0x0003, 0x3769: 0x0003,
|
||||
0x376a: 0x0003, 0x376b: 0x0003, 0x376c: 0x0003,
|
||||
// Block 0xde, offset 0x3780
|
||||
0x3780: 0x0002, 0x3781: 0x0004, 0x3782: 0x0002,
|
||||
0x3790: 0x0002, 0x3791: 0x0002,
|
||||
0x3792: 0x0002, 0x3793: 0x0002, 0x3794: 0x0002, 0x3795: 0x0002, 0x3796: 0x0002, 0x3797: 0x0002,
|
||||
0x3798: 0x0002, 0x3799: 0x0002, 0x379a: 0x0004, 0x379b: 0x0002, 0x379c: 0x0002, 0x379d: 0x0002,
|
||||
0x379e: 0x0002, 0x379f: 0x0002, 0x37a0: 0x0002, 0x37a1: 0x0002, 0x37a2: 0x0002, 0x37a3: 0x0002,
|
||||
0x37a4: 0x0002, 0x37a5: 0x0002, 0x37a6: 0x0002, 0x37a7: 0x0002, 0x37a8: 0x0002, 0x37a9: 0x0002,
|
||||
0x37aa: 0x0002, 0x37ab: 0x0002, 0x37ac: 0x0002, 0x37ad: 0x0002, 0x37ae: 0x0002, 0x37af: 0x0004,
|
||||
0x37b0: 0x0002, 0x37b1: 0x0002, 0x37b2: 0x0004, 0x37b3: 0x0004, 0x37b4: 0x0004, 0x37b5: 0x0004,
|
||||
0x37b6: 0x0004, 0x37b7: 0x0002, 0x37b8: 0x0004, 0x37b9: 0x0004, 0x37ba: 0x0004, 0x37bb: 0x0002,
|
||||
0x37a6: 0x0002, 0x37a7: 0x0002, 0x37a8: 0x0002, 0x37a9: 0x0002,
|
||||
0x37aa: 0x0002, 0x37ab: 0x0002, 0x37ac: 0x0002, 0x37ad: 0x0002, 0x37ae: 0x0002, 0x37af: 0x0002,
|
||||
0x37b0: 0x0002, 0x37b1: 0x0002, 0x37b2: 0x0002, 0x37b3: 0x0002, 0x37b4: 0x0002, 0x37b5: 0x0002,
|
||||
0x37b6: 0x0002, 0x37b7: 0x0002, 0x37b8: 0x0002, 0x37b9: 0x0002, 0x37ba: 0x0002, 0x37bb: 0x0002,
|
||||
0x37bc: 0x0002, 0x37bd: 0x0002, 0x37be: 0x0002, 0x37bf: 0x0002,
|
||||
// Block 0xdf, offset 0x37c0
|
||||
0x37c0: 0x0002, 0x37c1: 0x0002, 0x37c2: 0x0002, 0x37c3: 0x0002, 0x37c4: 0x0002, 0x37c5: 0x0002,
|
||||
0x37c6: 0x0002, 0x37c7: 0x0002, 0x37c8: 0x0002,
|
||||
0x37d0: 0x0004, 0x37d1: 0x0004,
|
||||
0x37e0: 0x0002, 0x37e1: 0x0002, 0x37e2: 0x0002, 0x37e3: 0x0002,
|
||||
0x37e4: 0x0002, 0x37e5: 0x0002,
|
||||
0x37c0: 0x0002, 0x37c1: 0x0002, 0x37c2: 0x0002,
|
||||
0x37d0: 0x0002, 0x37d1: 0x0002,
|
||||
0x37d2: 0x0002, 0x37d3: 0x0002, 0x37d4: 0x0002, 0x37d5: 0x0002, 0x37d6: 0x0002, 0x37d7: 0x0002,
|
||||
0x37d8: 0x0002, 0x37d9: 0x0002, 0x37da: 0x0002, 0x37db: 0x0002, 0x37dc: 0x0002, 0x37dd: 0x0002,
|
||||
0x37de: 0x0002, 0x37df: 0x0002, 0x37e0: 0x0002, 0x37e1: 0x0002, 0x37e2: 0x0002, 0x37e3: 0x0002,
|
||||
0x37e4: 0x0002, 0x37e5: 0x0002, 0x37e6: 0x0002, 0x37e7: 0x0002, 0x37e8: 0x0002, 0x37e9: 0x0002,
|
||||
0x37ea: 0x0002, 0x37eb: 0x0002, 0x37ec: 0x0002, 0x37ed: 0x0002, 0x37ee: 0x0002, 0x37ef: 0x0002,
|
||||
0x37f0: 0x0002, 0x37f1: 0x0002, 0x37f2: 0x0002, 0x37f3: 0x0002, 0x37f4: 0x0002, 0x37f5: 0x0002,
|
||||
0x37f6: 0x0002, 0x37f7: 0x0002, 0x37f8: 0x0002, 0x37f9: 0x0002, 0x37fa: 0x0002, 0x37fb: 0x0002,
|
||||
// Block 0xe0, offset 0x3800
|
||||
0x3800: 0x0004, 0x3801: 0x0004, 0x3802: 0x0004, 0x3803: 0x0004, 0x3804: 0x0004, 0x3805: 0x0004,
|
||||
0x3806: 0x0004, 0x3807: 0x0004, 0x3808: 0x0004, 0x3809: 0x0004, 0x380a: 0x0004, 0x380b: 0x0004,
|
||||
0x380c: 0x0004, 0x380d: 0x0004, 0x380e: 0x0004, 0x380f: 0x0004, 0x3810: 0x0004, 0x3811: 0x0004,
|
||||
0x3812: 0x0004, 0x3813: 0x0004, 0x3814: 0x0004, 0x3815: 0x0004, 0x3816: 0x0004, 0x3817: 0x0004,
|
||||
0x3818: 0x0004, 0x3819: 0x0004, 0x381a: 0x0004, 0x381b: 0x0004, 0x381c: 0x0004, 0x381d: 0x0004,
|
||||
0x381e: 0x0004, 0x381f: 0x0004, 0x3820: 0x0004,
|
||||
0x382d: 0x0004, 0x382e: 0x0004, 0x382f: 0x0004,
|
||||
0x3830: 0x0004, 0x3831: 0x0004, 0x3832: 0x0004, 0x3833: 0x0004, 0x3834: 0x0004, 0x3835: 0x0004,
|
||||
0x3837: 0x0004, 0x3838: 0x0004, 0x3839: 0x0004, 0x383a: 0x0004, 0x383b: 0x0004,
|
||||
0x383c: 0x0004, 0x383d: 0x0004, 0x383e: 0x0004, 0x383f: 0x0004,
|
||||
0x3800: 0x0002, 0x3801: 0x0002, 0x3802: 0x0002, 0x3803: 0x0002, 0x3804: 0x0002, 0x3805: 0x0002,
|
||||
0x3806: 0x0002, 0x3807: 0x0002, 0x3808: 0x0002,
|
||||
0x3810: 0x0002, 0x3811: 0x0002,
|
||||
0x3820: 0x0002, 0x3821: 0x0002, 0x3822: 0x0002, 0x3823: 0x0002,
|
||||
0x3824: 0x0002, 0x3825: 0x0002,
|
||||
// Block 0xe1, offset 0x3840
|
||||
0x3840: 0x0004, 0x3841: 0x0004, 0x3842: 0x0004, 0x3843: 0x0004, 0x3844: 0x0004, 0x3845: 0x0004,
|
||||
0x3846: 0x0004, 0x3847: 0x0004, 0x3848: 0x0004, 0x3849: 0x0004, 0x384a: 0x0004, 0x384b: 0x0004,
|
||||
0x384c: 0x0004, 0x384d: 0x0004, 0x384e: 0x0004, 0x384f: 0x0004, 0x3850: 0x0004, 0x3851: 0x0004,
|
||||
0x3852: 0x0004, 0x3853: 0x0004, 0x3854: 0x0004, 0x3855: 0x0004, 0x3856: 0x0004, 0x3857: 0x0004,
|
||||
0x3858: 0x0004, 0x3859: 0x0004, 0x385a: 0x0004, 0x385b: 0x0004, 0x385c: 0x0004, 0x385d: 0x0004,
|
||||
0x385e: 0x0004, 0x385f: 0x0004, 0x3860: 0x0004, 0x3861: 0x0004, 0x3862: 0x0004, 0x3863: 0x0004,
|
||||
0x3864: 0x0004, 0x3865: 0x0004, 0x3866: 0x0004, 0x3867: 0x0004, 0x3868: 0x0004, 0x3869: 0x0004,
|
||||
0x386a: 0x0004, 0x386b: 0x0004, 0x386c: 0x0004, 0x386d: 0x0004, 0x386e: 0x0004, 0x386f: 0x0004,
|
||||
0x3870: 0x0004, 0x3871: 0x0004, 0x3872: 0x0004, 0x3873: 0x0004, 0x3874: 0x0004, 0x3875: 0x0004,
|
||||
0x3876: 0x0004, 0x3877: 0x0004, 0x3878: 0x0004, 0x3879: 0x0004, 0x387a: 0x0004, 0x387b: 0x0004,
|
||||
0x387c: 0x0004, 0x387e: 0x0004, 0x387f: 0x0004,
|
||||
0x3840: 0x0002, 0x3841: 0x0002, 0x3842: 0x0002, 0x3843: 0x0002, 0x3844: 0x0002, 0x3845: 0x0002,
|
||||
0x3846: 0x0002, 0x3847: 0x0002, 0x3848: 0x0002, 0x3849: 0x0002, 0x384a: 0x0002, 0x384b: 0x0002,
|
||||
0x384c: 0x0002, 0x384d: 0x0002, 0x384e: 0x0002, 0x384f: 0x0002, 0x3850: 0x0002, 0x3851: 0x0002,
|
||||
0x3852: 0x0002, 0x3853: 0x0002, 0x3854: 0x0002, 0x3855: 0x0002, 0x3856: 0x0002, 0x3857: 0x0002,
|
||||
0x3858: 0x0002, 0x3859: 0x0002, 0x385a: 0x0002, 0x385b: 0x0002, 0x385c: 0x0002, 0x385d: 0x0002,
|
||||
0x385e: 0x0002, 0x385f: 0x0002, 0x3860: 0x0002,
|
||||
0x386d: 0x0002, 0x386e: 0x0002, 0x386f: 0x0002,
|
||||
0x3870: 0x0002, 0x3871: 0x0002, 0x3872: 0x0002, 0x3873: 0x0002, 0x3874: 0x0002, 0x3875: 0x0002,
|
||||
0x3877: 0x0002, 0x3878: 0x0002, 0x3879: 0x0002, 0x387a: 0x0002, 0x387b: 0x0002,
|
||||
0x387c: 0x0002, 0x387d: 0x0002, 0x387e: 0x0002, 0x387f: 0x0002,
|
||||
// Block 0xe2, offset 0x3880
|
||||
0x3880: 0x0004, 0x3881: 0x0004, 0x3882: 0x0004, 0x3883: 0x0004, 0x3884: 0x0004, 0x3885: 0x0004,
|
||||
0x3886: 0x0004, 0x3887: 0x0004, 0x3888: 0x0004, 0x3889: 0x0004, 0x388a: 0x0004, 0x388b: 0x0004,
|
||||
0x388c: 0x0004, 0x388d: 0x0004, 0x388e: 0x0004, 0x388f: 0x0004, 0x3890: 0x0004, 0x3891: 0x0004,
|
||||
0x3892: 0x0004, 0x3893: 0x0004,
|
||||
0x38a0: 0x0004, 0x38a1: 0x0004, 0x38a2: 0x0004, 0x38a3: 0x0004,
|
||||
0x38a4: 0x0004, 0x38a5: 0x0004, 0x38a6: 0x0004, 0x38a7: 0x0004, 0x38a8: 0x0004, 0x38a9: 0x0004,
|
||||
0x38aa: 0x0004, 0x38ab: 0x0004, 0x38ac: 0x0004, 0x38ad: 0x0004, 0x38ae: 0x0004, 0x38af: 0x0004,
|
||||
0x38b0: 0x0004, 0x38b1: 0x0004, 0x38b2: 0x0004, 0x38b3: 0x0004, 0x38b4: 0x0004, 0x38b5: 0x0004,
|
||||
0x38b6: 0x0004, 0x38b7: 0x0004, 0x38b8: 0x0004, 0x38b9: 0x0004, 0x38ba: 0x0004, 0x38bb: 0x0004,
|
||||
0x38bc: 0x0004, 0x38bd: 0x0004, 0x38be: 0x0004, 0x38bf: 0x0004,
|
||||
0x3880: 0x0002, 0x3881: 0x0002, 0x3882: 0x0002, 0x3883: 0x0002, 0x3884: 0x0002, 0x3885: 0x0002,
|
||||
0x3886: 0x0002, 0x3887: 0x0002, 0x3888: 0x0002, 0x3889: 0x0002, 0x388a: 0x0002, 0x388b: 0x0002,
|
||||
0x388c: 0x0002, 0x388d: 0x0002, 0x388e: 0x0002, 0x388f: 0x0002, 0x3890: 0x0002, 0x3891: 0x0002,
|
||||
0x3892: 0x0002, 0x3893: 0x0002, 0x3894: 0x0002, 0x3895: 0x0002, 0x3896: 0x0002, 0x3897: 0x0002,
|
||||
0x3898: 0x0002, 0x3899: 0x0002, 0x389a: 0x0002, 0x389b: 0x0002, 0x389c: 0x0002, 0x389d: 0x0002,
|
||||
0x389e: 0x0002, 0x389f: 0x0002, 0x38a0: 0x0002, 0x38a1: 0x0002, 0x38a2: 0x0002, 0x38a3: 0x0002,
|
||||
0x38a4: 0x0002, 0x38a5: 0x0002, 0x38a6: 0x0002, 0x38a7: 0x0002, 0x38a8: 0x0002, 0x38a9: 0x0002,
|
||||
0x38aa: 0x0002, 0x38ab: 0x0002, 0x38ac: 0x0002, 0x38ad: 0x0002, 0x38ae: 0x0002, 0x38af: 0x0002,
|
||||
0x38b0: 0x0002, 0x38b1: 0x0002, 0x38b2: 0x0002, 0x38b3: 0x0002, 0x38b4: 0x0002, 0x38b5: 0x0002,
|
||||
0x38b6: 0x0002, 0x38b7: 0x0002, 0x38b8: 0x0002, 0x38b9: 0x0002, 0x38ba: 0x0002, 0x38bb: 0x0002,
|
||||
0x38bc: 0x0002, 0x38be: 0x0002, 0x38bf: 0x0002,
|
||||
// Block 0xe3, offset 0x38c0
|
||||
0x38c0: 0x0004, 0x38c1: 0x0004, 0x38c2: 0x0004, 0x38c3: 0x0004, 0x38c4: 0x0004, 0x38c5: 0x0004,
|
||||
0x38c6: 0x0004, 0x38c7: 0x0004, 0x38c8: 0x0004, 0x38c9: 0x0004, 0x38ca: 0x0004,
|
||||
0x38cf: 0x0004, 0x38d0: 0x0004, 0x38d1: 0x0004,
|
||||
0x38d2: 0x0004, 0x38d3: 0x0004,
|
||||
0x38e0: 0x0004, 0x38e1: 0x0004, 0x38e2: 0x0004, 0x38e3: 0x0004,
|
||||
0x38e4: 0x0004, 0x38e5: 0x0004, 0x38e6: 0x0004, 0x38e7: 0x0004, 0x38e8: 0x0004, 0x38e9: 0x0004,
|
||||
0x38ea: 0x0004, 0x38eb: 0x0004, 0x38ec: 0x0004, 0x38ed: 0x0004, 0x38ee: 0x0004, 0x38ef: 0x0004,
|
||||
0x38f0: 0x0004, 0x38f4: 0x0004,
|
||||
0x38f8: 0x0004, 0x38f9: 0x0004, 0x38fa: 0x0004, 0x38fb: 0x0002,
|
||||
0x38c0: 0x0002, 0x38c1: 0x0002, 0x38c2: 0x0002, 0x38c3: 0x0002, 0x38c4: 0x0002, 0x38c5: 0x0002,
|
||||
0x38c6: 0x0002, 0x38c7: 0x0002, 0x38c8: 0x0002, 0x38c9: 0x0002, 0x38ca: 0x0002, 0x38cb: 0x0002,
|
||||
0x38cc: 0x0002, 0x38cd: 0x0002, 0x38ce: 0x0002, 0x38cf: 0x0002, 0x38d0: 0x0002, 0x38d1: 0x0002,
|
||||
0x38d2: 0x0002, 0x38d3: 0x0002,
|
||||
0x38e0: 0x0002, 0x38e1: 0x0002, 0x38e2: 0x0002, 0x38e3: 0x0002,
|
||||
0x38e4: 0x0002, 0x38e5: 0x0002, 0x38e6: 0x0002, 0x38e7: 0x0002, 0x38e8: 0x0002, 0x38e9: 0x0002,
|
||||
0x38ea: 0x0002, 0x38eb: 0x0002, 0x38ec: 0x0002, 0x38ed: 0x0002, 0x38ee: 0x0002, 0x38ef: 0x0002,
|
||||
0x38f0: 0x0002, 0x38f1: 0x0002, 0x38f2: 0x0002, 0x38f3: 0x0002, 0x38f4: 0x0002, 0x38f5: 0x0002,
|
||||
0x38f6: 0x0002, 0x38f7: 0x0002, 0x38f8: 0x0002, 0x38f9: 0x0002, 0x38fa: 0x0002, 0x38fb: 0x0002,
|
||||
0x38fc: 0x0002, 0x38fd: 0x0002, 0x38fe: 0x0002, 0x38ff: 0x0002,
|
||||
// Block 0xe4, offset 0x3900
|
||||
0x3900: 0x0004, 0x3901: 0x0004, 0x3902: 0x0004, 0x3903: 0x0004, 0x3904: 0x0004, 0x3905: 0x0004,
|
||||
0x3906: 0x0004, 0x3907: 0x0004, 0x3908: 0x0004, 0x3909: 0x0004, 0x390a: 0x0004, 0x390b: 0x0004,
|
||||
0x390c: 0x0004, 0x390d: 0x0004, 0x390e: 0x0004, 0x390f: 0x0004, 0x3910: 0x0004, 0x3911: 0x0004,
|
||||
0x3912: 0x0004, 0x3913: 0x0004, 0x3914: 0x0004, 0x3915: 0x0004, 0x3916: 0x0004, 0x3917: 0x0004,
|
||||
0x3918: 0x0004, 0x3919: 0x0004, 0x391a: 0x0004, 0x391b: 0x0004, 0x391c: 0x0004, 0x391d: 0x0004,
|
||||
0x391e: 0x0004, 0x391f: 0x0004, 0x3920: 0x0004, 0x3921: 0x0004, 0x3922: 0x0004, 0x3923: 0x0004,
|
||||
0x3924: 0x0004, 0x3925: 0x0004, 0x3926: 0x0004, 0x3927: 0x0004, 0x3928: 0x0004, 0x3929: 0x0004,
|
||||
0x392a: 0x0004, 0x392b: 0x0004, 0x392c: 0x0004, 0x392d: 0x0004, 0x392e: 0x0004, 0x392f: 0x0004,
|
||||
0x3930: 0x0004, 0x3931: 0x0004, 0x3932: 0x0004, 0x3933: 0x0004, 0x3934: 0x0004, 0x3935: 0x0004,
|
||||
0x3936: 0x0004, 0x3937: 0x0004, 0x3938: 0x0004, 0x3939: 0x0004, 0x393a: 0x0004, 0x393b: 0x0004,
|
||||
0x393c: 0x0004, 0x393d: 0x0004, 0x393e: 0x0004,
|
||||
0x3900: 0x0002, 0x3901: 0x0002, 0x3902: 0x0002, 0x3903: 0x0002, 0x3904: 0x0002, 0x3905: 0x0002,
|
||||
0x3906: 0x0002, 0x3907: 0x0002, 0x3908: 0x0002, 0x3909: 0x0002, 0x390a: 0x0002,
|
||||
0x390f: 0x0002, 0x3910: 0x0002, 0x3911: 0x0002,
|
||||
0x3912: 0x0002, 0x3913: 0x0002,
|
||||
0x3920: 0x0002, 0x3921: 0x0002, 0x3922: 0x0002, 0x3923: 0x0002,
|
||||
0x3924: 0x0002, 0x3925: 0x0002, 0x3926: 0x0002, 0x3927: 0x0002, 0x3928: 0x0002, 0x3929: 0x0002,
|
||||
0x392a: 0x0002, 0x392b: 0x0002, 0x392c: 0x0002, 0x392d: 0x0002, 0x392e: 0x0002, 0x392f: 0x0002,
|
||||
0x3930: 0x0002, 0x3934: 0x0002,
|
||||
0x3938: 0x0002, 0x3939: 0x0002, 0x393a: 0x0002, 0x393b: 0x0002,
|
||||
0x393c: 0x0002, 0x393d: 0x0002, 0x393e: 0x0002, 0x393f: 0x0002,
|
||||
// Block 0xe5, offset 0x3940
|
||||
0x3940: 0x0004, 0x3942: 0x0004, 0x3943: 0x0004, 0x3944: 0x0004, 0x3945: 0x0004,
|
||||
0x3946: 0x0004, 0x3947: 0x0004, 0x3948: 0x0004, 0x3949: 0x0004, 0x394a: 0x0004, 0x394b: 0x0004,
|
||||
0x394c: 0x0004, 0x394d: 0x0004, 0x394e: 0x0004, 0x394f: 0x0004, 0x3950: 0x0004, 0x3951: 0x0004,
|
||||
0x3952: 0x0004, 0x3953: 0x0004, 0x3954: 0x0004, 0x3955: 0x0004, 0x3956: 0x0004, 0x3957: 0x0004,
|
||||
0x3958: 0x0004, 0x3959: 0x0004, 0x395a: 0x0004, 0x395b: 0x0004, 0x395c: 0x0004, 0x395d: 0x0004,
|
||||
0x395e: 0x0004, 0x395f: 0x0004, 0x3960: 0x0004, 0x3961: 0x0004, 0x3962: 0x0004, 0x3963: 0x0004,
|
||||
0x3964: 0x0004, 0x3965: 0x0004, 0x3966: 0x0004, 0x3967: 0x0004, 0x3968: 0x0004, 0x3969: 0x0004,
|
||||
0x396a: 0x0004, 0x396b: 0x0004, 0x396c: 0x0004, 0x396d: 0x0004, 0x396e: 0x0004, 0x396f: 0x0004,
|
||||
0x3970: 0x0004, 0x3971: 0x0004, 0x3972: 0x0004, 0x3973: 0x0004, 0x3974: 0x0004, 0x3975: 0x0004,
|
||||
0x3976: 0x0004, 0x3977: 0x0004, 0x3978: 0x0004, 0x3979: 0x0004, 0x397a: 0x0004, 0x397b: 0x0004,
|
||||
0x397c: 0x0004, 0x397d: 0x0004, 0x397e: 0x0004, 0x397f: 0x0004,
|
||||
0x3940: 0x0002, 0x3941: 0x0002, 0x3942: 0x0002, 0x3943: 0x0002, 0x3944: 0x0002, 0x3945: 0x0002,
|
||||
0x3946: 0x0002, 0x3947: 0x0002, 0x3948: 0x0002, 0x3949: 0x0002, 0x394a: 0x0002, 0x394b: 0x0002,
|
||||
0x394c: 0x0002, 0x394d: 0x0002, 0x394e: 0x0002, 0x394f: 0x0002, 0x3950: 0x0002, 0x3951: 0x0002,
|
||||
0x3952: 0x0002, 0x3953: 0x0002, 0x3954: 0x0002, 0x3955: 0x0002, 0x3956: 0x0002, 0x3957: 0x0002,
|
||||
0x3958: 0x0002, 0x3959: 0x0002, 0x395a: 0x0002, 0x395b: 0x0002, 0x395c: 0x0002, 0x395d: 0x0002,
|
||||
0x395e: 0x0002, 0x395f: 0x0002, 0x3960: 0x0002, 0x3961: 0x0002, 0x3962: 0x0002, 0x3963: 0x0002,
|
||||
0x3964: 0x0002, 0x3965: 0x0002, 0x3966: 0x0002, 0x3967: 0x0002, 0x3968: 0x0002, 0x3969: 0x0002,
|
||||
0x396a: 0x0002, 0x396b: 0x0002, 0x396c: 0x0002, 0x396d: 0x0002, 0x396e: 0x0002, 0x396f: 0x0002,
|
||||
0x3970: 0x0002, 0x3971: 0x0002, 0x3972: 0x0002, 0x3973: 0x0002, 0x3974: 0x0002, 0x3975: 0x0002,
|
||||
0x3976: 0x0002, 0x3977: 0x0002, 0x3978: 0x0002, 0x3979: 0x0002, 0x397a: 0x0002, 0x397b: 0x0002,
|
||||
0x397c: 0x0002, 0x397d: 0x0002, 0x397e: 0x0002,
|
||||
// Block 0xe6, offset 0x3980
|
||||
0x3980: 0x0004, 0x3981: 0x0004, 0x3982: 0x0004, 0x3983: 0x0004, 0x3984: 0x0004, 0x3985: 0x0004,
|
||||
0x3986: 0x0004, 0x3987: 0x0004, 0x3988: 0x0004, 0x3989: 0x0004, 0x398a: 0x0004, 0x398b: 0x0004,
|
||||
0x398c: 0x0004, 0x398d: 0x0004, 0x398e: 0x0004, 0x398f: 0x0004, 0x3990: 0x0004, 0x3991: 0x0004,
|
||||
0x3992: 0x0004, 0x3993: 0x0004, 0x3994: 0x0004, 0x3995: 0x0004, 0x3996: 0x0004, 0x3997: 0x0004,
|
||||
0x3998: 0x0004, 0x3999: 0x0004, 0x399a: 0x0004, 0x399b: 0x0004, 0x399c: 0x0004, 0x399d: 0x0004,
|
||||
0x399e: 0x0004, 0x399f: 0x0004, 0x39a0: 0x0004, 0x39a1: 0x0004, 0x39a2: 0x0004, 0x39a3: 0x0004,
|
||||
0x39a4: 0x0004, 0x39a5: 0x0004, 0x39a6: 0x0004, 0x39a7: 0x0004, 0x39a8: 0x0004, 0x39a9: 0x0004,
|
||||
0x39aa: 0x0004, 0x39ab: 0x0004, 0x39ac: 0x0004, 0x39ad: 0x0004, 0x39ae: 0x0004, 0x39af: 0x0004,
|
||||
0x39b0: 0x0004, 0x39b1: 0x0004, 0x39b2: 0x0004, 0x39b3: 0x0004, 0x39b4: 0x0004, 0x39b5: 0x0004,
|
||||
0x39b6: 0x0004, 0x39b7: 0x0004, 0x39b8: 0x0004, 0x39b9: 0x0004, 0x39ba: 0x0004, 0x39bb: 0x0004,
|
||||
0x39bc: 0x0004, 0x39bd: 0x0004, 0x39be: 0x0004, 0x39bf: 0x0004,
|
||||
0x3980: 0x0002, 0x3982: 0x0002, 0x3983: 0x0002, 0x3984: 0x0002, 0x3985: 0x0002,
|
||||
0x3986: 0x0002, 0x3987: 0x0002, 0x3988: 0x0002, 0x3989: 0x0002, 0x398a: 0x0002, 0x398b: 0x0002,
|
||||
0x398c: 0x0002, 0x398d: 0x0002, 0x398e: 0x0002, 0x398f: 0x0002, 0x3990: 0x0002, 0x3991: 0x0002,
|
||||
0x3992: 0x0002, 0x3993: 0x0002, 0x3994: 0x0002, 0x3995: 0x0002, 0x3996: 0x0002, 0x3997: 0x0002,
|
||||
0x3998: 0x0002, 0x3999: 0x0002, 0x399a: 0x0002, 0x399b: 0x0002, 0x399c: 0x0002, 0x399d: 0x0002,
|
||||
0x399e: 0x0002, 0x399f: 0x0002, 0x39a0: 0x0002, 0x39a1: 0x0002, 0x39a2: 0x0002, 0x39a3: 0x0002,
|
||||
0x39a4: 0x0002, 0x39a5: 0x0002, 0x39a6: 0x0002, 0x39a7: 0x0002, 0x39a8: 0x0002, 0x39a9: 0x0002,
|
||||
0x39aa: 0x0002, 0x39ab: 0x0002, 0x39ac: 0x0002, 0x39ad: 0x0002, 0x39ae: 0x0002, 0x39af: 0x0002,
|
||||
0x39b0: 0x0002, 0x39b1: 0x0002, 0x39b2: 0x0002, 0x39b3: 0x0002, 0x39b4: 0x0002, 0x39b5: 0x0002,
|
||||
0x39b6: 0x0002, 0x39b7: 0x0002, 0x39b8: 0x0002, 0x39b9: 0x0002, 0x39ba: 0x0002, 0x39bb: 0x0002,
|
||||
0x39bc: 0x0002, 0x39bd: 0x0002, 0x39be: 0x0002, 0x39bf: 0x0002,
|
||||
// Block 0xe7, offset 0x39c0
|
||||
0x39c0: 0x0004, 0x39c1: 0x0004, 0x39c2: 0x0004, 0x39c3: 0x0004, 0x39c4: 0x0004, 0x39c5: 0x0004,
|
||||
0x39c6: 0x0004, 0x39c7: 0x0004, 0x39c8: 0x0004, 0x39c9: 0x0004, 0x39ca: 0x0004, 0x39cb: 0x0004,
|
||||
0x39cc: 0x0004, 0x39cd: 0x0004, 0x39ce: 0x0004, 0x39cf: 0x0004, 0x39d0: 0x0004, 0x39d1: 0x0004,
|
||||
0x39d2: 0x0004, 0x39d3: 0x0004, 0x39d4: 0x0004, 0x39d5: 0x0004, 0x39d6: 0x0004, 0x39d7: 0x0004,
|
||||
0x39d8: 0x0004, 0x39d9: 0x0004, 0x39da: 0x0004, 0x39db: 0x0004, 0x39dc: 0x0004, 0x39dd: 0x0004,
|
||||
0x39de: 0x0004, 0x39df: 0x0004, 0x39e0: 0x0004, 0x39e1: 0x0004, 0x39e2: 0x0004, 0x39e3: 0x0004,
|
||||
0x39e4: 0x0004, 0x39e5: 0x0004, 0x39e6: 0x0004, 0x39e7: 0x0004, 0x39e8: 0x0004, 0x39e9: 0x0004,
|
||||
0x39ea: 0x0004, 0x39eb: 0x0004, 0x39ec: 0x0004, 0x39ed: 0x0004, 0x39ee: 0x0004, 0x39ef: 0x0004,
|
||||
0x39f0: 0x0004, 0x39f1: 0x0004, 0x39f2: 0x0004, 0x39f3: 0x0004, 0x39f4: 0x0004, 0x39f5: 0x0004,
|
||||
0x39f6: 0x0004, 0x39f7: 0x0004, 0x39f8: 0x0004, 0x39f9: 0x0004, 0x39fa: 0x0004, 0x39fb: 0x0004,
|
||||
0x39fc: 0x0004, 0x39ff: 0x0004,
|
||||
0x39c0: 0x0002, 0x39c1: 0x0002, 0x39c2: 0x0002, 0x39c3: 0x0002, 0x39c4: 0x0002, 0x39c5: 0x0002,
|
||||
0x39c6: 0x0002, 0x39c7: 0x0002, 0x39c8: 0x0002, 0x39c9: 0x0002, 0x39ca: 0x0002, 0x39cb: 0x0002,
|
||||
0x39cc: 0x0002, 0x39cd: 0x0002, 0x39ce: 0x0002, 0x39cf: 0x0002, 0x39d0: 0x0002, 0x39d1: 0x0002,
|
||||
0x39d2: 0x0002, 0x39d3: 0x0002, 0x39d4: 0x0002, 0x39d5: 0x0002, 0x39d6: 0x0002, 0x39d7: 0x0002,
|
||||
0x39d8: 0x0002, 0x39d9: 0x0002, 0x39da: 0x0002, 0x39db: 0x0002, 0x39dc: 0x0002, 0x39dd: 0x0002,
|
||||
0x39de: 0x0002, 0x39df: 0x0002, 0x39e0: 0x0002, 0x39e1: 0x0002, 0x39e2: 0x0002, 0x39e3: 0x0002,
|
||||
0x39e4: 0x0002, 0x39e5: 0x0002, 0x39e6: 0x0002, 0x39e7: 0x0002, 0x39e8: 0x0002, 0x39e9: 0x0002,
|
||||
0x39ea: 0x0002, 0x39eb: 0x0002, 0x39ec: 0x0002, 0x39ed: 0x0002, 0x39ee: 0x0002, 0x39ef: 0x0002,
|
||||
0x39f0: 0x0002, 0x39f1: 0x0002, 0x39f2: 0x0002, 0x39f3: 0x0002, 0x39f4: 0x0002, 0x39f5: 0x0002,
|
||||
0x39f6: 0x0002, 0x39f7: 0x0002, 0x39f8: 0x0002, 0x39f9: 0x0002, 0x39fa: 0x0002, 0x39fb: 0x0002,
|
||||
0x39fc: 0x0002, 0x39ff: 0x0002,
|
||||
// Block 0xe8, offset 0x3a00
|
||||
0x3a00: 0x0004, 0x3a01: 0x0004, 0x3a02: 0x0004, 0x3a03: 0x0004, 0x3a04: 0x0004, 0x3a05: 0x0004,
|
||||
0x3a06: 0x0004, 0x3a07: 0x0004, 0x3a08: 0x0004, 0x3a09: 0x0004, 0x3a0a: 0x0004, 0x3a0b: 0x0004,
|
||||
0x3a0c: 0x0004, 0x3a0d: 0x0004, 0x3a0e: 0x0004, 0x3a0f: 0x0004, 0x3a10: 0x0004, 0x3a11: 0x0004,
|
||||
0x3a12: 0x0004, 0x3a13: 0x0004, 0x3a14: 0x0004, 0x3a15: 0x0004, 0x3a16: 0x0004, 0x3a17: 0x0004,
|
||||
0x3a18: 0x0004, 0x3a19: 0x0004, 0x3a1a: 0x0004, 0x3a1b: 0x0004, 0x3a1c: 0x0004, 0x3a1d: 0x0004,
|
||||
0x3a1e: 0x0004, 0x3a1f: 0x0004, 0x3a20: 0x0004, 0x3a21: 0x0004, 0x3a22: 0x0004, 0x3a23: 0x0004,
|
||||
0x3a24: 0x0004, 0x3a25: 0x0004, 0x3a26: 0x0004, 0x3a27: 0x0004, 0x3a28: 0x0004, 0x3a29: 0x0004,
|
||||
0x3a2a: 0x0004, 0x3a2b: 0x0004, 0x3a2c: 0x0004, 0x3a2d: 0x0004, 0x3a2e: 0x0004, 0x3a2f: 0x0004,
|
||||
0x3a30: 0x0004, 0x3a31: 0x0004, 0x3a32: 0x0004, 0x3a33: 0x0004, 0x3a34: 0x0004, 0x3a35: 0x0004,
|
||||
0x3a36: 0x0004, 0x3a37: 0x0004, 0x3a38: 0x0004, 0x3a39: 0x0004, 0x3a3a: 0x0004, 0x3a3b: 0x0004,
|
||||
0x3a3c: 0x0004, 0x3a3d: 0x0004,
|
||||
0x3a00: 0x0002, 0x3a01: 0x0002, 0x3a02: 0x0002, 0x3a03: 0x0002, 0x3a04: 0x0002, 0x3a05: 0x0002,
|
||||
0x3a06: 0x0002, 0x3a07: 0x0002, 0x3a08: 0x0002, 0x3a09: 0x0002, 0x3a0a: 0x0002, 0x3a0b: 0x0002,
|
||||
0x3a0c: 0x0002, 0x3a0d: 0x0002, 0x3a0e: 0x0002, 0x3a0f: 0x0002, 0x3a10: 0x0002, 0x3a11: 0x0002,
|
||||
0x3a12: 0x0002, 0x3a13: 0x0002, 0x3a14: 0x0002, 0x3a15: 0x0002, 0x3a16: 0x0002, 0x3a17: 0x0002,
|
||||
0x3a18: 0x0002, 0x3a19: 0x0002, 0x3a1a: 0x0002, 0x3a1b: 0x0002, 0x3a1c: 0x0002, 0x3a1d: 0x0002,
|
||||
0x3a1e: 0x0002, 0x3a1f: 0x0002, 0x3a20: 0x0002, 0x3a21: 0x0002, 0x3a22: 0x0002, 0x3a23: 0x0002,
|
||||
0x3a24: 0x0002, 0x3a25: 0x0002, 0x3a26: 0x0002, 0x3a27: 0x0002, 0x3a28: 0x0002, 0x3a29: 0x0002,
|
||||
0x3a2a: 0x0002, 0x3a2b: 0x0002, 0x3a2c: 0x0002, 0x3a2d: 0x0002, 0x3a2e: 0x0002, 0x3a2f: 0x0002,
|
||||
0x3a30: 0x0002, 0x3a31: 0x0002, 0x3a32: 0x0002, 0x3a33: 0x0002, 0x3a34: 0x0002, 0x3a35: 0x0002,
|
||||
0x3a36: 0x0002, 0x3a37: 0x0002, 0x3a38: 0x0002, 0x3a39: 0x0002, 0x3a3a: 0x0002, 0x3a3b: 0x0002,
|
||||
0x3a3c: 0x0002, 0x3a3d: 0x0002,
|
||||
// Block 0xe9, offset 0x3a40
|
||||
0x3a4b: 0x0004,
|
||||
0x3a4c: 0x0004, 0x3a4d: 0x0004, 0x3a4e: 0x0004, 0x3a50: 0x0004, 0x3a51: 0x0004,
|
||||
0x3a52: 0x0004, 0x3a53: 0x0004, 0x3a54: 0x0004, 0x3a55: 0x0004, 0x3a56: 0x0004, 0x3a57: 0x0004,
|
||||
0x3a58: 0x0004, 0x3a59: 0x0004, 0x3a5a: 0x0004, 0x3a5b: 0x0004, 0x3a5c: 0x0004, 0x3a5d: 0x0004,
|
||||
0x3a5e: 0x0004, 0x3a5f: 0x0004, 0x3a60: 0x0004, 0x3a61: 0x0004, 0x3a62: 0x0004, 0x3a63: 0x0004,
|
||||
0x3a64: 0x0004, 0x3a65: 0x0004, 0x3a66: 0x0004, 0x3a67: 0x0004,
|
||||
0x3a7a: 0x0004,
|
||||
0x3a4b: 0x0002,
|
||||
0x3a4c: 0x0002, 0x3a4d: 0x0002, 0x3a4e: 0x0002, 0x3a50: 0x0002, 0x3a51: 0x0002,
|
||||
0x3a52: 0x0002, 0x3a53: 0x0002, 0x3a54: 0x0002, 0x3a55: 0x0002, 0x3a56: 0x0002, 0x3a57: 0x0002,
|
||||
0x3a58: 0x0002, 0x3a59: 0x0002, 0x3a5a: 0x0002, 0x3a5b: 0x0002, 0x3a5c: 0x0002, 0x3a5d: 0x0002,
|
||||
0x3a5e: 0x0002, 0x3a5f: 0x0002, 0x3a60: 0x0002, 0x3a61: 0x0002, 0x3a62: 0x0002, 0x3a63: 0x0002,
|
||||
0x3a64: 0x0002, 0x3a65: 0x0002, 0x3a66: 0x0002, 0x3a67: 0x0002,
|
||||
0x3a7a: 0x0002,
|
||||
// Block 0xea, offset 0x3a80
|
||||
0x3a95: 0x0004, 0x3a96: 0x0004,
|
||||
0x3aa4: 0x0004,
|
||||
0x3a95: 0x0002, 0x3a96: 0x0002,
|
||||
0x3aa4: 0x0002,
|
||||
// Block 0xeb, offset 0x3ac0
|
||||
0x3afb: 0x0004,
|
||||
0x3afc: 0x0004, 0x3afd: 0x0004, 0x3afe: 0x0004, 0x3aff: 0x0004,
|
||||
0x3afb: 0x0002,
|
||||
0x3afc: 0x0002, 0x3afd: 0x0002, 0x3afe: 0x0002, 0x3aff: 0x0002,
|
||||
// Block 0xec, offset 0x3b00
|
||||
0x3b00: 0x0004, 0x3b01: 0x0004, 0x3b02: 0x0004, 0x3b03: 0x0004, 0x3b04: 0x0004, 0x3b05: 0x0004,
|
||||
0x3b06: 0x0004, 0x3b07: 0x0004, 0x3b08: 0x0004, 0x3b09: 0x0004, 0x3b0a: 0x0004, 0x3b0b: 0x0004,
|
||||
0x3b0c: 0x0004, 0x3b0d: 0x0004, 0x3b0e: 0x0004, 0x3b0f: 0x0004,
|
||||
0x3b00: 0x0002, 0x3b01: 0x0002, 0x3b02: 0x0002, 0x3b03: 0x0002, 0x3b04: 0x0002, 0x3b05: 0x0002,
|
||||
0x3b06: 0x0002, 0x3b07: 0x0002, 0x3b08: 0x0002, 0x3b09: 0x0002, 0x3b0a: 0x0002, 0x3b0b: 0x0002,
|
||||
0x3b0c: 0x0002, 0x3b0d: 0x0002, 0x3b0e: 0x0002, 0x3b0f: 0x0002,
|
||||
// Block 0xed, offset 0x3b40
|
||||
0x3b40: 0x0004, 0x3b41: 0x0004, 0x3b42: 0x0004, 0x3b43: 0x0004, 0x3b44: 0x0004, 0x3b45: 0x0004,
|
||||
0x3b4c: 0x0004, 0x3b50: 0x0004, 0x3b51: 0x0004,
|
||||
0x3b52: 0x0004, 0x3b55: 0x0004, 0x3b56: 0x0004, 0x3b57: 0x0004,
|
||||
0x3b5c: 0x0004, 0x3b5d: 0x0004,
|
||||
0x3b5e: 0x0004, 0x3b5f: 0x0004,
|
||||
0x3b6b: 0x0004, 0x3b6c: 0x0004,
|
||||
0x3b74: 0x0004, 0x3b75: 0x0004,
|
||||
0x3b76: 0x0004, 0x3b77: 0x0004, 0x3b78: 0x0004, 0x3b79: 0x0004, 0x3b7a: 0x0004, 0x3b7b: 0x0004,
|
||||
0x3b7c: 0x0004,
|
||||
0x3b40: 0x0002, 0x3b41: 0x0002, 0x3b42: 0x0002, 0x3b43: 0x0002, 0x3b44: 0x0002, 0x3b45: 0x0002,
|
||||
0x3b4c: 0x0002, 0x3b50: 0x0002, 0x3b51: 0x0002,
|
||||
0x3b52: 0x0002, 0x3b55: 0x0002, 0x3b56: 0x0002, 0x3b57: 0x0002,
|
||||
0x3b5c: 0x0002, 0x3b5d: 0x0002,
|
||||
0x3b5e: 0x0002, 0x3b5f: 0x0002,
|
||||
0x3b6b: 0x0002, 0x3b6c: 0x0002,
|
||||
0x3b74: 0x0002, 0x3b75: 0x0002,
|
||||
0x3b76: 0x0002, 0x3b77: 0x0002, 0x3b78: 0x0002, 0x3b79: 0x0002, 0x3b7a: 0x0002, 0x3b7b: 0x0002,
|
||||
0x3b7c: 0x0002,
|
||||
// Block 0xee, offset 0x3b80
|
||||
0x3ba0: 0x0004, 0x3ba1: 0x0004, 0x3ba2: 0x0004, 0x3ba3: 0x0004,
|
||||
0x3ba4: 0x0004, 0x3ba5: 0x0004, 0x3ba6: 0x0004, 0x3ba7: 0x0004, 0x3ba8: 0x0004, 0x3ba9: 0x0004,
|
||||
0x3baa: 0x0004, 0x3bab: 0x0004,
|
||||
0x3bb0: 0x0004,
|
||||
0x3ba0: 0x0002, 0x3ba1: 0x0002, 0x3ba2: 0x0002, 0x3ba3: 0x0002,
|
||||
0x3ba4: 0x0002, 0x3ba5: 0x0002, 0x3ba6: 0x0002, 0x3ba7: 0x0002, 0x3ba8: 0x0002, 0x3ba9: 0x0002,
|
||||
0x3baa: 0x0002, 0x3bab: 0x0002,
|
||||
0x3bb0: 0x0002,
|
||||
// Block 0xef, offset 0x3bc0
|
||||
0x3bcc: 0x0004, 0x3bcd: 0x0004, 0x3bce: 0x0004, 0x3bcf: 0x0004, 0x3bd0: 0x0004, 0x3bd1: 0x0004,
|
||||
0x3bd2: 0x0004, 0x3bd3: 0x0004, 0x3bd4: 0x0004, 0x3bd5: 0x0004, 0x3bd6: 0x0004, 0x3bd7: 0x0004,
|
||||
0x3bd8: 0x0004, 0x3bd9: 0x0004, 0x3bda: 0x0004, 0x3bdb: 0x0004, 0x3bdc: 0x0004, 0x3bdd: 0x0004,
|
||||
0x3bde: 0x0004, 0x3bdf: 0x0004, 0x3be0: 0x0004, 0x3be1: 0x0004, 0x3be2: 0x0004, 0x3be3: 0x0004,
|
||||
0x3be4: 0x0004, 0x3be5: 0x0004, 0x3be6: 0x0004, 0x3be7: 0x0004, 0x3be8: 0x0004, 0x3be9: 0x0004,
|
||||
0x3bea: 0x0004, 0x3beb: 0x0004, 0x3bec: 0x0004, 0x3bed: 0x0004, 0x3bee: 0x0004, 0x3bef: 0x0004,
|
||||
0x3bf0: 0x0004, 0x3bf1: 0x0004, 0x3bf2: 0x0004, 0x3bf3: 0x0004, 0x3bf4: 0x0004, 0x3bf5: 0x0004,
|
||||
0x3bf6: 0x0004, 0x3bf7: 0x0004, 0x3bf8: 0x0004, 0x3bf9: 0x0004, 0x3bfa: 0x0004,
|
||||
0x3bfc: 0x0004, 0x3bfd: 0x0004, 0x3bfe: 0x0004, 0x3bff: 0x0004,
|
||||
0x3bcc: 0x0002, 0x3bcd: 0x0002, 0x3bce: 0x0002, 0x3bcf: 0x0002, 0x3bd0: 0x0002, 0x3bd1: 0x0002,
|
||||
0x3bd2: 0x0002, 0x3bd3: 0x0002, 0x3bd4: 0x0002, 0x3bd5: 0x0002, 0x3bd6: 0x0002, 0x3bd7: 0x0002,
|
||||
0x3bd8: 0x0002, 0x3bd9: 0x0002, 0x3bda: 0x0002, 0x3bdb: 0x0002, 0x3bdc: 0x0002, 0x3bdd: 0x0002,
|
||||
0x3bde: 0x0002, 0x3bdf: 0x0002, 0x3be0: 0x0002, 0x3be1: 0x0002, 0x3be2: 0x0002, 0x3be3: 0x0002,
|
||||
0x3be4: 0x0002, 0x3be5: 0x0002, 0x3be6: 0x0002, 0x3be7: 0x0002, 0x3be8: 0x0002, 0x3be9: 0x0002,
|
||||
0x3bea: 0x0002, 0x3beb: 0x0002, 0x3bec: 0x0002, 0x3bed: 0x0002, 0x3bee: 0x0002, 0x3bef: 0x0002,
|
||||
0x3bf0: 0x0002, 0x3bf1: 0x0002, 0x3bf2: 0x0002, 0x3bf3: 0x0002, 0x3bf4: 0x0002, 0x3bf5: 0x0002,
|
||||
0x3bf6: 0x0002, 0x3bf7: 0x0002, 0x3bf8: 0x0002, 0x3bf9: 0x0002, 0x3bfa: 0x0002,
|
||||
0x3bfc: 0x0002, 0x3bfd: 0x0002, 0x3bfe: 0x0002, 0x3bff: 0x0002,
|
||||
// Block 0xf0, offset 0x3c00
|
||||
0x3c00: 0x0004, 0x3c01: 0x0004, 0x3c02: 0x0004, 0x3c03: 0x0004, 0x3c04: 0x0004, 0x3c05: 0x0004,
|
||||
0x3c07: 0x0004, 0x3c08: 0x0004, 0x3c09: 0x0004, 0x3c0a: 0x0004, 0x3c0b: 0x0004,
|
||||
0x3c0c: 0x0004, 0x3c0d: 0x0004, 0x3c0e: 0x0004, 0x3c0f: 0x0004, 0x3c10: 0x0004, 0x3c11: 0x0004,
|
||||
0x3c12: 0x0004, 0x3c13: 0x0004, 0x3c14: 0x0004, 0x3c15: 0x0004, 0x3c16: 0x0004, 0x3c17: 0x0004,
|
||||
0x3c18: 0x0004, 0x3c19: 0x0004, 0x3c1a: 0x0004, 0x3c1b: 0x0004, 0x3c1c: 0x0004, 0x3c1d: 0x0004,
|
||||
0x3c1e: 0x0004, 0x3c1f: 0x0004, 0x3c20: 0x0004, 0x3c21: 0x0004, 0x3c22: 0x0004, 0x3c23: 0x0004,
|
||||
0x3c24: 0x0004, 0x3c25: 0x0004, 0x3c26: 0x0004, 0x3c27: 0x0004, 0x3c28: 0x0004, 0x3c29: 0x0004,
|
||||
0x3c2a: 0x0004, 0x3c2b: 0x0004, 0x3c2c: 0x0004, 0x3c2d: 0x0004, 0x3c2e: 0x0004, 0x3c2f: 0x0004,
|
||||
0x3c30: 0x0004, 0x3c31: 0x0004, 0x3c32: 0x0004, 0x3c33: 0x0004, 0x3c34: 0x0004, 0x3c35: 0x0004,
|
||||
0x3c36: 0x0004, 0x3c37: 0x0004, 0x3c38: 0x0004, 0x3c39: 0x0004, 0x3c3a: 0x0004, 0x3c3b: 0x0004,
|
||||
0x3c3c: 0x0004, 0x3c3d: 0x0004, 0x3c3e: 0x0004, 0x3c3f: 0x0004,
|
||||
0x3c00: 0x0002, 0x3c01: 0x0002, 0x3c02: 0x0002, 0x3c03: 0x0002, 0x3c04: 0x0002, 0x3c05: 0x0002,
|
||||
0x3c07: 0x0002, 0x3c08: 0x0002, 0x3c09: 0x0002, 0x3c0a: 0x0002, 0x3c0b: 0x0002,
|
||||
0x3c0c: 0x0002, 0x3c0d: 0x0002, 0x3c0e: 0x0002, 0x3c0f: 0x0002, 0x3c10: 0x0002, 0x3c11: 0x0002,
|
||||
0x3c12: 0x0002, 0x3c13: 0x0002, 0x3c14: 0x0002, 0x3c15: 0x0002, 0x3c16: 0x0002, 0x3c17: 0x0002,
|
||||
0x3c18: 0x0002, 0x3c19: 0x0002, 0x3c1a: 0x0002, 0x3c1b: 0x0002, 0x3c1c: 0x0002, 0x3c1d: 0x0002,
|
||||
0x3c1e: 0x0002, 0x3c1f: 0x0002, 0x3c20: 0x0002, 0x3c21: 0x0002, 0x3c22: 0x0002, 0x3c23: 0x0002,
|
||||
0x3c24: 0x0002, 0x3c25: 0x0002, 0x3c26: 0x0002, 0x3c27: 0x0002, 0x3c28: 0x0002, 0x3c29: 0x0002,
|
||||
0x3c2a: 0x0002, 0x3c2b: 0x0002, 0x3c2c: 0x0002, 0x3c2d: 0x0002, 0x3c2e: 0x0002, 0x3c2f: 0x0002,
|
||||
0x3c30: 0x0002, 0x3c31: 0x0002, 0x3c32: 0x0002, 0x3c33: 0x0002, 0x3c34: 0x0002, 0x3c35: 0x0002,
|
||||
0x3c36: 0x0002, 0x3c37: 0x0002, 0x3c38: 0x0002, 0x3c39: 0x0002, 0x3c3a: 0x0002, 0x3c3b: 0x0002,
|
||||
0x3c3c: 0x0002, 0x3c3d: 0x0002, 0x3c3e: 0x0002, 0x3c3f: 0x0002,
|
||||
// Block 0xf1, offset 0x3c40
|
||||
0x3c70: 0x0004, 0x3c71: 0x0004, 0x3c72: 0x0004, 0x3c73: 0x0004, 0x3c74: 0x0004, 0x3c75: 0x0004,
|
||||
0x3c76: 0x0004, 0x3c77: 0x0004, 0x3c78: 0x0004, 0x3c79: 0x0004, 0x3c7a: 0x0004, 0x3c7b: 0x0004,
|
||||
0x3c7c: 0x0004,
|
||||
0x3c70: 0x0002, 0x3c71: 0x0002, 0x3c72: 0x0002, 0x3c73: 0x0002, 0x3c74: 0x0002, 0x3c75: 0x0002,
|
||||
0x3c76: 0x0002, 0x3c77: 0x0002, 0x3c78: 0x0002, 0x3c79: 0x0002, 0x3c7a: 0x0002, 0x3c7b: 0x0002,
|
||||
0x3c7c: 0x0002,
|
||||
// Block 0xf2, offset 0x3c80
|
||||
0x3c80: 0x0004, 0x3c81: 0x0004, 0x3c82: 0x0004, 0x3c83: 0x0004, 0x3c84: 0x0004, 0x3c85: 0x0004,
|
||||
0x3c86: 0x0004, 0x3c87: 0x0004, 0x3c88: 0x0004, 0x3c89: 0x0004,
|
||||
0x3c8f: 0x0004, 0x3c90: 0x0004, 0x3c91: 0x0004,
|
||||
0x3c92: 0x0004, 0x3c93: 0x0004, 0x3c94: 0x0004, 0x3c95: 0x0004, 0x3c96: 0x0004, 0x3c97: 0x0004,
|
||||
0x3c98: 0x0004, 0x3c99: 0x0004, 0x3c9a: 0x0004, 0x3c9b: 0x0004, 0x3c9c: 0x0004, 0x3c9d: 0x0004,
|
||||
0x3c9e: 0x0004, 0x3c9f: 0x0004, 0x3ca0: 0x0004, 0x3ca1: 0x0004, 0x3ca2: 0x0004, 0x3ca3: 0x0004,
|
||||
0x3ca4: 0x0004, 0x3ca5: 0x0004, 0x3ca6: 0x0004, 0x3ca7: 0x0004, 0x3ca8: 0x0004, 0x3ca9: 0x0004,
|
||||
0x3caa: 0x0004, 0x3cab: 0x0004, 0x3cac: 0x0004, 0x3cad: 0x0004, 0x3cae: 0x0004, 0x3caf: 0x0004,
|
||||
0x3cb0: 0x0004, 0x3cb1: 0x0004, 0x3cb2: 0x0004, 0x3cb3: 0x0004, 0x3cb4: 0x0004, 0x3cb5: 0x0004,
|
||||
0x3cb6: 0x0004, 0x3cb7: 0x0004, 0x3cb8: 0x0004, 0x3cb9: 0x0004, 0x3cba: 0x0004, 0x3cbb: 0x0004,
|
||||
0x3cbc: 0x0004, 0x3cbd: 0x0004, 0x3cbe: 0x0004, 0x3cbf: 0x0004,
|
||||
0x3c80: 0x0002, 0x3c81: 0x0002, 0x3c82: 0x0002, 0x3c83: 0x0002, 0x3c84: 0x0002, 0x3c85: 0x0002,
|
||||
0x3c86: 0x0002, 0x3c87: 0x0002, 0x3c88: 0x0002, 0x3c89: 0x0002,
|
||||
0x3c8f: 0x0002, 0x3c90: 0x0002, 0x3c91: 0x0002,
|
||||
0x3c92: 0x0002, 0x3c93: 0x0002, 0x3c94: 0x0002, 0x3c95: 0x0002, 0x3c96: 0x0002, 0x3c97: 0x0002,
|
||||
0x3c98: 0x0002, 0x3c99: 0x0002, 0x3c9a: 0x0002, 0x3c9b: 0x0002, 0x3c9c: 0x0002, 0x3c9d: 0x0002,
|
||||
0x3c9e: 0x0002, 0x3c9f: 0x0002, 0x3ca0: 0x0002, 0x3ca1: 0x0002, 0x3ca2: 0x0002, 0x3ca3: 0x0002,
|
||||
0x3ca4: 0x0002, 0x3ca5: 0x0002, 0x3ca6: 0x0002, 0x3ca7: 0x0002, 0x3ca8: 0x0002, 0x3ca9: 0x0002,
|
||||
0x3caa: 0x0002, 0x3cab: 0x0002, 0x3cac: 0x0002, 0x3cad: 0x0002, 0x3cae: 0x0002, 0x3caf: 0x0002,
|
||||
0x3cb0: 0x0002, 0x3cb1: 0x0002, 0x3cb2: 0x0002, 0x3cb3: 0x0002, 0x3cb4: 0x0002, 0x3cb5: 0x0002,
|
||||
0x3cb6: 0x0002, 0x3cb7: 0x0002, 0x3cb8: 0x0002, 0x3cb9: 0x0002, 0x3cba: 0x0002, 0x3cbb: 0x0002,
|
||||
0x3cbc: 0x0002, 0x3cbd: 0x0002, 0x3cbe: 0x0002, 0x3cbf: 0x0002,
|
||||
// Block 0xf3, offset 0x3cc0
|
||||
0x3cc0: 0x0004, 0x3cc1: 0x0004, 0x3cc2: 0x0004, 0x3cc3: 0x0004, 0x3cc4: 0x0004, 0x3cc5: 0x0004,
|
||||
0x3cc6: 0x0004,
|
||||
0x3cce: 0x0004, 0x3ccf: 0x0004, 0x3cd0: 0x0004, 0x3cd1: 0x0004,
|
||||
0x3cd2: 0x0004, 0x3cd3: 0x0004, 0x3cd4: 0x0004, 0x3cd5: 0x0004, 0x3cd6: 0x0004, 0x3cd7: 0x0004,
|
||||
0x3cd8: 0x0004, 0x3cd9: 0x0004, 0x3cda: 0x0004, 0x3cdb: 0x0004, 0x3cdc: 0x0004,
|
||||
0x3cdf: 0x0004, 0x3ce0: 0x0004, 0x3ce1: 0x0004, 0x3ce2: 0x0004, 0x3ce3: 0x0004,
|
||||
0x3ce4: 0x0004, 0x3ce5: 0x0004, 0x3ce6: 0x0004, 0x3ce7: 0x0004, 0x3ce8: 0x0004, 0x3ce9: 0x0004,
|
||||
0x3cf0: 0x0004, 0x3cf1: 0x0004, 0x3cf2: 0x0004, 0x3cf3: 0x0004, 0x3cf4: 0x0004, 0x3cf5: 0x0004,
|
||||
0x3cf6: 0x0004, 0x3cf7: 0x0004, 0x3cf8: 0x0004,
|
||||
0x3cc0: 0x0002, 0x3cc1: 0x0002, 0x3cc2: 0x0002, 0x3cc3: 0x0002, 0x3cc4: 0x0002, 0x3cc5: 0x0002,
|
||||
0x3cc6: 0x0002,
|
||||
0x3cce: 0x0002, 0x3ccf: 0x0002, 0x3cd0: 0x0002, 0x3cd1: 0x0002,
|
||||
0x3cd2: 0x0002, 0x3cd3: 0x0002, 0x3cd4: 0x0002, 0x3cd5: 0x0002, 0x3cd6: 0x0002, 0x3cd7: 0x0002,
|
||||
0x3cd8: 0x0002, 0x3cd9: 0x0002, 0x3cda: 0x0002, 0x3cdb: 0x0002, 0x3cdc: 0x0002,
|
||||
0x3cdf: 0x0002, 0x3ce0: 0x0002, 0x3ce1: 0x0002, 0x3ce2: 0x0002, 0x3ce3: 0x0002,
|
||||
0x3ce4: 0x0002, 0x3ce5: 0x0002, 0x3ce6: 0x0002, 0x3ce7: 0x0002, 0x3ce8: 0x0002, 0x3ce9: 0x0002,
|
||||
0x3cf0: 0x0002, 0x3cf1: 0x0002, 0x3cf2: 0x0002, 0x3cf3: 0x0002, 0x3cf4: 0x0002, 0x3cf5: 0x0002,
|
||||
0x3cf6: 0x0002, 0x3cf7: 0x0002, 0x3cf8: 0x0002,
|
||||
// Block 0xf4, offset 0x3d00
|
||||
0x3d00: 0x0002, 0x3d01: 0x0002, 0x3d02: 0x0002, 0x3d03: 0x0002, 0x3d04: 0x0002, 0x3d05: 0x0002,
|
||||
0x3d06: 0x0002, 0x3d07: 0x0002, 0x3d08: 0x0002, 0x3d09: 0x0002, 0x3d0a: 0x0002, 0x3d0b: 0x0002,
|
||||
0x3d0c: 0x0002, 0x3d0d: 0x0002, 0x3d0e: 0x0002, 0x3d0f: 0x0002, 0x3d10: 0x0002, 0x3d11: 0x0002,
|
||||
0x3d12: 0x0002, 0x3d13: 0x0002, 0x3d14: 0x0002, 0x3d15: 0x0002, 0x3d16: 0x0002, 0x3d17: 0x0002,
|
||||
0x3d18: 0x0002, 0x3d19: 0x0002, 0x3d1a: 0x0002, 0x3d1b: 0x0002, 0x3d1c: 0x0002, 0x3d1d: 0x0002,
|
||||
0x3d1e: 0x0002, 0x3d1f: 0x0002, 0x3d20: 0x0002, 0x3d21: 0x0002, 0x3d22: 0x0002, 0x3d23: 0x0002,
|
||||
0x3d24: 0x0002, 0x3d25: 0x0002, 0x3d26: 0x0002, 0x3d27: 0x0002, 0x3d28: 0x0002, 0x3d29: 0x0002,
|
||||
0x3d2a: 0x0002, 0x3d2b: 0x0002, 0x3d2c: 0x0002, 0x3d2d: 0x0002, 0x3d2e: 0x0002, 0x3d2f: 0x0002,
|
||||
0x3d30: 0x0002, 0x3d31: 0x0002, 0x3d32: 0x0002, 0x3d33: 0x0002, 0x3d34: 0x0002, 0x3d35: 0x0002,
|
||||
0x3d36: 0x0002, 0x3d37: 0x0002, 0x3d38: 0x0002, 0x3d39: 0x0002, 0x3d3a: 0x0002, 0x3d3b: 0x0002,
|
||||
0x3d3c: 0x0002, 0x3d3d: 0x0002,
|
||||
0x3d01: 0x0001,
|
||||
0x3d20: 0x0001, 0x3d21: 0x0001, 0x3d22: 0x0001, 0x3d23: 0x0001,
|
||||
0x3d24: 0x0001, 0x3d25: 0x0001, 0x3d26: 0x0001, 0x3d27: 0x0001, 0x3d28: 0x0001, 0x3d29: 0x0001,
|
||||
0x3d2a: 0x0001, 0x3d2b: 0x0001, 0x3d2c: 0x0001, 0x3d2d: 0x0001, 0x3d2e: 0x0001, 0x3d2f: 0x0001,
|
||||
0x3d30: 0x0001, 0x3d31: 0x0001, 0x3d32: 0x0001, 0x3d33: 0x0001, 0x3d34: 0x0001, 0x3d35: 0x0001,
|
||||
0x3d36: 0x0001, 0x3d37: 0x0001, 0x3d38: 0x0001, 0x3d39: 0x0001, 0x3d3a: 0x0001, 0x3d3b: 0x0001,
|
||||
0x3d3c: 0x0001, 0x3d3d: 0x0001, 0x3d3e: 0x0001, 0x3d3f: 0x0001,
|
||||
// Block 0xf5, offset 0x3d40
|
||||
0x3d41: 0x0001,
|
||||
0x3d60: 0x0001, 0x3d61: 0x0001, 0x3d62: 0x0001, 0x3d63: 0x0001,
|
||||
0x3d64: 0x0001, 0x3d65: 0x0001, 0x3d66: 0x0001, 0x3d67: 0x0001, 0x3d68: 0x0001, 0x3d69: 0x0001,
|
||||
0x3d6a: 0x0001, 0x3d6b: 0x0001, 0x3d6c: 0x0001, 0x3d6d: 0x0001, 0x3d6e: 0x0001, 0x3d6f: 0x0001,
|
||||
0x3d70: 0x0001, 0x3d71: 0x0001, 0x3d72: 0x0001, 0x3d73: 0x0001, 0x3d74: 0x0001, 0x3d75: 0x0001,
|
||||
0x3d76: 0x0001, 0x3d77: 0x0001, 0x3d78: 0x0001, 0x3d79: 0x0001, 0x3d7a: 0x0001, 0x3d7b: 0x0001,
|
||||
0x3d7c: 0x0001, 0x3d7d: 0x0001, 0x3d7e: 0x0001, 0x3d7f: 0x0001,
|
||||
// Block 0xf6, offset 0x3d80
|
||||
0x3d80: 0x0003, 0x3d81: 0x0003, 0x3d82: 0x0003, 0x3d83: 0x0003, 0x3d84: 0x0003, 0x3d85: 0x0003,
|
||||
0x3d86: 0x0003, 0x3d87: 0x0003, 0x3d88: 0x0003, 0x3d89: 0x0003, 0x3d8a: 0x0003, 0x3d8b: 0x0003,
|
||||
0x3d8c: 0x0003, 0x3d8d: 0x0003, 0x3d8e: 0x0003, 0x3d8f: 0x0003, 0x3d90: 0x0003, 0x3d91: 0x0003,
|
||||
0x3d92: 0x0003, 0x3d93: 0x0003, 0x3d94: 0x0003, 0x3d95: 0x0003, 0x3d96: 0x0003, 0x3d97: 0x0003,
|
||||
0x3d98: 0x0003, 0x3d99: 0x0003, 0x3d9a: 0x0003, 0x3d9b: 0x0003, 0x3d9c: 0x0003, 0x3d9d: 0x0003,
|
||||
0x3d9e: 0x0003, 0x3d9f: 0x0003, 0x3da0: 0x0003, 0x3da1: 0x0003, 0x3da2: 0x0003, 0x3da3: 0x0003,
|
||||
0x3da4: 0x0003, 0x3da5: 0x0003, 0x3da6: 0x0003, 0x3da7: 0x0003, 0x3da8: 0x0003, 0x3da9: 0x0003,
|
||||
0x3daa: 0x0003, 0x3dab: 0x0003, 0x3dac: 0x0003, 0x3dad: 0x0003, 0x3dae: 0x0003, 0x3daf: 0x0003,
|
||||
0x3db0: 0x0003, 0x3db1: 0x0003, 0x3db2: 0x0003, 0x3db3: 0x0003, 0x3db4: 0x0003, 0x3db5: 0x0003,
|
||||
0x3db6: 0x0003, 0x3db7: 0x0003, 0x3db8: 0x0003, 0x3db9: 0x0003, 0x3dba: 0x0003, 0x3dbb: 0x0003,
|
||||
0x3dbc: 0x0003, 0x3dbd: 0x0003,
|
||||
0x3d40: 0x0003, 0x3d41: 0x0003, 0x3d42: 0x0003, 0x3d43: 0x0003, 0x3d44: 0x0003, 0x3d45: 0x0003,
|
||||
0x3d46: 0x0003, 0x3d47: 0x0003, 0x3d48: 0x0003, 0x3d49: 0x0003, 0x3d4a: 0x0003, 0x3d4b: 0x0003,
|
||||
0x3d4c: 0x0003, 0x3d4d: 0x0003, 0x3d4e: 0x0003, 0x3d4f: 0x0003, 0x3d50: 0x0003, 0x3d51: 0x0003,
|
||||
0x3d52: 0x0003, 0x3d53: 0x0003, 0x3d54: 0x0003, 0x3d55: 0x0003, 0x3d56: 0x0003, 0x3d57: 0x0003,
|
||||
0x3d58: 0x0003, 0x3d59: 0x0003, 0x3d5a: 0x0003, 0x3d5b: 0x0003, 0x3d5c: 0x0003, 0x3d5d: 0x0003,
|
||||
0x3d5e: 0x0003, 0x3d5f: 0x0003, 0x3d60: 0x0003, 0x3d61: 0x0003, 0x3d62: 0x0003, 0x3d63: 0x0003,
|
||||
0x3d64: 0x0003, 0x3d65: 0x0003, 0x3d66: 0x0003, 0x3d67: 0x0003, 0x3d68: 0x0003, 0x3d69: 0x0003,
|
||||
0x3d6a: 0x0003, 0x3d6b: 0x0003, 0x3d6c: 0x0003, 0x3d6d: 0x0003, 0x3d6e: 0x0003, 0x3d6f: 0x0003,
|
||||
0x3d70: 0x0003, 0x3d71: 0x0003, 0x3d72: 0x0003, 0x3d73: 0x0003, 0x3d74: 0x0003, 0x3d75: 0x0003,
|
||||
0x3d76: 0x0003, 0x3d77: 0x0003, 0x3d78: 0x0003, 0x3d79: 0x0003, 0x3d7a: 0x0003, 0x3d7b: 0x0003,
|
||||
0x3d7c: 0x0003, 0x3d7d: 0x0003,
|
||||
}
|
||||
|
||||
// stringWidthIndex: 30 blocks, 1920 entries, 1920 bytes
|
||||
@@ -1673,11 +1653,11 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x593: 0xd4,
|
||||
0x5a3: 0xd5, 0x5a5: 0xd6,
|
||||
// Block 0x17, offset 0x5c0
|
||||
0x5c0: 0xd7, 0x5c3: 0xd8, 0x5c4: 0xd9, 0x5c5: 0xda, 0x5c6: 0xdb,
|
||||
0x5c8: 0xdc, 0x5c9: 0xdd, 0x5cc: 0xde, 0x5cd: 0xdf, 0x5ce: 0xe0, 0x5cf: 0xe1,
|
||||
0x5d0: 0xe2, 0x5d1: 0xe3, 0x5d2: 0xe4, 0x5d3: 0xe5, 0x5d4: 0xe6, 0x5d5: 0xe7, 0x5d6: 0xe8, 0x5d7: 0xe9,
|
||||
0x5d8: 0xe4, 0x5d9: 0xea, 0x5da: 0xe4, 0x5db: 0xeb, 0x5df: 0xec,
|
||||
0x5e4: 0xed, 0x5e5: 0xee, 0x5e6: 0xe4, 0x5e7: 0xe4,
|
||||
0x5c0: 0xd7, 0x5c3: 0xd8, 0x5c4: 0xd9, 0x5c5: 0xda, 0x5c6: 0xdb, 0x5c7: 0xdc,
|
||||
0x5c8: 0xdd, 0x5c9: 0xde, 0x5cc: 0xdf, 0x5cd: 0xe0, 0x5ce: 0xe1, 0x5cf: 0xe2,
|
||||
0x5d0: 0xe3, 0x5d1: 0xe4, 0x5d2: 0x39, 0x5d3: 0xe5, 0x5d4: 0xe6, 0x5d5: 0xe7, 0x5d6: 0xe8, 0x5d7: 0xe9,
|
||||
0x5d8: 0x39, 0x5d9: 0xea, 0x5da: 0x39, 0x5db: 0xeb, 0x5df: 0xec,
|
||||
0x5e4: 0xed, 0x5e5: 0xee, 0x5e6: 0x39, 0x5e7: 0x39,
|
||||
0x5e9: 0xef, 0x5ea: 0xf0, 0x5eb: 0xf1,
|
||||
// Block 0x18, offset 0x600
|
||||
0x600: 0x39, 0x601: 0x39, 0x602: 0x39, 0x603: 0x39, 0x604: 0x39, 0x605: 0x39, 0x606: 0x39, 0x607: 0x39,
|
||||
@@ -1687,7 +1667,7 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x620: 0x39, 0x621: 0x39, 0x622: 0x39, 0x623: 0x39, 0x624: 0x39, 0x625: 0x39, 0x626: 0x39, 0x627: 0x39,
|
||||
0x628: 0x39, 0x629: 0x39, 0x62a: 0x39, 0x62b: 0x39, 0x62c: 0x39, 0x62d: 0x39, 0x62e: 0x39, 0x62f: 0x39,
|
||||
0x630: 0x39, 0x631: 0x39, 0x632: 0x39, 0x633: 0x39, 0x634: 0x39, 0x635: 0x39, 0x636: 0x39, 0x637: 0x39,
|
||||
0x638: 0x39, 0x639: 0x39, 0x63a: 0x39, 0x63b: 0x39, 0x63c: 0x39, 0x63d: 0x39, 0x63e: 0x39, 0x63f: 0xf2,
|
||||
0x638: 0x39, 0x639: 0x39, 0x63a: 0x39, 0x63b: 0x39, 0x63c: 0x39, 0x63d: 0x39, 0x63e: 0x39, 0x63f: 0xe6,
|
||||
// Block 0x19, offset 0x640
|
||||
0x650: 0x0b, 0x651: 0x0c, 0x653: 0x0d, 0x656: 0x0e, 0x657: 0x06,
|
||||
0x658: 0x0f, 0x65a: 0x10, 0x65b: 0x11, 0x65c: 0x12, 0x65d: 0x13, 0x65e: 0x14, 0x65f: 0x15,
|
||||
@@ -1696,7 +1676,7 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x670: 0x06, 0x671: 0x06, 0x672: 0x06, 0x673: 0x06, 0x674: 0x06, 0x675: 0x06, 0x676: 0x06, 0x677: 0x06,
|
||||
0x678: 0x06, 0x679: 0x06, 0x67a: 0x06, 0x67b: 0x06, 0x67c: 0x06, 0x67d: 0x06, 0x67e: 0x06, 0x67f: 0x16,
|
||||
// Block 0x1a, offset 0x680
|
||||
0x680: 0xf3, 0x681: 0x08, 0x684: 0x08, 0x685: 0x08, 0x686: 0x08, 0x687: 0x09,
|
||||
0x680: 0xf2, 0x681: 0x08, 0x684: 0x08, 0x685: 0x08, 0x686: 0x08, 0x687: 0x09,
|
||||
// Block 0x1b, offset 0x6c0
|
||||
0x6c0: 0x5b, 0x6c1: 0x5b, 0x6c2: 0x5b, 0x6c3: 0x5b, 0x6c4: 0x5b, 0x6c5: 0x5b, 0x6c6: 0x5b, 0x6c7: 0x5b,
|
||||
0x6c8: 0x5b, 0x6c9: 0x5b, 0x6ca: 0x5b, 0x6cb: 0x5b, 0x6cc: 0x5b, 0x6cd: 0x5b, 0x6ce: 0x5b, 0x6cf: 0x5b,
|
||||
@@ -1705,7 +1685,7 @@ var stringWidthIndex = [1920]uint8{
|
||||
0x6e0: 0x5b, 0x6e1: 0x5b, 0x6e2: 0x5b, 0x6e3: 0x5b, 0x6e4: 0x5b, 0x6e5: 0x5b, 0x6e6: 0x5b, 0x6e7: 0x5b,
|
||||
0x6e8: 0x5b, 0x6e9: 0x5b, 0x6ea: 0x5b, 0x6eb: 0x5b, 0x6ec: 0x5b, 0x6ed: 0x5b, 0x6ee: 0x5b, 0x6ef: 0x5b,
|
||||
0x6f0: 0x5b, 0x6f1: 0x5b, 0x6f2: 0x5b, 0x6f3: 0x5b, 0x6f4: 0x5b, 0x6f5: 0x5b, 0x6f6: 0x5b, 0x6f7: 0x5b,
|
||||
0x6f8: 0x5b, 0x6f9: 0x5b, 0x6fa: 0x5b, 0x6fb: 0x5b, 0x6fc: 0x5b, 0x6fd: 0x5b, 0x6fe: 0x5b, 0x6ff: 0xf4,
|
||||
0x6f8: 0x5b, 0x6f9: 0x5b, 0x6fa: 0x5b, 0x6fb: 0x5b, 0x6fc: 0x5b, 0x6fd: 0x5b, 0x6fe: 0x5b, 0x6ff: 0xf3,
|
||||
// Block 0x1c, offset 0x700
|
||||
0x720: 0x18,
|
||||
0x730: 0x09, 0x731: 0x09, 0x732: 0x09, 0x733: 0x09, 0x734: 0x09, 0x735: 0x09, 0x736: 0x09, 0x737: 0x09,
|
||||
|
||||
128
vendor/github.com/clipperhouse/displaywidth/width.go
generated
vendored
128
vendor/github.com/clipperhouse/displaywidth/width.go
generated
vendored
@@ -34,7 +34,7 @@ func (options Options) String(s string) int {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return int(asciiWidths[s[0]])
|
||||
return asciiWidth(s[0])
|
||||
}
|
||||
|
||||
width := 0
|
||||
@@ -60,7 +60,7 @@ func (options Options) Bytes(s []byte) int {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return int(asciiWidths[s[0]])
|
||||
return asciiWidth(s[0])
|
||||
}
|
||||
|
||||
width := 0
|
||||
@@ -90,7 +90,7 @@ func Rune(r rune) int {
|
||||
// Iterating over runes to measure width is incorrect in many cases.
|
||||
func (options Options) Rune(r rune) int {
|
||||
if r < utf8.RuneSelf {
|
||||
return int(asciiWidths[byte(r)])
|
||||
return asciiWidth(byte(r))
|
||||
}
|
||||
|
||||
// Surrogates (U+D800-U+DFFF) are invalid UTF-8.
|
||||
@@ -102,9 +102,11 @@ func (options Options) Rune(r rune) int {
|
||||
n := utf8.EncodeRune(buf[:], r)
|
||||
|
||||
// Skip the grapheme iterator
|
||||
return lookupProperties(buf[:n]).width(options)
|
||||
return graphemeWidth(buf[:n], options)
|
||||
}
|
||||
|
||||
const _Default property = 0
|
||||
|
||||
// graphemeWidth returns the display width of a grapheme cluster.
|
||||
// The passed string must be a single grapheme cluster.
|
||||
func graphemeWidth[T stringish.Interface](s T, options Options) int {
|
||||
@@ -113,16 +115,39 @@ func graphemeWidth[T stringish.Interface](s T, options Options) int {
|
||||
case 0:
|
||||
return 0
|
||||
case 1:
|
||||
return int(asciiWidths[s[0]])
|
||||
return asciiWidth(s[0])
|
||||
}
|
||||
|
||||
return lookupProperties(s).width(options)
|
||||
p, sz := lookup(s)
|
||||
prop := property(p)
|
||||
|
||||
// Variation Selector 16 (VS16) requests emoji presentation
|
||||
if prop != _Wide && sz > 0 && len(s) >= sz+3 {
|
||||
vs := s[sz : sz+3]
|
||||
if isVS16(vs) {
|
||||
prop = _Wide
|
||||
}
|
||||
// VS15 (0x8E) requests text presentation but does not affect width,
|
||||
// in my reading of Unicode TR51. Falls through to return the base
|
||||
// character's property.
|
||||
}
|
||||
|
||||
if options.EastAsianWidth && prop == _East_Asian_Ambiguous {
|
||||
prop = _Wide
|
||||
}
|
||||
|
||||
if prop > upperBound {
|
||||
prop = _Default
|
||||
}
|
||||
|
||||
return propertyWidths[prop]
|
||||
}
|
||||
|
||||
// isRIPrefix checks if the slice matches the Regional Indicator prefix
|
||||
// (F0 9F 87). It assumes len(s) >= 3.
|
||||
func isRIPrefix[T stringish.Interface](s T) bool {
|
||||
return s[0] == 0xF0 && s[1] == 0x9F && s[2] == 0x87
|
||||
func asciiWidth(b byte) int {
|
||||
if b <= 0x1F || b == 0x7F {
|
||||
return 0
|
||||
}
|
||||
return 1
|
||||
}
|
||||
|
||||
// isVS16 checks if the slice matches VS16 (U+FE0F) UTF-8 encoding
|
||||
@@ -131,81 +156,12 @@ func isVS16[T stringish.Interface](s T) bool {
|
||||
return s[0] == 0xEF && s[1] == 0xB8 && s[2] == 0x8F
|
||||
}
|
||||
|
||||
// lookupProperties returns the properties for a grapheme.
|
||||
// The passed string must be at least one byte long.
|
||||
//
|
||||
// Callers must handle zero and single-byte strings upstream, both as an
|
||||
// optimization, and to reduce the scope of this function.
|
||||
func lookupProperties[T stringish.Interface](s T) property {
|
||||
l := len(s)
|
||||
|
||||
if s[0] < utf8.RuneSelf {
|
||||
// Check for variation selector after ASCII (e.g., keycap sequences like 1️⃣)
|
||||
if l >= 4 {
|
||||
// Subslice may help eliminate bounds checks
|
||||
vs := s[1:4]
|
||||
if isVS16(vs) {
|
||||
// VS16 requests emoji presentation (width 2)
|
||||
return _Emoji
|
||||
}
|
||||
// VS15 (0x8E) requests text presentation but does not affect width,
|
||||
// in my reading of Unicode TR51. Falls through to _Default.
|
||||
}
|
||||
return asciiProperties[s[0]]
|
||||
}
|
||||
|
||||
// Regional indicator pair (flag)
|
||||
if l >= 8 {
|
||||
// Subslice may help eliminate bounds checks
|
||||
ri := s[:8]
|
||||
// First rune
|
||||
if isRIPrefix(ri[0:3]) {
|
||||
b3 := ri[3]
|
||||
if b3 >= 0xA6 && b3 <= 0xBF {
|
||||
// Second rune
|
||||
if isRIPrefix(ri[4:7]) {
|
||||
b7 := ri[7]
|
||||
if b7 >= 0xA6 && b7 <= 0xBF {
|
||||
return _Emoji
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p, sz := lookup(s)
|
||||
|
||||
// Variation Selectors
|
||||
if sz > 0 && l >= sz+3 {
|
||||
// Subslice may help eliminate bounds checks
|
||||
vs := s[sz : sz+3]
|
||||
if isVS16(vs) {
|
||||
// VS16 requests emoji presentation (width 2)
|
||||
return _Emoji
|
||||
}
|
||||
// VS15 (0x8E) requests text presentation but does not affect width,
|
||||
// in my reading of Unicode TR51. Falls through to return the base
|
||||
// character's property.
|
||||
}
|
||||
|
||||
return property(p)
|
||||
// propertyWidths is a jump table of sorts, instead of a switch
|
||||
var propertyWidths = [4]int{
|
||||
_Default: 1,
|
||||
_Zero_Width: 0,
|
||||
_Wide: 2,
|
||||
_East_Asian_Ambiguous: 1,
|
||||
}
|
||||
|
||||
const _Default property = 0
|
||||
const boundsCheck = property(len(propertyWidths) - 1)
|
||||
|
||||
// width determines the display width of a character based on its properties,
|
||||
// and configuration options
|
||||
func (p property) width(options Options) int {
|
||||
if options.EastAsianWidth && p == _East_Asian_Ambiguous {
|
||||
return 2
|
||||
}
|
||||
|
||||
// Bounds check may help the compiler eliminate its bounds check,
|
||||
// and safety of course.
|
||||
if p > boundsCheck {
|
||||
return 1 // default width
|
||||
}
|
||||
|
||||
return propertyWidths[p]
|
||||
}
|
||||
const upperBound = property(len(propertyWidths) - 1)
|
||||
|
||||
3
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
3
vendor/github.com/go-resty/resty/v2/.gitignore
generated
vendored
@@ -26,5 +26,6 @@ _testmain.go
|
||||
coverage.out
|
||||
coverage.txt
|
||||
|
||||
# Exclude intellij IDE folders
|
||||
# Exclude IDE folders
|
||||
.idea/*
|
||||
.vscode/*
|
||||
|
||||
17
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
17
vendor/github.com/go-resty/resty/v2/BUILD.bazel
generated
vendored
@@ -1,5 +1,5 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
load("@bazel_gazelle//:def.bzl", "gazelle")
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
|
||||
|
||||
# gazelle:prefix github.com/go-resty/resty/v2
|
||||
# gazelle:go_naming_convention import_alias
|
||||
@@ -9,6 +9,7 @@ go_library(
|
||||
name = "resty",
|
||||
srcs = [
|
||||
"client.go",
|
||||
"digest.go",
|
||||
"middleware.go",
|
||||
"redirect.go",
|
||||
"request.go",
|
||||
@@ -18,11 +19,17 @@ go_library(
|
||||
"trace.go",
|
||||
"transport.go",
|
||||
"transport112.go",
|
||||
"transport_js.go",
|
||||
"transport_other.go",
|
||||
"util.go",
|
||||
"util_curl.go",
|
||||
],
|
||||
importpath = "github.com/go-resty/resty/v2",
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["@org_golang_x_net//publicsuffix:go_default_library"],
|
||||
deps = [
|
||||
"//shellescape",
|
||||
"@org_golang_x_net//publicsuffix:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
go_test(
|
||||
@@ -31,6 +38,7 @@ go_test(
|
||||
"client_test.go",
|
||||
"context_test.go",
|
||||
"example_test.go",
|
||||
"middleware_test.go",
|
||||
"request_test.go",
|
||||
"resty_test.go",
|
||||
"retry_test.go",
|
||||
@@ -38,7 +46,10 @@ go_test(
|
||||
],
|
||||
data = glob([".testdata/*"]),
|
||||
embed = [":resty"],
|
||||
deps = ["@org_golang_x_net//proxy:go_default_library"],
|
||||
deps = [
|
||||
"@org_golang_x_net//proxy:go_default_library",
|
||||
"@org_golang_x_time//rate:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
alias(
|
||||
|
||||
2
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
2
vendor/github.com/go-resty/resty/v2/LICENSE
generated
vendored
@@ -1,6 +1,6 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015-2021 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
|
||||
Copyright (c) 2015-2024 Jeevanandam M., https://myjeeva.com <jeeva@myjeeva.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
96
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
96
vendor/github.com/go-resty/resty/v2/README.md
generated
vendored
@@ -4,16 +4,12 @@
|
||||
<p align="center"><a href="#features">Features</a> section describes in detail about Resty capabilities</p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Amaster"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg" alt="Build Status"></a> <a href="https://codecov.io/gh/go-resty/resty/branch/master"><img src="https://codecov.io/gh/go-resty/resty/branch/master/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.7.0-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
|
||||
</p>
|
||||
<p align="center">
|
||||
<h4 align="center">Resty Communication Channels</h4>
|
||||
<p align="center"><a href="https://gitter.im/go_resty/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"><img src="https://badges.gitter.im/go_resty/community.svg" alt="Chat on Gitter - Resty Community"></a> <a href="https://twitter.com/go_resty"><img src="https://img.shields.io/badge/twitter-@go__resty-55acee.svg" alt="Twitter @go_resty"></a></p>
|
||||
<p align="center"><a href="https://github.com/go-resty/resty/actions/workflows/ci.yml?query=branch%3Av2"><img src="https://github.com/go-resty/resty/actions/workflows/ci.yml/badge.svg?branch=v2" alt="Build Status"></a> <a href="https://app.codecov.io/gh/go-resty/resty/tree/v2"><img src="https://codecov.io/gh/go-resty/resty/branch/v2/graph/badge.svg" alt="Code Coverage"></a> <a href="https://goreportcard.com/report/go-resty/resty"><img src="https://goreportcard.com/badge/go-resty/resty" alt="Go Report Card"></a> <a href="https://github.com/go-resty/resty/releases/latest"><img src="https://img.shields.io/badge/version-2.17.1-blue.svg" alt="Release Version"></a> <a href="https://pkg.go.dev/github.com/go-resty/resty/v2"><img src="https://pkg.go.dev/badge/github.com/go-resty/resty" alt="GoDoc"></a> <a href="LICENSE"><img src="https://img.shields.io/github/license/go-resty/resty.svg" alt="License"></a> <a href="https://github.com/avelino/awesome-go"><img src="https://awesome.re/mentioned-badge.svg" alt="Mentioned in Awesome Go"></a></p>
|
||||
</p>
|
||||
|
||||
## News
|
||||
|
||||
* v2.7.0 [released](https://github.com/go-resty/resty/releases/tag/v2.7.0) and tagged on Nov 03, 2021.
|
||||
* v2.17.1 [released](https://github.com/go-resty/resty/releases/tag/v2.17.1) and tagged on Dec 15, 2025.
|
||||
* v2.0.0 [released](https://github.com/go-resty/resty/releases/tag/v2.0.0) and tagged on Jul 16, 2019.
|
||||
* v1.12.0 [released](https://github.com/go-resty/resty/releases/tag/v1.12.0) and tagged on Feb 27, 2019.
|
||||
* v1.0 released and tagged on Sep 25, 2017. - Resty's first version was released on Sep 15, 2015 then it grew gradually as a very handy and helpful library. Its been a two years since first release. I'm very thankful to Resty users and its [contributors](https://github.com/go-resty/resty/graphs/contributors).
|
||||
@@ -62,9 +58,10 @@
|
||||
* goroutine concurrent safe
|
||||
* Resty Client trace, see [Client.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableTrace) and [Request.EnableTrace](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableTrace)
|
||||
* Since v2.4.0, trace info contains a `RequestAttempt` value, and the `Request` object contains an `Attempt` attribute
|
||||
* Supports on-demand CURL command generation, see [Client.EnableGenerateCurlOnDebug](https://pkg.go.dev/github.com/go-resty/resty/v2#Client.EnableGenerateCurlOnDebug), [Request.EnableGenerateCurlOnDebug](https://pkg.go.dev/github.com/go-resty/resty/v2#Request.EnableGenerateCurlOnDebug). It requires debug mode to be enabled.
|
||||
* Debug mode - clean and informative logging presentation
|
||||
* Gzip - Go does it automatically also resty has fallback handling too
|
||||
* Works fine with `HTTP/2` and `HTTP/1.1`
|
||||
* Works fine with `HTTP/2` and `HTTP/1.1`, also `HTTP/3` can be used with Resty, see this [comment](https://github.com/go-resty/resty/issues/846#issuecomment-2329696110)
|
||||
* [Bazel support](#bazel-support)
|
||||
* Easily mock Resty for testing, [for e.g.](#mocking-http-requests-using-httpmock-library)
|
||||
* Well tested client library
|
||||
@@ -86,6 +83,8 @@
|
||||
|
||||
#### Supported Go Versions
|
||||
|
||||
Recommended to use `go1.23` and above.
|
||||
|
||||
Initially Resty started supporting `go modules` since `v1.10.0` release.
|
||||
|
||||
Starting Resty v2 and higher versions, it fully embraces [go modules](https://github.com/golang/go/wiki/Modules) package release. It requires a Go version capable of understanding `/vN` suffixed imports:
|
||||
@@ -99,8 +98,6 @@ Starting Resty v2 and higher versions, it fully embraces [go modules](https://gi
|
||||
|
||||
Resty author also published following projects for Go Community.
|
||||
|
||||
* [aah framework](https://aahframework.org) - A secure, flexible, rapid Go web framework.
|
||||
* [THUMBAI](https://thumbai.app) - Go Mod Repository, Go Vanity Service and Simple Proxy Server.
|
||||
* [go-model](https://github.com/jeevatkm/go-model) - Robust & Easy to use model mapper and utility methods for Go `struct`.
|
||||
|
||||
|
||||
@@ -108,7 +105,7 @@ Resty author also published following projects for Go Community.
|
||||
|
||||
```bash
|
||||
# Go Modules
|
||||
require github.com/go-resty/resty/v2 v2.7.0
|
||||
require github.com/go-resty/resty/v2 v2.16.5
|
||||
```
|
||||
|
||||
## Usage
|
||||
@@ -265,7 +262,7 @@ resp, err := client.R().
|
||||
Post("https://myapp.com/login")
|
||||
|
||||
// POST of raw bytes for file upload. For example: upload file to Dropbox
|
||||
fileBytes, _ := ioutil.ReadFile("/Users/jeeva/mydocument.pdf")
|
||||
fileBytes, _ := os.ReadFile("/Users/jeeva/mydocument.pdf")
|
||||
|
||||
// See we are not setting content-type header, since go-resty automatically detects Content-Type for you
|
||||
resp, err := client.R().
|
||||
@@ -369,13 +366,13 @@ import jsoniter "github.com/json-iterator/go"
|
||||
|
||||
json := jsoniter.ConfigCompatibleWithStandardLibrary
|
||||
|
||||
client := resty.New()
|
||||
client.JSONMarshal = json.Marshal
|
||||
client.JSONUnmarshal = json.Unmarshal
|
||||
client := resty.New().
|
||||
SetJSONMarshaler(json.Marshal).
|
||||
SetJSONUnmarshaler(json.Unmarshal)
|
||||
|
||||
// similarly user could do for XML too with -
|
||||
client.XMLMarshal
|
||||
client.XMLUnmarshal
|
||||
client.SetXMLMarshaler(xml.Marshal).
|
||||
SetXMLUnmarshaler(xml.Unmarshal)
|
||||
```
|
||||
|
||||
### Multipart File(s) upload
|
||||
@@ -383,8 +380,8 @@ client.XMLUnmarshal
|
||||
#### Using io.Reader
|
||||
|
||||
```go
|
||||
profileImgBytes, _ := ioutil.ReadFile("/Users/jeeva/test-img.png")
|
||||
notesBytes, _ := ioutil.ReadFile("/Users/jeeva/text-file.txt")
|
||||
profileImgBytes, _ := os.ReadFile("/Users/jeeva/test-img.png")
|
||||
notesBytes, _ := os.ReadFile("/Users/jeeva/text-file.txt")
|
||||
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
@@ -475,7 +472,7 @@ resp, err := client.R().
|
||||
client := resty.New()
|
||||
|
||||
// Setting output directory path, If directory not exists then resty creates one!
|
||||
// This is optional one, if you're planning using absoule path in
|
||||
// This is optional one, if you're planning using absolute path in
|
||||
// `Request.SetOutput` and can used together.
|
||||
client.SetOutputDirectory("/Users/jeeva/Downloads")
|
||||
|
||||
@@ -556,6 +553,30 @@ client.OnError(func(req *resty.Request, err error) {
|
||||
})
|
||||
```
|
||||
|
||||
#### Generate CURL Command
|
||||
>Refer: [curl_cmd_test.go](https://github.com/go-resty/resty/blob/v2/curl_cmd_test.go)
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
resp, err := client.R().
|
||||
SetDebug(true).
|
||||
EnableGenerateCurlOnDebug(). // CURL command generated when debug mode enabled with this option
|
||||
SetBody(map[string]string{"name": "Alex"}).
|
||||
Post("https://httpbin.org/post")
|
||||
|
||||
curlCmdExecuted := resp.Request.GenerateCurlCommand()
|
||||
|
||||
// Explore curl command
|
||||
fmt.Println("Curl Command:\n ", curlCmdExecuted+"\n")
|
||||
|
||||
/* Output
|
||||
Curl Command:
|
||||
curl -X POST -H 'Content-Type: application/json' -H 'User-Agent: go-resty/2.14.0 (https://github.com/go-resty/resty)' -d '{"name":"Alex"}' https://httpbin.org/post
|
||||
*/
|
||||
```
|
||||
|
||||
#### Redirect Policy
|
||||
|
||||
Resty provides few ready to use redirect policy(s) also it supports multiple policies together.
|
||||
@@ -635,7 +656,7 @@ client.SetCertificates(cert1, cert2, cert3)
|
||||
|
||||
```go
|
||||
// Custom Root certificates from string
|
||||
// You can pass you certificates throught env variables as strings
|
||||
// You can pass you certificates through env variables as strings
|
||||
// you can add one or more root certificates, its get appended
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
client.SetRootCertificateFromString("-----BEGIN CERTIFICATE-----content-----END CERTIFICATE-----")
|
||||
@@ -654,7 +675,7 @@ if err != nil {
|
||||
client.SetCertificates(cert1, cert2, cert3)
|
||||
```
|
||||
|
||||
#### Proxy Settings - Client as well as at Request Level
|
||||
#### Proxy Settings
|
||||
|
||||
Default `Go` supports Proxy via environment variable `HTTP_PROXY`. Resty provides support via `SetProxy` & `RemoveProxy`.
|
||||
Choose as per your need.
|
||||
@@ -700,8 +721,9 @@ client.
|
||||
})
|
||||
```
|
||||
|
||||
Above setup will result in resty retrying requests returned non nil error up to
|
||||
3 times with delay increased after each attempt.
|
||||
By default, resty will retry requests that return a non-nil error during execution.
|
||||
Therefore, the above setup will result in resty retrying requests with non-nil errors up to 3 times,
|
||||
with the delay increasing after each attempt.
|
||||
|
||||
You can optionally provide client with [custom retry conditions](https://pkg.go.dev/github.com/go-resty/resty/v2#RetryConditionFunc):
|
||||
|
||||
@@ -718,10 +740,26 @@ client.AddRetryCondition(
|
||||
)
|
||||
```
|
||||
|
||||
Above example will make resty retry requests ended with `429 Too Many Requests`
|
||||
status code.
|
||||
The above example will make resty retry requests that end with a `429 Too Many Requests` status code.
|
||||
It's important to note that when you specify conditions using `AddRetryCondition`,
|
||||
it will override the default retry behavior, which retries on errors encountered during the request.
|
||||
If you want to retry on errors encountered during the request, similar to the default behavior,
|
||||
you'll need to configure it as follows:
|
||||
|
||||
```go
|
||||
// Create a Resty Client
|
||||
client := resty.New()
|
||||
|
||||
client.AddRetryCondition(
|
||||
func(r *resty.Response, err error) bool {
|
||||
// Including "err != nil" emulates the default retry behavior for errors encountered during the request.
|
||||
return err != nil || r.StatusCode() == http.StatusTooManyRequests
|
||||
},
|
||||
)
|
||||
```
|
||||
|
||||
Multiple retry conditions can be added.
|
||||
Note that if multiple conditions are specified, a retry will occur if any of the conditions are met.
|
||||
|
||||
It is also possible to use `resty.Backoff(...)` to get arbitrary retry scenarios
|
||||
implemented. [Reference](retry_test.go).
|
||||
@@ -778,7 +816,7 @@ client.SetTimeout(1 * time.Minute)
|
||||
// You can override all below settings and options at request level if you want to
|
||||
//--------------------------------------------------------------------------------
|
||||
// Host URL for all request. So you can use relative URL in the request
|
||||
client.SetHostURL("http://httpbin.org")
|
||||
client.SetBaseURL("http://httpbin.org")
|
||||
|
||||
// Headers for all request
|
||||
client.SetHeader("Accept", "application/json")
|
||||
@@ -803,7 +841,7 @@ client.SetCookies(cookies)
|
||||
client.SetQueryParam("user_id", "00001")
|
||||
client.SetQueryParams(map[string]string{ // sample of those who use this manner
|
||||
"api_key": "api-key-here",
|
||||
"api_secert": "api-secert",
|
||||
"api_secret": "api-secret",
|
||||
})
|
||||
client.R().SetQueryString("productId=232&template=fresh-sample&cat=resty&source=google&kw=buy a lot more")
|
||||
|
||||
@@ -842,10 +880,10 @@ client := resty.New()
|
||||
|
||||
// Set the previous transport that we created, set the scheme of the communication to the
|
||||
// socket and set the unixSocket as the HostURL.
|
||||
client.SetTransport(&transport).SetScheme("http").SetHostURL(unixSocket)
|
||||
client.SetTransport(&transport).SetScheme("http").SetBaseURL(unixSocket)
|
||||
|
||||
// No need to write the host's URL on the request, just the path.
|
||||
client.R().Get("/index.html")
|
||||
client.R().Get("http://localhost/index.html")
|
||||
```
|
||||
|
||||
#### Bazel Support
|
||||
|
||||
8
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
8
vendor/github.com/go-resty/resty/v2/WORKSPACE
generated
vendored
@@ -4,10 +4,10 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
|
||||
http_archive(
|
||||
name = "io_bazel_rules_go",
|
||||
sha256 = "69de5c704a05ff37862f7e0f5534d4f479418afc21806c887db544a316f3cb6b",
|
||||
sha256 = "80a98277ad1311dacd837f9b16db62887702e9f1d1c4c9f796d0121a46c8e184",
|
||||
urls = [
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.27.0/rules_go-v0.27.0.tar.gz",
|
||||
"https://mirror.bazel.build/github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
|
||||
"https://github.com/bazelbuild/rules_go/releases/download/v0.46.0/rules_go-v0.46.0.zip",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -24,7 +24,7 @@ load("@io_bazel_rules_go//go:deps.bzl", "go_register_toolchains", "go_rules_depe
|
||||
|
||||
go_rules_dependencies()
|
||||
|
||||
go_register_toolchains(version = "1.16")
|
||||
go_register_toolchains(version = "1.19")
|
||||
|
||||
load("@bazel_gazelle//:deps.bzl", "gazelle_dependencies")
|
||||
|
||||
|
||||
1071
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
1071
vendor/github.com/go-resty/resty/v2/client.go
generated
vendored
File diff suppressed because it is too large
Load Diff
327
vendor/github.com/go-resty/resty/v2/digest.go
generated
vendored
Normal file
327
vendor/github.com/go-resty/resty/v2/digest.go
generated
vendored
Normal file
@@ -0,0 +1,327 @@
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com)
|
||||
// 2023 Segev Dagan (https://github.com/segevda)
|
||||
// 2024 Philipp Wolfer (https://github.com/phw)
|
||||
// All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrDigestBadChallenge = errors.New("digest: challenge is bad")
|
||||
ErrDigestCharset = errors.New("digest: unsupported charset")
|
||||
ErrDigestAlgNotSupported = errors.New("digest: algorithm is not supported")
|
||||
ErrDigestQopNotSupported = errors.New("digest: no supported qop in list")
|
||||
ErrDigestNoQop = errors.New("digest: qop must be specified")
|
||||
)
|
||||
|
||||
var hashFuncs = map[string]func() hash.Hash{
|
||||
"": md5.New,
|
||||
"MD5": md5.New,
|
||||
"MD5-sess": md5.New,
|
||||
"SHA-256": sha256.New,
|
||||
"SHA-256-sess": sha256.New,
|
||||
"SHA-512-256": sha512.New,
|
||||
"SHA-512-256-sess": sha512.New,
|
||||
}
|
||||
|
||||
type digestCredentials struct {
|
||||
username, password string
|
||||
}
|
||||
|
||||
type digestTransport struct {
|
||||
digestCredentials
|
||||
transport http.RoundTripper
|
||||
}
|
||||
|
||||
func (dt *digestTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
// Copy the request, so we don't modify the input.
|
||||
req2 := new(http.Request)
|
||||
*req2 = *req
|
||||
req2.Header = make(http.Header)
|
||||
for k, s := range req.Header {
|
||||
req2.Header[k] = s
|
||||
}
|
||||
|
||||
// Fix http: ContentLength=xxx with Body length 0
|
||||
if req2.Body == nil {
|
||||
req2.ContentLength = 0
|
||||
} else if req2.GetBody != nil {
|
||||
var err error
|
||||
req2.Body, err = req2.GetBody()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Make a request to get the 401 that contains the challenge.
|
||||
resp, err := dt.transport.RoundTrip(req)
|
||||
if err != nil || resp.StatusCode != http.StatusUnauthorized {
|
||||
return resp, err
|
||||
}
|
||||
chal := resp.Header.Get(hdrWwwAuthenticateKey)
|
||||
if chal == "" {
|
||||
return resp, ErrDigestBadChallenge
|
||||
}
|
||||
|
||||
c, err := parseChallenge(chal)
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Form credentials based on the challenge
|
||||
cr := dt.newCredentials(req2, c)
|
||||
auth, err := cr.authorize()
|
||||
if err != nil {
|
||||
return resp, err
|
||||
}
|
||||
err = resp.Body.Close()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Make authenticated request
|
||||
req2.Header.Set(hdrAuthorizationKey, auth)
|
||||
return dt.transport.RoundTrip(req2)
|
||||
}
|
||||
|
||||
func (dt *digestTransport) newCredentials(req *http.Request, c *challenge) *credentials {
|
||||
return &credentials{
|
||||
username: dt.username,
|
||||
userhash: c.userhash,
|
||||
realm: c.realm,
|
||||
nonce: c.nonce,
|
||||
digestURI: req.URL.RequestURI(),
|
||||
algorithm: c.algorithm,
|
||||
sessionAlg: strings.HasSuffix(c.algorithm, "-sess"),
|
||||
opaque: c.opaque,
|
||||
messageQop: c.qop,
|
||||
nc: 0,
|
||||
method: req.Method,
|
||||
password: dt.password,
|
||||
}
|
||||
}
|
||||
|
||||
type challenge struct {
|
||||
realm string
|
||||
domain string
|
||||
nonce string
|
||||
opaque string
|
||||
stale string
|
||||
algorithm string
|
||||
qop string
|
||||
userhash string
|
||||
}
|
||||
|
||||
func (c *challenge) setValue(k, v string) error {
|
||||
switch k {
|
||||
case "realm":
|
||||
c.realm = v
|
||||
case "domain":
|
||||
c.domain = v
|
||||
case "nonce":
|
||||
c.nonce = v
|
||||
case "opaque":
|
||||
c.opaque = v
|
||||
case "stale":
|
||||
c.stale = v
|
||||
case "algorithm":
|
||||
c.algorithm = v
|
||||
case "qop":
|
||||
c.qop = v
|
||||
case "charset":
|
||||
if strings.ToUpper(v) != "UTF-8" {
|
||||
return ErrDigestCharset
|
||||
}
|
||||
case "userhash":
|
||||
c.userhash = v
|
||||
default:
|
||||
return ErrDigestBadChallenge
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseChallenge(input string) (*challenge, error) {
|
||||
const ws = " \n\r\t"
|
||||
s := strings.Trim(input, ws)
|
||||
if !strings.HasPrefix(s, "Digest ") {
|
||||
return nil, ErrDigestBadChallenge
|
||||
}
|
||||
s = strings.Trim(s[7:], ws)
|
||||
c := &challenge{}
|
||||
b := strings.Builder{}
|
||||
key := ""
|
||||
quoted := false
|
||||
for _, r := range s {
|
||||
switch r {
|
||||
case '"':
|
||||
quoted = !quoted
|
||||
case ',':
|
||||
if quoted {
|
||||
b.WriteRune(r)
|
||||
} else {
|
||||
val := strings.Trim(b.String(), ws)
|
||||
b.Reset()
|
||||
if err := c.setValue(key, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key = ""
|
||||
}
|
||||
case '=':
|
||||
if quoted {
|
||||
b.WriteRune(r)
|
||||
} else {
|
||||
key = strings.Trim(b.String(), ws)
|
||||
b.Reset()
|
||||
}
|
||||
default:
|
||||
b.WriteRune(r)
|
||||
}
|
||||
}
|
||||
if quoted || (key == "" && b.Len() > 0) {
|
||||
return nil, ErrDigestBadChallenge
|
||||
}
|
||||
if key != "" {
|
||||
val := strings.Trim(b.String(), ws)
|
||||
if err := c.setValue(key, val); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return c, nil
|
||||
}
|
||||
|
||||
type credentials struct {
|
||||
username string
|
||||
userhash string
|
||||
realm string
|
||||
nonce string
|
||||
digestURI string
|
||||
algorithm string
|
||||
sessionAlg bool
|
||||
cNonce string
|
||||
opaque string
|
||||
messageQop string
|
||||
nc int
|
||||
method string
|
||||
password string
|
||||
}
|
||||
|
||||
func (c *credentials) authorize() (string, error) {
|
||||
if _, ok := hashFuncs[c.algorithm]; !ok {
|
||||
return "", ErrDigestAlgNotSupported
|
||||
}
|
||||
|
||||
if err := c.validateQop(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := c.resp()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
sl := make([]string, 0, 10)
|
||||
if c.userhash == "true" {
|
||||
// RFC 7616 3.4.4
|
||||
c.username = c.h(fmt.Sprintf("%s:%s", c.username, c.realm))
|
||||
sl = append(sl, fmt.Sprintf(`userhash=%s`, c.userhash))
|
||||
}
|
||||
sl = append(sl, fmt.Sprintf(`username="%s"`, c.username))
|
||||
sl = append(sl, fmt.Sprintf(`realm="%s"`, c.realm))
|
||||
sl = append(sl, fmt.Sprintf(`nonce="%s"`, c.nonce))
|
||||
sl = append(sl, fmt.Sprintf(`uri="%s"`, c.digestURI))
|
||||
sl = append(sl, fmt.Sprintf(`response="%s"`, resp))
|
||||
sl = append(sl, fmt.Sprintf(`algorithm=%s`, c.algorithm))
|
||||
if c.opaque != "" {
|
||||
sl = append(sl, fmt.Sprintf(`opaque="%s"`, c.opaque))
|
||||
}
|
||||
if c.messageQop != "" {
|
||||
sl = append(sl, fmt.Sprintf("qop=%s", c.messageQop))
|
||||
sl = append(sl, fmt.Sprintf("nc=%08x", c.nc))
|
||||
sl = append(sl, fmt.Sprintf(`cnonce="%s"`, c.cNonce))
|
||||
}
|
||||
|
||||
return fmt.Sprintf("Digest %s", strings.Join(sl, ", ")), nil
|
||||
}
|
||||
|
||||
func (c *credentials) validateQop() error {
|
||||
// Currently only supporting auth quality of protection. TODO: add auth-int support
|
||||
// NOTE: cURL support auth-int qop for requests other than POST and PUT (i.e. w/o body) by hashing an empty string
|
||||
// is this applicable for resty? see: https://github.com/curl/curl/blob/307b7543ea1e73ab04e062bdbe4b5bb409eaba3a/lib/vauth/digest.c#L774
|
||||
if c.messageQop == "" {
|
||||
return ErrDigestNoQop
|
||||
}
|
||||
possibleQops := strings.Split(c.messageQop, ",")
|
||||
var authSupport bool
|
||||
for _, qop := range possibleQops {
|
||||
qop = strings.TrimSpace(qop)
|
||||
if qop == "auth" {
|
||||
authSupport = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !authSupport {
|
||||
return ErrDigestQopNotSupported
|
||||
}
|
||||
|
||||
c.messageQop = "auth"
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *credentials) h(data string) string {
|
||||
hfCtor := hashFuncs[c.algorithm]
|
||||
hf := hfCtor()
|
||||
_, _ = hf.Write([]byte(data)) // Hash.Write never returns an error
|
||||
return fmt.Sprintf("%x", hf.Sum(nil))
|
||||
}
|
||||
|
||||
func (c *credentials) resp() (string, error) {
|
||||
c.nc++
|
||||
|
||||
b := make([]byte, 16)
|
||||
_, err := io.ReadFull(rand.Reader, b)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c.cNonce = fmt.Sprintf("%x", b)[:32]
|
||||
|
||||
ha1 := c.ha1()
|
||||
ha2 := c.ha2()
|
||||
|
||||
return c.kd(ha1, fmt.Sprintf("%s:%08x:%s:%s:%s",
|
||||
c.nonce, c.nc, c.cNonce, c.messageQop, ha2)), nil
|
||||
}
|
||||
|
||||
func (c *credentials) kd(secret, data string) string {
|
||||
return c.h(fmt.Sprintf("%s:%s", secret, data))
|
||||
}
|
||||
|
||||
// RFC 7616 3.4.2
|
||||
func (c *credentials) ha1() string {
|
||||
ret := c.h(fmt.Sprintf("%s:%s:%s", c.username, c.realm, c.password))
|
||||
if c.sessionAlg {
|
||||
return c.h(fmt.Sprintf("%s:%s:%s", ret, c.nonce, c.cNonce))
|
||||
}
|
||||
|
||||
return ret
|
||||
}
|
||||
|
||||
// RFC 7616 3.4.3
|
||||
func (c *credentials) ha2() string {
|
||||
// currently no auth-int support
|
||||
return c.h(fmt.Sprintf("%s:%s", c.method, c.digestURI))
|
||||
}
|
||||
416
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
416
vendor/github.com/go-resty/resty/v2/middleware.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -9,13 +9,13 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -27,15 +27,76 @@ const debugRequestLogKey = "__restyDebugRequestLog"
|
||||
//_______________________________________________________________________
|
||||
|
||||
func parseRequestURL(c *Client, r *Request) error {
|
||||
// GitHub #103 Path Params
|
||||
if len(r.PathParams) > 0 {
|
||||
if l := len(c.PathParams) + len(c.RawPathParams) + len(r.PathParams) + len(r.RawPathParams); l > 0 {
|
||||
params := make(map[string]string, l)
|
||||
|
||||
// GitHub #103 Path Params
|
||||
for p, v := range r.PathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
params[p] = url.PathEscape(v)
|
||||
}
|
||||
}
|
||||
if len(c.PathParams) > 0 {
|
||||
for p, v := range c.PathParams {
|
||||
r.URL = strings.Replace(r.URL, "{"+p+"}", url.PathEscape(v), -1)
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = url.PathEscape(v)
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #663 Raw Path Params
|
||||
for p, v := range r.RawPathParams {
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = v
|
||||
}
|
||||
}
|
||||
for p, v := range c.RawPathParams {
|
||||
if _, ok := params[p]; !ok {
|
||||
params[p] = v
|
||||
}
|
||||
}
|
||||
|
||||
if len(params) > 0 {
|
||||
var prev int
|
||||
buf := acquireBuffer()
|
||||
defer releaseBuffer(buf)
|
||||
// search for the next or first opened curly bracket
|
||||
for curr := strings.Index(r.URL, "{"); curr == 0 || curr >= prev; curr = prev + strings.Index(r.URL[prev:], "{") {
|
||||
// write everything from the previous position up to the current
|
||||
if curr > prev {
|
||||
buf.WriteString(r.URL[prev:curr])
|
||||
}
|
||||
// search for the closed curly bracket from current position
|
||||
next := curr + strings.Index(r.URL[curr:], "}")
|
||||
// if not found, then write the remainder and exit
|
||||
if next < curr {
|
||||
buf.WriteString(r.URL[curr:])
|
||||
prev = len(r.URL)
|
||||
break
|
||||
}
|
||||
// special case for {}, without parameter's name
|
||||
if next == curr+1 {
|
||||
buf.WriteString("{}")
|
||||
} else {
|
||||
// check for the replacement
|
||||
key := r.URL[curr+1 : next]
|
||||
value, ok := params[key]
|
||||
/// keep the original string if the replacement not found
|
||||
if !ok {
|
||||
value = r.URL[curr : next+1]
|
||||
}
|
||||
buf.WriteString(value)
|
||||
}
|
||||
|
||||
// set the previous position after the closed curly bracket
|
||||
prev = next + 1
|
||||
if prev >= len(r.URL) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if buf.Len() > 0 {
|
||||
// write remainder
|
||||
if prev < len(r.URL) {
|
||||
buf.WriteString(r.URL[prev:])
|
||||
}
|
||||
r.URL = buf.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +114,12 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
r.URL = "/" + r.URL
|
||||
}
|
||||
|
||||
reqURL, err = url.Parse(c.HostURL + r.URL)
|
||||
// TODO: change to use c.BaseURL only in v3.0.0
|
||||
baseURL := c.BaseURL
|
||||
if len(baseURL) == 0 {
|
||||
baseURL = c.HostURL
|
||||
}
|
||||
reqURL, err = url.Parse(baseURL + r.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -65,33 +131,36 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
}
|
||||
|
||||
// Adding Query Param
|
||||
query := make(url.Values)
|
||||
for k, v := range c.QueryParam {
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
if len(c.QueryParam)+len(r.QueryParam) > 0 {
|
||||
for k, v := range c.QueryParam {
|
||||
// skip query parameter if it was set in request
|
||||
if _, ok := r.QueryParam[k]; ok {
|
||||
continue
|
||||
}
|
||||
|
||||
r.QueryParam[k] = v[:]
|
||||
}
|
||||
|
||||
// GitHub #123 Preserve query string order partially.
|
||||
// Since not feasible in `SetQuery*` resty methods, because
|
||||
// standard package `url.Encode(...)` sorts the query params
|
||||
// alphabetically
|
||||
if len(r.QueryParam) > 0 {
|
||||
if IsStringEmpty(reqURL.RawQuery) {
|
||||
reqURL.RawQuery = r.QueryParam.Encode()
|
||||
} else {
|
||||
reqURL.RawQuery = reqURL.RawQuery + "&" + r.QueryParam.Encode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range r.QueryParam {
|
||||
// remove query param from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
query.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
query.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #123 Preserve query string order partially.
|
||||
// Since not feasible in `SetQuery*` resty methods, because
|
||||
// standard package `url.Encode(...)` sorts the query params
|
||||
// alphabetically
|
||||
if len(query) > 0 {
|
||||
if IsStringEmpty(reqURL.RawQuery) {
|
||||
reqURL.RawQuery = query.Encode()
|
||||
} else {
|
||||
reqURL.RawQuery = reqURL.RawQuery + "&" + query.Encode()
|
||||
}
|
||||
// GH#797 Unescape query parameters
|
||||
if r.unescapeQueryParams && len(reqURL.RawQuery) > 0 {
|
||||
// at this point, all errors caught up in the above operations
|
||||
// so ignore the return error on query unescape; I realized
|
||||
// while writing the unit test
|
||||
unescapedQuery, _ := url.QueryUnescape(reqURL.RawQuery)
|
||||
reqURL.RawQuery = strings.ReplaceAll(unescapedQuery, " ", "+") // otherwise request becomes bad request
|
||||
}
|
||||
|
||||
r.URL = reqURL.String()
|
||||
@@ -100,71 +169,61 @@ func parseRequestURL(c *Client, r *Request) error {
|
||||
}
|
||||
|
||||
func parseRequestHeader(c *Client, r *Request) error {
|
||||
hdr := make(http.Header)
|
||||
for k := range c.Header {
|
||||
hdr[k] = append(hdr[k], c.Header[k]...)
|
||||
for k, v := range c.Header {
|
||||
if _, ok := r.Header[k]; ok {
|
||||
continue
|
||||
}
|
||||
r.Header[k] = v[:]
|
||||
}
|
||||
|
||||
for k := range r.Header {
|
||||
hdr.Del(k)
|
||||
hdr[k] = append(hdr[k], r.Header[k]...)
|
||||
if IsStringEmpty(r.Header.Get(hdrUserAgentKey)) {
|
||||
r.Header.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
}
|
||||
|
||||
if IsStringEmpty(hdr.Get(hdrUserAgentKey)) {
|
||||
hdr.Set(hdrUserAgentKey, hdrUserAgentValue)
|
||||
if ct := r.Header.Get(hdrContentTypeKey); IsStringEmpty(r.Header.Get(hdrAcceptKey)) && !IsStringEmpty(ct) && (IsJSONType(ct) || IsXMLType(ct)) {
|
||||
r.Header.Set(hdrAcceptKey, r.Header.Get(hdrContentTypeKey))
|
||||
}
|
||||
|
||||
ct := hdr.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(hdr.Get(hdrAcceptKey)) && !IsStringEmpty(ct) &&
|
||||
(IsJSONType(ct) || IsXMLType(ct)) {
|
||||
hdr.Set(hdrAcceptKey, hdr.Get(hdrContentTypeKey))
|
||||
}
|
||||
|
||||
r.Header = hdr
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseRequestBody(c *Client, r *Request) (err error) {
|
||||
func parseRequestBody(c *Client, r *Request) error {
|
||||
if isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
|
||||
// Handling Multipart
|
||||
if r.isMultiPart && !(r.Method == MethodPatch) {
|
||||
if err = handleMultipart(c, r); err != nil {
|
||||
return
|
||||
switch {
|
||||
case r.isMultiPart: // Handling Multipart
|
||||
if err := handleMultipart(c, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Form Data
|
||||
if len(c.FormData) > 0 || len(r.FormData) > 0 {
|
||||
case len(c.FormData) > 0 || len(r.FormData) > 0: // Handling Form Data
|
||||
handleFormData(c, r)
|
||||
|
||||
goto CL
|
||||
}
|
||||
|
||||
// Handling Request body
|
||||
if r.Body != nil {
|
||||
case r.Body == nil && r.bodyBuf == nil: // Handling Request body when nil body
|
||||
// Go http library omits Content-Length if body is nil; use http.NoBody to force it if SetContentLength is true
|
||||
r.Body = http.NoBody
|
||||
fallthrough
|
||||
case r.Body != nil: // Handling Request body
|
||||
handleContentType(c, r)
|
||||
|
||||
if err = handleRequestBody(c, r); err != nil {
|
||||
return
|
||||
if err := handleRequestBody(c, r); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CL:
|
||||
// by default resty won't set content length, you can if you want to :)
|
||||
if (c.setContentLength || r.setContentLength) && r.bodyBuf != nil {
|
||||
r.Header.Set(hdrContentLengthKey, fmt.Sprintf("%d", r.bodyBuf.Len()))
|
||||
if c.setContentLength || r.setContentLength {
|
||||
if r.bodyBuf == nil {
|
||||
r.Header.Set(hdrContentLengthKey, "0")
|
||||
} else {
|
||||
r.Header.Set(hdrContentLengthKey, strconv.Itoa(r.bodyBuf.Len()))
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
if r.bodyBuf == nil {
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
if reader, ok := r.Body.(io.Reader); ok && isPayloadSupported(r.Method, c.AllowGetMethodPayload) {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, reader)
|
||||
} else if c.setContentLength || r.setContentLength {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, http.NoBody)
|
||||
@@ -172,7 +231,9 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, nil)
|
||||
}
|
||||
} else {
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, r.bodyBuf)
|
||||
// fix data race: must deep copy.
|
||||
bodyBuf := bytes.NewBuffer(append([]byte{}, r.bodyBuf.Bytes()...))
|
||||
r.RawRequest, err = http.NewRequest(r.Method, r.URL, bodyBuf)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -206,17 +267,19 @@ func createHTTPRequest(c *Client, r *Request) (err error) {
|
||||
r.RawRequest = r.RawRequest.WithContext(r.ctx)
|
||||
}
|
||||
|
||||
bodyCopy, err := getBodyCopy(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// assign get body func for the underlying raw request instance
|
||||
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
if bodyCopy != nil {
|
||||
return ioutil.NopCloser(bytes.NewReader(bodyCopy.Bytes())), nil
|
||||
if r.RawRequest.GetBody == nil {
|
||||
bodyCopy, err := getBodyCopy(r)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if bodyCopy != nil {
|
||||
buf := bodyCopy.Bytes()
|
||||
r.RawRequest.GetBody = func() (io.ReadCloser, error) {
|
||||
b := bytes.NewReader(buf)
|
||||
return io.NopCloser(b), nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
return
|
||||
@@ -235,43 +298,60 @@ func addCredentials(c *Client, r *Request) error {
|
||||
|
||||
if !c.DisableWarn {
|
||||
if isBasicAuth && !strings.HasPrefix(r.URL, "https") {
|
||||
c.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
|
||||
r.log.Warnf("Using Basic Auth in HTTP mode is not secure, use HTTPS")
|
||||
}
|
||||
}
|
||||
|
||||
// Set the Authorization Header Scheme
|
||||
var authScheme string
|
||||
if !IsStringEmpty(r.AuthScheme) {
|
||||
authScheme = r.AuthScheme
|
||||
} else if !IsStringEmpty(c.AuthScheme) {
|
||||
authScheme = c.AuthScheme
|
||||
} else {
|
||||
authScheme = "Bearer"
|
||||
// Build the token Auth header
|
||||
if !IsStringEmpty(r.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, strings.TrimSpace(r.AuthScheme+" "+r.Token))
|
||||
} else if !IsStringEmpty(c.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, strings.TrimSpace(r.AuthScheme+" "+c.Token))
|
||||
}
|
||||
|
||||
// Build the Token Auth header
|
||||
if !IsStringEmpty(r.Token) { // takes precedence
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+r.Token)
|
||||
} else if !IsStringEmpty(c.Token) {
|
||||
r.RawRequest.Header.Set(c.HeaderAuthorizationKey, authScheme+" "+c.Token)
|
||||
return nil
|
||||
}
|
||||
|
||||
func createCurlCmd(c *Client, r *Request) (err error) {
|
||||
if r.Debug && r.generateCurlOnDebug {
|
||||
if r.resultCurlCmd == nil {
|
||||
r.resultCurlCmd = new(string)
|
||||
}
|
||||
*r.resultCurlCmd = buildCurlRequest(r.RawRequest, c.httpClient.Jar)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func requestLogger(c *Client, r *Request) error {
|
||||
if c.Debug {
|
||||
if r.Debug {
|
||||
rr := r.RawRequest
|
||||
rl := &RequestLog{Header: copyHeaders(rr.Header), Body: r.fmtBodyString(c.debugBodySizeLimit)}
|
||||
rh := copyHeaders(rr.Header)
|
||||
if c.GetClient().Jar != nil {
|
||||
for _, cookie := range c.GetClient().Jar.Cookies(r.RawRequest.URL) {
|
||||
s := fmt.Sprintf("%s=%s", cookie.Name, cookie.Value)
|
||||
if c := rh.Get("Cookie"); c != "" {
|
||||
rh.Set("Cookie", c+"; "+s)
|
||||
} else {
|
||||
rh.Set("Cookie", s)
|
||||
}
|
||||
}
|
||||
}
|
||||
rl := &RequestLog{Header: rh, Body: r.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.requestLog != nil {
|
||||
if err := c.requestLog(rl); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
// fmt.Sprintf("COOKIES:\n%s\n", composeCookies(c.GetClient().Jar, *rr.URL)) +
|
||||
|
||||
reqLog := "\n==============================================================================\n" +
|
||||
"~~~ REQUEST ~~~\n" +
|
||||
reqLog := "\n==============================================================================\n"
|
||||
|
||||
if r.Debug && r.generateCurlOnDebug {
|
||||
reqLog += "~~~ REQUEST(CURL) ~~~\n" +
|
||||
fmt.Sprintf(" %v\n", *r.resultCurlCmd)
|
||||
}
|
||||
|
||||
reqLog += "~~~ REQUEST ~~~\n" +
|
||||
fmt.Sprintf("%s %s %s\n", r.Method, rr.URL.RequestURI(), rr.Proto) +
|
||||
fmt.Sprintf("HOST : %s\n", rr.URL.Host) +
|
||||
fmt.Sprintf("HEADERS:\n%s\n", composeHeaders(c, r, rl.Header)) +
|
||||
@@ -290,7 +370,7 @@ func requestLogger(c *Client, r *Request) error {
|
||||
//_______________________________________________________________________
|
||||
|
||||
func responseLogger(c *Client, res *Response) error {
|
||||
if c.Debug {
|
||||
if res.Request.Debug {
|
||||
rl := &ResponseLog{Header: copyHeaders(res.Header()), Body: res.fmtBodyString(c.debugBodySizeLimit)}
|
||||
if c.responseLog != nil {
|
||||
if err := c.responseLog(rl); err != nil {
|
||||
@@ -301,7 +381,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
debugLog := res.Request.values[debugRequestLogKey].(string)
|
||||
debugLog += "~~~ RESPONSE ~~~\n" +
|
||||
fmt.Sprintf("STATUS : %s\n", res.Status()) +
|
||||
fmt.Sprintf("PROTO : %s\n", res.RawResponse.Proto) +
|
||||
fmt.Sprintf("PROTO : %s\n", res.Proto()) +
|
||||
fmt.Sprintf("RECEIVED AT : %v\n", res.ReceivedAt().Format(time.RFC3339Nano)) +
|
||||
fmt.Sprintf("TIME DURATION: %v\n", res.Time()) +
|
||||
"HEADERS :\n" +
|
||||
@@ -313,7 +393,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
}
|
||||
debugLog += "==============================================================================\n"
|
||||
|
||||
c.log.Debugf("%s", debugLog)
|
||||
res.Request.log.Debugf("%s", debugLog)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -321,6 +401,7 @@ func responseLogger(c *Client, res *Response) error {
|
||||
|
||||
func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
if res.StatusCode() == http.StatusNoContent {
|
||||
res.Request.Error = nil
|
||||
return
|
||||
}
|
||||
// Handles only JSON or XML content type
|
||||
@@ -343,7 +424,10 @@ func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
}
|
||||
|
||||
if res.Request.Error != nil {
|
||||
err = Unmarshalc(c, ct, res.body, res.Request.Error)
|
||||
unmarshalErr := Unmarshalc(c, ct, res.body, res.Request.Error)
|
||||
if unmarshalErr != nil {
|
||||
c.log.Warnf("Cannot unmarshal response body: %s", unmarshalErr)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -351,13 +435,20 @@ func parseResponseBody(c *Client, res *Response) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func handleMultipart(c *Client, r *Request) (err error) {
|
||||
func handleMultipart(c *Client, r *Request) error {
|
||||
r.bodyBuf = acquireBuffer()
|
||||
w := multipart.NewWriter(r.bodyBuf)
|
||||
|
||||
// Set boundary if not set by user
|
||||
if r.multipartBoundary != "" {
|
||||
if err := w.SetBoundary(r.multipartBoundary); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
if err := w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -366,12 +457,11 @@ func handleMultipart(c *Client, r *Request) (err error) {
|
||||
for k, v := range r.FormData {
|
||||
for _, iv := range v {
|
||||
if strings.HasPrefix(k, "@") { // file
|
||||
err = addFile(w, k[1:], iv)
|
||||
if err != nil {
|
||||
return
|
||||
if err := addFile(w, k[1:], iv); err != nil {
|
||||
return err
|
||||
}
|
||||
} else { // form value
|
||||
if err = w.WriteField(k, iv); err != nil {
|
||||
if err := w.WriteField(k, iv); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -379,55 +469,41 @@ func handleMultipart(c *Client, r *Request) (err error) {
|
||||
}
|
||||
|
||||
// #21 - adding io.Reader support
|
||||
if len(r.multipartFiles) > 0 {
|
||||
for _, f := range r.multipartFiles {
|
||||
err = addFileReader(w, f)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
for _, f := range r.multipartFiles {
|
||||
if err := addFileReader(w, f); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
// GitHub #130 adding multipart field support with content type
|
||||
if len(r.multipartFields) > 0 {
|
||||
for _, mf := range r.multipartFields {
|
||||
if err = addMultipartFormField(w, mf); err != nil {
|
||||
return
|
||||
}
|
||||
for _, mf := range r.multipartFields {
|
||||
if err := addMultipartFormField(w, mf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
r.Header.Set(hdrContentTypeKey, w.FormDataContentType())
|
||||
err = w.Close()
|
||||
|
||||
return
|
||||
return w.Close()
|
||||
}
|
||||
|
||||
func handleFormData(c *Client, r *Request) {
|
||||
formData := url.Values{}
|
||||
|
||||
for k, v := range c.FormData {
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
if _, ok := r.FormData[k]; ok {
|
||||
continue
|
||||
}
|
||||
r.FormData[k] = v[:]
|
||||
}
|
||||
|
||||
for k, v := range r.FormData {
|
||||
// remove form data field from client level by key
|
||||
// since overrides happens for that key in the request
|
||||
formData.Del(k)
|
||||
|
||||
for _, iv := range v {
|
||||
formData.Add(k, iv)
|
||||
}
|
||||
}
|
||||
|
||||
r.bodyBuf = bytes.NewBuffer([]byte(formData.Encode()))
|
||||
r.bodyBuf = acquireBuffer()
|
||||
r.bodyBuf.WriteString(r.FormData.Encode())
|
||||
r.Header.Set(hdrContentTypeKey, formContentType)
|
||||
r.isFormData = true
|
||||
}
|
||||
|
||||
func handleContentType(c *Client, r *Request) {
|
||||
if r.Body == http.NoBody {
|
||||
return
|
||||
}
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
if IsStringEmpty(contentType) {
|
||||
contentType = DetectContentType(r.Body)
|
||||
@@ -435,45 +511,42 @@ func handleContentType(c *Client, r *Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func handleRequestBody(c *Client, r *Request) (err error) {
|
||||
func handleRequestBody(c *Client, r *Request) error {
|
||||
var bodyBytes []byte
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
r.bodyBuf = nil
|
||||
|
||||
if reader, ok := r.Body.(io.Reader); ok {
|
||||
switch body := r.Body.(type) {
|
||||
case io.Reader:
|
||||
if c.setContentLength || r.setContentLength { // keep backward compatibility
|
||||
r.bodyBuf = acquireBuffer()
|
||||
_, err = r.bodyBuf.ReadFrom(reader)
|
||||
if _, err := r.bodyBuf.ReadFrom(body); err != nil {
|
||||
return err
|
||||
}
|
||||
r.Body = nil
|
||||
} else {
|
||||
// Otherwise buffer less processing for `io.Reader`, sounds good.
|
||||
return
|
||||
return nil
|
||||
}
|
||||
} else if b, ok := r.Body.([]byte); ok {
|
||||
bodyBytes = b
|
||||
} else if s, ok := r.Body.(string); ok {
|
||||
bodyBytes = []byte(s)
|
||||
} else if IsJSONType(contentType) &&
|
||||
(kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) {
|
||||
r.bodyBuf, err = jsonMarshal(c, r, r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
case []byte:
|
||||
bodyBytes = body
|
||||
case string:
|
||||
bodyBytes = []byte(body)
|
||||
default:
|
||||
contentType := r.Header.Get(hdrContentTypeKey)
|
||||
kind := kindOf(r.Body)
|
||||
var err error
|
||||
if IsJSONType(contentType) && (kind == reflect.Struct || kind == reflect.Map || kind == reflect.Slice) {
|
||||
r.bodyBuf, err = jsonMarshal(c, r, r.Body)
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
bodyBytes, err = c.XMLMarshal(r.Body)
|
||||
}
|
||||
} else if IsXMLType(contentType) && (kind == reflect.Struct) {
|
||||
bodyBytes, err = c.XMLMarshal(r.Body)
|
||||
if err != nil {
|
||||
return
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if bodyBytes == nil && r.bodyBuf == nil {
|
||||
err = errors.New("unsupported 'Body' type/value")
|
||||
}
|
||||
|
||||
// if any errors during body bytes handling, return it
|
||||
if err != nil {
|
||||
return
|
||||
return errors.New("unsupported 'Body' type/value")
|
||||
}
|
||||
|
||||
// []byte into Buffer
|
||||
@@ -482,7 +555,7 @@ func handleRequestBody(c *Client, r *Request) (err error) {
|
||||
_, _ = r.bodyBuf.Write(bodyBytes)
|
||||
}
|
||||
|
||||
return
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveResponseIntoFile(c *Client, res *Response) error {
|
||||
@@ -521,20 +594,25 @@ func saveResponseIntoFile(c *Client, res *Response) error {
|
||||
func getBodyCopy(r *Request) (*bytes.Buffer, error) {
|
||||
// If r.bodyBuf present, return the copy
|
||||
if r.bodyBuf != nil {
|
||||
return bytes.NewBuffer(r.bodyBuf.Bytes()), nil
|
||||
bodyCopy := acquireBuffer()
|
||||
if _, err := io.Copy(bodyCopy, bytes.NewReader(r.bodyBuf.Bytes())); err != nil {
|
||||
// cannot use io.Copy(bodyCopy, r.bodyBuf) because io.Copy reset r.bodyBuf
|
||||
return nil, err
|
||||
}
|
||||
return bodyCopy, nil
|
||||
}
|
||||
|
||||
// Maybe body is `io.Reader`.
|
||||
// Note: Resty user have to watchout for large body size of `io.Reader`
|
||||
if r.RawRequest.Body != nil {
|
||||
b, err := ioutil.ReadAll(r.RawRequest.Body)
|
||||
b, err := io.ReadAll(r.RawRequest.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Restore the Body
|
||||
closeq(r.RawRequest.Body)
|
||||
r.RawRequest.Body = ioutil.NopCloser(bytes.NewBuffer(b))
|
||||
r.RawRequest.Body = io.NopCloser(bytes.NewBuffer(b))
|
||||
|
||||
// Return the Body bytes
|
||||
return bytes.NewBuffer(b), nil
|
||||
|
||||
47
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
47
vendor/github.com/go-resty/resty/v2/redirect.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -12,18 +12,23 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrAutoRedirectDisabled = errors.New("auto redirect is disabled")
|
||||
)
|
||||
|
||||
type (
|
||||
// RedirectPolicy to regulate the redirects in the resty client.
|
||||
// Objects implementing the RedirectPolicy interface can be registered as
|
||||
// RedirectPolicy to regulate the redirects in the Resty client.
|
||||
// Objects implementing the [RedirectPolicy] interface can be registered as
|
||||
//
|
||||
// Apply function should return nil to continue the redirect jounery, otherwise
|
||||
// Apply function should return nil to continue the redirect journey; otherwise
|
||||
// return error to stop the redirect.
|
||||
RedirectPolicy interface {
|
||||
Apply(req *http.Request, via []*http.Request) error
|
||||
}
|
||||
|
||||
// The RedirectPolicyFunc type is an adapter to allow the use of ordinary functions as RedirectPolicy.
|
||||
// If f is a function with the appropriate signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls f.
|
||||
// The [RedirectPolicyFunc] type is an adapter to allow the use of ordinary
|
||||
// functions as [RedirectPolicy]. If `f` is a function with the appropriate
|
||||
// signature, RedirectPolicyFunc(f) is a RedirectPolicy object that calls `f`.
|
||||
RedirectPolicyFunc func(*http.Request, []*http.Request) error
|
||||
)
|
||||
|
||||
@@ -32,16 +37,18 @@ func (f RedirectPolicyFunc) Apply(req *http.Request, via []*http.Request) error
|
||||
return f(req, via)
|
||||
}
|
||||
|
||||
// NoRedirectPolicy is used to disable redirects in the HTTP client
|
||||
// resty.SetRedirectPolicy(NoRedirectPolicy())
|
||||
// NoRedirectPolicy is used to disable redirects in the Resty client
|
||||
//
|
||||
// resty.SetRedirectPolicy(NoRedirectPolicy())
|
||||
func NoRedirectPolicy() RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
return errors.New("auto redirect is disabled")
|
||||
return ErrAutoRedirectDisabled
|
||||
})
|
||||
}
|
||||
|
||||
// FlexibleRedirectPolicy is convenient method to create No of redirect policy for HTTP client.
|
||||
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
|
||||
// FlexibleRedirectPolicy method is convenient for creating several redirect policies for Resty clients.
|
||||
//
|
||||
// resty.SetRedirectPolicy(FlexibleRedirectPolicy(20))
|
||||
func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
|
||||
return RedirectPolicyFunc(func(req *http.Request, via []*http.Request) error {
|
||||
if len(via) >= noOfRedirect {
|
||||
@@ -52,9 +59,10 @@ func FlexibleRedirectPolicy(noOfRedirect int) RedirectPolicy {
|
||||
})
|
||||
}
|
||||
|
||||
// DomainCheckRedirectPolicy is convenient method to define domain name redirect rule in resty client.
|
||||
// Redirect is allowed for only mentioned host in the policy.
|
||||
// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
// DomainCheckRedirectPolicy method is convenient for defining domain name redirect rules in Resty clients.
|
||||
// Redirect is allowed only for the host mentioned in the policy.
|
||||
//
|
||||
// resty.SetRedirectPolicy(DomainCheckRedirectPolicy("host1.com", "host2.org", "host3.net"))
|
||||
func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
|
||||
hosts := make(map[string]bool)
|
||||
for _, h := range hostnames {
|
||||
@@ -72,10 +80,6 @@ func DomainCheckRedirectPolicy(hostnames ...string) RedirectPolicy {
|
||||
return fn
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func getHostname(host string) (hostname string) {
|
||||
if strings.Index(host, ":") > 0 {
|
||||
host, _, _ = net.SplitHostPort(host)
|
||||
@@ -84,10 +88,11 @@ func getHostname(host string) (hostname string) {
|
||||
return
|
||||
}
|
||||
|
||||
// By default Golang will not redirect request headers
|
||||
// after go throughing various discussion comments from thread
|
||||
// By default, Golang will not redirect request headers.
|
||||
// After reading through the various discussion comments from the thread -
|
||||
// https://github.com/golang/go/issues/4800
|
||||
// Resty will add all the headers during a redirect for the same host
|
||||
// Resty will add all the headers during a redirect for the same host and
|
||||
// adds library user-agent if the Host is different.
|
||||
func checkHostAndAddHeaders(cur *http.Request, pre *http.Request) {
|
||||
curHostname := getHostname(cur.URL.Host)
|
||||
preHostname := getHostname(pre.URL.Host)
|
||||
|
||||
865
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
865
vendor/github.com/go-resty/resty/v2/request.go
generated
vendored
File diff suppressed because it is too large
Load Diff
64
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
64
vendor/github.com/go-resty/resty/v2/response.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -17,7 +17,7 @@ import (
|
||||
// Response struct and methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// Response struct holds response values of executed request.
|
||||
// Response struct holds response values of executed requests.
|
||||
type Response struct {
|
||||
Request *Request
|
||||
RawResponse *http.Response
|
||||
@@ -27,9 +27,10 @@ type Response struct {
|
||||
receivedAt time.Time
|
||||
}
|
||||
|
||||
// Body method returns HTTP response as []byte array for the executed request.
|
||||
// Body method returns the HTTP response as `[]byte` slice for the executed request.
|
||||
//
|
||||
// Note: `Response.Body` might be nil, if `Request.SetOutput` is used.
|
||||
// NOTE: [Response.Body] might be nil if [Request.SetOutput] is used.
|
||||
// Also see [Request.SetDoNotParseResponse], [Client.SetDoNotParseResponse]
|
||||
func (r *Response) Body() []byte {
|
||||
if r.RawResponse == nil {
|
||||
return []byte{}
|
||||
@@ -37,7 +38,18 @@ func (r *Response) Body() []byte {
|
||||
return r.body
|
||||
}
|
||||
|
||||
// SetBody method sets [Response] body in byte slice. Typically,
|
||||
// It is helpful for test cases.
|
||||
//
|
||||
// resp.SetBody([]byte("This is test body content"))
|
||||
// resp.SetBody(nil)
|
||||
func (r *Response) SetBody(b []byte) *Response {
|
||||
r.body = b
|
||||
return r
|
||||
}
|
||||
|
||||
// Status method returns the HTTP status string for the executed request.
|
||||
//
|
||||
// Example: 200 OK
|
||||
func (r *Response) Status() string {
|
||||
if r.RawResponse == nil {
|
||||
@@ -47,6 +59,7 @@ func (r *Response) Status() string {
|
||||
}
|
||||
|
||||
// StatusCode method returns the HTTP status code for the executed request.
|
||||
//
|
||||
// Example: 200
|
||||
func (r *Response) StatusCode() int {
|
||||
if r.RawResponse == nil {
|
||||
@@ -64,11 +77,15 @@ func (r *Response) Proto() string {
|
||||
}
|
||||
|
||||
// Result method returns the response value as an object if it has one
|
||||
//
|
||||
// See [Request.SetResult]
|
||||
func (r *Response) Result() interface{} {
|
||||
return r.Request.Result
|
||||
}
|
||||
|
||||
// Error method returns the error object if it has one
|
||||
//
|
||||
// See [Request.SetError], [Client.SetError]
|
||||
func (r *Response) Error() interface{} {
|
||||
return r.Request.Error
|
||||
}
|
||||
@@ -81,7 +98,7 @@ func (r *Response) Header() http.Header {
|
||||
return r.RawResponse.Header
|
||||
}
|
||||
|
||||
// Cookies method to access all the response cookies
|
||||
// Cookies method to returns all the response cookies
|
||||
func (r *Response) Cookies() []*http.Cookie {
|
||||
if r.RawResponse == nil {
|
||||
return make([]*http.Cookie, 0)
|
||||
@@ -89,18 +106,20 @@ func (r *Response) Cookies() []*http.Cookie {
|
||||
return r.RawResponse.Cookies()
|
||||
}
|
||||
|
||||
// String method returns the body of the server response as String.
|
||||
// String method returns the body of the HTTP response as a `string`.
|
||||
// It returns an empty string if it is nil or the body is zero length.
|
||||
func (r *Response) String() string {
|
||||
if r.body == nil {
|
||||
if len(r.body) == 0 {
|
||||
return ""
|
||||
}
|
||||
return strings.TrimSpace(string(r.body))
|
||||
}
|
||||
|
||||
// Time method returns the time of HTTP response time that from request we sent and received a request.
|
||||
// Time method returns the duration of HTTP response time from the request we sent
|
||||
// and received a request.
|
||||
//
|
||||
// See `Response.ReceivedAt` to know when client received response and see `Response.Request.Time` to know
|
||||
// when client sent a request.
|
||||
// See [Response.ReceivedAt] to know when the client received a response and see
|
||||
// `Response.Request.Time` to know when the client sent a request.
|
||||
func (r *Response) Time() time.Duration {
|
||||
if r.Request.clientTrace != nil {
|
||||
return r.Request.TraceInfo().TotalTime
|
||||
@@ -108,23 +127,25 @@ func (r *Response) Time() time.Duration {
|
||||
return r.receivedAt.Sub(r.Request.Time)
|
||||
}
|
||||
|
||||
// ReceivedAt method returns when response got received from server for the request.
|
||||
// ReceivedAt method returns the time we received a response from the server for the request.
|
||||
func (r *Response) ReceivedAt() time.Time {
|
||||
return r.receivedAt
|
||||
}
|
||||
|
||||
// Size method returns the HTTP response size in bytes. Ya, you can relay on HTTP `Content-Length` header,
|
||||
// however it won't be good for chucked transfer/compressed response. Since Resty calculates response size
|
||||
// at the client end. You will get actual size of the http response.
|
||||
// Size method returns the HTTP response size in bytes. Yeah, you can rely on HTTP `Content-Length`
|
||||
// header, however it won't be available for chucked transfer/compressed response.
|
||||
// Since Resty captures response size details when processing the response body
|
||||
// when possible. So that users get the actual size of response bytes.
|
||||
func (r *Response) Size() int64 {
|
||||
return r.size
|
||||
}
|
||||
|
||||
// RawBody method exposes the HTTP raw response body. Use this method in-conjunction with `SetDoNotParseResponse`
|
||||
// option otherwise you get an error as `read err: http: read on closed response body`.
|
||||
// RawBody method exposes the HTTP raw response body. Use this method in conjunction with
|
||||
// [Client.SetDoNotParseResponse] or [Request.SetDoNotParseResponse]
|
||||
// option; otherwise, you get an error as `read err: http: read on closed response body.`
|
||||
//
|
||||
// Do not forget to close the body, otherwise you might get into connection leaks, no connection reuse.
|
||||
// Basically you have taken over the control of response parsing from `Resty`.
|
||||
// You have taken over the control of response parsing from Resty.
|
||||
func (r *Response) RawBody() io.ReadCloser {
|
||||
if r.RawResponse == nil {
|
||||
return nil
|
||||
@@ -142,10 +163,6 @@ func (r *Response) IsError() bool {
|
||||
return r.StatusCode() > 399
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Response Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (r *Response) setReceivedAt() {
|
||||
r.receivedAt = time.Now()
|
||||
if r.Request.clientTrace != nil {
|
||||
@@ -154,7 +171,10 @@ func (r *Response) setReceivedAt() {
|
||||
}
|
||||
|
||||
func (r *Response) fmtBodyString(sl int64) string {
|
||||
if r.body != nil {
|
||||
if r.Request.client.notParseResponse || r.Request.notParseResponse {
|
||||
return "***** DO NOT PARSE RESPONSE - Enabled *****"
|
||||
}
|
||||
if len(r.body) > 0 {
|
||||
if int64(len(r.body)) > sl {
|
||||
return fmt.Sprintf("***** RESPONSE TOO LARGE (size - %d) *****", len(r.body))
|
||||
}
|
||||
|
||||
8
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
8
vendor/github.com/go-resty/resty/v2/resty.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
// Version # of resty
|
||||
const Version = "2.7.0"
|
||||
const Version = "2.17.1"
|
||||
|
||||
// New method creates a new Resty client.
|
||||
func New() *Client {
|
||||
@@ -24,12 +24,12 @@ func New() *Client {
|
||||
})
|
||||
}
|
||||
|
||||
// NewWithClient method creates a new Resty client with given `http.Client`.
|
||||
// NewWithClient method creates a new Resty client with given [http.Client].
|
||||
func NewWithClient(hc *http.Client) *Client {
|
||||
return createClient(hc)
|
||||
}
|
||||
|
||||
// NewWithLocalAddr method creates a new Resty client with given Local Address
|
||||
// NewWithLocalAddr method creates a new Resty client with the given Local Address.
|
||||
// to dial from.
|
||||
func NewWithLocalAddr(localAddr net.Addr) *Client {
|
||||
cookieJar, _ := cookiejar.New(&cookiejar.Options{PublicSuffixList: publicsuffix.List})
|
||||
|
||||
58
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
58
vendor/github.com/go-resty/resty/v2/retry.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@ package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"io"
|
||||
"math"
|
||||
"math/rand"
|
||||
"sync"
|
||||
@@ -22,7 +23,7 @@ type (
|
||||
// Option is to create convenient retry options like wait time, max retries, etc.
|
||||
Option func(*Options)
|
||||
|
||||
// RetryConditionFunc type is for retry condition function
|
||||
// RetryConditionFunc type is for the retry condition function
|
||||
// input: non-nil Response OR request execution error
|
||||
RetryConditionFunc func(*Response, error) bool
|
||||
|
||||
@@ -32,8 +33,8 @@ type (
|
||||
// RetryAfterFunc returns time to wait before retry
|
||||
// For example, it can parse HTTP Retry-After header
|
||||
// https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
|
||||
// Non-nil error is returned if it is found that request is not retryable
|
||||
// (0, nil) is a special result means 'use default algorithm'
|
||||
// Non-nil error is returned if it is found that the request is not retryable
|
||||
// (0, nil) is a special result that means 'use default algorithm'
|
||||
RetryAfterFunc func(*Client, *Response) (time.Duration, error)
|
||||
|
||||
// Options struct is used to hold retry settings.
|
||||
@@ -43,6 +44,7 @@ type (
|
||||
maxWaitTime time.Duration
|
||||
retryConditions []RetryConditionFunc
|
||||
retryHooks []OnRetryFunc
|
||||
resetReaders bool
|
||||
}
|
||||
)
|
||||
|
||||
@@ -67,7 +69,7 @@ func MaxWaitTime(value time.Duration) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// RetryConditions sets the conditions that will be checked for retry.
|
||||
// RetryConditions sets the conditions that will be checked for retry
|
||||
func RetryConditions(conditions []RetryConditionFunc) Option {
|
||||
return func(o *Options) {
|
||||
o.retryConditions = conditions
|
||||
@@ -81,6 +83,14 @@ func RetryHooks(hooks []OnRetryFunc) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// ResetMultipartReaders sets a boolean value which will lead the start being seeked out
|
||||
// on all multipart file readers if they implement [io.ReadSeeker]
|
||||
func ResetMultipartReaders(value bool) Option {
|
||||
return func(o *Options) {
|
||||
o.resetReaders = value
|
||||
}
|
||||
}
|
||||
|
||||
// Backoff retries with increasing timeout duration up until X amount of retries
|
||||
// (Default is 3 attempts, Override with option Retries(n))
|
||||
func Backoff(operation func() (*Response, error), options ...Option) error {
|
||||
@@ -125,6 +135,15 @@ func Backoff(operation func() (*Response, error), options ...Option) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if opts.resetReaders {
|
||||
if err := resetFileReaders(resp.Request.multipartFiles); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := resetFieldReaders(resp.Request.multipartFields); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
for _, hook := range opts.retryHooks {
|
||||
hook(resp, err)
|
||||
}
|
||||
@@ -186,13 +205,16 @@ func sleepDuration(resp *Response, min, max time.Duration, attempt int) (time.Du
|
||||
}
|
||||
|
||||
// Return capped exponential backoff with jitter
|
||||
// http://www.awsarchitectureblog.com/2015/03/backoff.html
|
||||
// https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
|
||||
func jitterBackoff(min, max time.Duration, attempt int) time.Duration {
|
||||
base := float64(min)
|
||||
capLevel := float64(max)
|
||||
|
||||
temp := math.Min(capLevel, base*math.Exp2(float64(attempt)))
|
||||
ri := time.Duration(temp / 2)
|
||||
if ri == 0 {
|
||||
ri = time.Nanosecond
|
||||
}
|
||||
result := randDuration(ri)
|
||||
|
||||
if result < min {
|
||||
@@ -219,3 +241,27 @@ func newRnd() *rand.Rand {
|
||||
var src = rand.NewSource(seed)
|
||||
return rand.New(src)
|
||||
}
|
||||
|
||||
func resetFileReaders(files []*File) error {
|
||||
for _, f := range files {
|
||||
if rs, ok := f.Reader.(io.ReadSeeker); ok {
|
||||
if _, err := rs.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resetFieldReaders(fields []*MultipartField) error {
|
||||
for _, f := range fields {
|
||||
if rs, ok := f.Reader.(io.ReadSeeker); ok {
|
||||
if _, err := rs.Seek(0, io.SeekStart); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
14
vendor/github.com/go-resty/resty/v2/shellescape/BUILD.bazel
generated
vendored
Normal file
14
vendor/github.com/go-resty/resty/v2/shellescape/BUILD.bazel
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
load("@io_bazel_rules_go//go:def.bzl", "go_library")
|
||||
|
||||
go_library(
|
||||
name = "shellescape",
|
||||
srcs = ["shellescape.go"],
|
||||
importpath = "github.com/go-resty/resty/v2/shellescape",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
alias(
|
||||
name = "go_default_library",
|
||||
actual = ":shellescape",
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
40
vendor/github.com/go-resty/resty/v2/shellescape/shellescape.go
generated
vendored
Normal file
40
vendor/github.com/go-resty/resty/v2/shellescape/shellescape.go
generated
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// Copyright (c) 2015-present Jeevanandam M (jeeva@myjeeva.com)
|
||||
// 2024 Ahuigo (https://github.com/ahuigo)
|
||||
// All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
/*
|
||||
Package shellescape provides the methods to escape arbitrary
|
||||
strings for a safe use as command line arguments in the most common
|
||||
POSIX shells.
|
||||
|
||||
The original Python package which this work was inspired by can be found
|
||||
at https://pypi.python.org/pypi/shellescape.
|
||||
*/
|
||||
package shellescape
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var pattern *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
pattern = regexp.MustCompile(`[^\w@%+=:,./-]`)
|
||||
}
|
||||
|
||||
// Quote method returns a shell-escaped version of the string. The returned value
|
||||
// can safely be used as one token in a shell command line.
|
||||
func Quote(s string) string {
|
||||
if len(s) == 0 {
|
||||
return "''"
|
||||
}
|
||||
|
||||
if pattern.MatchString(s) {
|
||||
return "'" + strings.ReplaceAll(s, "'", "'\"'\"'") + "'"
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
52
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
52
vendor/github.com/go-resty/resty/v2/trace.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"crypto/tls"
|
||||
"net"
|
||||
"net/http/httptrace"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -16,32 +17,30 @@ import (
|
||||
// TraceInfo struct
|
||||
//_______________________________________________________________________
|
||||
|
||||
// TraceInfo struct is used provide request trace info such as DNS lookup
|
||||
// TraceInfo struct is used to provide request trace info such as DNS lookup
|
||||
// duration, Connection obtain duration, Server processing duration, etc.
|
||||
//
|
||||
// Since v2.0.0
|
||||
type TraceInfo struct {
|
||||
// DNSLookup is a duration that transport took to perform
|
||||
// DNSLookup is the duration that transport took to perform
|
||||
// DNS lookup.
|
||||
DNSLookup time.Duration
|
||||
|
||||
// ConnTime is a duration that took to obtain a successful connection.
|
||||
// ConnTime is the duration it took to obtain a successful connection.
|
||||
ConnTime time.Duration
|
||||
|
||||
// TCPConnTime is a duration that took to obtain the TCP connection.
|
||||
// TCPConnTime is the duration it took to obtain the TCP connection.
|
||||
TCPConnTime time.Duration
|
||||
|
||||
// TLSHandshake is a duration that TLS handshake took place.
|
||||
// TLSHandshake is the duration of the TLS handshake.
|
||||
TLSHandshake time.Duration
|
||||
|
||||
// ServerTime is a duration that server took to respond first byte.
|
||||
// ServerTime is the server's duration for responding to the first byte.
|
||||
ServerTime time.Duration
|
||||
|
||||
// ResponseTime is a duration since first response byte from server to
|
||||
// ResponseTime is the duration since the first response byte from the server to
|
||||
// request completion.
|
||||
ResponseTime time.Duration
|
||||
|
||||
// TotalTime is a duration that total request took end-to-end.
|
||||
// TotalTime is the duration of the total time request taken end-to-end.
|
||||
TotalTime time.Duration
|
||||
|
||||
// IsConnReused is whether this connection has been previously
|
||||
@@ -52,7 +51,7 @@ type TraceInfo struct {
|
||||
// idle pool.
|
||||
IsConnWasIdle bool
|
||||
|
||||
// ConnIdleTime is a duration how long the connection was previously
|
||||
// ConnIdleTime is the duration how long the connection that was previously
|
||||
// idle, if IsConnWasIdle is true.
|
||||
ConnIdleTime time.Duration
|
||||
|
||||
@@ -68,10 +67,11 @@ type TraceInfo struct {
|
||||
// ClientTrace struct and its methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// tracer struct maps the `httptrace.ClientTrace` hooks into Fields
|
||||
// with same naming for easy understanding. Plus additional insights
|
||||
// Request.
|
||||
// clientTrace struct maps the [httptrace.ClientTrace] hooks into Fields
|
||||
// with the same naming for easy understanding. Plus additional insights
|
||||
// [Request].
|
||||
type clientTrace struct {
|
||||
lock sync.RWMutex
|
||||
getConn time.Time
|
||||
dnsStart time.Time
|
||||
dnsDone time.Time
|
||||
@@ -84,46 +84,60 @@ type clientTrace struct {
|
||||
gotConnInfo httptrace.GotConnInfo
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Trace unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
func (t *clientTrace) createContext(ctx context.Context) context.Context {
|
||||
return httptrace.WithClientTrace(
|
||||
ctx,
|
||||
&httptrace.ClientTrace{
|
||||
DNSStart: func(_ httptrace.DNSStartInfo) {
|
||||
t.lock.Lock()
|
||||
t.dnsStart = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
DNSDone: func(_ httptrace.DNSDoneInfo) {
|
||||
t.lock.Lock()
|
||||
t.dnsDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
ConnectStart: func(_, _ string) {
|
||||
t.lock.Lock()
|
||||
if t.dnsDone.IsZero() {
|
||||
t.dnsDone = time.Now()
|
||||
}
|
||||
if t.dnsStart.IsZero() {
|
||||
t.dnsStart = t.dnsDone
|
||||
}
|
||||
t.lock.Unlock()
|
||||
},
|
||||
ConnectDone: func(net, addr string, err error) {
|
||||
t.lock.Lock()
|
||||
t.connectDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GetConn: func(_ string) {
|
||||
t.lock.Lock()
|
||||
t.getConn = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GotConn: func(ci httptrace.GotConnInfo) {
|
||||
t.lock.Lock()
|
||||
t.gotConn = time.Now()
|
||||
t.gotConnInfo = ci
|
||||
t.lock.Unlock()
|
||||
},
|
||||
GotFirstResponseByte: func() {
|
||||
t.lock.Lock()
|
||||
t.gotFirstResponseByte = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
TLSHandshakeStart: func() {
|
||||
t.lock.Lock()
|
||||
t.tlsHandshakeStart = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
TLSHandshakeDone: func(_ tls.ConnectionState, _ error) {
|
||||
t.lock.Lock()
|
||||
t.tlsHandshakeDone = time.Now()
|
||||
t.lock.Unlock()
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
5
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
5
vendor/github.com/go-resty/resty/v2/transport.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
//go:build go1.13
|
||||
// +build go1.13
|
||||
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -24,7 +25,7 @@ func createTransport(localAddr net.Addr) *http.Transport {
|
||||
}
|
||||
return &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: dialer.DialContext,
|
||||
DialContext: transportDialContext(dialer),
|
||||
ForceAttemptHTTP2: true,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
|
||||
3
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
3
vendor/github.com/go-resty/resty/v2/transport112.go
generated
vendored
@@ -1,6 +1,7 @@
|
||||
//go:build !go1.13
|
||||
// +build !go1.13
|
||||
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
|
||||
17
vendor/github.com/go-resty/resty/v2/transport_js.go
generated
vendored
Normal file
17
vendor/github.com/go-resty/resty/v2/transport_js.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build js && wasm
|
||||
// +build js,wasm
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func transportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return nil
|
||||
}
|
||||
17
vendor/github.com/go-resty/resty/v2/transport_other.go
generated
vendored
Normal file
17
vendor/github.com/go-resty/resty/v2/transport_other.go
generated
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright 2021 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build !(js && wasm)
|
||||
// +build !js !wasm
|
||||
|
||||
package resty
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
)
|
||||
|
||||
func transportDialContext(dialer *net.Dialer) func(context.Context, string, string) (net.Conn, error) {
|
||||
return dialer.DialContext
|
||||
}
|
||||
102
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
102
vendor/github.com/go-resty/resty/v2/util.go
generated
vendored
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2015-2021 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// Copyright (c) 2015-2024 Jeevanandam M (jeeva@myjeeva.com), All rights reserved.
|
||||
// resty source code and usage is governed by a MIT style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
@@ -6,6 +6,7 @@ package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
@@ -18,7 +19,6 @@ import (
|
||||
"runtime"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
@@ -64,6 +64,16 @@ func (l *logger) output(format string, v ...interface{}) {
|
||||
l.l.Printf(format, v...)
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Rate Limiter interface
|
||||
//_______________________________________________________________________
|
||||
|
||||
type RateLimiter interface {
|
||||
Allow() bool
|
||||
}
|
||||
|
||||
var ErrRateLimitExceeded = errors.New("rate limit exceeded")
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Helper methods
|
||||
//_______________________________________________________________________
|
||||
@@ -134,10 +144,6 @@ type ResponseLog struct {
|
||||
Body string
|
||||
}
|
||||
|
||||
//‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
|
||||
// Package Unexported methods
|
||||
//_______________________________________________________________________
|
||||
|
||||
// way to disable the HTML escape as opt-in
|
||||
func jsonMarshal(c *Client, r *Request, d interface{}) (*bytes.Buffer, error) {
|
||||
if !r.jsonEscapeHTML || !c.jsonEscapeHTML {
|
||||
@@ -205,7 +211,7 @@ func writeMultipartFormFile(w *multipart.Writer, fieldName, fileName string, r i
|
||||
return err
|
||||
}
|
||||
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf)))
|
||||
partWriter, err := w.CreatePart(createMultipartHeader(fieldName, fileName, http.DetectContentType(cbuf[:size])))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -279,7 +285,13 @@ func functionName(i interface{}) string {
|
||||
}
|
||||
|
||||
func acquireBuffer() *bytes.Buffer {
|
||||
return bufPool.Get().(*bytes.Buffer)
|
||||
buf := bufPool.Get().(*bytes.Buffer)
|
||||
if buf.Len() == 0 {
|
||||
buf.Reset()
|
||||
return buf
|
||||
}
|
||||
bufPool.Put(buf)
|
||||
return new(bytes.Buffer)
|
||||
}
|
||||
|
||||
func releaseBuffer(buf *bytes.Buffer) {
|
||||
@@ -289,32 +301,10 @@ func releaseBuffer(buf *bytes.Buffer) {
|
||||
}
|
||||
}
|
||||
|
||||
// requestBodyReleaser wraps requests's body and implements custom Close for it.
|
||||
// The Close method closes original body and releases request body back to sync.Pool.
|
||||
type requestBodyReleaser struct {
|
||||
releaseOnce sync.Once
|
||||
reqBuf *bytes.Buffer
|
||||
io.ReadCloser
|
||||
}
|
||||
|
||||
func newRequestBodyReleaser(respBody io.ReadCloser, reqBuf *bytes.Buffer) io.ReadCloser {
|
||||
if reqBuf == nil {
|
||||
return respBody
|
||||
func backToBufPool(buf *bytes.Buffer) {
|
||||
if buf != nil {
|
||||
bufPool.Put(buf)
|
||||
}
|
||||
|
||||
return &requestBodyReleaser{
|
||||
reqBuf: reqBuf,
|
||||
ReadCloser: respBody,
|
||||
}
|
||||
}
|
||||
|
||||
func (rr *requestBodyReleaser) Close() error {
|
||||
err := rr.ReadCloser.Close()
|
||||
rr.releaseOnce.Do(func() {
|
||||
releaseBuffer(rr.reqBuf)
|
||||
})
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func closeq(v interface{}) {
|
||||
@@ -328,25 +318,7 @@ func silently(_ ...interface{}) {}
|
||||
func composeHeaders(c *Client, r *Request, hdrs http.Header) string {
|
||||
str := make([]string, 0, len(hdrs))
|
||||
for _, k := range sortHeaderKeys(hdrs) {
|
||||
var v string
|
||||
if k == "Cookie" {
|
||||
cv := strings.TrimSpace(strings.Join(hdrs[k], ", "))
|
||||
if c.GetClient().Jar != nil {
|
||||
for _, c := range c.GetClient().Jar.Cookies(r.RawRequest.URL) {
|
||||
if cv != "" {
|
||||
cv = cv + "; " + c.String()
|
||||
} else {
|
||||
cv = c.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, cv))
|
||||
} else {
|
||||
v = strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", ")))
|
||||
}
|
||||
if v != "" {
|
||||
str = append(str, "\t"+v)
|
||||
}
|
||||
str = append(str, "\t"+strings.TrimSpace(fmt.Sprintf("%25s: %s", k, strings.Join(hdrs[k], ", "))))
|
||||
}
|
||||
return strings.Join(str, "\n")
|
||||
}
|
||||
@@ -368,6 +340,32 @@ func copyHeaders(hdrs http.Header) http.Header {
|
||||
return nh
|
||||
}
|
||||
|
||||
func wrapErrors(n error, inner error) error {
|
||||
if inner == nil {
|
||||
return n
|
||||
}
|
||||
if n == nil {
|
||||
return inner
|
||||
}
|
||||
return &restyError{
|
||||
err: n,
|
||||
inner: inner,
|
||||
}
|
||||
}
|
||||
|
||||
type restyError struct {
|
||||
err error
|
||||
inner error
|
||||
}
|
||||
|
||||
func (e *restyError) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
func (e *restyError) Unwrap() error {
|
||||
return e.inner
|
||||
}
|
||||
|
||||
type noRetryErr struct {
|
||||
err error
|
||||
}
|
||||
|
||||
78
vendor/github.com/go-resty/resty/v2/util_curl.go
generated
vendored
Normal file
78
vendor/github.com/go-resty/resty/v2/util_curl.go
generated
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
package resty
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/go-resty/resty/v2/shellescape"
|
||||
)
|
||||
|
||||
func buildCurlRequest(req *http.Request, httpCookiejar http.CookieJar) (curl string) {
|
||||
// 1. Generate curl raw headers
|
||||
|
||||
curl = "curl -X " + req.Method + " "
|
||||
// req.Host + req.URL.Path + "?" + req.URL.RawQuery + " " + req.Proto + " "
|
||||
headers := dumpCurlHeaders(req)
|
||||
for _, kv := range *headers {
|
||||
curl += `-H ` + shellescape.Quote(kv[0]+": "+kv[1]) + ` `
|
||||
}
|
||||
|
||||
// 2. Generate curl cookies
|
||||
// TODO validate this block of code, I think its not required since cookie captured via Headers
|
||||
if cookieJar, ok := httpCookiejar.(*cookiejar.Jar); ok {
|
||||
cookies := cookieJar.Cookies(req.URL)
|
||||
if len(cookies) > 0 {
|
||||
curl += `-H ` + shellescape.Quote(dumpCurlCookies(cookies)) + " "
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Generate curl body
|
||||
if req.Body != nil {
|
||||
buf, _ := io.ReadAll(req.Body)
|
||||
req.Body = io.NopCloser(bytes.NewBuffer(buf)) // important!!
|
||||
curl += `-d ` + shellescape.Quote(string(buf)) + " "
|
||||
}
|
||||
|
||||
urlString := shellescape.Quote(req.URL.String())
|
||||
if urlString == "''" {
|
||||
urlString = "'http://unexecuted-request'"
|
||||
}
|
||||
curl += urlString
|
||||
return curl
|
||||
}
|
||||
|
||||
// dumpCurlCookies dumps cookies to curl format
|
||||
func dumpCurlCookies(cookies []*http.Cookie) string {
|
||||
sb := strings.Builder{}
|
||||
sb.WriteString("Cookie: ")
|
||||
for _, cookie := range cookies {
|
||||
sb.WriteString(cookie.Name + "=" + url.QueryEscape(cookie.Value) + "&")
|
||||
}
|
||||
return strings.TrimRight(sb.String(), "&")
|
||||
}
|
||||
|
||||
// dumpCurlHeaders dumps headers to curl format
|
||||
func dumpCurlHeaders(req *http.Request) *[][2]string {
|
||||
headers := [][2]string{}
|
||||
for k, vs := range req.Header {
|
||||
for _, v := range vs {
|
||||
headers = append(headers, [2]string{k, v})
|
||||
}
|
||||
}
|
||||
n := len(headers)
|
||||
for i := 0; i < n; i++ {
|
||||
for j := n - 1; j > i; j-- {
|
||||
jj := j - 1
|
||||
h1, h2 := headers[j], headers[jj]
|
||||
if h1[0] < h2[0] {
|
||||
headers[jj], headers[j] = headers[j], headers[jj]
|
||||
}
|
||||
}
|
||||
}
|
||||
return &headers
|
||||
}
|
||||
5
vendor/github.com/olekukonko/ll/global.go
generated
vendored
5
vendor/github.com/olekukonko/ll/global.go
generated
vendored
@@ -667,3 +667,8 @@ func Inspect(values ...interface{}) {
|
||||
o := NewInspector(defaultLogger)
|
||||
o.Log(2, values...)
|
||||
}
|
||||
|
||||
func Apply(opts ...Option) *Logger {
|
||||
return defaultLogger.Apply(opts...)
|
||||
|
||||
}
|
||||
|
||||
20
vendor/github.com/olekukonko/ll/lh/colorized.go
generated
vendored
20
vendor/github.com/olekukonko/ll/lh/colorized.go
generated
vendored
@@ -29,6 +29,7 @@ type Palette struct {
|
||||
Info string // Color for Info level messages
|
||||
Warn string // Color for Warn level messages
|
||||
Error string // Color for Error level messages
|
||||
Fatal string // Color for Fatal level messages
|
||||
Title string // Color for dump titles (BEGIN/END separators)
|
||||
}
|
||||
|
||||
@@ -47,10 +48,11 @@ var darkPalette = Palette{
|
||||
Hex: "\033[38;5;156m", // Light green for hex values
|
||||
Ascii: "\033[38;5;224m", // Light pink for ASCII values
|
||||
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Red for Error level
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Standard red
|
||||
Fatal: "\033[1;31m", // Bold red - stands out more
|
||||
}
|
||||
|
||||
// lightPalette defines colors optimized for light terminal backgrounds.
|
||||
@@ -68,10 +70,11 @@ var lightPalette = Palette{
|
||||
Hex: "\033[38;5;156m", // Light green for hex values
|
||||
Ascii: "\033[38;5;224m", // Light pink for ASCII values
|
||||
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Red for Error level
|
||||
Debug: "\033[36m", // Cyan for Debug level
|
||||
Info: "\033[32m", // Green for Info level
|
||||
Warn: "\033[33m", // Yellow for Warn level
|
||||
Error: "\033[31m", // Standard red
|
||||
Fatal: "\033[1;31m", // Bold red - stands out more
|
||||
}
|
||||
|
||||
// ColorizedHandler is a handler that outputs log entries with ANSI color codes.
|
||||
@@ -250,6 +253,7 @@ func (h *ColorizedHandler) formatLevel(b *strings.Builder, e *lx.Entry) {
|
||||
lx.LevelInfo: h.palette.Info, // Green
|
||||
lx.LevelWarn: h.palette.Warn, // Yellow
|
||||
lx.LevelError: h.palette.Error, // Red
|
||||
lx.LevelFatal: h.palette.Fatal, // Bold Red
|
||||
}[e.Level]
|
||||
|
||||
b.WriteString(color)
|
||||
|
||||
13
vendor/github.com/olekukonko/ll/lh/multi.go
generated
vendored
13
vendor/github.com/olekukonko/ll/lh/multi.go
generated
vendored
@@ -3,6 +3,7 @@ package lh
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/olekukonko/ll/lx"
|
||||
)
|
||||
|
||||
@@ -30,6 +31,18 @@ func NewMultiHandler(h ...lx.Handler) *MultiHandler {
|
||||
}
|
||||
}
|
||||
|
||||
// Len returns the number of handlers in the MultiHandler.
|
||||
func (h *MultiHandler) Len() int {
|
||||
return len(h.Handlers)
|
||||
}
|
||||
|
||||
// Append adds one or more lx.Handler instances to the MultiHandler's list of handlers.
|
||||
func (h *MultiHandler) Append(handlers ...lx.Handler) {
|
||||
for _, e := range handlers {
|
||||
h.Handlers = append(h.Handlers, e)
|
||||
}
|
||||
}
|
||||
|
||||
// Handle implements the Handler interface, calling Handle on each handler in sequence.
|
||||
// It collects any errors from handlers and combines them into a single error using errors.Join.
|
||||
// If no errors occur, it returns nil. Thread-safe if the underlying handlers are thread-safe.
|
||||
|
||||
5
vendor/github.com/olekukonko/ll/lh/slog.go
generated
vendored
5
vendor/github.com/olekukonko/ll/lh/slog.go
generated
vendored
@@ -2,8 +2,9 @@ package lh
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/olekukonko/ll/lx"
|
||||
"log/slog"
|
||||
|
||||
"github.com/olekukonko/ll/lx"
|
||||
)
|
||||
|
||||
// SlogHandler adapts a slog.Handler to implement lx.Handler.
|
||||
@@ -81,7 +82,7 @@ func toSlogLevel(level lx.LevelType) slog.Level {
|
||||
return slog.LevelInfo
|
||||
case lx.LevelWarn:
|
||||
return slog.LevelWarn
|
||||
case lx.LevelError:
|
||||
case lx.LevelError, lx.LevelFatal:
|
||||
return slog.LevelError
|
||||
default:
|
||||
return slog.LevelInfo // Default for unknown levels
|
||||
|
||||
128
vendor/github.com/olekukonko/ll/ll.go
generated
vendored
128
vendor/github.com/olekukonko/ll/ll.go
generated
vendored
@@ -39,6 +39,8 @@ type Logger struct {
|
||||
stackBufferSize int // Buffer size for capturing stack traces
|
||||
separator string // Separator for namespace paths (e.g., "/")
|
||||
entries atomic.Int64 // Tracks total log entries sent to handler
|
||||
fatalExits bool
|
||||
fatalStack bool
|
||||
}
|
||||
|
||||
// New creates a new Logger with the given namespace and optional configurations.
|
||||
@@ -71,22 +73,71 @@ func New(namespace string, opts ...Option) *Logger {
|
||||
return logger
|
||||
}
|
||||
|
||||
// AddContext adds a key-value pair to the logger's context, modifying it directly.
|
||||
// Unlike Context, it mutates the existing context. It is thread-safe using a write lock.
|
||||
// Apply applies one or more functional options to the default/global logger.
|
||||
// Useful for late configuration (e.g., after migration, attach VictoriaLogs handler,
|
||||
// set level, add middleware, etc.) without changing existing New() calls.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app").Enable()
|
||||
// logger.AddContext("user", "alice")
|
||||
// logger.Info("Action") // Output: [app] INFO: Action [user=alice]
|
||||
func (l *Logger) AddContext(key string, value interface{}) *Logger {
|
||||
// // In main() or init(), after setting up handler
|
||||
// ll.Apply(
|
||||
// ll.Handler(vlBatched),
|
||||
// ll.Level(ll.LevelInfo),
|
||||
// ll.Use(rateLimiterMiddleware),
|
||||
// )
|
||||
//
|
||||
// Returns the default logger for chaining (if needed).
|
||||
func (l *Logger) Apply(opts ...Option) *Logger {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
for _, opt := range opts {
|
||||
if opt != nil {
|
||||
opt(l)
|
||||
}
|
||||
}
|
||||
return l
|
||||
}
|
||||
|
||||
// AddContext adds one or more key-value pairs to the logger's persistent context.
|
||||
// These fields will be included in **every** subsequent log message from this logger
|
||||
// (and its child namespace loggers).
|
||||
//
|
||||
// It supports variadic key-value pairs (string key, any value).
|
||||
// Non-string keys or uneven number of arguments will be safely ignored/logged.
|
||||
//
|
||||
// Returns the logger for chaining.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// logger.AddContext("user", "alice", "env", "prod")
|
||||
// logger.AddContext("request_id", reqID, "trace_id", traceID)
|
||||
// logger.AddContext("service", "payment") // single pair
|
||||
func (l *Logger) AddContext(pairs ...any) *Logger {
|
||||
l.mu.Lock()
|
||||
defer l.mu.Unlock()
|
||||
|
||||
// Initialize context map if nil
|
||||
// Lazy initialization of context map
|
||||
if l.context == nil {
|
||||
l.context = make(map[string]interface{})
|
||||
}
|
||||
l.context[key] = value
|
||||
|
||||
// Process key-value pairs
|
||||
for i := 0; i < len(pairs)-1; i += 2 {
|
||||
key, ok := pairs[i].(string)
|
||||
if !ok {
|
||||
l.Warnf("AddContext: non-string key at index %d: %v", i, pairs[i])
|
||||
continue
|
||||
}
|
||||
|
||||
value := pairs[i+1]
|
||||
l.context[key] = value
|
||||
}
|
||||
|
||||
// Optional: warn about uneven number of arguments
|
||||
if len(pairs)%2 != 0 {
|
||||
l.Warn("AddContext: uneven number of arguments, last value ignored")
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
@@ -357,6 +408,7 @@ func (l *Logger) Output(values ...interface{}) {
|
||||
l.output(2, values...)
|
||||
}
|
||||
|
||||
// mark logs the caller's file and line number along with an optional custom name label for tracing execution flow.
|
||||
func (l *Logger) output(skip int, values ...interface{}) {
|
||||
if !l.shouldLog(lx.LevelInfo) {
|
||||
return
|
||||
@@ -536,8 +588,10 @@ func (l *Logger) Fatal(args ...any) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
l.log(lx.LevelError, lx.ClassText, cat.Space(args...), nil, false)
|
||||
os.Exit(1)
|
||||
l.log(lx.LevelFatal, lx.ClassText, cat.Space(args...), nil, l.fatalStack)
|
||||
if l.fatalExits {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// Fatalf logs a formatted message at Error level with a stack trace and exits the program.
|
||||
@@ -795,6 +849,7 @@ func (l *Logger) Mark(name ...string) {
|
||||
l.mark(2, name...)
|
||||
}
|
||||
|
||||
// mark logs the caller's file and line number along with an optional custom name label for tracing execution flow.
|
||||
func (l *Logger) mark(skip int, names ...string) {
|
||||
// Skip logging if Info level is not enabled
|
||||
if !l.shouldLog(lx.LevelInfo) {
|
||||
@@ -978,7 +1033,7 @@ func (l *Logger) Panic(args ...any) {
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
l.log(lx.LevelError, lx.ClassText, msg, nil, true)
|
||||
l.log(lx.LevelFatal, lx.ClassText, msg, nil, true)
|
||||
panic(msg)
|
||||
}
|
||||
|
||||
@@ -1459,54 +1514,3 @@ func (l *Logger) shouldLog(level lx.LevelType) bool {
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// WithHandler sets the handler for the logger as a functional option for configuring
|
||||
// a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithHandler(lh.NewJSONHandler(os.Stdout)))
|
||||
func WithHandler(handler lx.Handler) Option {
|
||||
return func(l *Logger) {
|
||||
l.handler = handler
|
||||
}
|
||||
}
|
||||
|
||||
// WithTimestamped returns an Option that configures timestamp settings for the logger's existing handler.
|
||||
// It enables or disables timestamp logging and optionally sets the timestamp format if the handler
|
||||
// supports the lx.Timestamper interface. If no handler is set, the function has no effect.
|
||||
// Parameters:
|
||||
//
|
||||
// enable: Boolean to enable or disable timestamp logging
|
||||
// format: Optional string(s) to specify the timestamp format
|
||||
func WithTimestamped(enable bool, format ...string) Option {
|
||||
return func(l *Logger) {
|
||||
if l.handler != nil { // Check if a handler is set
|
||||
// Verify if the handler supports the lx.Timestamper interface
|
||||
if h, ok := l.handler.(lx.Timestamper); ok {
|
||||
h.Timestamped(enable, format...) // Apply timestamp settings to the handler
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithLevel sets the minimum log level for the logger as a functional option for
|
||||
// configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithLevel(lx.LevelWarn))
|
||||
func WithLevel(level lx.LevelType) Option {
|
||||
return func(l *Logger) {
|
||||
l.level = level
|
||||
}
|
||||
}
|
||||
|
||||
// WithStyle sets the namespace formatting style for the logger as a functional option
|
||||
// for configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithStyle(lx.NestedPath))
|
||||
func WithStyle(style lx.StyleType) Option {
|
||||
return func(l *Logger) {
|
||||
l.style = style
|
||||
}
|
||||
}
|
||||
|
||||
7
vendor/github.com/olekukonko/ll/lx/lx.go
generated
vendored
7
vendor/github.com/olekukonko/ll/lx/lx.go
generated
vendored
@@ -36,6 +36,7 @@ const (
|
||||
LevelInfo // Info level for general operational messages
|
||||
LevelWarn // Warn level for warning conditions
|
||||
LevelError // Error level for error conditions requiring attention
|
||||
LevelFatal // Fatal level for critical error conditions
|
||||
LevelDebug // None level for logs without a specific severity (e.g., raw output)
|
||||
LevelUnknown // None level for logs without a specific severity (e.g., raw output)
|
||||
)
|
||||
@@ -45,7 +46,9 @@ const (
|
||||
DebugString = "DEBUG"
|
||||
InfoString = "INFO"
|
||||
WarnString = "WARN"
|
||||
WarningString = "WARNING"
|
||||
ErrorString = "ERROR"
|
||||
FatalString = "FATAL"
|
||||
NoneString = "NONE"
|
||||
UnknownString = "UNKNOWN"
|
||||
|
||||
@@ -98,6 +101,8 @@ func (l LevelType) String() string {
|
||||
return WarnString
|
||||
case LevelError:
|
||||
return ErrorString
|
||||
case LevelFatal:
|
||||
return FatalString
|
||||
case LevelNone:
|
||||
return NoneString
|
||||
default:
|
||||
@@ -114,7 +119,7 @@ func LevelParse(s string) LevelType {
|
||||
return LevelDebug
|
||||
case InfoString:
|
||||
return LevelInfo
|
||||
case WarnString, "WARNING": // Allow both "WARN" and "WARNING"
|
||||
case WarnString, WarningString: // Allow both "WARN" and "WARNING"
|
||||
return LevelWarn
|
||||
case ErrorString:
|
||||
return LevelError
|
||||
|
||||
67
vendor/github.com/olekukonko/ll/options.go
generated
vendored
Normal file
67
vendor/github.com/olekukonko/ll/options.go
generated
vendored
Normal file
@@ -0,0 +1,67 @@
|
||||
package ll
|
||||
|
||||
import "github.com/olekukonko/ll/lx"
|
||||
|
||||
// WithHandler sets the handler for the logger as a functional option for configuring
|
||||
// a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithHandler(lh.NewJSONHandler(os.Stdout)))
|
||||
func WithHandler(handler lx.Handler) Option {
|
||||
return func(l *Logger) {
|
||||
l.handler = handler
|
||||
}
|
||||
}
|
||||
|
||||
// WithTimestamped returns an Option that configures timestamp settings for the logger's existing handler.
|
||||
// It enables or disables timestamp logging and optionally sets the timestamp format if the handler
|
||||
// supports the lx.Timestamper interface. If no handler is set, the function has no effect.
|
||||
// Parameters:
|
||||
//
|
||||
// enable: Boolean to enable or disable timestamp logging
|
||||
// format: Optional string(s) to specify the timestamp format
|
||||
func WithTimestamped(enable bool, format ...string) Option {
|
||||
return func(l *Logger) {
|
||||
if l.handler != nil { // Check if a handler is set
|
||||
// Verify if the handler supports the lx.Timestamper interface
|
||||
if h, ok := l.handler.(lx.Timestamper); ok {
|
||||
h.Timestamped(enable, format...) // Apply timestamp settings to the handler
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithLevel sets the minimum log level for the logger as a functional option for
|
||||
// configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithLevel(lx.LevelWarn))
|
||||
func WithLevel(level lx.LevelType) Option {
|
||||
return func(l *Logger) {
|
||||
l.level = level
|
||||
}
|
||||
}
|
||||
|
||||
// WithStyle sets the namespace formatting style for the logger as a functional option
|
||||
// for configuring a new logger instance.
|
||||
// Example:
|
||||
//
|
||||
// logger := New("app", WithStyle(lx.NestedPath))
|
||||
func WithStyle(style lx.StyleType) Option {
|
||||
return func(l *Logger) {
|
||||
l.style = style
|
||||
}
|
||||
}
|
||||
|
||||
// Functional options (can be passed to New() or applied later)
|
||||
func WithFatalExits(enabled bool) Option {
|
||||
return func(l *Logger) {
|
||||
l.fatalExits = enabled
|
||||
}
|
||||
}
|
||||
|
||||
func WithFatalStack(enabled bool) Option {
|
||||
return func(l *Logger) {
|
||||
l.fatalStack = enabled
|
||||
}
|
||||
}
|
||||
6
vendor/github.com/olekukonko/tablewriter/README.md
generated
vendored
6
vendor/github.com/olekukonko/tablewriter/README.md
generated
vendored
@@ -28,7 +28,7 @@ go get github.com/olekukonko/tablewriter@v0.0.5
|
||||
#### Latest Version
|
||||
The latest stable version
|
||||
```bash
|
||||
go get github.com/olekukonko/tablewriter@v1.1.2
|
||||
go get github.com/olekukonko/tablewriter@v1.1.3
|
||||
```
|
||||
|
||||
**Warning:** Version `v1.0.0` contains missing functionality and should not be used.
|
||||
@@ -62,7 +62,7 @@ func main() {
|
||||
data := [][]string{
|
||||
{"Package", "Version", "Status"},
|
||||
{"tablewriter", "v0.0.5", "legacy"},
|
||||
{"tablewriter", "v1.1.2", "latest"},
|
||||
{"tablewriter", "v1.1.3", "latest"},
|
||||
}
|
||||
|
||||
table := tablewriter.NewWriter(os.Stdout)
|
||||
@@ -77,7 +77,7 @@ func main() {
|
||||
│ PACKAGE │ VERSION │ STATUS │
|
||||
├─────────────┼─────────┼────────┤
|
||||
│ tablewriter │ v0.0.5 │ legacy │
|
||||
│ tablewriter │ v1.1.2 │ latest │
|
||||
│ tablewriter │ v1.1.3 │ latest │
|
||||
└─────────────┴─────────┴────────┘
|
||||
```
|
||||
|
||||
|
||||
424
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/ea.go
generated
vendored
Normal file
424
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/ea.go
generated
vendored
Normal file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
Package twwidth provides intelligent East Asian width detection.
|
||||
|
||||
In 2025/2026, most modern terminal emulators (VSCode, Windows Terminal, iTerm2,
|
||||
Alacritty) and modern monospace fonts (Hack, Fira Code, Cascadia Code) treat
|
||||
box-drawing characters as Single Width, regardless of the underlying OS Locale.
|
||||
|
||||
Detection Logic (in order of priority):
|
||||
- RUNEWIDTH_EASTASIAN environment variable (explicit user override)
|
||||
- Force Legacy Mode (programmatic override for backward compatibility)
|
||||
- Modern environment detection (VSCode, Windows Terminal, etc. -> Narrow)
|
||||
- Locale-based detection (CJK locales in traditional terminals -> Wide)
|
||||
|
||||
This prioritization ensures that:
|
||||
- Users can always override behavior using RUNEWIDTH_EASTASIAN
|
||||
- Modern development environments work correctly by default
|
||||
- Traditional CJK terminals maintain compatibility via locale checks
|
||||
|
||||
Examples:
|
||||
|
||||
// Force narrow borders (for Hack font in zh_CN)
|
||||
RUNEWIDTH_EASTASIAN=0 go run .
|
||||
|
||||
// Force wide borders (for legacy CJK terminals)
|
||||
RUNEWIDTH_EASTASIAN=1 go run .
|
||||
*/
|
||||
package twwidth
|
||||
|
||||
import (
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Environment Variable Constants
|
||||
const (
|
||||
EnvLCAll = "LC_ALL"
|
||||
EnvLCCtype = "LC_CTYPE"
|
||||
EnvLang = "LANG"
|
||||
EnvRuneWidthEastAsian = "RUNEWIDTH_EASTASIAN"
|
||||
EnvTerm = "TERM"
|
||||
EnvTermProgram = "TERM_PROGRAM"
|
||||
EnvTermProgramWsl = "TERM_PROGRAM_WSL"
|
||||
EnvWTProfile = "WT_PROFILE_ID" // Windows Terminal
|
||||
EnvConEmuANSI = "ConEmuANSI" // ConEmu
|
||||
EnvAlacritty = "ALACRITTY_LOG" // Alacritty
|
||||
EnvVTEVersion = "VTE_VERSION" // GNOME/VTE
|
||||
)
|
||||
|
||||
const (
|
||||
overwriteOn = "override_on"
|
||||
overwriteOff = "override_off"
|
||||
|
||||
envModern = "modern_env"
|
||||
envCjk = "locale_cjk"
|
||||
envAscii = "default_ascii"
|
||||
)
|
||||
|
||||
// CJK Language Codes (Prefixes)
|
||||
// Covers ISO 639-1 (2-letter) and common full names used in some systems.
|
||||
var cjkPrefixes = []string{
|
||||
"zh", "ja", "ko", // Standard: Chinese, Japanese, Korean
|
||||
"chi", "zho", // ISO 639-2/B and T for Chinese
|
||||
"jpn", "kor", // ISO 639-2 for Japanese, Korean
|
||||
"chinese", "japanese", "korean", // Full names (rare but possible in some legacy systems)
|
||||
}
|
||||
|
||||
// CJK Region Codes
|
||||
// Checks for specific regions that imply CJK font usage (e.g., en_HK).
|
||||
var cjkRegions = map[string]bool{
|
||||
"cn": true, // China
|
||||
"tw": true, // Taiwan
|
||||
"hk": true, // Hong Kong
|
||||
"mo": true, // Macau
|
||||
"jp": true, // Japan
|
||||
"kr": true, // South Korea
|
||||
"kp": true, // North Korea
|
||||
"sg": true, // Singapore (Often uses CJK fonts)
|
||||
}
|
||||
|
||||
// Modern environments that should use narrow borders (1-width box chars)
|
||||
var modernEnvironments = map[string]bool{
|
||||
// Terminal programs
|
||||
"vscode": true, "visual studio code": true,
|
||||
"iterm.app": true, "iterm2": true,
|
||||
"windows terminal": true, "windowsterminal": true,
|
||||
"alacritty": true, "kitty": true,
|
||||
"hyper": true, "tabby": true, "terminus": true, "fluentterminal": true,
|
||||
"warp": true, "ghostty": true, "rio": true,
|
||||
"jetbrains-jediterm": true,
|
||||
|
||||
// Terminal types (TERM signatures)
|
||||
"xterm-kitty": true, "xterm-ghostty": true, "wezterm": true,
|
||||
}
|
||||
|
||||
var (
|
||||
eastAsianOnce sync.Once
|
||||
eastAsianVal bool
|
||||
|
||||
// Legacy override control
|
||||
// Renamed to cfgMu to avoid conflict with width.go's mu
|
||||
cfgMu sync.RWMutex
|
||||
forceLegacyEastAsian = false
|
||||
)
|
||||
|
||||
type Enviroment struct {
|
||||
GOOS string `json:"goos"`
|
||||
LC_ALL string `json:"lc_all"`
|
||||
LC_CTYPE string `json:"lc_ctype"`
|
||||
LANG string `json:"lang"`
|
||||
RUNEWIDTH_EASTASIAN string `json:"runewidth_eastasian"`
|
||||
TERM string `json:"term"`
|
||||
TERM_PROGRAM string `json:"term_program"`
|
||||
}
|
||||
|
||||
// State captures the calculated internal state.
|
||||
type State struct {
|
||||
NormalizedLocale string `json:"normalized_locale"`
|
||||
IsCJKLocale bool `json:"is_cjk_locale"`
|
||||
IsModernEnv bool `json:"is_modern_env"`
|
||||
LegacyOverrideMode bool `json:"legacy_override_mode"`
|
||||
}
|
||||
|
||||
// Detection aggregates all debug information regarding East Asian width detection.
|
||||
type Detection struct {
|
||||
AutoUseEastAsian bool `json:"auto_use_east_asian"`
|
||||
DetectionMode string `json:"detection_mode"`
|
||||
Raw Enviroment `json:"raw"`
|
||||
Derived State `json:"derived"`
|
||||
}
|
||||
|
||||
// EastAsianForceLegacy forces the detection logic to ignore modern environment checks.
|
||||
// It relies solely on Locale detection. This is useful for applications that need
|
||||
// strict backward compatibility.
|
||||
//
|
||||
// Note: This does NOT override RUNEWIDTH_EASTASIAN. User environment variables take precedence.
|
||||
// This should be called before the first table render.
|
||||
func EastAsianForceLegacy(force bool) {
|
||||
cfgMu.Lock()
|
||||
defer cfgMu.Unlock()
|
||||
forceLegacyEastAsian = force
|
||||
}
|
||||
|
||||
// EastAsianDetect checks the environment variables to determine if
|
||||
// East Asian width calculations should be enabled.
|
||||
func EastAsianDetect() bool {
|
||||
eastAsianOnce.Do(func() {
|
||||
eastAsianVal = detectEastAsian()
|
||||
})
|
||||
return eastAsianVal
|
||||
}
|
||||
|
||||
// EastAsianConservative is a stricter version that only defaults to Narrow
|
||||
// if the terminal is definitely known to be modern (e.g. VSCode, iTerm2).
|
||||
// It avoids heuristics like checking "xterm" in the TERM variable.
|
||||
func EastAsianConservative() bool {
|
||||
// Check overrides first
|
||||
if val, found := checkOverrides(); found {
|
||||
return val
|
||||
}
|
||||
|
||||
// Stricter modern environment detection
|
||||
if isConservativeModernEnvironment() {
|
||||
return false
|
||||
}
|
||||
|
||||
// Fall back to locale
|
||||
return checkLocale()
|
||||
}
|
||||
|
||||
// EastAsianMode returns the decision path used for the current environment.
|
||||
// Useful for debugging why a specific width was chosen.
|
||||
func EastAsianMode() string {
|
||||
// Check override
|
||||
if val, found := checkOverrides(); found {
|
||||
if val {
|
||||
return overwriteOn
|
||||
}
|
||||
return overwriteOff
|
||||
}
|
||||
|
||||
cfgMu.RLock()
|
||||
legacy := forceLegacyEastAsian
|
||||
cfgMu.RUnlock()
|
||||
|
||||
if legacy {
|
||||
if checkLocale() {
|
||||
return envCjk
|
||||
}
|
||||
return envAscii
|
||||
}
|
||||
|
||||
if isModernEnvironment() {
|
||||
return envModern
|
||||
}
|
||||
|
||||
if checkLocale() {
|
||||
return envCjk
|
||||
}
|
||||
|
||||
return envAscii
|
||||
}
|
||||
|
||||
// Debugging returns detailed information about the detection decision.
|
||||
// Useful for users to include in Github issues.
|
||||
func Debugging() Detection {
|
||||
locale := getNormalizedLocale()
|
||||
|
||||
cfgMu.RLock()
|
||||
legacy := forceLegacyEastAsian
|
||||
cfgMu.RUnlock()
|
||||
|
||||
return Detection{
|
||||
AutoUseEastAsian: EastAsianDetect(),
|
||||
DetectionMode: EastAsianMode(),
|
||||
Raw: Enviroment{
|
||||
GOOS: runtime.GOOS,
|
||||
LC_ALL: os.Getenv(EnvLCAll),
|
||||
LC_CTYPE: os.Getenv(EnvLCCtype),
|
||||
LANG: os.Getenv(EnvLang),
|
||||
RUNEWIDTH_EASTASIAN: os.Getenv(EnvRuneWidthEastAsian),
|
||||
TERM: os.Getenv(EnvTerm),
|
||||
TERM_PROGRAM: os.Getenv(EnvTermProgram),
|
||||
},
|
||||
Derived: State{
|
||||
NormalizedLocale: locale,
|
||||
IsCJKLocale: isCJKLocale(locale),
|
||||
IsModernEnv: isModernEnvironment(),
|
||||
LegacyOverrideMode: legacy,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// detectEastAsian evaluates the environment and locale settings to determine if East Asian width rules should apply.
|
||||
func detectEastAsian() bool {
|
||||
// User Override check (Highest Priority)
|
||||
if val, found := checkOverrides(); found {
|
||||
return val
|
||||
}
|
||||
|
||||
// Force Legacy Mode check
|
||||
cfgMu.RLock()
|
||||
isLegacy := forceLegacyEastAsian
|
||||
cfgMu.RUnlock()
|
||||
|
||||
if isLegacy {
|
||||
// Legacy mode ignores modern environment checks,
|
||||
// relying solely on locale.
|
||||
return checkLocale()
|
||||
}
|
||||
|
||||
// Modern Environment Detection
|
||||
// If modern, we assume Single Width (return false)
|
||||
if isModernEnvironment() {
|
||||
return false
|
||||
}
|
||||
|
||||
// 4. Locale Fallback
|
||||
return checkLocale()
|
||||
}
|
||||
|
||||
// checkOverrides looks for RUNEWIDTH_EASTASIAN
|
||||
func checkOverrides() (bool, bool) {
|
||||
if rw := os.Getenv(EnvRuneWidthEastAsian); rw != "" {
|
||||
rw = strings.ToLower(rw)
|
||||
if rw == "0" || rw == "off" || rw == "false" || rw == "no" {
|
||||
return false, true
|
||||
}
|
||||
if rw == "1" || rw == "on" || rw == "true" || rw == "yes" {
|
||||
return true, true
|
||||
}
|
||||
}
|
||||
return false, false
|
||||
}
|
||||
|
||||
// checkLocale performs the string analysis on LANG/LC_ALL
|
||||
func checkLocale() bool {
|
||||
locale := getNormalizedLocale()
|
||||
if locale == "" {
|
||||
return false
|
||||
}
|
||||
return isCJKLocale(locale)
|
||||
}
|
||||
|
||||
// isModernEnvironment performs comprehensive checks for modern terminal capabilities.
|
||||
func isModernEnvironment() bool {
|
||||
// Check TERM_PROGRAM (Most reliable)
|
||||
if termProg := os.Getenv(EnvTermProgram); termProg != "" {
|
||||
termProgLower := strings.ToLower(termProg)
|
||||
if modernEnvironments[termProgLower] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Check WSL specific variable
|
||||
if os.Getenv(EnvTermProgramWsl) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Windows Specifics
|
||||
if runtime.GOOS == "windows" {
|
||||
// Windows Terminal
|
||||
if os.Getenv(EnvWTProfile) != "" {
|
||||
return true
|
||||
}
|
||||
// ConEmu/Cmder
|
||||
if os.Getenv(EnvConEmuANSI) == "ON" {
|
||||
return true
|
||||
}
|
||||
// Modern Windows console (Windows 10+) check via TERM
|
||||
if term := os.Getenv(EnvTerm); term != "" {
|
||||
termLower := strings.ToLower(term)
|
||||
if strings.Contains(termLower, "xterm") ||
|
||||
strings.Contains(termLower, "vt") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// VTE-based terminals (GNOME Terminal, Tilix, etc.)
|
||||
if os.Getenv(EnvVTEVersion) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check for Alacritty specifically
|
||||
if os.Getenv(EnvAlacritty) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
// Check TERM for modern terminal signatures
|
||||
if term := os.Getenv(EnvTerm); term != "" {
|
||||
termLower := strings.ToLower(term)
|
||||
// Specific modern terminals often put their name in TERM
|
||||
if modernEnvironments[termLower] {
|
||||
return true
|
||||
}
|
||||
// Heuristics for standard modern-capable descriptors
|
||||
if strings.Contains(termLower, "xterm") && !strings.Contains(termLower, "xterm-mono") {
|
||||
return true
|
||||
}
|
||||
if strings.Contains(termLower, "screen") ||
|
||||
strings.Contains(termLower, "tmux") {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// isConservativeModernEnvironment performs strict checks only for known modern terminals.
|
||||
func isConservativeModernEnvironment() bool {
|
||||
termProg := strings.ToLower(os.Getenv(EnvTermProgram))
|
||||
|
||||
// Allow-list of definitely modern terminals
|
||||
switch termProg {
|
||||
case "vscode", "visual studio code":
|
||||
return true
|
||||
case "iterm.app", "iterm2":
|
||||
return true
|
||||
case "windows terminal", "windowsterminal":
|
||||
return true
|
||||
case "alacritty", "wezterm", "kitty", "ghostty":
|
||||
return true
|
||||
case "warp", "tabby", "hyper":
|
||||
return true
|
||||
}
|
||||
|
||||
// Windows Terminal via specific Env
|
||||
if os.Getenv(EnvWTProfile) != "" {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// isCJKLocale determines if a given locale string corresponds to a CJK (Chinese, Japanese, Korean) language or region.
|
||||
func isCJKLocale(locale string) bool {
|
||||
// Check Language Prefix
|
||||
for _, prefix := range cjkPrefixes {
|
||||
if strings.HasPrefix(locale, prefix) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// Check Regions
|
||||
parts := strings.Split(locale, "_")
|
||||
if len(parts) > 1 {
|
||||
for _, part := range parts[1:] {
|
||||
if cjkRegions[part] {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// getNormalizedLocale returns the normalized locale by inspecting environment variables LC_ALL, LC_CTYPE, and LANG.
|
||||
func getNormalizedLocale() string {
|
||||
var locale string
|
||||
if loc := os.Getenv(EnvLCAll); loc != "" {
|
||||
locale = loc
|
||||
} else if loc := os.Getenv(EnvLCCtype); loc != "" {
|
||||
locale = loc
|
||||
} else if loc := os.Getenv(EnvLang); loc != "" {
|
||||
locale = loc
|
||||
}
|
||||
|
||||
// Fast fail for empty or standard C/POSIX locales
|
||||
if locale == "" || locale == "C" || locale == "POSIX" {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Strip encoding and modifiers
|
||||
if idx := strings.IndexByte(locale, '.'); idx != -1 {
|
||||
locale = locale[:idx]
|
||||
}
|
||||
if idx := strings.IndexByte(locale, '@'); idx != -1 {
|
||||
locale = locale[:idx]
|
||||
}
|
||||
|
||||
return strings.ToLower(locale)
|
||||
}
|
||||
237
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/width.go
generated
vendored
237
vendor/github.com/olekukonko/tablewriter/pkg/twwidth/width.go
generated
vendored
@@ -1,3 +1,4 @@
|
||||
// width.go
|
||||
package twwidth
|
||||
|
||||
import (
|
||||
@@ -21,6 +22,10 @@ const (
|
||||
// Options allows for configuring width calculation on a per-call basis.
|
||||
type Options struct {
|
||||
EastAsianWidth bool
|
||||
|
||||
// Explicitly force box drawing chars to be narrow
|
||||
// regardless of EastAsianWidth setting.
|
||||
ForceNarrowBorders bool
|
||||
}
|
||||
|
||||
// globalOptions holds the global displaywidth configuration, including East Asian width settings.
|
||||
@@ -36,12 +41,25 @@ var widthCache *twcache.LRU[string, int]
|
||||
var ansi = Filter()
|
||||
|
||||
func init() {
|
||||
// Initialize global options by detecting from the environment,
|
||||
// which is the one key feature we get from go-runewidth.
|
||||
isEastAsian := EastAsianDetect()
|
||||
|
||||
cond := runewidth.NewCondition()
|
||||
cond.EastAsianWidth = isEastAsian
|
||||
|
||||
globalOptions = Options{
|
||||
EastAsianWidth: cond.EastAsianWidth,
|
||||
EastAsianWidth: isEastAsian,
|
||||
|
||||
// Auto-enable ForceNarrowBorders for edge cases.
|
||||
// If EastAsianWidth is ON (e.g. forced via Env Var), but we detect
|
||||
// a modern environment, we might technically want to narrow borders
|
||||
// while keeping text wide.
|
||||
//
|
||||
// Note: In the standard EastAsian logic, isEastAsian will
|
||||
// ALREADY be false for modern environments, so this boolean implies
|
||||
// a specific "Forced On" scenario.
|
||||
ForceNarrowBorders: isEastAsian && isModernEnvironment(),
|
||||
}
|
||||
|
||||
widthCache = twcache.NewLRU[string, int](cacheCapacity)
|
||||
}
|
||||
|
||||
@@ -55,6 +73,14 @@ func makeCacheKey(str string, eastAsianWidth bool) string {
|
||||
return cachePrefix + str
|
||||
}
|
||||
|
||||
// Display calculates the visual width of a string using a specific runewidth.Condition.
|
||||
// Deprecated: use WidthWithOptions with the new twwidth.Options struct instead.
|
||||
// This function is kept for backward compatibility.
|
||||
func Display(cond *runewidth.Condition, str string) int {
|
||||
opts := Options{EastAsianWidth: cond.EastAsianWidth}
|
||||
return WidthWithOptions(str, opts)
|
||||
}
|
||||
|
||||
// Filter compiles and returns a regular expression for matching ANSI escape sequences,
|
||||
// including CSI (Control Sequence Introducer) and OSC (Operating System Command) sequences.
|
||||
// The returned regex can be used to strip ANSI codes from strings.
|
||||
@@ -73,25 +99,15 @@ func Filter() *regexp.Regexp {
|
||||
return regexp.MustCompile("(" + regCSI + "|" + regOSC + ")")
|
||||
}
|
||||
|
||||
// SetOptions sets the global options for width calculation.
|
||||
// This function is thread-safe.
|
||||
func SetOptions(opts Options) {
|
||||
// GetCacheStats returns current cache statistics
|
||||
func GetCacheStats() (size, capacity int, hitRate float64) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if globalOptions.EastAsianWidth != opts.EastAsianWidth {
|
||||
globalOptions = opts
|
||||
widthCache.Purge()
|
||||
}
|
||||
}
|
||||
|
||||
// SetEastAsian enables or disables East Asian width handling globally.
|
||||
// This function is thread-safe.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// twdw.SetEastAsian(true) // Enable East Asian width handling
|
||||
func SetEastAsian(enable bool) {
|
||||
SetOptions(Options{EastAsianWidth: enable})
|
||||
if widthCache == nil {
|
||||
return 0, 0, 0
|
||||
}
|
||||
return widthCache.Len(), widthCache.Cap(), widthCache.HitRate()
|
||||
}
|
||||
|
||||
// IsEastAsian returns the current East Asian width setting.
|
||||
@@ -108,6 +124,22 @@ func IsEastAsian() bool {
|
||||
return globalOptions.EastAsianWidth
|
||||
}
|
||||
|
||||
// SetCacheCapacity changes the cache size dynamically
|
||||
// If capacity <= 0, disables caching entirely
|
||||
func SetCacheCapacity(capacity int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
if capacity <= 0 {
|
||||
widthCache = nil // nil = fully disabled
|
||||
return
|
||||
}
|
||||
|
||||
newCache := twcache.NewLRU[string, int](capacity)
|
||||
widthCache = newCache
|
||||
}
|
||||
|
||||
// SetCondition sets the global East Asian width setting based on a runewidth.Condition.
|
||||
// Deprecated: use SetOptions with the new twwidth.Options struct instead.
|
||||
// This function is kept for backward compatibility.
|
||||
func SetCondition(cond *runewidth.Condition) {
|
||||
@@ -120,55 +152,33 @@ func SetCondition(cond *runewidth.Condition) {
|
||||
}
|
||||
}
|
||||
|
||||
// Width calculates the visual width of a string using the global cache for performance.
|
||||
// It excludes ANSI escape sequences and accounts for the global East Asian width setting.
|
||||
// SetEastAsian enables or disables East Asian width handling globally.
|
||||
// This function is thread-safe.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.Width("Hello\x1b[31mWorld") // Returns 10
|
||||
func Width(str string) int {
|
||||
currentEA := IsEastAsian()
|
||||
key := makeCacheKey(str, currentEA)
|
||||
// twdw.SetEastAsian(true) // Enable East Asian width handling
|
||||
func SetEastAsian(enable bool) {
|
||||
SetOptions(Options{EastAsianWidth: enable})
|
||||
}
|
||||
|
||||
if w, found := widthCache.Get(key); found {
|
||||
return w
|
||||
// SetForceNarrow to preserve the new flag, or create a new setter
|
||||
func SetForceNarrow(enable bool) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
globalOptions.ForceNarrowBorders = enable
|
||||
widthCache.Purge() // Clear cache because widths might change
|
||||
}
|
||||
|
||||
// SetOptions sets the global options for width calculation.
|
||||
// This function is thread-safe.
|
||||
func SetOptions(opts Options) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if globalOptions.EastAsianWidth != opts.EastAsianWidth || globalOptions.ForceNarrowBorders != opts.ForceNarrowBorders {
|
||||
globalOptions = opts
|
||||
widthCache.Purge()
|
||||
}
|
||||
|
||||
opts := displaywidth.Options{EastAsianWidth: currentEA}
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
calculatedWidth := opts.String(stripped)
|
||||
|
||||
widthCache.Add(key, calculatedWidth)
|
||||
return calculatedWidth
|
||||
}
|
||||
|
||||
// WidthWithOptions calculates the visual width of a string with specific options,
|
||||
// bypassing the global settings and cache. This is useful for one-shot calculations
|
||||
// where global state is not desired.
|
||||
func WidthWithOptions(str string, opts Options) int {
|
||||
dwOpts := displaywidth.Options{EastAsianWidth: opts.EastAsianWidth}
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
return dwOpts.String(stripped)
|
||||
}
|
||||
|
||||
// WidthNoCache calculates the visual width of a string without using the global cache.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.WidthNoCache("Hello\x1b[31mWorld") // Returns 10
|
||||
func WidthNoCache(str string) int {
|
||||
// This function's behavior is equivalent to a one-shot calculation
|
||||
// using the current global options. The WidthWithOptions function
|
||||
// does not interact with the cache, thus fulfilling the requirement.
|
||||
return WidthWithOptions(str, Options{EastAsianWidth: IsEastAsian()})
|
||||
}
|
||||
|
||||
// Deprecated: use WidthWithOptions with the new twwidth.Options struct instead.
|
||||
// This function is kept for backward compatibility.
|
||||
func Display(cond *runewidth.Condition, str string) int {
|
||||
opts := Options{EastAsianWidth: cond.EastAsianWidth}
|
||||
return WidthWithOptions(str, opts)
|
||||
}
|
||||
|
||||
// Truncate shortens a string to fit within a specified visual width, optionally
|
||||
@@ -235,11 +245,13 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
|
||||
// Case 4: String needs truncation (sDisplayWidth > maxWidth).
|
||||
// maxWidth is the total budget for the final string (content + suffix).
|
||||
currentGlobalEastAsianWidth := IsEastAsian()
|
||||
mu.Lock()
|
||||
currentOpts := globalOptions
|
||||
mu.Unlock()
|
||||
|
||||
// Special case for EastAsian true: if only suffix fits, return suffix.
|
||||
// Special case for EastAsianDetect true: if only suffix fits, return suffix.
|
||||
// This was derived from previous test behavior.
|
||||
if len(suffixStr) > 0 && currentGlobalEastAsianWidth {
|
||||
if len(suffixStr) > 0 && currentOpts.EastAsianWidth {
|
||||
provisionalContentWidth := maxWidth - suffixDisplayWidth
|
||||
if provisionalContentWidth == 0 { // Exactly enough space for suffix only
|
||||
return suffixStr
|
||||
@@ -271,8 +283,6 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
inAnsiSequence := false
|
||||
ansiWrittenToContent := false
|
||||
|
||||
dwOpts := displaywidth.Options{EastAsianWidth: currentGlobalEastAsianWidth}
|
||||
|
||||
for _, r := range s {
|
||||
if r == '\x1b' {
|
||||
inAnsiSequence = true
|
||||
@@ -305,7 +315,7 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
ansiSeqBuf.Reset()
|
||||
}
|
||||
} else { // Normal character
|
||||
runeDisplayWidth := dwOpts.Rune(r)
|
||||
runeDisplayWidth := calculateRunewidth(r, currentOpts)
|
||||
if targetContentForIteration == 0 { // No budget for content at all
|
||||
break
|
||||
}
|
||||
@@ -342,28 +352,81 @@ func Truncate(s string, maxWidth int, suffix ...string) string {
|
||||
return result
|
||||
}
|
||||
|
||||
// SetCacheCapacity changes the cache size dynamically
|
||||
// If capacity <= 0, disables caching entirely
|
||||
func SetCacheCapacity(capacity int) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
if capacity <= 0 {
|
||||
widthCache = nil // nil = fully disabled
|
||||
return
|
||||
// Width calculates the visual width of a string using the global cache for performance.
|
||||
// It excludes ANSI escape sequences and accounts for the global East Asian width setting.
|
||||
// This function is thread-safe.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.Width("Hello\x1b[31mWorld") // Returns 10
|
||||
func Width(str string) int {
|
||||
// Fast path ASCII (Optimization)
|
||||
if len(str) == 1 && str[0] < 0x80 {
|
||||
return 1
|
||||
}
|
||||
|
||||
newCache := twcache.NewLRU[string, int](capacity)
|
||||
widthCache = newCache
|
||||
}
|
||||
|
||||
// GetCacheStats returns current cache statistics
|
||||
func GetCacheStats() (size, capacity int, hitRate float64) {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
currentOpts := globalOptions
|
||||
mu.Unlock()
|
||||
|
||||
if widthCache == nil {
|
||||
return 0, 0, 0
|
||||
key := makeCacheKey(str, currentOpts.EastAsianWidth)
|
||||
|
||||
// Check Cache (Optimization)
|
||||
if w, found := widthCache.Get(key); found {
|
||||
return w
|
||||
}
|
||||
return widthCache.Len(), widthCache.Cap(), widthCache.HitRate()
|
||||
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
calculatedWidth := 0
|
||||
|
||||
for _, r := range stripped {
|
||||
calculatedWidth += calculateRunewidth(r, currentOpts)
|
||||
}
|
||||
|
||||
// Store in Cache
|
||||
widthCache.Add(key, calculatedWidth)
|
||||
return calculatedWidth
|
||||
}
|
||||
|
||||
// WidthNoCache calculates the visual width of a string without using the global cache.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// width := twdw.WidthNoCache("Hello\x1b[31mWorld") // Returns 10
|
||||
func WidthNoCache(str string) int {
|
||||
// This function's behavior is equivalent to a one-shot calculation
|
||||
// using the current global options. The WidthWithOptions function
|
||||
// does not interact with the cache, thus fulfilling the requirement.
|
||||
mu.Lock()
|
||||
opts := globalOptions
|
||||
mu.Unlock()
|
||||
return WidthWithOptions(str, opts)
|
||||
}
|
||||
|
||||
// WidthWithOptions calculates the visual width of a string with specific options,
|
||||
// bypassing the global settings and cache. This is useful for one-shot calculations
|
||||
// where global state is not desired.
|
||||
func WidthWithOptions(str string, opts Options) int {
|
||||
stripped := ansi.ReplaceAllLiteralString(str, "")
|
||||
calculatedWidth := 0
|
||||
for _, r := range stripped {
|
||||
calculatedWidth += calculateRunewidth(r, opts)
|
||||
}
|
||||
return calculatedWidth
|
||||
}
|
||||
|
||||
// calculateRunewidth calculates the width of a single rune based on the provided options.
|
||||
// It applies narrow overrides for box drawing characters if configured.
|
||||
func calculateRunewidth(r rune, opts Options) int {
|
||||
if opts.ForceNarrowBorders && isBoxDrawingChar(r) {
|
||||
return 1
|
||||
}
|
||||
|
||||
dwOpts := displaywidth.Options{EastAsianWidth: opts.EastAsianWidth}
|
||||
return dwOpts.Rune(r)
|
||||
}
|
||||
|
||||
// isBoxDrawingChar checks if a rune is within the Unicode Box Drawing range.
|
||||
func isBoxDrawingChar(r rune) bool {
|
||||
return r >= 0x2500 && r <= 0x257F
|
||||
}
|
||||
|
||||
23
vendor/github.com/olekukonko/tablewriter/renderer/colorized.go
generated
vendored
23
vendor/github.com/olekukonko/tablewriter/renderer/colorized.go
generated
vendored
@@ -4,7 +4,6 @@ import (
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/olekukonko/ll"
|
||||
"github.com/olekukonko/ll/lh"
|
||||
"github.com/olekukonko/tablewriter/pkg/twwidth"
|
||||
@@ -24,28 +23,6 @@ type ColorizedConfig struct {
|
||||
Symbols tw.Symbols // Symbols for table drawing (e.g., corners, lines)
|
||||
}
|
||||
|
||||
// Colors is a slice of color attributes for use with fatih/color, such as color.FgWhite or color.Bold.
|
||||
type Colors []color.Attribute
|
||||
|
||||
// Tint defines foreground and background color settings for table elements, with optional per-column overrides.
|
||||
type Tint struct {
|
||||
FG Colors // Foreground color attributes
|
||||
BG Colors // Background color attributes
|
||||
Columns []Tint // Per-column color settings
|
||||
}
|
||||
|
||||
// Apply applies the Tint's foreground and background colors to the given text, returning the text unchanged if no colors are set.
|
||||
func (t Tint) Apply(text string) string {
|
||||
if len(t.FG) == 0 && len(t.BG) == 0 {
|
||||
return text
|
||||
}
|
||||
// Combine foreground and background colors
|
||||
combinedColors := append(t.FG, t.BG...)
|
||||
// Create a color function and apply it to the text
|
||||
c := color.New(combinedColors...).SprintFunc()
|
||||
return c(text)
|
||||
}
|
||||
|
||||
// Colorized renders colored ASCII tables with customizable borders, colors, and alignments.
|
||||
type Colorized struct {
|
||||
config ColorizedConfig // Renderer configuration
|
||||
|
||||
25
vendor/github.com/olekukonko/tablewriter/renderer/tint.go
generated
vendored
Normal file
25
vendor/github.com/olekukonko/tablewriter/renderer/tint.go
generated
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
package renderer
|
||||
|
||||
import "github.com/fatih/color"
|
||||
|
||||
// Colors is a slice of color attributes for use with fatih/color, such as color.FgWhite or color.Bold.
|
||||
type Colors []color.Attribute
|
||||
|
||||
// Tint defines foreground and background color settings for table elements, with optional per-column overrides.
|
||||
type Tint struct {
|
||||
FG Colors // Foreground color attributes
|
||||
BG Colors // Background color attributes
|
||||
Columns []Tint // Per-column color settings
|
||||
}
|
||||
|
||||
// Apply applies the Tint's foreground and background colors to the given text, returning the text unchanged if no colors are set.
|
||||
func (t Tint) Apply(text string) string {
|
||||
if len(t.FG) == 0 && len(t.BG) == 0 {
|
||||
return text
|
||||
}
|
||||
// Combine foreground and background colors
|
||||
combinedColors := append(t.FG, t.BG...)
|
||||
// Create a color function and apply it to the text
|
||||
c := color.New(combinedColors...).SprintFunc()
|
||||
return c(text)
|
||||
}
|
||||
25
vendor/github.com/olekukonko/tablewriter/tablewriter.go
generated
vendored
25
vendor/github.com/olekukonko/tablewriter/tablewriter.go
generated
vendored
@@ -4,7 +4,6 @@ import (
|
||||
"bytes"
|
||||
"io"
|
||||
"math"
|
||||
"os"
|
||||
"reflect"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -419,7 +418,6 @@ func (t *Table) Options(opts ...Option) *Table {
|
||||
}
|
||||
|
||||
// force debugging mode if set
|
||||
// This should be move away form WithDebug
|
||||
if t.config.Debug {
|
||||
t.logger.Enable()
|
||||
t.logger.Resume()
|
||||
@@ -434,11 +432,28 @@ func (t *Table) Options(opts ...Option) *Table {
|
||||
goArch := runtime.GOARCH
|
||||
numCPU := runtime.NumCPU()
|
||||
|
||||
t.logger.Infof("Environment: LC_CTYPE=%s, LANG=%s, TERM=%s", os.Getenv("LC_CTYPE"), os.Getenv("LANG"), os.Getenv("TERM"))
|
||||
t.logger.Infof("Go Runtime: Version=%s, OS=%s, Arch=%s, CPUs=%d", goVersion, goOS, goArch, numCPU)
|
||||
// Use the new struct-based info.
|
||||
// No type assertions or magic strings needed.
|
||||
info := twwidth.Debugging()
|
||||
|
||||
t.logger.Infof("Go Runtime: Version=%s, OS=%s, Arch=%s, CPUs=%d",
|
||||
goVersion, goOS, goArch, numCPU)
|
||||
|
||||
t.logger.Infof("Environment: LC_CTYPE=%s, LANG=%s, TERM=%s, TERM_PROGRAM=%s",
|
||||
info.Raw.LC_CTYPE,
|
||||
info.Raw.LANG,
|
||||
info.Raw.TERM,
|
||||
info.Raw.TERM_PROGRAM,
|
||||
)
|
||||
|
||||
t.logger.Infof("East Asian Detection: Auto=%v, Mode=%s, ModernEnv=%v, CJKLocale=%v",
|
||||
info.AutoUseEastAsian,
|
||||
info.DetectionMode,
|
||||
info.Derived.IsModernEnv,
|
||||
info.Derived.IsCJKLocale,
|
||||
)
|
||||
|
||||
// send logger to renderer
|
||||
// this will overwrite the default logger
|
||||
t.renderer.Logger(t.logger)
|
||||
return t
|
||||
}
|
||||
|
||||
22
vendor/github.com/olekukonko/tablewriter/zoo.go
generated
vendored
22
vendor/github.com/olekukonko/tablewriter/zoo.go
generated
vendored
@@ -991,7 +991,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
constraintTotalCellWidth := 0
|
||||
hasConstraint := false
|
||||
|
||||
// 1. Check new Widths.PerColumn (highest priority)
|
||||
// Check new Widths.PerColumn (highest priority)
|
||||
if t.config.Widths.Constrained() {
|
||||
|
||||
if colWidth, ok := t.config.Widths.PerColumn.OK(colIdx); ok && colWidth > 0 {
|
||||
@@ -1001,7 +1001,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
colIdx, constraintTotalCellWidth)
|
||||
}
|
||||
|
||||
// 2. Check new Widths.Global
|
||||
// Check new Widths.Global
|
||||
if !hasConstraint && t.config.Widths.Global > 0 {
|
||||
constraintTotalCellWidth = t.config.Widths.Global
|
||||
hasConstraint = true
|
||||
@@ -1009,7 +1009,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Fall back to legacy ColMaxWidths.PerColumn (backward compatibility)
|
||||
// Fall back to legacy ColMaxWidths.PerColumn (backward compatibility)
|
||||
if !hasConstraint && config.ColMaxWidths.PerColumn != nil {
|
||||
if colMax, ok := config.ColMaxWidths.PerColumn.OK(colIdx); ok && colMax > 0 {
|
||||
constraintTotalCellWidth = colMax
|
||||
@@ -1019,7 +1019,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
}
|
||||
}
|
||||
|
||||
// 4. Fall back to legacy ColMaxWidths.Global
|
||||
// Fall back to legacy ColMaxWidths.Global
|
||||
if !hasConstraint && config.ColMaxWidths.Global > 0 {
|
||||
constraintTotalCellWidth = config.ColMaxWidths.Global
|
||||
hasConstraint = true
|
||||
@@ -1027,7 +1027,7 @@ func (t *Table) calculateContentMaxWidth(colIdx int, config tw.CellConfig, padLe
|
||||
constraintTotalCellWidth)
|
||||
}
|
||||
|
||||
// 5. Fall back to table MaxWidth if auto-wrapping
|
||||
// Fall back to table MaxWidth if auto-wrapping
|
||||
if !hasConstraint && t.config.MaxWidth > 0 && config.Formatting.AutoWrap != tw.WrapNone {
|
||||
constraintTotalCellWidth = t.config.MaxWidth
|
||||
hasConstraint = true
|
||||
@@ -1217,14 +1217,10 @@ func (t *Table) convertToString(value interface{}) string {
|
||||
// convertItemToCells is responsible for converting a single input item (which could be
|
||||
// a struct, a basic type, or an item implementing Stringer/Formatter) into a slice
|
||||
// of strings, where each string represents a cell for the table row.
|
||||
// zoo.go
|
||||
|
||||
// convertItemToCells is responsible for converting a single input item into a slice of strings.
|
||||
// It now uses the unified struct parser for structs.
|
||||
func (t *Table) convertItemToCells(item interface{}) ([]string, error) {
|
||||
t.logger.Debugf("convertItemToCells: Converting item of type %T", item)
|
||||
|
||||
// 1. User-defined table-wide stringer (t.stringer) takes highest precedence.
|
||||
// User-defined table-wide stringer (t.stringer) takes highest precedence.
|
||||
if t.stringer != nil {
|
||||
res, err := t.convertToStringer(item)
|
||||
if err == nil {
|
||||
@@ -1234,13 +1230,13 @@ func (t *Table) convertItemToCells(item interface{}) ([]string, error) {
|
||||
t.logger.Warnf("convertItemToCells: Custom table stringer was set but incompatible for type %T: %v. Will attempt other methods.", item, err)
|
||||
}
|
||||
|
||||
// 2. Handle untyped nil directly.
|
||||
// Handle untyped nil directly.
|
||||
if item == nil {
|
||||
t.logger.Debugf("convertItemToCells: Item is untyped nil. Returning single empty cell.")
|
||||
return []string{""}, nil
|
||||
}
|
||||
|
||||
// 3. Use the new unified struct parser. It handles pointers and embedding.
|
||||
// Use the new unified struct parser. It handles pointers and embedding.
|
||||
// We only care about the values it returns.
|
||||
_, values := t.extractFieldsAndValuesFromStruct(item)
|
||||
if values != nil {
|
||||
@@ -1248,7 +1244,7 @@ func (t *Table) convertItemToCells(item interface{}) ([]string, error) {
|
||||
return values, nil
|
||||
}
|
||||
|
||||
// 4. Fallback for any other single item (e.g., basic types, or types that implement Stringer/Formatter).
|
||||
// Fallback for any other single item (e.g., basic types, or types that implement Stringer/Formatter).
|
||||
// This code path is now for non-struct types.
|
||||
if formatter, ok := item.(tw.Formatter); ok {
|
||||
t.logger.Debugf("convertItemToCells: Item (non-struct, type %T) is tw.Formatter. Using Format().", item)
|
||||
|
||||
17
vendor/modules.txt
vendored
17
vendor/modules.txt
vendored
@@ -255,7 +255,7 @@ github.com/cespare/xxhash/v2
|
||||
# github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73
|
||||
## explicit
|
||||
github.com/cevaris/ordered_map
|
||||
# github.com/clipperhouse/displaywidth v0.6.0
|
||||
# github.com/clipperhouse/displaywidth v0.6.2
|
||||
## explicit; go 1.18
|
||||
github.com/clipperhouse/displaywidth
|
||||
# github.com/clipperhouse/stringish v0.1.1
|
||||
@@ -637,9 +637,10 @@ github.com/go-redis/redis/v8/internal/pool
|
||||
github.com/go-redis/redis/v8/internal/proto
|
||||
github.com/go-redis/redis/v8/internal/rand
|
||||
github.com/go-redis/redis/v8/internal/util
|
||||
# github.com/go-resty/resty/v2 v2.7.0
|
||||
## explicit; go 1.11
|
||||
# github.com/go-resty/resty/v2 v2.17.1
|
||||
## explicit; go 1.23.0
|
||||
github.com/go-resty/resty/v2
|
||||
github.com/go-resty/resty/v2/shellescape
|
||||
# github.com/go-sql-driver/mysql v1.9.3
|
||||
## explicit; go 1.21.0
|
||||
github.com/go-sql-driver/mysql
|
||||
@@ -805,7 +806,7 @@ github.com/gorilla/schema
|
||||
## explicit; go 1.14
|
||||
github.com/grpc-ecosystem/go-grpc-middleware
|
||||
github.com/grpc-ecosystem/go-grpc-middleware/recovery
|
||||
# github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.4
|
||||
# github.com/grpc-ecosystem/grpc-gateway/v2 v2.27.5
|
||||
## explicit; go 1.24.0
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/internal/httprule
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2/protoc-gen-openapiv2/options
|
||||
@@ -1202,12 +1203,12 @@ github.com/olekukonko/cat
|
||||
# github.com/olekukonko/errors v1.1.0
|
||||
## explicit; go 1.21
|
||||
github.com/olekukonko/errors
|
||||
# github.com/olekukonko/ll v0.1.3
|
||||
# github.com/olekukonko/ll v0.1.4-0.20260115111900-9e59c2286df0
|
||||
## explicit; go 1.21
|
||||
github.com/olekukonko/ll
|
||||
github.com/olekukonko/ll/lh
|
||||
github.com/olekukonko/ll/lx
|
||||
# github.com/olekukonko/tablewriter v1.1.2
|
||||
# github.com/olekukonko/tablewriter v1.1.3
|
||||
## explicit; go 1.21
|
||||
github.com/olekukonko/tablewriter
|
||||
github.com/olekukonko/tablewriter/pkg/twcache
|
||||
@@ -2593,12 +2594,12 @@ golang.org/x/tools/internal/versions
|
||||
# google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb
|
||||
## explicit; go 1.23.0
|
||||
google.golang.org/genproto/protobuf/field_mask
|
||||
# google.golang.org/genproto/googleapis/api v0.0.0-20251222181119-0a764e51fe1b
|
||||
# google.golang.org/genproto/googleapis/api v0.0.0-20260120221211-b8f7ae30c516
|
||||
## explicit; go 1.24.0
|
||||
google.golang.org/genproto/googleapis/api
|
||||
google.golang.org/genproto/googleapis/api/annotations
|
||||
google.golang.org/genproto/googleapis/api/httpbody
|
||||
# google.golang.org/genproto/googleapis/rpc v0.0.0-20251222181119-0a764e51fe1b
|
||||
# google.golang.org/genproto/googleapis/rpc v0.0.0-20260120221211-b8f7ae30c516
|
||||
## explicit; go 1.24.0
|
||||
google.golang.org/genproto/googleapis/rpc/errdetails
|
||||
google.golang.org/genproto/googleapis/rpc/status
|
||||
|
||||
Reference in New Issue
Block a user