From f0cfcbb268ed75a474baddf96d1374f382c242f8 Mon Sep 17 00:00:00 2001 From: Aldino Kemal Date: Sun, 8 Jun 2025 06:12:12 +0700 Subject: [PATCH] chore: update dependencies and fix configuration - update to v6.0.2 - enable foreign keys in SQLite database - fix docker documentation example - update dependencies including whatsmeow and mcp-go - improve database URI flag documentation --- docs/openapi.yaml | 166 +++++++++++++++++++++++++++++++++++++---- readme.md | 65 ++++++++++++---- src/.env.example | 2 +- src/cmd/root.go | 2 +- src/config/settings.go | 2 +- src/go.mod | 16 ++-- src/go.sum | 32 ++++---- 7 files changed, 228 insertions(+), 57 deletions(-) diff --git a/docs/openapi.yaml b/docs/openapi.yaml index 3b34482..f95c6a3 100644 --- a/docs/openapi.yaml +++ b/docs/openapi.yaml @@ -1,7 +1,7 @@ openapi: "3.0.0" info: title: WhatsApp API MultiDevice - version: 5.4.0 + version: 6.0.0 description: This API is used for sending whatsapp via API servers: - url: http://localhost:3000 @@ -175,6 +175,12 @@ paths: type: boolean example: true description: Whether to fetch a preview of the avatar + - name: is_community + in: query + schema: + type: boolean + example: false + description: Whether to fetch a community avatar responses: '200': description: OK @@ -367,6 +373,10 @@ paths: type: string example: 3EB089B9D6ADD58153C561 description: Message ID that you want reply + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -422,6 +432,10 @@ paths: type: boolean example: false description: Compress image + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -461,6 +475,10 @@ paths: type: string format: binary description: Audio to send + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -504,6 +522,10 @@ paths: type: string format: binary description: File to send + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -545,7 +567,7 @@ paths: description: Caption to send view_once: type: boolean - example: 'false' + example: false description: View once video: type: string @@ -553,8 +575,12 @@ paths: description: Video to send compress: type: boolean - example: 'false' + example: false description: Compress video + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -598,6 +624,10 @@ paths: type: string example: '6289685024992' description: Contact phone number + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -641,6 +671,10 @@ paths: type: string example: 'Halo ini contoh caption' description: Caption to send + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -684,6 +718,10 @@ paths: type: string example: '110.370529' description: Longitude coordinate + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message responses: '200': description: OK @@ -771,13 +809,17 @@ paths: schema: type: object properties: - presence: + type: type: string - description: The presence status to send + description: The presence type to send enum: [available, unavailable] example: 'available' + is_forwarded: + type: boolean + example: false + description: Whether this is a forwarded message required: - - presence + - type responses: '200': description: OK @@ -1020,6 +1062,94 @@ paths: application/json: schema: $ref: '#/components/schemas/ErrorInternalServer' + /message/{message_id}/star: + post: + operationId: starMessage + tags: + - message + summary: Star message + parameters: + - in: path + name: message_id + schema: + type: string + required: true + description: Message ID + requestBody: + content: + application/json: + schema: + type: object + properties: + phone: + type: string + example: '62819273192397132@s.whatsapp.net' + description: Phone number with country code + required: + - phone + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternalServer' + /message/{message_id}/unstar: + post: + operationId: unstarMessage + tags: + - message + summary: Unstar message + parameters: + - in: path + name: message_id + schema: + type: string + required: true + description: Message ID + requestBody: + content: + application/json: + schema: + type: object + properties: + phone: + type: string + example: '62819273192397132@s.whatsapp.net' + description: Phone number with country code + required: + - phone + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '#/components/schemas/GenericResponse' + '400': + description: Bad Request + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorBadRequest' + '500': + description: Internal Server Error + content: + application/json: + schema: + $ref: '#/components/schemas/ErrorInternalServer' /group: post: operationId: createGroup @@ -1269,13 +1399,15 @@ paths: type: string example: '120363024512399999@g.us' description: The group ID - participant_id: - type: string - example: '6281234567890' - description: The participant's WhatsApp ID to approve + participants: + type: array + items: + type: string + example: ['6281234567890'] + description: Array of participant WhatsApp IDs to approve required: - group_id - - participant_id + - participants responses: '200': description: OK @@ -1311,13 +1443,15 @@ paths: type: string example: '120363024512399999@g.us' description: The group ID - participant_id: - type: string - example: '6281234567890' - description: The participant's WhatsApp ID to reject + participants: + type: array + items: + type: string + example: ['6281234567890'] + description: Array of participant WhatsApp IDs to reject required: - group_id - - participant_id + - participants responses: '200': description: OK diff --git a/readme.md b/readme.md index 35ca6df..2136097 100644 --- a/readme.md +++ b/readme.md @@ -68,19 +68,52 @@ can be set in three ways (in order of priority): ### Environment Variables +You can configure the application using environment variables. Configuration can be set in three ways (in order of priority): + +1. Command-line flags (highest priority) +2. Environment variables +3. `.env` file (lowest priority) + To use environment variables: -1. Copy `.env.example` to `.env` in your project root +1. Copy `.env.example` to `.env` in your project root (`cp src/.env.example src/.env`) 2. Modify the values in `.env` according to your needs 3. Or set the same variables as system environment variables -See [.env.example](./src/.env.example) for all available configuration options. +#### Available Environment Variables + +| Variable | Description | Default | Example | +|----------|-------------|---------|---------| +| `APP_PORT` | Application port | `3000` | `APP_PORT=8080` | +| `APP_DEBUG` | Enable debug logging | `false` | `APP_DEBUG=true` | +| `APP_OS` | OS name (device name in WhatsApp) | `Chrome` | `APP_OS=MyApp` | +| `APP_BASIC_AUTH` | Basic authentication credentials | - | `APP_BASIC_AUTH=user1:pass1,user2:pass2` | +| `APP_CHAT_FLUSH_INTERVAL` | Chat flush interval in days | `7` | `APP_CHAT_FLUSH_INTERVAL=30` | +| `DB_URI` | Database connection URI | `file:storages/whatsapp.db?_foreign_keys=on` | `DB_URI=postgres://user:pass@host/db` | +| `WHATSAPP_AUTO_REPLY` | Auto-reply message | - | `WHATSAPP_AUTO_REPLY="Auto reply message"` | +| `WHATSAPP_WEBHOOK` | Webhook URL(s) for events (comma-separated) | - | `WHATSAPP_WEBHOOK=https://webhook.site/xxx` | +| `WHATSAPP_WEBHOOK_SECRET` | Webhook secret for validation | `secret` | `WHATSAPP_WEBHOOK_SECRET=super-secret-key` | +| `WHATSAPP_ACCOUNT_VALIDATION` | Enable account validation | `true` | `WHATSAPP_ACCOUNT_VALIDATION=false` | +| `WHATSAPP_CHAT_STORAGE` | Enable chat storage | `true` | `WHATSAPP_CHAT_STORAGE=false` | Note: Command-line flags will override any values set in environment variables or `.env` file. -- For more command `./main --help` +- For more command `./whatsapp --help` + +## Requirements -## Required (without docker) +### System Requirements + +- **Go 1.24.0 or higher** (for building from source) +- **FFmpeg** (for media processing) + +### Platform Support + +- Linux (x86_64, ARM64) +- macOS (Intel, Apple Silicon) +- Windows (x86_64) - WSL recommended + +### Dependencies (without docker) - Mac OS: - `brew install ffmpeg` @@ -89,7 +122,7 @@ Note: Command-line flags will override any values set in environment variables o - `sudo apt update` - `sudo apt install ffmpeg` - Windows (not recomended, prefer using [WSL](https://docs.microsoft.com/en-us/windows/wsl/install)): - - install ffmpeg, download [here](https://www.ffmpeg.org/download.html#build-windows) + - install ffmpeg, [download here](https://www.ffmpeg.org/download.html#build-windows) - add to ffmpeg to [environment variable](https://www.google.com/search?q=windows+add+to+environment+path) ## How to use @@ -99,7 +132,7 @@ Note: Command-line flags will override any values set in environment variables o 1. Clone this repo: `git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice` 2. Open the folder that was cloned via cmd/terminal. 3. run `cd src` -4. run `go run main.go` +4. run `go run . rest` (for REST API mode) 5. Open `http://localhost:3000` ### Docker (you don't need to install in required) @@ -118,9 +151,9 @@ Note: Command-line flags will override any values set in environment variables o 1. Linux & MacOS: `go build -o whatsapp` 2. Windows (CMD / PowerShell): `go build -o whatsapp.exe` 5. run - 1. Linux & MacOS: `./whatsapp` + 1. Linux & MacOS: `./whatsapp rest` (for REST API mode) 1. run `./whatsapp --help` for more detail flags - 2. Windows: `.\whatsapp.exe` or you can double-click it + 2. Windows: `.\whatsapp.exe rest` (for REST API mode) 1. run `.\whatsapp.exe --help` for more detail flags 6. open `http://localhost:3000` in browser @@ -131,7 +164,7 @@ This application can also run as an MCP server, allowing AI agents and tools to 1. Clone this repo `git clone https://github.com/aldinokemal/go-whatsapp-web-multidevice` 2. Open the folder that was cloned via cmd/terminal. 3. run `cd src` -4. run `go run main.go mcp` or build the binary and run `./whatsapp mcp` +4. run `go run . mcp` or build the binary and run `./whatsapp mcp` 5. The MCP server will start on `http://localhost:8080` by default #### MCP Server Options @@ -153,7 +186,9 @@ This application can also run as an MCP server, allowing AI agents and tools to ### MCP Configuration -make sure you have running MCP server, `./whatsapp mcp` +Make sure you have the MCP server running: `./whatsapp mcp` + +For AI tools that support MCP with SSE (like Cursor), add this configuration: ```json { @@ -162,12 +197,13 @@ make sure you have running MCP server, `./whatsapp mcp` "url": "http://localhost:8080/sse" } } +} ``` ### Production Mode REST (docker) ```bash -docker run --detach --publish=3000:3000 --name=whatsapp --restart=always --volume=$(docker volume create --name=whatsapp):/app/storages aldinokemal2104/go-whatsapp-web-multidevice --autoreply="Dont't reply this message please" +docker run --detach --publish=3000:3000 --name=whatsapp --restart=always --volume=$(docker volume create --name=whatsapp):/app/storages aldinokemal2104/go-whatsapp-web-multidevice rest --autoreply="Dont't reply this message please" ``` ### Production Mode REST (docker compose) @@ -272,6 +308,7 @@ You can fork or edit this source code ! | ✅ | Edit Message | POST | /message/:message_id/update | | ✅ | Read Message (DM) | POST | /message/:message_id/read | | ✅ | Star Message | POST | /message/:message_id/star | +| ✅ | Unstar Message | POST | /message/:message_id/unstar | | ✅ | Join Group With Link | POST | /group/join-with-link | | ✅ | Leave Group | POST | /group/leave | | ✅ | Create Group | POST | /group | @@ -279,9 +316,9 @@ You can fork or edit this source code ! | ✅ | Remove Participant in Group | POST | /group/participants/remove | | ✅ | Promote Participant in Group | POST | /group/participants/promote | | ✅ | Demote Participant in Group | POST | /group/participants/demote | -| ✅ | List Requested Participants in Group | POST | /group/participants/requested | -| ✅ | Approve Requested Participant in Group | POST | /group/participants/requested/approve | -| ✅ | Reject Requested Participant in Group | POST | /group/participants/requested/reject | +| ✅ | List Requested Participants in Group | GET | /group/participant-requests | +| ✅ | Approve Requested Participant in Group | POST | /group/participant-requests/approve | +| ✅ | Reject Requested Participant in Group | POST | /group/participant-requests/reject | | ✅ | Unfollow Newsletter | POST | /newsletter/unfollow | ```txt diff --git a/src/.env.example b/src/.env.example index 4c5e126..80a226a 100644 --- a/src/.env.example +++ b/src/.env.example @@ -6,7 +6,7 @@ APP_BASIC_AUTH=user1:pass1,user2:pass2 APP_CHAT_FLUSH_INTERVAL=7 # Database Settings -DB_URI="file:storages/whatsapp.db?_foreign_keys=off" +DB_URI="file:storages/whatsapp.db?_foreign_keys=on" # WhatsApp Settings WHATSAPP_AUTO_REPLY="Auto reply message" diff --git a/src/cmd/root.go b/src/cmd/root.go index 33013c1..1f76819 100644 --- a/src/cmd/root.go +++ b/src/cmd/root.go @@ -149,7 +149,7 @@ func initFlags() { &config.DBURI, "db-uri", "", config.DBURI, - `the database uri to store the connection data database uri (by default, we'll use sqlite3 under storages/whatsapp.db). database uri --db-uri | example: --db-uri="file:storages/whatsapp.db?_foreign_keys=off or postgres://user:password@localhost:5432/whatsapp"`, + `the database uri to store the connection data database uri (by default, we'll use sqlite3 under storages/whatsapp.db). database uri --db-uri | example: --db-uri="file:storages/whatsapp.db?_foreign_keys=on or postgres://user:password@localhost:5432/whatsapp"`, ) // WhatsApp flags diff --git a/src/config/settings.go b/src/config/settings.go index 62d0ae0..053f550 100644 --- a/src/config/settings.go +++ b/src/config/settings.go @@ -5,7 +5,7 @@ import ( ) var ( - AppVersion = "v6.0.1" + AppVersion = "v6.0.2" AppPort = "3000" AppDebug = false AppOs = "AldinoKemal" diff --git a/src/go.mod b/src/go.mod index d74b214..e2aded4 100644 --- a/src/go.mod +++ b/src/go.mod @@ -12,7 +12,7 @@ require ( github.com/gofiber/websocket/v2 v2.2.1 github.com/google/uuid v1.6.0 github.com/lib/pq v1.10.9 - github.com/mark3labs/mcp-go v0.29.0 + github.com/mark3labs/mcp-go v0.31.0 github.com/mattn/go-sqlite3 v1.14.28 github.com/sirupsen/logrus v1.9.3 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e @@ -21,8 +21,8 @@ require ( github.com/stretchr/testify v1.10.0 github.com/valyala/fasthttp v1.62.0 go.mau.fi/libsignal v0.2.0 - go.mau.fi/whatsmeow v0.0.0-20250521125706-91ac75c2f61a - golang.org/x/image v0.27.0 + go.mau.fi/whatsmeow v0.0.0-20250606170101-3afe34f8ab8f + golang.org/x/image v0.28.0 google.golang.org/protobuf v1.36.6 ) @@ -52,17 +52,17 @@ require ( github.com/savsgio/gotils v0.0.0-20250408102913-196191ec6287 // indirect github.com/sourcegraph/conc v0.3.0 // indirect github.com/spf13/afero v1.14.0 // indirect - github.com/spf13/cast v1.8.0 // indirect + github.com/spf13/cast v1.9.2 // indirect github.com/spf13/pflag v1.0.6 // indirect github.com/subosito/gotenv v1.6.0 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/yosida95/uritemplate/v3 v3.0.2 // indirect go.mau.fi/util v0.8.7 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/crypto v0.38.0 // indirect - golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 // indirect - golang.org/x/net v0.40.0 // indirect + golang.org/x/crypto v0.39.0 // indirect + golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 // indirect + golang.org/x/net v0.41.0 // indirect golang.org/x/sys v0.33.0 // indirect - golang.org/x/text v0.25.0 // indirect + golang.org/x/text v0.26.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/src/go.sum b/src/go.sum index 403d22f..9a954eb 100644 --- a/src/go.sum +++ b/src/go.sum @@ -58,8 +58,8 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/mark3labs/mcp-go v0.29.0 h1:sH1NBcumKskhxqYzhXfGc201D7P76TVXiT0fGVhabeI= -github.com/mark3labs/mcp-go v0.29.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4= +github.com/mark3labs/mcp-go v0.31.0 h1:4UxSV8aM770OPmTvaVe/b1rA2oZAjBMhGBfUgOGut+4= +github.com/mark3labs/mcp-go v0.31.0/go.mod h1:rXqOudj/djTORU/ThxYx8fqEVj/5pvTuuebQ2RC7uk4= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= @@ -100,8 +100,8 @@ github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9yS github.com/sourcegraph/conc v0.3.0/go.mod h1:Sdozi7LEKbFPqYX2/J+iBAM6HpqSLTASQIKqDmF7Mt0= github.com/spf13/afero v1.14.0 h1:9tH6MapGnn/j0eb0yIXiLjERO8RB6xIVZRDCX7PtqWA= github.com/spf13/afero v1.14.0/go.mod h1:acJQ8t0ohCGuMN3O+Pv0V0hgMxNYDlvdk+VTfyZmbYo= -github.com/spf13/cast v1.8.0 h1:gEN9K4b8Xws4EX0+a0reLmhq8moKn7ntRlQYgjPeCDk= -github.com/spf13/cast v1.8.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE= +github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo= github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo= github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0= github.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o= @@ -128,8 +128,8 @@ go.mau.fi/libsignal v0.2.0 h1:oRXj3OHhEJq51BFEM8/50UZblmWiTYH93hsNTPcbk90= go.mau.fi/libsignal v0.2.0/go.mod h1:tvjoDsMejgT38CXTXwqaYu8itBiY8O2Mb6biWvZBb9k= go.mau.fi/util v0.8.7 h1:ywKarPxouJQEEijTs4mPlxC7F4AWEKokEpWc+2TYy6c= go.mau.fi/util v0.8.7/go.mod h1:j6R3cENakc1f8HpQeFl0N15UiSTcNmIfDBNJUbL71RY= -go.mau.fi/whatsmeow v0.0.0-20250521125706-91ac75c2f61a h1:PYtzz5wdma64I47CiquGicyubzg3HIPkH/jMzpmHu8g= -go.mau.fi/whatsmeow v0.0.0-20250521125706-91ac75c2f61a/go.mod h1:Qy3L3BNBcnxfrAQ09lmFMa0ItZfg8zl9DzxKrptzfU4= +go.mau.fi/whatsmeow v0.0.0-20250606170101-3afe34f8ab8f h1:8csRM0kOS9nGgT162JFwi3FZ93NPM6fWVf/d5AfTceA= +go.mau.fi/whatsmeow v0.0.0-20250606170101-3afe34f8ab8f/go.mod h1:Qy3L3BNBcnxfrAQ09lmFMa0ItZfg8zl9DzxKrptzfU4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -138,13 +138,13 @@ golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliY golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= -golang.org/x/crypto v0.38.0 h1:jt+WWG8IZlBnVbomuhg2Mdq0+BBQaHbtqHEFEigjUV8= -golang.org/x/crypto v0.38.0/go.mod h1:MvrbAqul58NNYPKnOra203SB9vpuZW0e+RRZV+Ggqjw= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6 h1:y5zboxd6LQAqYIhHnB48p0ByQ/GnQx2BE33L8BOHQkI= -golang.org/x/exp v0.0.0-20250506013437-ce4c2cf36ca6/go.mod h1:U6Lno4MTRCDY+Ba7aCcauB9T60gsv5s4ralQzP72ZoQ= +golang.org/x/crypto v0.39.0 h1:SHs+kF4LP+f+p14esP5jAoDpHU8Gu/v9lFRK6IT5imM= +golang.org/x/crypto v0.39.0/go.mod h1:L+Xg3Wf6HoL4Bn4238Z6ft6KfEpN0tJGo53AAPC632U= +golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476 h1:bsqhLWFR6G6xiQcb+JoGqdKdRU6WzPWmK8E0jxTjzo4= +golang.org/x/exp v0.0.0-20250606033433-dcc06ee1d476/go.mod h1:3//PLf8L/X+8b4vuAfHzxeRUl04Adcb341+IGKfnqS8= golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/image v0.27.0 h1:C8gA4oWU/tKkdCfYT6T2u4faJu3MeNS5O8UPWlPF61w= -golang.org/x/image v0.27.0/go.mod h1:xbdrClrAUway1MUTEZDq9mz/UpRwYAkFFNUslZtcB+g= +golang.org/x/image v0.28.0 h1:gdem5JW1OLS4FbkWgLO+7ZeFzYtL3xClb97GaUzYMFE= +golang.org/x/image v0.28.0/go.mod h1:GUJYXtnGKEUgggyzh+Vxt+AviiCcyiwpsl8iQ8MvwGY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -159,8 +159,8 @@ golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= -golang.org/x/net v0.40.0 h1:79Xs7wF06Gbdcg4kdCCIQArK11Z1hr5POQ6+fIYHNuY= -golang.org/x/net v0.40.0/go.mod h1:y0hY0exeL2Pku80/zKK7tpntoX23cqL3Oa6njdgRtds= +golang.org/x/net v0.41.0 h1:vBTly1HeNPEn3wtREYfy4GZ/NECgw2Cnl+nK6Nz3uvw= +golang.org/x/net v0.41.0/go.mod h1:B/K4NNqkfmg07DQYrbwvSluqCJOOXwUjeb/5lOisjbA= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -202,8 +202,8 @@ golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= -golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4= -golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA= +golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M= +golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=