Compare commits
43 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
26596acf80 | ||
![]() |
e63870a631 | ||
![]() |
ce782ff6fb | ||
![]() |
c6716e030c | ||
![]() |
4ab72acec6 | ||
![]() |
30aae8e257 | ||
![]() |
d7b7ff7bb4 | ||
![]() |
6fe0cff342 | ||
![]() |
5f75f9886d | ||
![]() |
5d9604cd15 | ||
![]() |
cc36ebf1c9 | ||
![]() |
e6adecfd81 | ||
![]() |
5c8f224e3b | ||
![]() |
952221d3b9 | ||
![]() |
496d5b4ec7 | ||
![]() |
2623a412c4 | ||
![]() |
d64eed49bc | ||
![]() |
fffa29c2f3 | ||
![]() |
4da1444ffc | ||
![]() |
21c4e56d16 | ||
![]() |
5356b3856a | ||
![]() |
320c996a21 | ||
![]() |
69c74be7bb | ||
![]() |
aefa70891c | ||
![]() |
1b9877fda4 | ||
![]() |
0205a67309 | ||
![]() |
e3cafeaf92 | ||
![]() |
e7b193788a | ||
![]() |
17da95b094 | ||
![]() |
c5e49eec96 | ||
![]() |
24bc0f127b | ||
![]() |
f0f801402d | ||
![]() |
663850a2b8 | ||
![]() |
c51753cab1 | ||
![]() |
b3be2e208c | ||
![]() |
c30e90ff3f | ||
![]() |
e4c0ca0f48 | ||
![]() |
9c203327c0 | ||
![]() |
ccb5b1d075 | ||
![]() |
0dbbd0414c | ||
![]() |
e7b3ebf98a | ||
![]() |
5bc18fb780 | ||
![]() |
df30366072 |
22
.github/dependabot.yml
vendored
22
.github/dependabot.yml
vendored
@@ -1,22 +0,0 @@
|
||||
# Docs: <https://docs.github.com/en/free-pro-team@latest/github/administering-a-repository/customizing-dependency-updates>
|
||||
|
||||
version: 2
|
||||
|
||||
updates:
|
||||
- package-ecosystem: gomod
|
||||
directory: /
|
||||
schedule: {interval: weekly}
|
||||
reviewers: [42wim]
|
||||
assignees: [42wim]
|
||||
|
||||
- package-ecosystem: github-actions
|
||||
directory: /
|
||||
schedule: {interval: weekly}
|
||||
reviewers: [42wim]
|
||||
assignees: [42wim]
|
||||
|
||||
- package-ecosystem: docker
|
||||
directory: /
|
||||
schedule: {interval: weekly}
|
||||
reviewers: [42wim]
|
||||
assignees: [42wim]
|
14
Dockerfile_whatsappmulti
Normal file
14
Dockerfile_whatsappmulti
Normal file
@@ -0,0 +1,14 @@
|
||||
FROM alpine AS builder
|
||||
|
||||
COPY . /go/src/matterbridge
|
||||
RUN apk --no-cache add go git \
|
||||
&& cd /go/src/matterbridge \
|
||||
&& CGO_ENABLED=0 go build -tags whatsappmulti -mod vendor -ldflags "-X github.com/42wim/matterbridge/version.GitHash=$(git log --pretty=format:'%h' -n 1)" -o /bin/matterbridge
|
||||
|
||||
FROM alpine
|
||||
RUN apk --no-cache add ca-certificates mailcap
|
||||
COPY --from=builder /bin/matterbridge /bin/matterbridge
|
||||
RUN mkdir /etc/matterbridge \
|
||||
&& touch /etc/matterbridge/matterbridge.toml \
|
||||
&& ln -sf /matterbridge.toml /etc/matterbridge/matterbridge.toml
|
||||
ENTRYPOINT ["/bin/matterbridge", "-conf", "/etc/matterbridge/matterbridge.toml"]
|
74
README.md
74
README.md
@@ -58,21 +58,22 @@ And more...
|
||||
- [Binaries](#binaries)
|
||||
- [Packages](#packages)
|
||||
- [Building](#building)
|
||||
- [Building with whatsapp (beta) multidevice support](#building-with-whatsapp-beta-multidevice-support)
|
||||
- [Configuration](#configuration)
|
||||
- [Basic configuration](#basic-configuration)
|
||||
- [Settings](#settings)
|
||||
- [Advanced configuration](#advanced-configuration)
|
||||
- [Examples](#examples)
|
||||
- [Bridge mattermost (off-topic) - irc (#testing)](#bridge-mattermost-off-topic---irc-testing)
|
||||
- [Bridge slack (#general) - discord (general)](#bridge-slack-general---discord-general)
|
||||
- [Running](#running)
|
||||
- [Docker](#docker)
|
||||
- [Systemd](#systemd)
|
||||
- [Changelog](#changelog)
|
||||
- [FAQ](#faq)
|
||||
- [Related projects](#related-projects)
|
||||
- [Articles / Tutorials](#articles--tutorials)
|
||||
- [Thanks](#thanks)
|
||||
- [Examples](#examples)
|
||||
- [Bridge mattermost (off-topic) - irc (#testing)](#bridge-mattermost-off-topic---irc-testing)
|
||||
- [Bridge slack (#general) - discord (general)](#bridge-slack-general---discord-general)
|
||||
- [Running](#running)
|
||||
- [Docker](#docker)
|
||||
- [Systemd](#systemd)
|
||||
- [Changelog](#changelog)
|
||||
- [FAQ](#faq)
|
||||
- [Related projects](#related-projects)
|
||||
- [Articles / Tutorials](#articles--tutorials)
|
||||
- [Thanks](#thanks)
|
||||
|
||||
## Features
|
||||
|
||||
@@ -89,6 +90,7 @@ And more...
|
||||
|
||||
- [Discord](https://discordapp.com)
|
||||
- [Gitter](https://gitter.im)
|
||||
- [Harmony](https://harmonyapp.io)
|
||||
- [IRC](http://www.mirc.com/servers.html)
|
||||
- [Keybase](https://keybase.io)
|
||||
- [Matrix](https://matrix.org)
|
||||
@@ -105,6 +107,8 @@ And more...
|
||||
- [Twitch](https://twitch.tv)
|
||||
- [VK](https://vk.com/)
|
||||
- [WhatsApp](https://www.whatsapp.com/)
|
||||
- Whatsapp legacy is natively supported
|
||||
- Whatsapp multidevice beta is natively supported but you need to build yourself, see [here](#building-with-whatsapp-beta-multidevice-support)
|
||||
- [XMPP](https://xmpp.org)
|
||||
- [Zulip](https://zulipchat.com)
|
||||
|
||||
@@ -120,6 +124,8 @@ And more...
|
||||
- [Counter-Strike, half-life and more](https://forums.alliedmods.net/showthread.php?t=319430)
|
||||
- [MatterAMXX](https://github.com/GabeIggy/MatterAMXX)
|
||||
- [Vintage Story](https://github.com/NikkyAI/vs-matterbridge)
|
||||
- [Ultima Online Emulator](https://github.com/kuoushi/ServUO-Matterbridge)
|
||||
- [Teamspeak](https://github.com/Archeb/ts-matterbridge)
|
||||
|
||||
### API
|
||||
|
||||
@@ -138,6 +144,8 @@ Used by the projects below. Feel free to make a PR to add your project to this l
|
||||
- [matterbabble](https://github.com/DeclanHoare/matterbabble) (Discourse support)
|
||||
- [MatterAMXX](https://forums.alliedmods.net/showthread.php?t=319430) (Counter-Strike, half-life and more via AMXX mod)
|
||||
- [Vintage Story](https://github.com/NikkyAI/vs-matterbridge)
|
||||
- [ServUO-matterbridge](https://github.com/kuoushi/ServUO-Matterbridge) (A matterbridge connector for ServUO servers)
|
||||
- [ts-matterbridge](https://github.com/Archeb/ts-matterbridge) (Integrate teamspeak chat with matterbridge)
|
||||
|
||||
## Chat with us
|
||||
|
||||
@@ -164,10 +172,10 @@ See <https://github.com/42wim/matterbridge/wiki>
|
||||
|
||||
### Binaries
|
||||
|
||||
- Latest stable release [v1.24.0](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Latest stable release [v1.25.0](https://github.com/42wim/matterbridge/releases/latest)
|
||||
- Development releases (follows master) can be downloaded [here](https://github.com/42wim/matterbridge/actions) selecting the latest green build and then artifacts.
|
||||
|
||||
To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest). On \*nix platforms you may need to make the binary executable - you can do this by running `chmod a+x` on the binary (example: `chmod a+x matterbridge-1.20.0-linux-64bit`). After downloading (and making the binary executable, if necessary), follow the instructions on the [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
|
||||
To install or upgrade just download the latest [binary](https://github.com/42wim/matterbridge/releases/latest). On \*nix platforms you may need to make the binary executable - you can do this by running `chmod a+x` on the binary (example: `chmod a+x matterbridge-1.24.1-linux-64bit`). After downloading (and making the binary executable, if necessary), follow the instructions on the [howto](https://github.com/42wim/matterbridge/wiki/How-to-create-your-config) for a step by step walkthrough for creating your configuration.
|
||||
|
||||
### Packages
|
||||
|
||||
@@ -182,10 +190,13 @@ Most people just want to use binaries, you can find those [here](https://github.
|
||||
If you really want to build from source, follow these instructions:
|
||||
Go 1.17+ is required. Make sure you have [Go](https://golang.org/doc/install) properly installed.
|
||||
|
||||
Building the binary with **all** the bridges enabled needs about 3GB RAM to compile.
|
||||
You can reduce this memory requirement to 0,5GB RAM by adding the `nomsteams` tag if you don't need/use the Microsoft Teams bridge
|
||||
|
||||
To install the latest stable run:
|
||||
|
||||
```bash
|
||||
go install github.com/42wim/matterbridge
|
||||
go install github.com/42wim/matterbridge@17da95b094e4bb433e5fe240fa42067d94d908c1
|
||||
```
|
||||
|
||||
To install the latest dev run:
|
||||
@@ -194,6 +205,36 @@ To install the latest dev run:
|
||||
go install github.com/42wim/matterbridge@master
|
||||
```
|
||||
|
||||
To install the latest stable run without msteams or zulip bridge:
|
||||
|
||||
```bash
|
||||
go install -tags nomsteams,nozulip github.com/42wim/matterbridge@17da95b094e4bb433e5fe240fa42067d94d908c1
|
||||
```
|
||||
|
||||
You should now have matterbridge binary in the ~/go/bin directory:
|
||||
|
||||
```bash
|
||||
$ ls ~/go/bin/
|
||||
matterbridge
|
||||
```
|
||||
|
||||
## Building with whatsapp (beta) multidevice support
|
||||
|
||||
Because the library we use for Whatsapp multidevice support includes a GPL3 library we can not provide you binaries.
|
||||
(as this would require the Matterbridge to change it license to GPL)
|
||||
|
||||
So this means you have to build it yourself using the instructions below:
|
||||
|
||||
```bash
|
||||
go install -tags whatsappmulti github.com/42wim/matterbridge@master
|
||||
```
|
||||
|
||||
If you're low on memory and don't need msteams:
|
||||
|
||||
```bash
|
||||
go install -tags nomsteams,whatsappmulti github.com/42wim/matterbridge@master
|
||||
```
|
||||
|
||||
You should now have matterbridge binary in the ~/go/bin directory:
|
||||
|
||||
```bash
|
||||
@@ -323,6 +364,8 @@ See [FAQ](https://github.com/42wim/matterbridge/wiki/FAQ)
|
||||
- [nextcloud talk](https://github.com/nextcloud/talk_matterbridge) (Integrates matterbridge in Nextcloud Talk)
|
||||
- [mattercraft](https://github.com/raws/mattercraft) (Minecraft bridge)
|
||||
- [vs-matterbridge](https://github.com/NikkyAI/vs-matterbridge) (Vintage Story bridge)
|
||||
- [ServUO-matterbridge](https://github.com/kuoushi/ServUO-Matterbridge) (A matterbridge connector for ServUO servers)
|
||||
- [ts-matterbridge](https://github.com/Archeb/ts-matterbridge) (Integrate teamspeak chat with matterbridge)
|
||||
|
||||
## Articles / Tutorials
|
||||
|
||||
@@ -356,6 +399,7 @@ Matterbridge wouldn't exist without these libraries:
|
||||
- gops - <https://github.com/google/gops>
|
||||
- gozulipbot - <https://github.com/ifo/gozulipbot>
|
||||
- gumble - <https://github.com/layeh/gumble>
|
||||
- harmony - <https://github.com/harmony-development/shibshib>
|
||||
- irc - <https://github.com/lrstanley/girc>
|
||||
- keybase - <https://github.com/keybase/go-keybase-chat-bot>
|
||||
- matrix - <https://github.com/matrix-org/gomatrix>
|
||||
@@ -363,6 +407,7 @@ Matterbridge wouldn't exist without these libraries:
|
||||
- msgraph.go - <https://github.com/yaegashi/msgraph.go>
|
||||
- mumble - <https://github.com/layeh/gumble>
|
||||
- nctalk - <https://github.com/gary-kim/go-nc-talk>
|
||||
- rocketchat - <https://github.com/RocketChat/Rocket.Chat.Go.SDK>
|
||||
- slack - <https://github.com/nlopes/slack>
|
||||
- sshchat - <https://github.com/shazow/ssh-chat>
|
||||
- steam - <https://github.com/Philipp15b/go-steam>
|
||||
@@ -370,6 +415,7 @@ Matterbridge wouldn't exist without these libraries:
|
||||
- tengo - <https://github.com/d5/tengo>
|
||||
- vk - <https://github.com/SevereCloud/vksdk>
|
||||
- whatsapp - <https://github.com/Rhymen/go-whatsapp>
|
||||
- whatsapp - <https://github.com/tulir/whatsmeow>
|
||||
- xmpp - <https://github.com/mattn/go-xmpp>
|
||||
- zulip - <https://github.com/ifo/gozulipbot>
|
||||
|
||||
|
@@ -10,8 +10,8 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/discord/transmitter"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
lru "github.com/hashicorp/golang-lru"
|
||||
"github.com/matterbridge/discordgo"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -272,7 +272,8 @@ func (b *Bdiscord) Send(msg config.Message) (string, error) {
|
||||
// Handle prefix hint for unthreaded messages.
|
||||
if msg.ParentNotFound() {
|
||||
msg.ParentID = ""
|
||||
msg.Text = fmt.Sprintf("[thread]: %s", msg.Text)
|
||||
msg.Text = strings.TrimPrefix(msg.Text, "\n")
|
||||
msg.Text = fmt.Sprintf("> %s %s", msg.Username, msg.Text)
|
||||
}
|
||||
|
||||
// Use webhook to send the message
|
||||
|
@@ -2,8 +2,8 @@ package bdiscord
|
||||
|
||||
import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"github.com/matterbridge/discordgo"
|
||||
)
|
||||
|
||||
func (b *Bdiscord) messageDelete(s *discordgo.Session, m *discordgo.MessageDelete) { //nolint:unparam
|
||||
@@ -56,7 +56,7 @@ func (b *Bdiscord) messageUpdate(s *discordgo.Session, m *discordgo.MessageUpdat
|
||||
return
|
||||
}
|
||||
// only when message is actually edited
|
||||
if m.Message.EditedTimestamp != "" {
|
||||
if m.Message.EditedTimestamp != nil {
|
||||
b.Log.Debugf("Sending edit message")
|
||||
m.Content += b.GetString("EditSuffix")
|
||||
msg := &discordgo.MessageCreate{
|
||||
|
@@ -3,7 +3,7 @@ package bdiscord
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/matterbridge/discordgo"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
|
@@ -6,7 +6,7 @@ import (
|
||||
"strings"
|
||||
"unicode"
|
||||
|
||||
"github.com/matterbridge/discordgo"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
func (b *Bdiscord) getAllowedMentions() *discordgo.MessageAllowedMentions {
|
||||
|
@@ -20,7 +20,7 @@ import (
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/matterbridge/discordgo"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package transmitter
|
||||
|
||||
import (
|
||||
"github.com/matterbridge/discordgo"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
// isDiscordPermissionError returns false for nil, and true if a Discord RESTError with code discordgo.ErrorCodeMissionPermissions
|
||||
|
@@ -5,7 +5,7 @@ import (
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/matterbridge/discordgo"
|
||||
"github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
// shouldMessageUseWebhooks checks if have a channel specific webhook, if we're not using auto webhooks
|
||||
@@ -89,7 +89,7 @@ func (b *Bdiscord) webhookSend(msg *config.Message, channelID string) (*discordg
|
||||
&discordgo.WebhookParams{
|
||||
Username: msg.Username,
|
||||
AvatarURL: msg.Avatar,
|
||||
File: &file,
|
||||
Files: []*discordgo.File{&file},
|
||||
Content: content,
|
||||
AllowedMentions: b.getAllowedMentions(),
|
||||
},
|
||||
|
32
bridge/irc/charset.go
Normal file
32
bridge/irc/charset.go
Normal file
@@ -0,0 +1,32 @@
|
||||
package birc
|
||||
|
||||
import (
|
||||
"golang.org/x/text/encoding"
|
||||
"golang.org/x/text/encoding/japanese"
|
||||
"golang.org/x/text/encoding/korean"
|
||||
"golang.org/x/text/encoding/simplifiedchinese"
|
||||
"golang.org/x/text/encoding/traditionalchinese"
|
||||
"golang.org/x/text/encoding/unicode"
|
||||
)
|
||||
|
||||
var encoders = map[string]encoding.Encoding{
|
||||
"utf-8": unicode.UTF8,
|
||||
"iso-2022-jp": japanese.ISO2022JP,
|
||||
"big5": traditionalchinese.Big5,
|
||||
"gbk": simplifiedchinese.GBK,
|
||||
"euc-kr": korean.EUCKR,
|
||||
"gb2312": simplifiedchinese.HZGB2312,
|
||||
"shift-jis": japanese.ShiftJIS,
|
||||
"euc-jp": japanese.EUCJP,
|
||||
"gb18030": simplifiedchinese.GB18030,
|
||||
}
|
||||
|
||||
func toUTF8(from string, input string) string {
|
||||
enc, ok := encoders[from]
|
||||
if !ok {
|
||||
return input
|
||||
}
|
||||
|
||||
res, _ := enc.NewDecoder().String(input)
|
||||
return res
|
||||
}
|
@@ -11,7 +11,6 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
"github.com/lrstanley/girc"
|
||||
"github.com/missdeer/golib/ic"
|
||||
"github.com/paulrosania/go-charset/charset"
|
||||
"github.com/saintfish/chardet"
|
||||
|
||||
@@ -24,12 +23,12 @@ func (b *Birc) handleCharset(msg *config.Message) error {
|
||||
if b.GetString("Charset") != "" {
|
||||
switch b.GetString("Charset") {
|
||||
case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp":
|
||||
msg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), msg.Text)
|
||||
msg.Text = toUTF8(b.GetString("Charset"), msg.Text)
|
||||
default:
|
||||
buf := new(bytes.Buffer)
|
||||
w, err := charset.NewWriter(b.GetString("Charset"), buf)
|
||||
if err != nil {
|
||||
b.Log.Errorf("charset from utf-8 conversion failed: %s", err)
|
||||
b.Log.Errorf("charset to utf-8 conversion failed: %s", err)
|
||||
return err
|
||||
}
|
||||
fmt.Fprint(w, msg.Text)
|
||||
@@ -227,7 +226,7 @@ func (b *Birc) handlePrivMsg(client *girc.Client, event girc.Event) {
|
||||
}
|
||||
switch mycharset {
|
||||
case "gbk", "gb18030", "gb2312", "big5", "euc-kr", "euc-jp", "shift-jis", "iso-2022-jp":
|
||||
rmsg.Text = ic.ConvertString("utf-8", b.GetString("Charset"), rmsg.Text)
|
||||
rmsg.Text = toUTF8(b.GetString("Charset"), rmsg.Text)
|
||||
default:
|
||||
r, err := charset.NewReader(mycharset, strings.NewReader(rmsg.Text))
|
||||
if err != nil {
|
||||
|
@@ -362,8 +362,10 @@ func (b *Birc) skipPrivMsg(event girc.Event) bool {
|
||||
return true
|
||||
}
|
||||
// don't forward message from ourself
|
||||
if event.Source.Name == b.Nick {
|
||||
return true
|
||||
if event.Source != nil {
|
||||
if event.Source.Name == b.Nick {
|
||||
return true
|
||||
}
|
||||
}
|
||||
// don't forward messages we sent via RELAYMSG
|
||||
if relayedNick, ok := event.Tags.Get("draft/relaymsg"); ok && relayedNick == b.Nick {
|
||||
|
@@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
matrix "github.com/matrix-org/gomatrix"
|
||||
matrix "github.com/matterbridge/gomatrix"
|
||||
)
|
||||
|
||||
func newMatrixUsername(username string) *matrixUsername {
|
||||
|
@@ -12,7 +12,7 @@ import (
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
matrix "github.com/matrix-org/gomatrix"
|
||||
matrix "github.com/matterbridge/gomatrix"
|
||||
)
|
||||
|
||||
var (
|
||||
|
70
bridge/mumble/codec.go
Normal file
70
bridge/mumble/codec.go
Normal file
@@ -0,0 +1,70 @@
|
||||
package bmumble
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"layeh.com/gumble/gumble"
|
||||
)
|
||||
|
||||
// This is a dummy implementation of a Gumble audio codec which claims
|
||||
// to implement Opus, but does not actually do anything. This serves
|
||||
// as a workaround until https://github.com/layeh/gumble/pull/61 is
|
||||
// merged.
|
||||
// See https://github.com/42wim/matterbridge/issues/1750 for details.
|
||||
|
||||
const (
|
||||
audioCodecIDOpus = 4
|
||||
)
|
||||
|
||||
func registerNullCodecAsOpus() {
|
||||
codec := &NullCodec{
|
||||
encoder: &NullAudioEncoder{},
|
||||
decoder: &NullAudioDecoder{},
|
||||
}
|
||||
gumble.RegisterAudioCodec(audioCodecIDOpus, codec)
|
||||
}
|
||||
|
||||
type NullCodec struct {
|
||||
encoder *NullAudioEncoder
|
||||
decoder *NullAudioDecoder
|
||||
}
|
||||
|
||||
func (c *NullCodec) ID() int {
|
||||
return audioCodecIDOpus
|
||||
}
|
||||
|
||||
func (c *NullCodec) NewEncoder() gumble.AudioEncoder {
|
||||
e := &NullAudioEncoder{}
|
||||
return e
|
||||
}
|
||||
|
||||
func (c *NullCodec) NewDecoder() gumble.AudioDecoder {
|
||||
d := &NullAudioDecoder{}
|
||||
return d
|
||||
}
|
||||
|
||||
type NullAudioEncoder struct{}
|
||||
|
||||
func (e *NullAudioEncoder) ID() int {
|
||||
return audioCodecIDOpus
|
||||
}
|
||||
|
||||
func (e *NullAudioEncoder) Encode(pcm []int16, mframeSize, maxDataBytes int) ([]byte, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (e *NullAudioEncoder) Reset() {
|
||||
}
|
||||
|
||||
type NullAudioDecoder struct{}
|
||||
|
||||
func (d *NullAudioDecoder) ID() int {
|
||||
return audioCodecIDOpus
|
||||
}
|
||||
|
||||
func (d *NullAudioDecoder) Decode(data []byte, frameSize int) ([]int16, error) {
|
||||
return nil, fmt.Errorf("not implemented")
|
||||
}
|
||||
|
||||
func (d *NullAudioDecoder) Reset() {
|
||||
}
|
@@ -185,6 +185,7 @@ func (b *Bmumble) doConnect() error {
|
||||
gumbleConfig.Password = password
|
||||
}
|
||||
|
||||
registerNullCodecAsOpus()
|
||||
client, err := gumble.DialWithDialer(new(net.Dialer), b.GetString("Server"), gumbleConfig, &b.tlsConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@@ -87,6 +87,9 @@ func (b *Bslack) populateMessageWithUserInfo(ev *slack.MessageEvent, rmsg *confi
|
||||
if user.Profile.DisplayName != "" {
|
||||
rmsg.Username = user.Profile.DisplayName
|
||||
}
|
||||
if b.GetBool("UseFullName") && user.Profile.RealName != "" {
|
||||
rmsg.Username = user.Profile.RealName
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@@ -321,7 +321,7 @@ func (b *Bslack) sendRTM(msg config.Message) (string, error) {
|
||||
}
|
||||
|
||||
// Upload a file if it exists.
|
||||
if msg.Extra != nil {
|
||||
if len(msg.Extra) > 0 {
|
||||
extraMsgs := helper.HandleExtra(&msg, b.General)
|
||||
for i := range extraMsgs {
|
||||
rmsg := &extraMsgs[i]
|
||||
@@ -332,7 +332,7 @@ func (b *Bslack) sendRTM(msg config.Message) (string, error) {
|
||||
}
|
||||
}
|
||||
// Upload files if necessary (from Slack, Telegram or Mattermost).
|
||||
b.uploadFile(&msg, channelInfo.ID)
|
||||
return b.uploadFile(&msg, channelInfo.ID)
|
||||
}
|
||||
|
||||
// Post message.
|
||||
@@ -443,7 +443,8 @@ func (b *Bslack) postMessage(msg *config.Message, channelInfo *slack.Channel) (s
|
||||
}
|
||||
|
||||
// uploadFile handles native upload of files
|
||||
func (b *Bslack) uploadFile(msg *config.Message, channelID string) {
|
||||
func (b *Bslack) uploadFile(msg *config.Message, channelID string) (string, error) {
|
||||
var messageID string
|
||||
for _, f := range msg.Extra["file"] {
|
||||
fi, ok := f.(config.FileInfo)
|
||||
if !ok {
|
||||
@@ -471,13 +472,22 @@ func (b *Bslack) uploadFile(msg *config.Message, channelID string) {
|
||||
})
|
||||
if err != nil {
|
||||
b.Log.Errorf("uploadfile %#v", err)
|
||||
return
|
||||
return "", err
|
||||
}
|
||||
if res.ID != "" {
|
||||
b.Log.Debugf("Adding file ID %s to cache with timestamp %s", res.ID, ts.String())
|
||||
b.cache.Add("file"+res.ID, ts)
|
||||
|
||||
// search for message id by uploaded file in private/public channels, get thread timestamp from uploaded file
|
||||
if v, ok := res.Shares.Private[channelID]; ok && len(v) > 0 {
|
||||
messageID = v[0].Ts
|
||||
}
|
||||
if v, ok := res.Shares.Public[channelID]; ok && len(v) > 0 {
|
||||
messageID = v[0].Ts
|
||||
}
|
||||
}
|
||||
}
|
||||
return messageID, nil
|
||||
}
|
||||
|
||||
func (b *Bslack) prepareMessageOptions(msg *config.Message) []slack.MsgOption {
|
||||
|
@@ -57,6 +57,11 @@ func (b *Btelegram) handleForwarded(rmsg *config.Message, message *tgbotapi.Mess
|
||||
return
|
||||
}
|
||||
|
||||
if message.ForwardFromChat != nil && message.ForwardFrom == nil {
|
||||
rmsg.Text = "Forwarded from " + message.ForwardFromChat.Title + ": " + rmsg.Text
|
||||
return
|
||||
}
|
||||
|
||||
if message.ForwardFrom == nil {
|
||||
rmsg.Text = "Forwarded from " + unknownUser + ": " + rmsg.Text
|
||||
return
|
||||
@@ -66,6 +71,9 @@ func (b *Btelegram) handleForwarded(rmsg *config.Message, message *tgbotapi.Mess
|
||||
if b.GetBool("UseFirstName") {
|
||||
usernameForward = message.ForwardFrom.FirstName
|
||||
}
|
||||
if b.GetBool("UseFullName") {
|
||||
usernameForward = message.ForwardFrom.FirstName + " " + message.ForwardFrom.LastName
|
||||
}
|
||||
|
||||
if usernameForward == "" {
|
||||
usernameForward = message.ForwardFrom.UserName
|
||||
@@ -89,6 +97,9 @@ func (b *Btelegram) handleQuoting(rmsg *config.Message, message *tgbotapi.Messag
|
||||
if b.GetBool("UseFirstName") {
|
||||
usernameReply = message.ReplyToMessage.From.FirstName
|
||||
}
|
||||
if b.GetBool("UseFullName") {
|
||||
usernameReply = message.ReplyToMessage.From.FirstName + " " + message.ReplyToMessage.From.LastName
|
||||
}
|
||||
if usernameReply == "" {
|
||||
usernameReply = message.ReplyToMessage.From.UserName
|
||||
if usernameReply == "" {
|
||||
@@ -100,7 +111,11 @@ func (b *Btelegram) handleQuoting(rmsg *config.Message, message *tgbotapi.Messag
|
||||
usernameReply = unknownUser
|
||||
}
|
||||
if !b.GetBool("QuoteDisable") {
|
||||
rmsg.Text = b.handleQuote(rmsg.Text, usernameReply, message.ReplyToMessage.Text)
|
||||
quote := message.ReplyToMessage.Text
|
||||
if quote == "" {
|
||||
quote = message.ReplyToMessage.Caption
|
||||
}
|
||||
rmsg.Text = b.handleQuote(rmsg.Text, usernameReply, quote)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -112,6 +127,9 @@ func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Messa
|
||||
if b.GetBool("UseFirstName") {
|
||||
rmsg.Username = message.From.FirstName
|
||||
}
|
||||
if b.GetBool("UseFullName") {
|
||||
rmsg.Username = message.From.FirstName + " " + message.From.LastName
|
||||
}
|
||||
if rmsg.Username == "" {
|
||||
rmsg.Username = message.From.UserName
|
||||
if rmsg.Username == "" {
|
||||
@@ -129,6 +147,9 @@ func (b *Btelegram) handleUsername(rmsg *config.Message, message *tgbotapi.Messa
|
||||
if b.GetBool("UseFirstName") {
|
||||
rmsg.Username = message.SenderChat.FirstName
|
||||
}
|
||||
if b.GetBool("UseFullName") {
|
||||
rmsg.Username = message.SenderChat.FirstName + " " + message.SenderChat.LastName
|
||||
}
|
||||
|
||||
if rmsg.Username == "" || rmsg.Username == "Channel_Bot" {
|
||||
rmsg.Username = message.SenderChat.UserName
|
||||
@@ -182,6 +203,14 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) {
|
||||
rmsg.ID = strconv.Itoa(message.MessageID)
|
||||
rmsg.Channel = strconv.FormatInt(message.Chat.ID, 10)
|
||||
|
||||
// preserve threading from telegram reply
|
||||
if message.ReplyToMessage != nil {
|
||||
rmsg.ParentID = strconv.Itoa(message.ReplyToMessage.MessageID)
|
||||
}
|
||||
|
||||
// handle entities (adding URLs)
|
||||
b.handleEntities(&rmsg, message)
|
||||
|
||||
// handle username
|
||||
b.handleUsername(&rmsg, message)
|
||||
|
||||
@@ -197,11 +226,9 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) {
|
||||
// quote the previous message
|
||||
b.handleQuoting(&rmsg, message)
|
||||
|
||||
// handle entities (adding URLs)
|
||||
b.handleEntities(&rmsg, message)
|
||||
|
||||
if rmsg.Text != "" || len(rmsg.Extra) > 0 {
|
||||
rmsg.Text = helper.RemoveEmptyNewLines(rmsg.Text)
|
||||
// Comment the next line out due to avoid removing empty lines in Telegram
|
||||
// rmsg.Text = helper.RemoveEmptyNewLines(rmsg.Text)
|
||||
// channels don't have (always?) user information. see #410
|
||||
if message.From != nil {
|
||||
rmsg.Avatar = helper.GetAvatar(b.avatarMap, strconv.FormatInt(message.From.ID, 10), b.General)
|
||||
@@ -416,8 +443,8 @@ func (b *Btelegram) handleEdit(msg *config.Message, chatid int64) (string, error
|
||||
}
|
||||
|
||||
// handleUploadFile handles native upload of files
|
||||
func (b *Btelegram) handleUploadFile(msg *config.Message, chatid int64) string {
|
||||
var c tgbotapi.Chattable
|
||||
func (b *Btelegram) handleUploadFile(msg *config.Message, chatid int64, parentID int) (string, error) {
|
||||
var media []interface{}
|
||||
for _, f := range msg.Extra["file"] {
|
||||
fi := f.(config.FileInfo)
|
||||
file := tgbotapi.FileBytes{
|
||||
@@ -426,32 +453,42 @@ func (b *Btelegram) handleUploadFile(msg *config.Message, chatid int64) string {
|
||||
}
|
||||
switch filepath.Ext(fi.Name) {
|
||||
case ".jpg", ".jpe", ".png":
|
||||
pc := tgbotapi.NewPhoto(chatid, file)
|
||||
pc.Caption, pc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = pc
|
||||
pc := tgbotapi.NewInputMediaPhoto(file)
|
||||
if fi.Comment != "" {
|
||||
pc.Caption, pc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
}
|
||||
media = append(media, pc)
|
||||
case ".mp4", ".m4v":
|
||||
vc := tgbotapi.NewVideo(chatid, file)
|
||||
vc.Caption, vc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = vc
|
||||
vc := tgbotapi.NewInputMediaVideo(file)
|
||||
if fi.Comment != "" {
|
||||
vc.Caption, vc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
}
|
||||
media = append(media, vc)
|
||||
case ".mp3", ".oga":
|
||||
ac := tgbotapi.NewAudio(chatid, file)
|
||||
ac.Caption, ac.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = ac
|
||||
ac := tgbotapi.NewInputMediaAudio(file)
|
||||
if fi.Comment != "" {
|
||||
ac.Caption, ac.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
}
|
||||
media = append(media, ac)
|
||||
case ".ogg":
|
||||
voc := tgbotapi.NewVoice(chatid, file)
|
||||
voc.Caption, voc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = voc
|
||||
voc.ReplyToMessageID = parentID
|
||||
res, err := b.c.Send(voc)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return strconv.Itoa(res.MessageID), nil
|
||||
default:
|
||||
dc := tgbotapi.NewDocument(chatid, file)
|
||||
dc.Caption, dc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
c = dc
|
||||
}
|
||||
_, err := b.c.Send(c)
|
||||
if err != nil {
|
||||
b.Log.Errorf("file upload failed: %#v", err)
|
||||
dc := tgbotapi.NewInputMediaDocument(file)
|
||||
if fi.Comment != "" {
|
||||
dc.Caption, dc.ParseMode = TGGetParseMode(b, msg.Username, fi.Comment)
|
||||
}
|
||||
media = append(media, dc)
|
||||
}
|
||||
}
|
||||
return ""
|
||||
|
||||
return b.sendMediaFiles(msg, chatid, parentID, media)
|
||||
}
|
||||
|
||||
func (b *Btelegram) handleQuote(message, quoteNick, quoteMessage string) string {
|
||||
@@ -483,31 +520,51 @@ func (b *Btelegram) handleEntities(rmsg *config.Message, message *tgbotapi.Messa
|
||||
|
||||
// for now only do URL replacements
|
||||
for _, e := range message.Entities {
|
||||
|
||||
asRunes := utf16.Encode([]rune(rmsg.Text))
|
||||
|
||||
if e.Type == "text_link" {
|
||||
offset := e.Offset + indexMovedBy
|
||||
url, err := e.ParseURL()
|
||||
if err != nil {
|
||||
b.Log.Errorf("entity text_link url parse failed: %s", err)
|
||||
continue
|
||||
}
|
||||
utfEncodedString := utf16.Encode([]rune(rmsg.Text))
|
||||
if e.Offset+e.Length > len(utfEncodedString) {
|
||||
b.Log.Errorf("entity length is too long %d > %d", e.Offset+e.Length, len(utfEncodedString))
|
||||
if offset+e.Length > len(utfEncodedString) {
|
||||
b.Log.Errorf("entity length is too long %d > %d", offset+e.Length, len(utfEncodedString))
|
||||
continue
|
||||
}
|
||||
link := utf16.Decode(utfEncodedString[e.Offset : e.Offset+e.Length])
|
||||
rmsg.Text = strings.Replace(rmsg.Text, string(link), url.String(), 1)
|
||||
rmsg.Text = string(utf16.Decode(asRunes[:offset+e.Length])) + " (" + url.String() + ")" + string(utf16.Decode(asRunes[offset+e.Length:]))
|
||||
indexMovedBy += len(url.String()) + 3
|
||||
}
|
||||
|
||||
if e.Type == "code" {
|
||||
offset := e.Offset + indexMovedBy
|
||||
rmsg.Text = rmsg.Text[:offset] + "`" + rmsg.Text[offset:offset+e.Length] + "`" + rmsg.Text[offset+e.Length:]
|
||||
rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "`" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "`" + string(utf16.Decode(asRunes[offset+e.Length:]))
|
||||
indexMovedBy += 2
|
||||
}
|
||||
|
||||
if e.Type == "pre" {
|
||||
offset := e.Offset + indexMovedBy
|
||||
rmsg.Text = rmsg.Text[:offset] + "```\n" + rmsg.Text[offset:offset+e.Length] + "\n```" + rmsg.Text[offset+e.Length:]
|
||||
rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "```\n" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "```\n" + string(utf16.Decode(asRunes[offset+e.Length:]))
|
||||
indexMovedBy += 8
|
||||
}
|
||||
|
||||
if e.Type == "bold" {
|
||||
offset := e.Offset + indexMovedBy
|
||||
rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "*" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "*" + string(utf16.Decode(asRunes[offset+e.Length:]))
|
||||
indexMovedBy += 2
|
||||
}
|
||||
if e.Type == "italic" {
|
||||
offset := e.Offset + indexMovedBy
|
||||
rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "_" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "_" + string(utf16.Decode(asRunes[offset+e.Length:]))
|
||||
indexMovedBy += 2
|
||||
}
|
||||
if e.Type == "strike" {
|
||||
offset := e.Offset + indexMovedBy
|
||||
rmsg.Text = string(utf16.Decode(asRunes[:offset])) + "~" + string(utf16.Decode(asRunes[offset:offset+e.Length])) + "~" + string(utf16.Decode(asRunes[offset+e.Length:]))
|
||||
indexMovedBy += 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package btelegram
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"log"
|
||||
"strconv"
|
||||
@@ -108,16 +109,27 @@ func (b *Btelegram) Send(msg config.Message) (string, error) {
|
||||
return b.handleDelete(&msg, chatid)
|
||||
}
|
||||
|
||||
// Handle prefix hint for unthreaded messages.
|
||||
if msg.ParentNotFound() {
|
||||
msg.ParentID = ""
|
||||
msg.Text = fmt.Sprintf("[reply]: %s", msg.Text)
|
||||
}
|
||||
|
||||
var parentID int
|
||||
if msg.ParentID != "" {
|
||||
parentID, _ = b.intParentID(msg.ParentID)
|
||||
}
|
||||
|
||||
// Upload a file if it exists
|
||||
if msg.Extra != nil {
|
||||
for _, rmsg := range helper.HandleExtra(&msg, b.General) {
|
||||
if _, msgErr := b.sendMessage(chatid, rmsg.Username, rmsg.Text); msgErr != nil {
|
||||
if _, msgErr := b.sendMessage(chatid, rmsg.Username, rmsg.Text, parentID); msgErr != nil {
|
||||
b.Log.Errorf("sendMessage failed: %s", msgErr)
|
||||
}
|
||||
}
|
||||
// check if we have files to upload (from slack, telegram or mattermost)
|
||||
if len(msg.Extra["file"]) > 0 {
|
||||
b.handleUploadFile(&msg, chatid)
|
||||
return b.handleUploadFile(&msg, chatid, parentID)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,7 +143,7 @@ func (b *Btelegram) Send(msg config.Message) (string, error) {
|
||||
// Ignore empty text field needs for prevent double messages from whatsapp to telegram
|
||||
// when sending media with text caption
|
||||
if msg.Text != "" {
|
||||
return b.sendMessage(chatid, msg.Username, msg.Text)
|
||||
return b.sendMessage(chatid, msg.Username, msg.Text, parentID)
|
||||
}
|
||||
|
||||
return "", nil
|
||||
@@ -145,10 +157,10 @@ func (b *Btelegram) getFileDirectURL(id string) string {
|
||||
return res
|
||||
}
|
||||
|
||||
func (b *Btelegram) sendMessage(chatid int64, username, text string) (string, error) {
|
||||
func (b *Btelegram) sendMessage(chatid int64, username, text string, parentID int) (string, error) {
|
||||
m := tgbotapi.NewMessage(chatid, "")
|
||||
m.Text, m.ParseMode = TGGetParseMode(b, username, text)
|
||||
|
||||
m.ReplyToMessageID = parentID
|
||||
m.DisableWebPagePreview = b.GetBool("DisableWebPagePreview")
|
||||
|
||||
res, err := b.c.Send(m)
|
||||
@@ -158,6 +170,29 @@ func (b *Btelegram) sendMessage(chatid int64, username, text string) (string, er
|
||||
return strconv.Itoa(res.MessageID), nil
|
||||
}
|
||||
|
||||
// sendMediaFiles native upload media files via media group
|
||||
func (b *Btelegram) sendMediaFiles(msg *config.Message, chatid int64, parentID int, media []interface{}) (string, error) {
|
||||
if len(media) == 0 {
|
||||
return "", nil
|
||||
}
|
||||
mg := tgbotapi.MediaGroupConfig{ChatID: chatid, ChannelUsername: msg.Username, Media: media, ReplyToMessageID: parentID}
|
||||
messages, err := b.c.SendMediaGroup(mg)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// return first message id
|
||||
return strconv.Itoa(messages[0].MessageID), nil
|
||||
}
|
||||
|
||||
// intParentID return integer parent id for telegram message
|
||||
func (b *Btelegram) intParentID(parentID string) (int, error) {
|
||||
pid, err := strconv.Atoi(parentID)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return pid, nil
|
||||
}
|
||||
|
||||
func (b *Btelegram) cacheAvatar(msg *config.Message) (string, error) {
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
/* if we have a sha we have successfully uploaded the file to the media server,
|
||||
|
@@ -1,3 +1,4 @@
|
||||
// nolint:goconst
|
||||
package bwhatsapp
|
||||
|
||||
import (
|
||||
@@ -134,6 +135,7 @@ func (b *Bwhatsapp) HandleTextMessage(message whatsapp.TextMessage) {
|
||||
}
|
||||
|
||||
// HandleImageMessage sent from WhatsApp, relay it to the brige
|
||||
// nolint:funlen
|
||||
func (b *Bwhatsapp) HandleImageMessage(message whatsapp.ImageMessage) {
|
||||
if message.Info.FromMe || message.Info.Timestamp < b.startedAt {
|
||||
return
|
||||
|
@@ -111,8 +111,7 @@ func (b *Bwhatsapp) getSenderName(senderJid string) string {
|
||||
}
|
||||
|
||||
// try to reload this contact
|
||||
_, err := b.conn.Contacts()
|
||||
if err != nil {
|
||||
if _, err := b.conn.Contacts(); err != nil {
|
||||
b.Log.Errorf("error on update of contacts: %v", err)
|
||||
}
|
||||
|
||||
|
@@ -40,6 +40,11 @@ type Bwhatsapp struct {
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
number := cfg.GetString(cfgNumber)
|
||||
|
||||
cfg.Log.Warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
cfg.Log.Warn("This bridge is deprecated and not supported anymore. Use the new multidevice whatsapp bridge")
|
||||
cfg.Log.Warn("See https://github.com/42wim/matterbridge#building-with-whatsapp-beta-multidevice-support for more info")
|
||||
cfg.Log.Warn("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!")
|
||||
|
||||
if number == "" {
|
||||
cfg.Log.Fatalf("Missing configuration for WhatsApp bridge: Number")
|
||||
}
|
||||
|
344
bridge/whatsappmulti/handlers.go
Normal file
344
bridge/whatsappmulti/handlers.go
Normal file
@@ -0,0 +1,344 @@
|
||||
// +build whatsappmulti
|
||||
|
||||
package bwhatsapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"mime"
|
||||
"strings"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/42wim/matterbridge/bridge/helper"
|
||||
|
||||
"go.mau.fi/whatsmeow/binary/proto"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
"go.mau.fi/whatsmeow/types/events"
|
||||
)
|
||||
|
||||
// nolint:gocritic
|
||||
func (b *Bwhatsapp) eventHandler(evt interface{}) {
|
||||
switch e := evt.(type) {
|
||||
case *events.Message:
|
||||
b.handleMessage(e)
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bwhatsapp) handleMessage(message *events.Message) {
|
||||
msg := message.Message
|
||||
switch {
|
||||
case msg == nil, message.Info.IsFromMe, message.Info.Timestamp.Before(b.startedAt):
|
||||
return
|
||||
}
|
||||
|
||||
b.Log.Infof("Receiving message %#v", msg)
|
||||
|
||||
switch {
|
||||
case msg.Conversation != nil || msg.ExtendedTextMessage != nil:
|
||||
b.handleTextMessage(message.Info, msg)
|
||||
case msg.VideoMessage != nil:
|
||||
b.handleVideoMessage(message)
|
||||
case msg.AudioMessage != nil:
|
||||
b.handleAudioMessage(message)
|
||||
case msg.DocumentMessage != nil:
|
||||
b.handleDocumentMessage(message)
|
||||
case msg.ImageMessage != nil:
|
||||
b.handleImageMessage(message)
|
||||
}
|
||||
}
|
||||
|
||||
// nolint:funlen
|
||||
func (b *Bwhatsapp) handleTextMessage(messageInfo types.MessageInfo, msg *proto.Message) {
|
||||
senderJID := messageInfo.Sender
|
||||
channel := messageInfo.Chat
|
||||
|
||||
senderName := b.getSenderName(messageInfo.Sender)
|
||||
if senderName == "" {
|
||||
senderName = "Someone" // don't expose telephone number
|
||||
}
|
||||
|
||||
if msg.GetExtendedTextMessage() == nil && msg.GetConversation() == "" {
|
||||
b.Log.Debugf("message without text content? %#v", msg)
|
||||
return
|
||||
}
|
||||
|
||||
var text string
|
||||
|
||||
// nolint:nestif
|
||||
if msg.GetExtendedTextMessage() == nil {
|
||||
text = msg.GetConversation()
|
||||
} else {
|
||||
text = msg.GetExtendedTextMessage().GetText()
|
||||
ci := msg.GetExtendedTextMessage().GetContextInfo()
|
||||
|
||||
if senderJID == (types.JID{}) && ci.Participant != nil {
|
||||
senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer)
|
||||
}
|
||||
|
||||
if ci.MentionedJid != nil {
|
||||
// handle user mentions
|
||||
for _, mentionedJID := range ci.MentionedJid {
|
||||
numberAndSuffix := strings.SplitN(mentionedJID, "@", 2)
|
||||
|
||||
// mentions comes as telephone numbers and we don't want to expose it to other bridges
|
||||
// replace it with something more meaninful to others
|
||||
mention := b.getSenderNotify(types.NewJID(numberAndSuffix[0], types.DefaultUserServer))
|
||||
if mention == "" {
|
||||
mention = "someone"
|
||||
}
|
||||
|
||||
text = strings.Replace(text, "@"+numberAndSuffix[0], "@"+mention, 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rmsg := config.Message{
|
||||
UserID: senderJID.String(),
|
||||
Username: senderName,
|
||||
Text: text,
|
||||
Channel: channel.String(),
|
||||
Account: b.Account,
|
||||
Protocol: b.Protocol,
|
||||
Extra: make(map[string][]interface{}),
|
||||
// ParentID: TODO, // TODO handle thread replies // map from Info.QuotedMessageID string
|
||||
ID: messageInfo.ID,
|
||||
}
|
||||
|
||||
if avatarURL, exists := b.userAvatars[senderJID.String()]; exists {
|
||||
rmsg.Avatar = avatarURL
|
||||
}
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
// HandleImageMessage sent from WhatsApp, relay it to the brige
|
||||
func (b *Bwhatsapp) handleImageMessage(msg *events.Message) {
|
||||
imsg := msg.Message.GetImageMessage()
|
||||
|
||||
senderJID := msg.Info.Sender
|
||||
senderName := b.getSenderName(senderJID)
|
||||
ci := imsg.GetContextInfo()
|
||||
|
||||
if senderJID == (types.JID{}) && ci.Participant != nil {
|
||||
senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer)
|
||||
}
|
||||
|
||||
rmsg := config.Message{
|
||||
UserID: senderJID.String(),
|
||||
Username: senderName,
|
||||
Channel: msg.Info.Chat.String(),
|
||||
Account: b.Account,
|
||||
Protocol: b.Protocol,
|
||||
Extra: make(map[string][]interface{}),
|
||||
ID: msg.Info.ID,
|
||||
}
|
||||
|
||||
if avatarURL, exists := b.userAvatars[senderJID.String()]; exists {
|
||||
rmsg.Avatar = avatarURL
|
||||
}
|
||||
|
||||
fileExt, err := mime.ExtensionsByType(imsg.GetMimetype())
|
||||
if err != nil {
|
||||
b.Log.Errorf("Mimetype detection error: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// rename .jfif to .jpg https://github.com/42wim/matterbridge/issues/1292
|
||||
if fileExt[0] == ".jfif" {
|
||||
fileExt[0] = ".jpg"
|
||||
}
|
||||
|
||||
// rename .jpe to .jpg https://github.com/42wim/matterbridge/issues/1463
|
||||
if fileExt[0] == ".jpe" {
|
||||
fileExt[0] = ".jpg"
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0])
|
||||
|
||||
b.Log.Debugf("Trying to download %s with type %s", filename, imsg.GetMimetype())
|
||||
|
||||
data, err := b.wc.Download(imsg)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Download image failed: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Move file to bridge storage
|
||||
helper.HandleDownloadData(b.Log, &rmsg, filename, imsg.GetCaption(), "", &data, b.General)
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
// HandleVideoMessage downloads video messages
|
||||
func (b *Bwhatsapp) handleVideoMessage(msg *events.Message) {
|
||||
imsg := msg.Message.GetVideoMessage()
|
||||
|
||||
senderJID := msg.Info.Sender
|
||||
senderName := b.getSenderName(senderJID)
|
||||
ci := imsg.GetContextInfo()
|
||||
|
||||
if senderJID == (types.JID{}) && ci.Participant != nil {
|
||||
senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer)
|
||||
}
|
||||
|
||||
rmsg := config.Message{
|
||||
UserID: senderJID.String(),
|
||||
Username: senderName,
|
||||
Channel: msg.Info.Chat.String(),
|
||||
Account: b.Account,
|
||||
Protocol: b.Protocol,
|
||||
Extra: make(map[string][]interface{}),
|
||||
ID: msg.Info.ID,
|
||||
}
|
||||
|
||||
if avatarURL, exists := b.userAvatars[senderJID.String()]; exists {
|
||||
rmsg.Avatar = avatarURL
|
||||
}
|
||||
|
||||
fileExt, err := mime.ExtensionsByType(imsg.GetMimetype())
|
||||
if err != nil {
|
||||
b.Log.Errorf("Mimetype detection error: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if len(fileExt) == 0 {
|
||||
fileExt = append(fileExt, ".mp4")
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0])
|
||||
|
||||
b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, imsg.GetFileLength(), imsg.GetMimetype())
|
||||
|
||||
data, err := b.wc.Download(imsg)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Download video failed: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Move file to bridge storage
|
||||
helper.HandleDownloadData(b.Log, &rmsg, filename, imsg.GetCaption(), "", &data, b.General)
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
// HandleAudioMessage downloads audio messages
|
||||
func (b *Bwhatsapp) handleAudioMessage(msg *events.Message) {
|
||||
imsg := msg.Message.GetAudioMessage()
|
||||
|
||||
senderJID := msg.Info.Sender
|
||||
senderName := b.getSenderName(senderJID)
|
||||
ci := imsg.GetContextInfo()
|
||||
|
||||
if senderJID == (types.JID{}) && ci.Participant != nil {
|
||||
senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer)
|
||||
}
|
||||
|
||||
rmsg := config.Message{
|
||||
UserID: senderJID.String(),
|
||||
Username: senderName,
|
||||
Channel: msg.Info.Chat.String(),
|
||||
Account: b.Account,
|
||||
Protocol: b.Protocol,
|
||||
Extra: make(map[string][]interface{}),
|
||||
ID: msg.Info.ID,
|
||||
}
|
||||
|
||||
if avatarURL, exists := b.userAvatars[senderJID.String()]; exists {
|
||||
rmsg.Avatar = avatarURL
|
||||
}
|
||||
|
||||
fileExt, err := mime.ExtensionsByType(imsg.GetMimetype())
|
||||
if err != nil {
|
||||
b.Log.Errorf("Mimetype detection error: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
if len(fileExt) == 0 {
|
||||
fileExt = append(fileExt, ".ogg")
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%v%v", msg.Info.ID, fileExt[0])
|
||||
|
||||
b.Log.Debugf("Trying to download %s with size %#v and type %s", filename, imsg.GetFileLength(), imsg.GetMimetype())
|
||||
|
||||
data, err := b.wc.Download(imsg)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Download video failed: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Move file to bridge storage
|
||||
helper.HandleDownloadData(b.Log, &rmsg, filename, "audio message", "", &data, b.General)
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
|
||||
b.Remote <- rmsg
|
||||
}
|
||||
|
||||
// HandleDocumentMessage downloads documents
|
||||
func (b *Bwhatsapp) handleDocumentMessage(msg *events.Message) {
|
||||
imsg := msg.Message.GetDocumentMessage()
|
||||
|
||||
senderJID := msg.Info.Sender
|
||||
senderName := b.getSenderName(senderJID)
|
||||
ci := imsg.GetContextInfo()
|
||||
|
||||
if senderJID == (types.JID{}) && ci.Participant != nil {
|
||||
senderJID = types.NewJID(ci.GetParticipant(), types.DefaultUserServer)
|
||||
}
|
||||
|
||||
rmsg := config.Message{
|
||||
UserID: senderJID.String(),
|
||||
Username: senderName,
|
||||
Channel: msg.Info.Chat.String(),
|
||||
Account: b.Account,
|
||||
Protocol: b.Protocol,
|
||||
Extra: make(map[string][]interface{}),
|
||||
ID: msg.Info.ID,
|
||||
}
|
||||
|
||||
if avatarURL, exists := b.userAvatars[senderJID.String()]; exists {
|
||||
rmsg.Avatar = avatarURL
|
||||
}
|
||||
|
||||
fileExt, err := mime.ExtensionsByType(imsg.GetMimetype())
|
||||
if err != nil {
|
||||
b.Log.Errorf("Mimetype detection error: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
filename := fmt.Sprintf("%v", imsg.GetFileName())
|
||||
|
||||
b.Log.Debugf("Trying to download %s with extension %s and type %s", filename, fileExt, imsg.GetMimetype())
|
||||
|
||||
data, err := b.wc.Download(imsg)
|
||||
if err != nil {
|
||||
b.Log.Errorf("Download document message failed: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Move file to bridge storage
|
||||
helper.HandleDownloadData(b.Log, &rmsg, filename, "document", "", &data, b.General)
|
||||
|
||||
b.Log.Debugf("<= Sending message from %s on %s to gateway", senderJID, b.Account)
|
||||
b.Log.Debugf("<= Message is %#v", rmsg)
|
||||
|
||||
b.Remote <- rmsg
|
||||
}
|
108
bridge/whatsappmulti/helpers.go
Normal file
108
bridge/whatsappmulti/helpers.go
Normal file
@@ -0,0 +1,108 @@
|
||||
// +build whatsappmulti
|
||||
|
||||
package bwhatsapp
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"go.mau.fi/whatsmeow/store"
|
||||
"go.mau.fi/whatsmeow/store/sqlstore"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
)
|
||||
|
||||
type ProfilePicInfo struct {
|
||||
URL string `json:"eurl"`
|
||||
Tag string `json:"tag"`
|
||||
Status int16 `json:"status"`
|
||||
}
|
||||
|
||||
func (b *Bwhatsapp) getSenderName(senderJid types.JID) string {
|
||||
if sender, exists := b.contacts[senderJid]; exists {
|
||||
if sender.FullName != "" {
|
||||
return sender.FullName
|
||||
}
|
||||
// if user is not in phone contacts
|
||||
// it is the most obvious scenario unless you sync your phone contacts with some remote updated source
|
||||
// users can change it in their WhatsApp settings -> profile -> click on Avatar
|
||||
if sender.PushName != "" {
|
||||
return sender.PushName
|
||||
}
|
||||
|
||||
if sender.FirstName != "" {
|
||||
return sender.FirstName
|
||||
}
|
||||
}
|
||||
|
||||
// try to reload this contact
|
||||
if _, err := b.wc.Store.Contacts.GetAllContacts(); err != nil {
|
||||
b.Log.Errorf("error on update of contacts: %v", err)
|
||||
}
|
||||
|
||||
allcontacts, err := b.wc.Store.Contacts.GetAllContacts()
|
||||
if err != nil {
|
||||
b.Log.Errorf("error on update of contacts: %v", err)
|
||||
}
|
||||
|
||||
if len(allcontacts) > 0 {
|
||||
b.contacts = allcontacts
|
||||
}
|
||||
|
||||
if sender, exists := b.contacts[senderJid]; exists {
|
||||
if sender.FullName != "" {
|
||||
return sender.FullName
|
||||
}
|
||||
// if user is not in phone contacts
|
||||
// it is the most obvious scenario unless you sync your phone contacts with some remote updated source
|
||||
// users can change it in their WhatsApp settings -> profile -> click on Avatar
|
||||
if sender.PushName != "" {
|
||||
return sender.PushName
|
||||
}
|
||||
|
||||
if sender.FirstName != "" {
|
||||
return sender.FirstName
|
||||
}
|
||||
}
|
||||
|
||||
return "Someone"
|
||||
}
|
||||
|
||||
func (b *Bwhatsapp) getSenderNotify(senderJid types.JID) string {
|
||||
if sender, exists := b.contacts[senderJid]; exists {
|
||||
return sender.PushName
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
func (b *Bwhatsapp) GetProfilePicThumb(jid string) (*types.ProfilePictureInfo, error) {
|
||||
pjid, _ := types.ParseJID(jid)
|
||||
info, err := b.wc.GetProfilePictureInfo(pjid, true)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get avatar: %v", err)
|
||||
}
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func isGroupJid(identifier string) bool {
|
||||
return strings.HasSuffix(identifier, "@g.us") ||
|
||||
strings.HasSuffix(identifier, "@temp") ||
|
||||
strings.HasSuffix(identifier, "@broadcast")
|
||||
}
|
||||
|
||||
func (b *Bwhatsapp) getDevice() (*store.Device, error) {
|
||||
device := &store.Device{}
|
||||
|
||||
storeContainer, err := sqlstore.New("sqlite", "file:"+b.Config.GetString("sessionfile")+".db?_foreign_keys=on&_pragma=busy_timeout=10000", nil)
|
||||
if err != nil {
|
||||
return device, fmt.Errorf("failed to connect to database: %v", err)
|
||||
}
|
||||
|
||||
device, err = storeContainer.GetFirstDevice()
|
||||
if err != nil {
|
||||
return device, fmt.Errorf("failed to get device: %v", err)
|
||||
}
|
||||
|
||||
return device, nil
|
||||
}
|
333
bridge/whatsappmulti/whatsapp.go
Normal file
333
bridge/whatsappmulti/whatsapp.go
Normal file
@@ -0,0 +1,333 @@
|
||||
// +build whatsappmulti
|
||||
|
||||
package bwhatsapp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
"github.com/42wim/matterbridge/bridge"
|
||||
"github.com/42wim/matterbridge/bridge/config"
|
||||
"github.com/mdp/qrterminal"
|
||||
|
||||
"go.mau.fi/whatsmeow"
|
||||
"go.mau.fi/whatsmeow/binary/proto"
|
||||
"go.mau.fi/whatsmeow/types"
|
||||
waLog "go.mau.fi/whatsmeow/util/log"
|
||||
|
||||
goproto "google.golang.org/protobuf/proto"
|
||||
|
||||
_ "modernc.org/sqlite" // needed for sqlite
|
||||
)
|
||||
|
||||
const (
|
||||
// Account config parameters
|
||||
cfgNumber = "Number"
|
||||
)
|
||||
|
||||
// Bwhatsapp Bridge structure keeping all the information needed for relying
|
||||
type Bwhatsapp struct {
|
||||
*bridge.Config
|
||||
|
||||
startedAt time.Time
|
||||
wc *whatsmeow.Client
|
||||
contacts map[types.JID]types.ContactInfo
|
||||
users map[string]types.ContactInfo
|
||||
userAvatars map[string]string
|
||||
}
|
||||
|
||||
// New Create a new WhatsApp bridge. This will be called for each [whatsapp.<server>] entry you have in the config file
|
||||
func New(cfg *bridge.Config) bridge.Bridger {
|
||||
number := cfg.GetString(cfgNumber)
|
||||
|
||||
if number == "" {
|
||||
cfg.Log.Fatalf("Missing configuration for WhatsApp bridge: Number")
|
||||
}
|
||||
|
||||
b := &Bwhatsapp{
|
||||
Config: cfg,
|
||||
|
||||
users: make(map[string]types.ContactInfo),
|
||||
userAvatars: make(map[string]string),
|
||||
}
|
||||
|
||||
return b
|
||||
}
|
||||
|
||||
// Connect to WhatsApp. Required implementation of the Bridger interface
|
||||
func (b *Bwhatsapp) Connect() error {
|
||||
device, err := b.getDevice()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
number := b.GetString(cfgNumber)
|
||||
if number == "" {
|
||||
return errors.New("whatsapp's telephone number need to be configured")
|
||||
}
|
||||
|
||||
b.Log.Debugln("Connecting to WhatsApp..")
|
||||
|
||||
b.wc = whatsmeow.NewClient(device, waLog.Stdout("Client", "INFO", true))
|
||||
b.wc.AddEventHandler(b.eventHandler)
|
||||
|
||||
firstlogin := false
|
||||
var qrChan <-chan whatsmeow.QRChannelItem
|
||||
if b.wc.Store.ID == nil {
|
||||
firstlogin = true
|
||||
qrChan, err = b.wc.GetQRChannel(context.Background())
|
||||
if err != nil && !errors.Is(err, whatsmeow.ErrQRStoreContainsID) {
|
||||
return errors.New("failed to to get QR channel:" + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
err = b.wc.Connect()
|
||||
if err != nil {
|
||||
return errors.New("failed to connect to WhatsApp: " + err.Error())
|
||||
}
|
||||
|
||||
if b.wc.Store.ID == nil {
|
||||
for evt := range qrChan {
|
||||
if evt.Event == "code" {
|
||||
qrterminal.GenerateHalfBlock(evt.Code, qrterminal.L, os.Stdout)
|
||||
} else {
|
||||
b.Log.Infof("QR channel result: %s", evt.Event)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disconnect and reconnect on our first login/pairing
|
||||
// for some reason the GetJoinedGroups in JoinChannel doesn't work on first login
|
||||
if firstlogin {
|
||||
b.wc.Disconnect()
|
||||
time.Sleep(time.Second)
|
||||
|
||||
err = b.wc.Connect()
|
||||
if err != nil {
|
||||
return errors.New("failed to connect to WhatsApp: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
b.Log.Infoln("WhatsApp connection successful")
|
||||
|
||||
b.contacts, err = b.wc.Store.Contacts.GetAllContacts()
|
||||
if err != nil {
|
||||
return errors.New("failed to get contacts: " + err.Error())
|
||||
}
|
||||
|
||||
b.startedAt = time.Now()
|
||||
|
||||
// map all the users
|
||||
for id, contact := range b.contacts {
|
||||
if !isGroupJid(id.String()) && id.String() != "status@broadcast" {
|
||||
// it is user
|
||||
b.users[id.String()] = contact
|
||||
}
|
||||
}
|
||||
|
||||
// get user avatar asynchronously
|
||||
b.Log.Info("Getting user avatars..")
|
||||
|
||||
for jid := range b.users {
|
||||
info, err := b.GetProfilePicThumb(jid)
|
||||
if err != nil {
|
||||
b.Log.Warnf("Could not get profile photo of %s: %v", jid, err)
|
||||
} else {
|
||||
b.Lock()
|
||||
if info != nil {
|
||||
b.userAvatars[jid] = info.URL
|
||||
}
|
||||
b.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
b.Log.Info("Finished getting avatars..")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Disconnect is called while reconnecting to the bridge
|
||||
// Required implementation of the Bridger interface
|
||||
func (b *Bwhatsapp) Disconnect() error {
|
||||
b.wc.Disconnect()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// JoinChannel Join a WhatsApp group specified in gateway config as channel='number-id@g.us' or channel='Channel name'
|
||||
// Required implementation of the Bridger interface
|
||||
// https://github.com/42wim/matterbridge/blob/2cfd880cdb0df29771bf8f31df8d990ab897889d/bridge/bridge.go#L11-L16
|
||||
func (b *Bwhatsapp) JoinChannel(channel config.ChannelInfo) error {
|
||||
byJid := isGroupJid(channel.Name)
|
||||
|
||||
groups, err := b.wc.GetJoinedGroups()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// verify if we are member of the given group
|
||||
if byJid {
|
||||
gJID, err := types.ParseJID(channel.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, group := range groups {
|
||||
if group.JID == gJID {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foundGroups := []string{}
|
||||
|
||||
for _, group := range groups {
|
||||
if group.Name == channel.Name {
|
||||
foundGroups = append(foundGroups, group.Name)
|
||||
}
|
||||
}
|
||||
|
||||
switch len(foundGroups) {
|
||||
case 0:
|
||||
// didn't match any group - print out possibilites
|
||||
for _, group := range groups {
|
||||
b.Log.Infof("%s %s", group.JID, group.Name)
|
||||
}
|
||||
return fmt.Errorf("please specify group's JID from the list above instead of the name '%s'", channel.Name)
|
||||
case 1:
|
||||
return fmt.Errorf("group name might change. Please configure gateway with channel=\"%v\" instead of channel=\"%v\"", foundGroups[0], channel.Name)
|
||||
default:
|
||||
return fmt.Errorf("there is more than one group with name '%s'. Please specify one of JIDs as channel name: %v", channel.Name, foundGroups)
|
||||
}
|
||||
}
|
||||
|
||||
// Post a document message from the bridge to WhatsApp
|
||||
func (b *Bwhatsapp) PostDocumentMessage(msg config.Message, filetype string) (string, error) {
|
||||
groupJID, _ := types.ParseJID(msg.Channel)
|
||||
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
|
||||
resp, err := b.wc.Upload(context.Background(), *fi.Data, whatsmeow.MediaDocument)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Post document message
|
||||
var message proto.Message
|
||||
|
||||
message.DocumentMessage = &proto.DocumentMessage{
|
||||
Title: &fi.Name,
|
||||
FileName: &fi.Name,
|
||||
Mimetype: &filetype,
|
||||
MediaKey: resp.MediaKey,
|
||||
FileEncSha256: resp.FileEncSHA256,
|
||||
FileSha256: resp.FileSHA256,
|
||||
FileLength: goproto.Uint64(resp.FileLength),
|
||||
Url: &resp.URL,
|
||||
}
|
||||
|
||||
b.Log.Debugf("=> Sending %#v", msg)
|
||||
|
||||
ID := whatsmeow.GenerateMessageID()
|
||||
_, err = b.wc.SendMessage(groupJID, ID, &message)
|
||||
|
||||
return ID, err
|
||||
}
|
||||
|
||||
// Post an image message from the bridge to WhatsApp
|
||||
// Handle, for sure image/jpeg, image/png and image/gif MIME types
|
||||
func (b *Bwhatsapp) PostImageMessage(msg config.Message, filetype string) (string, error) {
|
||||
groupJID, _ := types.ParseJID(msg.Channel)
|
||||
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
|
||||
caption := msg.Username + fi.Comment
|
||||
|
||||
resp, err := b.wc.Upload(context.Background(), *fi.Data, whatsmeow.MediaImage)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var message proto.Message
|
||||
|
||||
message.ImageMessage = &proto.ImageMessage{
|
||||
Mimetype: &filetype,
|
||||
Caption: &caption,
|
||||
MediaKey: resp.MediaKey,
|
||||
FileEncSha256: resp.FileEncSHA256,
|
||||
FileSha256: resp.FileSHA256,
|
||||
FileLength: goproto.Uint64(resp.FileLength),
|
||||
Url: &resp.URL,
|
||||
}
|
||||
|
||||
b.Log.Debugf("=> Sending %#v", msg)
|
||||
|
||||
ID := whatsmeow.GenerateMessageID()
|
||||
_, err = b.wc.SendMessage(groupJID, ID, &message)
|
||||
|
||||
return ID, err
|
||||
}
|
||||
|
||||
// Send a message from the bridge to WhatsApp
|
||||
func (b *Bwhatsapp) Send(msg config.Message) (string, error) {
|
||||
groupJID, _ := types.ParseJID(msg.Channel)
|
||||
|
||||
b.Log.Debugf("=> Receiving %#v", msg)
|
||||
|
||||
// Delete message
|
||||
if msg.Event == config.EventMsgDelete {
|
||||
if msg.ID == "" {
|
||||
// No message ID in case action is executed on a message sent before the bridge was started
|
||||
// and then the bridge cache doesn't have this message ID mapped
|
||||
return "", nil
|
||||
}
|
||||
|
||||
_, err := b.wc.RevokeMessage(groupJID, msg.ID)
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Edit message
|
||||
if msg.ID != "" {
|
||||
b.Log.Debugf("updating message with id %s", msg.ID)
|
||||
|
||||
if b.GetString("editsuffix") != "" {
|
||||
msg.Text += b.GetString("EditSuffix")
|
||||
} else {
|
||||
msg.Text += " (edited)"
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Upload a file
|
||||
if msg.Extra["file"] != nil {
|
||||
fi := msg.Extra["file"][0].(config.FileInfo)
|
||||
filetype := mime.TypeByExtension(filepath.Ext(fi.Name))
|
||||
|
||||
b.Log.Debugf("Extra file is %#v", filetype)
|
||||
|
||||
// TODO: add different types
|
||||
// TODO: add webp conversion
|
||||
switch filetype {
|
||||
case "image/jpeg", "image/png", "image/gif":
|
||||
return b.PostImageMessage(msg, filetype)
|
||||
default:
|
||||
return b.PostDocumentMessage(msg, filetype)
|
||||
}
|
||||
}
|
||||
|
||||
text := msg.Username + msg.Text
|
||||
|
||||
var message proto.Message
|
||||
|
||||
message.Conversation = &text
|
||||
|
||||
ID := whatsmeow.GenerateMessageID()
|
||||
_, err := b.wc.SendMessage(groupJID, ID, &message)
|
||||
|
||||
return ID, err
|
||||
}
|
62
changelog.md
62
changelog.md
@@ -1,3 +1,56 @@
|
||||
# v1.25.0
|
||||
|
||||
## Breaking changes
|
||||
|
||||
- whatsapp: deprecated, the library <https://github.com/Rhymen/go-whatsapp> isn't maintained anymore.
|
||||
We're switching to <https://github.com/tulir/whatsmeow> but as this uses a GPL3 licensed library we can't provide you with binaries.
|
||||
You'll need to build it yourself. More information about this can be found here: <https://github.com/42wim/matterbridge#building-with-whatsapp-beta-multidevice-support>
|
||||
|
||||
## New features
|
||||
|
||||
- whatsappmulti: whatsapp multidevice support added - more info <https://github.com/42wim/matterbridge#building-with-whatsapp-beta-multidevice-support>
|
||||
- general: Add Dockerfile_whatsappmulti for building with WhatsApp Multi-Device support (Whatsmeow) (#1774)
|
||||
- telegram: Add UseFullName option (telegram) (#1777)
|
||||
- slack: Use slack real name as user name (slack) (#1775)
|
||||
|
||||
## Enhancements
|
||||
|
||||
- general: Ignore sending file with comment, if comment contains IgnoreMessages value (#1783)
|
||||
- general: Update dependencies (#1784)
|
||||
- irc: Update lrstanley/girc dep (#1773)
|
||||
- slack: Preserve threading for messages with files (slack) (#1781)
|
||||
- telegram: Preserve threading from telegram replies (telegram) (#1776)
|
||||
- telegram: Multiple media in one message (telegram) (#1779)
|
||||
- whatsapp: Add whatsapp deprecation warning (#1792)
|
||||
|
||||
## Bugfix
|
||||
|
||||
- discord: Change discord non-native threading behaviour (discord) (#1791)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@sas1024, @tpxtron
|
||||
|
||||
# v1.24.1
|
||||
|
||||
## Enhancements
|
||||
|
||||
- discord: Switch to discordgo upstream again (#1759)
|
||||
- general: Update dependencies and vendor (#1761)
|
||||
- general: Create inmessage-logger.tengo (#1688) (#1747)
|
||||
- general: Add OpenRC service file (#1746)
|
||||
- irc: Refactor utf-8 conversion (irc) (#1767)
|
||||
|
||||
## Bugfixes
|
||||
|
||||
- irc: Fix panic in irc. Closes #1751 (#1760)
|
||||
- mumble: Implement a workaround to signal Opus support (mumble) (#1764)
|
||||
- telegram: Fix for complex-formatted Telegram text (#1765)
|
||||
- telegram: Fix Telegram channel title in forwards (#1753)
|
||||
- telegram: Fix Telegram Problem (unforwarded formatting and skipping of linebreaks) (#1749)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@s3lph, @ValdikSS, @reckel-jm, @CyberTailor
|
||||
|
||||
# v1.24.0
|
||||
|
||||
## New features
|
||||
@@ -30,6 +83,9 @@
|
||||
- matrix: Make HTMLDisable work correct (matrix) (#1716)
|
||||
- whatsapp: Make EditSuffix option actually work (whatsapp). Fixes #1510 (#1728)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@DavyJohnesev, @GoliathLabs, @pontaoski, @PeGaSuS-Coder, @dependabot[bot], @vpzomtrrfrt, @SevereCloud, @soloam, @YashRE42, @danwalmsley, @SuperSandro2000, @inzanity
|
||||
|
||||
# v1.23.2
|
||||
|
||||
If you're running whatsapp you should update.
|
||||
@@ -38,6 +94,9 @@ If you're running whatsapp you should update.
|
||||
|
||||
- whatsapp: Update go-whatsapp version (#1630)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@snikpic
|
||||
|
||||
# v1.23.1
|
||||
|
||||
If you're running mattermost 6 you should update.
|
||||
@@ -52,6 +111,9 @@ If you're running mattermost 6 you should update.
|
||||
- xmpp: Use a new msgID when replacing messages (xmpp). Fixes #1584 (#1623)
|
||||
- zulip: Add better error handling on Zulip (#1589)
|
||||
|
||||
This release couldn't exist without the following contributors:
|
||||
@Polynomdivision, @minecraftchest1, @alexmv
|
||||
|
||||
# v1.23.0
|
||||
|
||||
## New features
|
||||
|
15
contrib/inmessage-logger.tengo
Normal file
15
contrib/inmessage-logger.tengo
Normal file
@@ -0,0 +1,15 @@
|
||||
fmt := import("fmt")
|
||||
os := import("os")
|
||||
times := import("times")
|
||||
|
||||
if msgText != "" && msgUsername != "system" {
|
||||
os.chdir("/var/www/matterbridge")
|
||||
file := os.open_file("inmessage.log", os.o_append|os.o_wronly|os.o_create, 0644)
|
||||
file.write_string(fmt.sprintf(
|
||||
"[%s] <%s> %s\n",
|
||||
times.time_format(times.now(), times.format_rfc1123),
|
||||
msgUsername,
|
||||
msgText
|
||||
))
|
||||
file.close()
|
||||
}
|
19
contrib/matterbridge.openrc
Executable file
19
contrib/matterbridge.openrc
Executable file
@@ -0,0 +1,19 @@
|
||||
#!/sbin/openrc-run
|
||||
# Copyright 2021-2022 Gentoo Authors
|
||||
# Distributed under the terms of the GNU General Public License v2
|
||||
|
||||
command=/usr/bin/matterbridge
|
||||
command_args="-conf ${MATTERBRIDGE_CONF:-/etc/matterbridge/bridge.toml} ${MATTERBRIDGE_ARGS}"
|
||||
command_user="matterbridge:matterbridge"
|
||||
pidfile="/run/${RC_SVCNAME}.pid"
|
||||
command_background=1
|
||||
output_log="/var/log/${RC_SVCNAME}.log"
|
||||
error_log="${output_log}"
|
||||
|
||||
depend() {
|
||||
need net
|
||||
}
|
||||
|
||||
start_pre() {
|
||||
checkpath -f "${output_log}" -o "${command_user}" || return 1
|
||||
}
|
@@ -1,4 +1,5 @@
|
||||
// +build !nowhatsapp
|
||||
// +build !whatsappmulti
|
||||
|
||||
package bridgemap
|
||||
|
||||
|
11
gateway/bridgemap/bwhatsappmulti.go
Normal file
11
gateway/bridgemap/bwhatsappmulti.go
Normal file
@@ -0,0 +1,11 @@
|
||||
// +build whatsappmulti
|
||||
|
||||
package bridgemap
|
||||
|
||||
import (
|
||||
bwhatsapp "github.com/42wim/matterbridge/bridge/whatsappmulti"
|
||||
)
|
||||
|
||||
func init() {
|
||||
FullMap["whatsapp"] = bwhatsapp.New
|
||||
}
|
@@ -299,13 +299,30 @@ func (gw *Gateway) ignoreMessage(msg *config.Message) bool {
|
||||
|
||||
igNicks := strings.Fields(gw.Bridges[msg.Account].GetString("IgnoreNicks"))
|
||||
igMessages := strings.Fields(gw.Bridges[msg.Account].GetString("IgnoreMessages"))
|
||||
if gw.ignoreTextEmpty(msg) || gw.ignoreText(msg.Username, igNicks) || gw.ignoreText(msg.Text, igMessages) {
|
||||
if gw.ignoreTextEmpty(msg) || gw.ignoreText(msg.Username, igNicks) || gw.ignoreText(msg.Text, igMessages) || gw.ignoreFilesComment(msg.Extra, igMessages) {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ignoreFilesComment returns true if we need to ignore a file with matched comment.
|
||||
func (gw *Gateway) ignoreFilesComment(extra map[string][]interface{}, igMessages []string) bool {
|
||||
if extra == nil {
|
||||
return false
|
||||
}
|
||||
for _, f := range extra["file"] {
|
||||
fi, ok := f.(config.FileInfo)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if gw.ignoreText(fi.Comment, igMessages) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (gw *Gateway) modifyUsername(msg *config.Message, dest *bridge.Bridge) string {
|
||||
if dest.GetBool("StripNick") {
|
||||
re := regexp.MustCompile("[^a-zA-Z0-9]+")
|
||||
|
71
go.mod
71
go.mod
@@ -7,32 +7,32 @@ require (
|
||||
github.com/Philipp15b/go-steam v1.0.1-0.20200727090957-6ae9b3c0a560
|
||||
github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c
|
||||
github.com/SevereCloud/vksdk/v2 v2.13.1
|
||||
github.com/d5/tengo/v2 v2.10.0
|
||||
github.com/bwmarrin/discordgo v0.24.0
|
||||
github.com/d5/tengo/v2 v2.10.1
|
||||
github.com/davecgh/go-spew v1.1.1
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/go-telegram-bot-api/telegram-bot-api/v5 v5.5.1
|
||||
github.com/gomarkdown/markdown v0.0.0-20211207152620-5d6539fd8bfc
|
||||
github.com/gomarkdown/markdown v0.0.0-20220310201231-552c6011c0b8
|
||||
github.com/google/gops v0.3.22
|
||||
github.com/gorilla/schema v1.2.0
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/harmony-development/shibshib v0.0.0-20211127182844-512296f7c548
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa
|
||||
github.com/hashicorp/golang-lru v0.5.4
|
||||
github.com/jpillora/backoff v1.0.0
|
||||
github.com/keybase/go-keybase-chat-bot v0.0.0-20211201215354-ee4b23828b55
|
||||
github.com/kyokomi/emoji/v2 v2.2.8
|
||||
github.com/labstack/echo/v4 v4.6.3
|
||||
github.com/lrstanley/girc v0.0.0-20211023233735-147f0ff77566
|
||||
github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
|
||||
github.com/kyokomi/emoji/v2 v2.2.9
|
||||
github.com/labstack/echo/v4 v4.7.2
|
||||
github.com/lrstanley/girc v0.0.0-20220321215535-9664730c7858
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20211016222428-79310a412696
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20210201201054-fb39a175b4f7
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20211030125215-791a06c5f1be
|
||||
github.com/matterbridge/gomatrix v0.0.0-20220205235239-607eb9ee6419
|
||||
github.com/matterbridge/gozulipbot v0.0.0-20211023205727-a19d6c1f3b75
|
||||
github.com/matterbridge/logrus-prefixed-formatter v0.5.3-0.20200523233437-d971309a77ba
|
||||
github.com/matterbridge/matterclient v0.0.0-20211107234719-faca3cd42315
|
||||
github.com/mattermost/mattermost-server/v5 v5.39.3
|
||||
github.com/mattermost/mattermost-server/v6 v6.3.0
|
||||
github.com/mattermost/mattermost-server/v6 v6.5.0
|
||||
github.com/mattn/godown v0.0.1
|
||||
github.com/missdeer/golib v1.0.4
|
||||
github.com/mdp/qrterminal v1.0.1
|
||||
github.com/nelsonken/gomf v0.0.0-20180504123937-a9dd2f9deae9
|
||||
github.com/paulrosania/go-charset v0.0.0-20190326053356-55c9d7a5834c
|
||||
github.com/rs/xid v1.3.0
|
||||
@@ -40,21 +40,26 @@ require (
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca
|
||||
github.com/shazow/ssh-chat v1.10.1
|
||||
github.com/sirupsen/logrus v1.8.1
|
||||
github.com/slack-go/slack v0.10.0
|
||||
github.com/slack-go/slack v0.10.2
|
||||
github.com/spf13/viper v1.10.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
github.com/vincent-petithory/dataurl v1.0.0
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
github.com/yaegashi/msgraph.go v0.1.4
|
||||
github.com/zfjagann/golang-ring v0.0.0-20210116075443-7c86fdb43134
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8
|
||||
go.mau.fi/whatsmeow v0.0.0-20220329131721-9f73bc00d158
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a
|
||||
golang.org/x/text v0.3.7
|
||||
gomod.garykim.dev/nc-talk v0.3.0
|
||||
google.golang.org/protobuf v1.27.1
|
||||
gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b
|
||||
modernc.org/sqlite v1.15.4
|
||||
)
|
||||
|
||||
require (
|
||||
filippo.io/edwards25519 v1.0.0-rc.1 // indirect
|
||||
github.com/Benau/go_rlottie v0.0.0-20210807002906-98c1b2421989 // indirect
|
||||
github.com/Jeffail/gabs v1.4.0 // indirect
|
||||
github.com/apex/log v1.9.0 // indirect
|
||||
@@ -68,13 +73,15 @@ require (
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gopackage/ddp v0.0.3 // indirect
|
||||
github.com/graph-gophers/graphql-go v1.3.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
|
||||
github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // indirect
|
||||
github.com/klauspost/compress v1.14.2 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.0.11 // indirect
|
||||
github.com/labstack/gommon v0.3.1 // indirect
|
||||
github.com/magiconair/properties v1.8.5 // indirect
|
||||
github.com/mattermost/go-i18n v1.11.1-0.20211013152124-5c415071e404 // indirect
|
||||
@@ -86,7 +93,7 @@ require (
|
||||
github.com/mattn/go-runewidth v0.0.13 // indirect
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
|
||||
github.com/minio/md5-simd v1.1.2 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.16 // indirect
|
||||
github.com/minio/minio-go/v7 v7.0.21 // indirect
|
||||
github.com/minio/sha256-simd v1.0.0 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.3 // indirect
|
||||
@@ -95,17 +102,19 @@ require (
|
||||
github.com/monaco-io/request v1.0.5 // indirect
|
||||
github.com/mreiferson/go-httpclient v0.0.0-20201222173833-5e475fde3a4d // indirect
|
||||
github.com/mrexodia/wray v0.0.0-20160318003008-78a2c1f284ff // indirect
|
||||
github.com/opentracing/opentracing-go v1.2.0 // indirect
|
||||
github.com/pborman/uuid v1.2.1 // indirect
|
||||
github.com/pelletier/go-toml v1.9.4 // indirect
|
||||
github.com/philhofer/fwd v1.1.1 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect
|
||||
github.com/rickb777/date v1.12.4 // indirect
|
||||
github.com/rickb777/plural v1.2.0 // indirect
|
||||
github.com/rivo/uniseg v0.2.0 // indirect
|
||||
github.com/shazow/rateio v0.0.0-20200113175441-4461efc8bdc4 // indirect
|
||||
github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 // indirect
|
||||
github.com/spf13/afero v1.6.0 // indirect
|
||||
github.com/spf13/cast v1.4.1 // indirect
|
||||
github.com/spf13/jwalterweatherman v1.1.0 // indirect
|
||||
@@ -119,23 +128,35 @@ require (
|
||||
github.com/wiggin77/cfg v1.0.2 // indirect
|
||||
github.com/wiggin77/merror v1.0.3 // indirect
|
||||
github.com/wiggin77/srslog v1.0.1 // indirect
|
||||
go.mau.fi/libsignal v0.0.0-20220315232917-871a40435d3b // indirect
|
||||
go.uber.org/atomic v1.9.0 // indirect
|
||||
go.uber.org/multierr v1.7.0 // indirect
|
||||
go.uber.org/zap v1.17.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 // indirect
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9 // indirect
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd // indirect
|
||||
golang.org/x/mod v0.5.1 // indirect
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d // indirect
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
|
||||
golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
|
||||
golang.org/x/tools v0.1.9 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2 // indirect
|
||||
gopkg.in/ini.v1 v1.66.3 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.0.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
lukechampine.com/uint128 v1.1.1 // indirect
|
||||
modernc.org/cc/v3 v3.35.24 // indirect
|
||||
modernc.org/ccgo/v3 v3.15.18 // indirect
|
||||
modernc.org/libc v1.14.12 // indirect
|
||||
modernc.org/mathutil v1.4.1 // indirect
|
||||
modernc.org/memory v1.0.7 // indirect
|
||||
modernc.org/opt v0.1.1 // indirect
|
||||
modernc.org/strutil v1.1.1 // indirect
|
||||
modernc.org/token v1.0.0 // indirect
|
||||
rsc.io/qr v0.2.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/matrix-org/gomatrix => github.com/matterbridge/gomatrix v0.0.0-20220205235239-607eb9ee6419
|
||||
//replace github.com/matrix-org/gomatrix => github.com/matterbridge/gomatrix v0.0.0-20220205235239-607eb9ee6419
|
||||
|
||||
go 1.17
|
||||
|
333
go.sum
333
go.sum
@@ -32,6 +32,7 @@ cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aD
|
||||
cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI=
|
||||
cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4=
|
||||
cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc=
|
||||
cloud.google.com/go v0.98.0/go.mod h1:ua6Ush4NALrHk5QXDWnjvZHN93OuF0HfuEPq9I1X0cM=
|
||||
cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA=
|
||||
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
|
||||
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
|
||||
@@ -54,7 +55,6 @@ cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0Zeo
|
||||
cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk=
|
||||
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
|
||||
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
|
||||
cloud.google.com/go/storage v1.16.1/go.mod h1:LaNorbty3ehnU3rEjXSNV/NRgQA0O8Y+uh6bPe5UOk4=
|
||||
code.sajari.com/docconv v1.1.1-0.20210427001343-7b3472bc323a/go.mod h1:KPNt2zuWplps1W0TpOb6ltHj4Xu+j6h7a+YkqGHrxQE=
|
||||
code.sajari.com/docconv v1.2.0/go.mod h1:r8yfCP6OKbZ9Xkd87aBa4nfpk6ud/PoyLwex3n6cXSc=
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.4.9/go.mod h1:ueLzZcP7LPhPulEBukGn4aLh7Mx9YJwpVJ9nL2FYltw=
|
||||
@@ -63,6 +63,8 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7
|
||||
dmitri.shuralyov.com/html/belt v0.0.0-20180602232347-f7d459c86be0/go.mod h1:JLBrvjyP0v+ecvNYvCpyZgu5/xkfAUhi6wJj28eUfSU=
|
||||
dmitri.shuralyov.com/service/change v0.0.0-20181023043359-a85b471d5412/go.mod h1:a1inKt/atXimZ4Mv927x+r7UpyzRUf4emIoiiSC2TN4=
|
||||
dmitri.shuralyov.com/state v0.0.0-20180228185332-28bcc343414c/go.mod h1:0PRwlb0D6DFvNNtx+9ybjezNCa8XF0xaYcETyp6rHWU=
|
||||
filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU=
|
||||
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
|
||||
git.apache.org/thrift.git v0.0.0-20180902110319-2566ecd5d999/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
git.apache.org/thrift.git v0.12.0/go.mod h1:fPE2ZNJGynbRyZ4dJvy6G277gSllfV2HJqblrnkyeyg=
|
||||
@@ -72,7 +74,6 @@ github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOv
|
||||
github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k=
|
||||
github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v26.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-sdk-for-go v55.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
|
||||
github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
|
||||
github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
|
||||
@@ -80,7 +81,6 @@ github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSW
|
||||
github.com/Azure/go-autorest v11.5.2+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
|
||||
github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw=
|
||||
github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A=
|
||||
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
|
||||
@@ -88,7 +88,6 @@ github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4Uw
|
||||
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
|
||||
github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE=
|
||||
github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
|
||||
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
|
||||
@@ -116,7 +115,7 @@ github.com/Masterminds/glide v0.13.2/go.mod h1:STyF5vcenH/rUqTEv+/hBXlSTo7KYwg2o
|
||||
github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
|
||||
github.com/Masterminds/squirrel v1.5.0/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/squirrel v1.5.1/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/squirrel v1.5.2/go.mod h1:NNaOrjSoIDfDA40n7sr2tPNZRfjzjA400rg+riTZj10=
|
||||
github.com/Masterminds/vcs v1.13.0/go.mod h1:N09YCmOQr6RLxC6UNHzuVwAdodYbbnycGHSmwVJjcKA=
|
||||
github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
@@ -165,7 +164,6 @@ github.com/advancedlogic/GoOse v0.0.0-20200830213114-1225d531e0ad/go.mod h1:f3HC
|
||||
github.com/advancedlogic/GoOse v0.0.0-20210820140952-9d5822d4a625/go.mod h1:f3HCSN1fBWjcpGtXyM119MJgeQl838v6so/PQOqvE1w=
|
||||
github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY=
|
||||
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
|
||||
github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
|
||||
github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
|
||||
@@ -175,7 +173,6 @@ github.com/alexcesaro/log v0.0.0-20150915221235-61e686294e58/go.mod h1:YNfsMyWSs
|
||||
github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0=
|
||||
github.com/andybalholm/brotli v1.0.0/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.1/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.2/go.mod h1:loMXtMfwqflxFJPmdbJO0a3KNoPuLBgiu3qAvBg8x/Y=
|
||||
github.com/andybalholm/brotli v1.0.3/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/brotli v1.0.4/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
|
||||
github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
|
||||
@@ -212,8 +209,7 @@ github.com/aws/aws-sdk-go v1.17.7/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN
|
||||
github.com/aws/aws-sdk-go v1.19.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.20.6/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.38.67/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go v1.40.42/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.42.11/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
|
||||
github.com/aws/aws-sdk-go v1.42.49/go.mod h1:OGr6lGMAKGlG9CVrYnWYDKIyb829c6EVBRjxqjmPepc=
|
||||
github.com/aws/aws-sdk-go-v2 v1.8.0/go.mod h1:xEFuWz+3TYdlPRuo+CqATbeDWIWyaT5uAPwPaWtgse0=
|
||||
github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.6.0/go.mod h1:TNtBVmka80lRPk5+S9ZqVfFszOQAGJJ9KbT3EM3CHNU=
|
||||
@@ -241,6 +237,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21
|
||||
github.com/aws/smithy-go v1.7.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E=
|
||||
github.com/aybabtme/rgbterm v0.0.0-20170906152045-cc83f3b3ce59/go.mod h1:q/89r3U2H7sSsE2t6Kca0lfwTK8JdoNGS/yzM/4iH5I=
|
||||
github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4=
|
||||
github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g=
|
||||
github.com/beevik/etree v1.1.0/go.mod h1:r8Aw8JqVegEf0w2fDnATrX9VpkMcyFeM0FhwO62wh+A=
|
||||
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
@@ -290,6 +287,8 @@ github.com/buger/jsonparser v0.0.0-20181115193947-bf1c66bbce23/go.mod h1:bbYlZJ7
|
||||
github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8=
|
||||
github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50=
|
||||
github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE=
|
||||
github.com/bwmarrin/discordgo v0.24.0 h1:Gw4MYxqHdvhO99A3nXnSLy97z5pmIKHZVJ1JY5ZDPqY=
|
||||
github.com/bwmarrin/discordgo v0.24.0/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
|
||||
github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
@@ -438,6 +437,7 @@ github.com/couchbase/vellum v1.0.2/go.mod h1:FcwrEivFpNi24R3jLOs3n+fs5RnuQnQqCLB
|
||||
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
|
||||
github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
@@ -450,8 +450,9 @@ github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1S
|
||||
github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s=
|
||||
github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8=
|
||||
github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I=
|
||||
github.com/d5/tengo/v2 v2.10.0 h1:gR3VwfJDBlffV8WzfSNNJ7WJtWduwbTKlAu14cA2fRs=
|
||||
github.com/d5/tengo/v2 v2.10.0/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/d5/tengo/v2 v2.10.1 h1:Z7vmTAQfdoExNEB9kxgqxvoBBW9bf+8uYMiDyriX5HM=
|
||||
github.com/d5/tengo/v2 v2.10.1/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8=
|
||||
github.com/dave/jennifer v1.4.1/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -469,11 +470,9 @@ github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8
|
||||
github.com/dhui/dktest v0.3.3/go.mod h1:EML9sP4sqJELHn4jV7B0TY8oF6077nk83/tz7M56jcQ=
|
||||
github.com/dhui/dktest v0.3.7/go.mod h1:nYMOkafiA07WchSwKnKFUSbGMb2hMm5DrCGiXYG6gwM=
|
||||
github.com/die-net/lrucache v0.0.0-20181227122439-19a39ef22a11/go.mod h1:ew0MSjCVDdtGMjF3kzLK9hwdgF5mOE8SbYVF3Rc7mkU=
|
||||
github.com/die-net/lrucache v0.0.0-20190707192454-883874fe3947/go.mod h1:KsMcjmY1UCGl7ozPbdVPDOvLaFeXnptSvtNRczhxNto=
|
||||
github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ=
|
||||
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
|
||||
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
|
||||
github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
|
||||
github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
|
||||
github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
|
||||
@@ -523,15 +522,13 @@ github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htX
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=
|
||||
github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8=
|
||||
github.com/fasthttp/websocket v1.4.3-rc.9/go.mod h1:eXL2zqDbexYJxaCw8/PQlm7VcMK6uoGvwbYbTdt4dFo=
|
||||
github.com/fasthttp/websocket v1.4.3-rc.10/go.mod h1:xU7SHrziVFuFx3IO24nLKcu4tm3QykCFXhwtwRk9Xd0=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fatih/set v0.2.1/go.mod h1:+RKtMCH+favT2+3YecHGxcc0b4KyVWA1QWWJUs4E0CI=
|
||||
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
|
||||
github.com/fcjr/aia-transport-go v1.2.2/go.mod h1:onSqSq3tGkM14WusDx7q9FTheS9R1KBtD+QBWI6zG/w=
|
||||
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
@@ -555,13 +552,12 @@ github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYis
|
||||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
|
||||
github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc=
|
||||
github.com/getsentry/sentry-go v0.11.0/go.mod h1:KBQIxiZAetw62Cj8Ri964vAEWVdgfaUCn30Q3bCvANo=
|
||||
github.com/getsentry/sentry-go v0.12.0/go.mod h1:NSap0JBYWzHND8oMbyi0+XZhUalc1TBdRL1M71JZW2c=
|
||||
github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gigawattio/window v0.0.0-20180317192513-0f5467e35573/go.mod h1:eBvb3i++NHDH4Ugo9qCvMw8t0mTSctaEa5blJbWcNxs=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/gin-gonic/gin v1.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
||||
github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/glycerine/go-unsnap-stream v0.0.0-20181221182339-f9677308dec2/go.mod h1:/20jfyN9Y5QPEAprSgKAUr+glWDY39ZiUEAYOEv5dsE=
|
||||
github.com/glycerine/goconvey v0.0.0-20190410193231-58a59202ab31/go.mod h1:Ogl1Tioa0aV7gstGFO7KhffUsb9M4ydbEbbxpcEDc24=
|
||||
@@ -588,6 +584,7 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
|
||||
github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas=
|
||||
github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU=
|
||||
github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8=
|
||||
github.com/go-morph/morph v0.2.3-0.20220215130848-76392b135ee5/go.mod h1:XQh5WcM351wOV3z3zEWRM8RaJ65E2p4P7WWbmFAi8x4=
|
||||
github.com/go-ole/go-ole v1.2.5/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-ole/go-ole v1.2.6-0.20210915003542-8b1f7f90f6b1/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
@@ -597,8 +594,6 @@ github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL9
|
||||
github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||
github.com/go-playground/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-redis/redis/v8 v8.0.0/go.mod h1:isLoQT/NFSP7V67lyvM9GmdvLdyZ7pEhsXvvyQtnQTo=
|
||||
github.com/go-redis/redis/v8 v8.10.0/go.mod h1:vXLTvigok0VtUX0znvbcEW1SOt4OA9CU1ZfnOtKOaiM=
|
||||
github.com/go-redis/redis/v8 v8.11.4/go.mod h1:2Z2wHZXdQpCDXEGzqMockDpNyYvi2l4Pxt6RJr792+w=
|
||||
@@ -650,8 +645,6 @@ github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblf
|
||||
github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4=
|
||||
github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/gofiber/fiber/v2 v2.20.1/go.mod h1:/LdZHMUXZvTTo7gU4+b1hclqCAdoQphNQ9bi9gutPyI=
|
||||
github.com/gofiber/websocket/v2 v2.0.12/go.mod h1:lQRy0u5ACJfiez/e/bhGeYvM0/M940Y3NFw14U3/otI=
|
||||
github.com/gofrs/uuid v3.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU=
|
||||
@@ -711,8 +704,8 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW
|
||||
github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
|
||||
github.com/gomarkdown/markdown v0.0.0-20211207152620-5d6539fd8bfc h1:mmMAHzJGtMsCaDyRgPNMO6cbSzeKCZxHTA1Sn/wirko=
|
||||
github.com/gomarkdown/markdown v0.0.0-20211207152620-5d6539fd8bfc/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/gomarkdown/markdown v0.0.0-20220310201231-552c6011c0b8 h1:YVvt637ygnOO9qjLBVmPOvrUmCz/i8YECSu/8UlOQW0=
|
||||
github.com/gomarkdown/markdown v0.0.0-20220310201231-552c6011c0b8/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4=
|
||||
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
|
||||
@@ -778,9 +771,10 @@ github.com/gopackage/ddp v0.0.3/go.mod h1:3hUXYG6C/6JsoxKsQaK7st09+GP9RZBFPzyAlU
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20210621113107-84c6004145de/go.mod h1:MtKwTfDNYAP5EtbQSMYjTSqvj1aXJKQRASWq3bwaP+g=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20211111143520-d0d5ecc1a356 h1:d3wWSjdOuGrMHa8+Tvw3z9EGPzATpzVq1BmGK3+IyeU=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20211111143520-d0d5ecc1a356/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd h1:D/H64OK+VY7O0guGbCQaFKwAZlU5t764R++kgIdAGog=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI=
|
||||
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
|
||||
github.com/gorilla/css v1.0.0/go.mod h1:Dn721qIggHpt4+EFCcTLTU/vk5ySda2ReITrtgBl60c=
|
||||
github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.4.2/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
|
||||
@@ -794,8 +788,11 @@ github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlI
|
||||
github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/graph-gophers/graphql-go v1.3.0 h1:Eb9x/q6MFpCLz7jBCiP/WTxjSDrYLR1QY41SORZyNJ0=
|
||||
github.com/graph-gophers/graphql-go v1.3.0/go.mod h1:9CQHMSxwO4MprSdzoIEobiHpoLtHm77vfxsvsIN5Vuc=
|
||||
github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
|
||||
@@ -811,10 +808,10 @@ github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFb
|
||||
github.com/h2non/go-is-svg v0.0.0-20160927212452-35e8c4b0612c/go.mod h1:ObS/W+h8RYb1Y7fYivughjxojTmIu5iAIjSrSLCLeqE=
|
||||
github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4=
|
||||
github.com/hako/durafmt v0.0.0-20210608085754-5c1018a4e16b/go.mod h1:VzxiSdG6j1pi7rwGm/xYI5RbtpBgM8sARDXlvEvxlu0=
|
||||
github.com/harmony-development/hrpc v0.0.0-20211020182021-788fc204a0fe/go.mod h1:B+5b0+n0UpMtqAGtJ2oYlgsArI9LbSJ0/HoySJNzDFY=
|
||||
github.com/harmony-development/shibshib v0.0.0-20211127182844-512296f7c548 h1:jAnKjA+wco4ONGpCtINd0t+sC+ffF+yYScGqgJ2OG4o=
|
||||
github.com/harmony-development/shibshib v0.0.0-20211127182844-512296f7c548/go.mod h1:e3LPbk9jFYwu72EVyGPJC7CKBBSmxb4ZdyJalaaskdc=
|
||||
github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa h1:0EefSRfsNrdEwmoGVz4+cMG8++5M2XhvJ1tTRmmrJu8=
|
||||
github.com/harmony-development/shibshib v0.0.0-20220101224523-c98059d09cfa/go.mod h1:+KEOMb29OC2kRa5BajwNM2NEjHTbQA/Z3gKYARLHREI=
|
||||
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
|
||||
github.com/hashicorp/consul/api v1.11.0/go.mod h1:XjsvQN+RJGWI2TWy1/kqaE16HrR2J/FWgkYjdZQsX9M=
|
||||
github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
|
||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
|
||||
github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
|
||||
@@ -829,6 +826,7 @@ github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39
|
||||
github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v0.16.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.0.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-hclog v1.1.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
|
||||
@@ -859,11 +857,15 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64=
|
||||
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
|
||||
github.com/hashicorp/mdns v1.0.1/go.mod h1:4gW7WsVCke5TE7EPeYliwHlRUyBtfCwuFwuMg2DmyNY=
|
||||
github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc=
|
||||
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
|
||||
github.com/hashicorp/memberlist v0.2.2/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.2.4/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE=
|
||||
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
|
||||
github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKENpqIUyk=
|
||||
github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4=
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20210316155119-a95892c5f864/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ=
|
||||
@@ -983,6 +985,7 @@ github.com/kataras/iris/v12 v12.1.8/go.mod h1:LMYy4VlP67TQ3Zgriz8RE2h2kMZV2SgMYb
|
||||
github.com/kataras/neffos v0.0.14/go.mod h1:8lqADm8PnbeFfL7CLXh1WHw53dG27MC3pgi2R1rmoTE=
|
||||
github.com/kataras/pio v0.0.2/go.mod h1:hAoW0t9UmXi4R5Oyq5Z4irTbaTsOemSrDGUtaTl7Dro=
|
||||
github.com/kataras/sitemap v0.0.5/go.mod h1:KY2eugMKiPwsJgx7+U103YZehfvNGOXURubcGyk0Bz8=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
|
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
|
||||
github.com/kettek/apng v0.0.0-20191108220231-414630eed80f h1:dnCYnTSltLuPMfc7dMrkz2uBUcEf/OFBR8yRh3oRT98=
|
||||
github.com/kettek/apng v0.0.0-20191108220231-414630eed80f/go.mod h1:x78/VRQYKuCftMWS0uK5e+F5RJ7S4gSlESRWI0Prl6Q=
|
||||
@@ -1015,8 +1018,8 @@ github.com/klauspost/cpuid v1.3.1/go.mod h1:bYW4mA6ZgKPob1/Dlai2LviZJO7KGI3uoWLd
|
||||
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.6/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9 h1:lgaqFMSdTdQYdZ04uHyN2d/eKdOMyi2YLSvlQIBFYa4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.0.11 h1:i2lw1Pm7Yi/4O6XCSyJWqEHI2MDw2FzUK6o/D21xn2A=
|
||||
github.com/klauspost/cpuid/v2 v2.0.11/go.mod h1:g2LTdtYhdyuGPqyWyv7qRAmj1WBqxuObKfj5c0PQa7c=
|
||||
github.com/klauspost/pgzip v1.2.4/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
|
||||
github.com/kljensen/snowball v0.6.0/go.mod h1:27N7E8fVU5H68RlUmnWwZCfxgt4POBJfENGMvNRhldw=
|
||||
@@ -1038,18 +1041,18 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8 h1:jcofPxjHWEkJtkIbcLHvZhxKgCPl6C7MyjTrD4KDqUE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.8/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/kyokomi/emoji/v2 v2.2.9 h1:UWYkjplPZ4rMPvLxc+/e12/xTqoRcn55oUySkpZ554g=
|
||||
github.com/kyokomi/emoji/v2 v2.2.9/go.mod h1:JUcn42DTdsXJo1SWanHh4HKDEyPaR5CqkmoirZZP9qE=
|
||||
github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g=
|
||||
github.com/labstack/echo/v4 v4.6.3 h1:VhPuIZYxsbPmo4m9KAkMU/el2442eB7EBFFhNTTT9ac=
|
||||
github.com/labstack/echo/v4 v4.6.3/go.mod h1:Hk5OiHj0kDqmFq7aHe7eDqI7CUhuCrfpupQtLGGLm7A=
|
||||
github.com/labstack/echo/v4 v4.5.0/go.mod h1:czIriw4a0C1dFun+ObrXp7ok03xON0N1awStJ6ArI7Y=
|
||||
github.com/labstack/echo/v4 v4.7.2 h1:Kv2/p8OaQ+M6Ex4eGimg9b9e6icoxA42JSlOR3msKtI=
|
||||
github.com/labstack/echo/v4 v4.7.2/go.mod h1:xkCDAdFCIf8jsFQ5NnbK7oqaF/yU1A1X20Ltm0OvSks=
|
||||
github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k=
|
||||
github.com/labstack/gommon v0.3.1 h1:OomWaJXm7xR6L1HmEtGyQf26TEn7V6X88mktX9kee9o=
|
||||
github.com/labstack/gommon v0.3.1/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=
|
||||
github.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=
|
||||
github.com/ledongthuc/pdf v0.0.0-20210621053716-e28cb8259002/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||
github.com/levigross/exp-html v0.0.0-20120902181939-8df60c69a8f5/go.mod h1:QMe2wuKJ0o7zIVE8AqiT8rd8epmm6WDIZ2wyuBqYPzM=
|
||||
github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
|
||||
@@ -1059,8 +1062,8 @@ github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lrstanley/girc v0.0.0-20211023233735-147f0ff77566 h1:tseAo8DbdhZa+PLuJW0p/P8b7I9LUiVpIpboAHkLsoM=
|
||||
github.com/lrstanley/girc v0.0.0-20211023233735-147f0ff77566/go.mod h1:liX5MxHPrwgHaKowoLkYGwbXfYABh1jbZ6FpElbGF1I=
|
||||
github.com/lrstanley/girc v0.0.0-20220321215535-9664730c7858 h1:IIbHCRHuANbPoQymk4BWGcRI47RXHOt7bDxPbxQ9rms=
|
||||
github.com/lrstanley/girc v0.0.0-20220321215535-9664730c7858/go.mod h1:liX5MxHPrwgHaKowoLkYGwbXfYABh1jbZ6FpElbGF1I=
|
||||
github.com/lunixbochs/vtclean v1.0.0/go.mod h1:pHhQNgMf3btfWnGBVipUOjRYhoOsdGqdm/+2c2E2WMI=
|
||||
github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w=
|
||||
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
|
||||
@@ -1079,8 +1082,6 @@ github.com/marstr/guid v0.0.0-20170427235115-8bdf7d1a087c/go.mod h1:74gB1z2wpxxI
|
||||
github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20211016222428-79310a412696 h1:pmPKkN3RJM9wVMZidR99epzK0+gatQiqVtvP1FacZcQ=
|
||||
github.com/matterbridge/Rocket.Chat.Go.SDK v0.0.0-20211016222428-79310a412696/go.mod h1:c6MxwqHD+0HvtAJjsHMIdPCiAwGiQwPRPTp69ACMg8A=
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20210201201054-fb39a175b4f7 h1:4J2YZuY8dIYrxbLMsWGqPZb/B59ygCwSBkyZHez5PSY=
|
||||
github.com/matterbridge/discordgo v0.21.2-0.20210201201054-fb39a175b4f7/go.mod h1:411nZYv0UMMrtppR5glXop1foboJiFAowy+42U+Ahvw=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20211030125215-791a06c5f1be h1:zlirT+LngOJ60G6FVzI87DljGZLUnfNzmXja61EjtYM=
|
||||
github.com/matterbridge/go-xmpp v0.0.0-20211030125215-791a06c5f1be/go.mod h1:ECDRehsR9TYTKCAsRS8/wLeOk6UUqDydw47ln7wG41Q=
|
||||
github.com/matterbridge/gomatrix v0.0.0-20220205235239-607eb9ee6419 h1:dx8x2J3EsVwP3hBGNmVT/otz4b42p7TRQ6Cu4BK2910=
|
||||
@@ -1108,8 +1109,8 @@ github.com/mattermost/logr/v2 v2.0.15/go.mod h1:mpPp935r5dIkFDo2y9Q87cQWhFR/4xXp
|
||||
github.com/mattermost/mattermost-server/v5 v5.39.3 h1:A5z/NlR4Xcwxx5UnlaNgUGP5hgj4KOV/CwpFg3OtlvQ=
|
||||
github.com/mattermost/mattermost-server/v5 v5.39.3/go.mod h1:MDmVSmsSsqwNkuZ7rQ0osuXVCzrR1IUqGR7I0QU91sY=
|
||||
github.com/mattermost/mattermost-server/v6 v6.0.0/go.mod h1:+S8CsNEPv1FOl1usaPBQ6Gu9+Sm1Cc9YdU/Qh1YMGVI=
|
||||
github.com/mattermost/mattermost-server/v6 v6.3.0 h1:wxUBvu6whm2FAMm5n2J4xbchtrSndRW3g3VQnGt8KPw=
|
||||
github.com/mattermost/mattermost-server/v6 v6.3.0/go.mod h1:L9gIoi9ESBh/NefsaZCfOVBMnbhx+v3kXhInGt3DQmA=
|
||||
github.com/mattermost/mattermost-server/v6 v6.5.0 h1:9S+/vQirO4XNpT+4TC/MlHNYpd2bgFvoRnBkImRCtNQ=
|
||||
github.com/mattermost/mattermost-server/v6 v6.5.0/go.mod h1:JRRn3uSrynvCY45ystGEJqis/Xo8PFhCDSO4SNDMncU=
|
||||
github.com/mattermost/rsc v0.0.0-20160330161541-bbaefb05eaa0/go.mod h1:nV5bfVpT//+B1RPD2JvRnxbkLmJEYXmRaaVl15fsXjs=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
@@ -1146,12 +1147,16 @@ github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vq
|
||||
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible h1:gXHsfypPkaMZrKbD5209QV9jbUTJKjyR5WD3HYQSd+U=
|
||||
github.com/mattn/go-sqlite3 v2.0.3+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
|
||||
github.com/mattn/godown v0.0.1 h1:39uk50ufLVQFs0eapIJVX5fCS74a1Fs2g5f1MVqIHdE=
|
||||
github.com/mattn/godown v0.0.1/go.mod h1:/ivCKurgV/bx6yqtP/Jtc2Xmrv3beCYBvlfAUl4X5g4=
|
||||
github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4=
|
||||
github.com/mdp/qrterminal v1.0.1 h1:07+fzVDlPuBlXS8tB0ktTAyf+Lp1j2+2zK3fBOL5b7c=
|
||||
github.com/mdp/qrterminal v1.0.1/go.mod h1:Z33WhxQe9B6CdW37HaVqcRKzP+kByF3q/qLxOGe12xQ=
|
||||
github.com/mediocregopher/radix/v3 v3.4.2/go.mod h1:8FL3F6UQRXHXIBSPUs5h0RybMF8i4n7wVopoX3x7Bv8=
|
||||
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
|
||||
github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d h1:5PJl274Y63IEHC+7izoQE9x6ikvDFZS2mDVS3drnohI=
|
||||
@@ -1160,25 +1165,29 @@ github.com/mholt/archiver/v3 v3.5.0/go.mod h1:qqTTPUK/HZPFgFQ/TJ3BzvTpF/dPtFVJXd
|
||||
github.com/mholt/archiver/v3 v3.5.1/go.mod h1:e3dqJ7H78uzsRSEACH1joayhuSyhnonssnDhppzS1L4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.1/go.mod h1:hsXNsILzKxV+sX77C5b8FSuKF00vh2OMYv+xgHpAMF4=
|
||||
github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc=
|
||||
github.com/microcosm-cc/bluemonday v1.0.18/go.mod h1:Z0r70sCuXHig8YpBzCc5eGHAap2K7e/u082ZUpDRRqM=
|
||||
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
|
||||
github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso=
|
||||
github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI=
|
||||
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
|
||||
github.com/miekg/dns v1.1.46/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME=
|
||||
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
|
||||
github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw=
|
||||
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
|
||||
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
|
||||
github.com/minio/minio-go/v7 v7.0.11/go.mod h1:WoyW+ySKAKjY98B9+7ZbI8z8S3jaxaisdcvj9TGlazA=
|
||||
github.com/minio/minio-go/v7 v7.0.16 h1:GspaSBS8lOuEUCAqMe0W3UxSoyOA4b4F8PTspRVI+k4=
|
||||
github.com/minio/minio-go/v7 v7.0.16/go.mod h1:pUV0Pc+hPd1nccgmzQF/EXh48l/Z/yps6QPF1aaie4g=
|
||||
github.com/minio/minio-go/v7 v7.0.21 h1:xrc4BQr1Fa4s5RwY0xfMjPZFJ1bcYBCCHYlngBdWV+k=
|
||||
github.com/minio/minio-go/v7 v7.0.21/go.mod h1:ei5JjmxwHaMrgsMrn4U/+Nmg+d8MKS1U2DAn1ou4+Do=
|
||||
github.com/minio/sha256-simd v0.1.1/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM=
|
||||
github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g=
|
||||
github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM=
|
||||
github.com/missdeer/golib v1.0.4 h1:tM7MJIPffXSmwFCTOCMjL5C7JsT5SQ+OmZwzssZQOa8=
|
||||
github.com/missdeer/golib v1.0.4/go.mod h1:mPN/UcszFq0GxKfQsZI3aFOiRjnzXCBZ392od3guGEY=
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
|
||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -1208,7 +1217,6 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8=
|
||||
github.com/monaco-io/request v1.0.5 h1:QAJb5m1pCPZUGv3zzTZn7GlQI3q+uJWi7fH9QxDGbm4=
|
||||
github.com/monaco-io/request v1.0.5/go.mod h1:EmggwHktBsbJmCgwZXqy7o0H1NNsAstQBWZrFVd3xtQ=
|
||||
github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc=
|
||||
@@ -1285,6 +1293,7 @@ github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7
|
||||
github.com/onsi/gomega v1.16.0 h1:6gjqkI8iiRHMvdccRJM8rVKjCWk6ZIm6FTm3ddIe4/c=
|
||||
github.com/onsi/gomega v1.16.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY=
|
||||
github.com/oov/psd v0.0.0-20210618170533-9fb823ddb631/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8=
|
||||
github.com/oov/psd v0.0.0-20220121172623-5db5eafcecbb/go.mod h1:GHI1bnmAcbp96z6LNfBJvtrjxhaXGkbsk967utPlvL8=
|
||||
github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
|
||||
@@ -1308,6 +1317,8 @@ github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mo
|
||||
github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE=
|
||||
github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo=
|
||||
github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8=
|
||||
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
|
||||
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
|
||||
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
|
||||
github.com/openzipkin/zipkin-go v0.1.1/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
github.com/openzipkin/zipkin-go v0.1.3/go.mod h1:NtoC/o8u3JlF1lSlyPNswIbeQH9bJTmOf0Erfk+hxe8=
|
||||
@@ -1341,7 +1352,7 @@ github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi
|
||||
github.com/pierrec/lz4/v4 v4.0.3/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.8/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.11/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pierrec/lz4/v4 v4.1.14/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
|
||||
github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8=
|
||||
github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
@@ -1369,6 +1380,7 @@ github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3O
|
||||
github.com/prometheus/client_golang v1.4.1/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
|
||||
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
|
||||
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
|
||||
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
|
||||
github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
|
||||
@@ -1405,8 +1417,10 @@ github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqn
|
||||
github.com/rcrowley/go-metrics v0.0.0-20190826022208-cac0b30c2563/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
|
||||
github.com/reflog/dateconstraints v0.2.1/go.mod h1:Ax8AxTBcJc3E/oVS2hd2j7RDM/5MDtuPwuR7lIHtPLo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk=
|
||||
github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
|
||||
github.com/richardlehane/mscfb v1.0.3/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||
github.com/richardlehane/mscfb v1.0.4/go.mod h1:YzVpcZg9czvAuhk9T+a3avCpcFPMUWm7gK3DypaEsUk=
|
||||
github.com/richardlehane/msoleps v1.0.1/go.mod h1:BWev5JBpU9Ko2WAgmZEuiz4/u3ZYTKbjLycmwiWUfWg=
|
||||
github.com/rickb777/date v1.12.4 h1:+6IzcCCS/1t17DrmnEvrznyq7nM8vPwir6/UhlyohKw=
|
||||
github.com/rickb777/date v1.12.4/go.mod h1:xP0eo/I5qmUt97yRGClHZfyLZ3ikMw6v6SU5MOGZTE0=
|
||||
@@ -1426,30 +1440,32 @@ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTE
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU=
|
||||
github.com/rs/cors v1.8.0/go.mod h1:EBwu+T5AvHOcXwvZIkQFjUN6s8Czyqw12GL/Y0tUyRM=
|
||||
github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
|
||||
github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
||||
github.com/rs/xid v1.3.0 h1:6NjYksEUlhurdVehpc7S7dk6DAmcKv8V9gG0FsVN2U4=
|
||||
github.com/rs/xid v1.3.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||
github.com/rudderlabs/analytics-go v3.3.1+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
|
||||
github.com/rudderlabs/analytics-go v3.3.2+incompatible/go.mod h1:LF8/ty9kUX4PTY3l5c97K3nZZaX5Hwsvt+NBaRL/f30=
|
||||
github.com/russellhaering/goxmldsig v1.1.0/go.mod h1:QK8GhXPB3+AfuCrfo0oRISa9NfzeCpWmxeGnqEpDF9o=
|
||||
github.com/russellhaering/goxmldsig v1.1.1/go.mod h1:gM4MDENBQf7M+V824SGfyIUVFWydB7n0KkEubVJl+Tw=
|
||||
github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
|
||||
github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk=
|
||||
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
|
||||
github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4=
|
||||
github.com/sagikazarmark/crypt v0.3.0/go.mod h1:uD/D+6UF4SrIR1uGEv7bBNkNqLGqUr43MRiaGWX1Nig=
|
||||
github.com/sagikazarmark/crypt v0.4.0/go.mod h1:ALv2SRj7GxYV4HO9elxH9nS6M9gW+xDNxqmyJ6RfDFM=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||
github.com/satori/go.uuid v0.0.0-20180103174451-36e9d2ebbde5/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/savsgio/gotils v0.0.0-20210921075833-21a6215cb0e4/go.mod h1:oejLrk1Y/5zOF+c/aHtXqn3TFlzzbAgPWg8zBiAHDas=
|
||||
github.com/schollz/closestmatch v2.1.0+incompatible/go.mod h1:RtP1ddjLong6gTkbtmuhtR2uUrrJOpYzYRvbcPAid+g=
|
||||
github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw=
|
||||
github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg=
|
||||
@@ -1504,10 +1520,10 @@ github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE
|
||||
github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 h1:A7o8tOERTtpD/poS+2VoassCjXpjHn916luXbf5QKD0=
|
||||
github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882/go.mod h1:5IwJoz9Pw7JsrCN4/skkxUtSWT7myuUPLhCgv6Q5vvQ=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
|
||||
github.com/slack-go/slack v0.10.0 h1:L16Eqg3QZzRKGXIVsFSZdJdygjOphb2FjRUwH6VrFu8=
|
||||
github.com/slack-go/slack v0.10.0/go.mod h1:wWL//kk0ho+FcQXcBTmEafUI5dz4qz5f4mMk8oIkioQ=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9 h1:lpEzuenPuO1XNTeikEmvqYFcU37GVLl8SRNblzyvGBE=
|
||||
github.com/skip2/go-qrcode v0.0.0-20190110000554-dc11ecdae0a9/go.mod h1:PLPIyL7ikehBD1OAjmKKiOEhbvWyHGaNDjquXMcYABo=
|
||||
github.com/slack-go/slack v0.10.2 h1:KMN/h2sgUninHXvQI8PrR/PHBUuWp2NPvz2Kr66tki4=
|
||||
github.com/slack-go/slack v0.10.2/go.mod h1:5FLdBRv7VW/d9EBxx/eEktOptWygbA9K2QK/KW7ds1s=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/assertions v1.0.0 h1:UVQPSSmc3qtTi+zPPkCXvZX9VvW/xT/NsRvKfwY81a8=
|
||||
github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM=
|
||||
@@ -1538,6 +1554,7 @@ github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tL
|
||||
github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE=
|
||||
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
|
||||
github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk=
|
||||
github.com/spf13/cobra v1.3.0/go.mod h1:BrRVncBjOJa/eUcVVm9CE+oC6as8k+VYr4NY7WCi9V4=
|
||||
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
|
||||
github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk=
|
||||
github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo=
|
||||
@@ -1551,6 +1568,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM
|
||||
github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE=
|
||||
github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg=
|
||||
github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns=
|
||||
github.com/spf13/viper v1.10.0/go.mod h1:SoyBPwAtKDzypXNDFKN5kzH7ppppbGZtls1UpIy5AsM=
|
||||
github.com/spf13/viper v1.10.1 h1:nuJZuYpG7gTj/XqiUwg8bA0cp1+M2mC3J4g5luUYBKk=
|
||||
github.com/spf13/viper v1.10.1/go.mod h1:IGlFPqhNAPKRxohIzWpI5QEy4kuI7tcl5WvR+8qy1rU=
|
||||
github.com/splitio/go-client/v6 v6.1.0/go.mod h1:CEGAEFT99Fwb32ZIRcnZoXTMXddtB6IIpTmt3RP8mnM=
|
||||
@@ -1586,7 +1604,7 @@ github.com/tebeka/snowball v0.4.2/go.mod h1:4IfL14h1lvwZcp1sfXuuc7/7yCsvVffTWxWx
|
||||
github.com/tecbot/gorocksdb v0.0.0-20191217155057-f0fad39f321c/go.mod h1:ahpPrc7HpcfEWDQRZEmnXMzHY03mLDYMCxeDzy46i+8=
|
||||
github.com/throttled/throttled v2.2.5+incompatible/go.mod h1:0BjlrEGQmvxps+HuXLsyRdqpSRvJpq0PNIsOtqP9Nos=
|
||||
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
||||
github.com/tidwall/gjson v1.11.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
@@ -1610,6 +1628,7 @@ github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1
|
||||
github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM=
|
||||
github.com/tylerb/graceful v1.2.15/go.mod h1:LPYTbOYmUTdabwRt0TGhLllQ0MUNbs0Y5q1WXJOI9II=
|
||||
github.com/uber/jaeger-client-go v2.29.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-client-go v2.30.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk=
|
||||
github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
@@ -1628,14 +1647,10 @@ github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKn
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w=
|
||||
github.com/valyala/fasthttp v1.29.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
|
||||
github.com/valyala/fasthttp v1.30.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
|
||||
github.com/valyala/fasthttp v1.31.0/go.mod h1:2rsYD01CKFrjjsvFxx75KlEUNpWNBY9JWD3K/7o2Cus=
|
||||
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
|
||||
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio=
|
||||
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
|
||||
github.com/viant/assertly v0.4.8/go.mod h1:aGifi++jvCrUaklKEKT0BU95igDNaqkvz+49uaYMPRU=
|
||||
github.com/viant/toolbox v0.24.0/go.mod h1:OxMCG57V0PXuIP2HNQrtJf2CjqdmbrOx5EkMILuUhzM=
|
||||
github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI=
|
||||
@@ -1695,8 +1710,8 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.3.8/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.4/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.5/go.mod h1:rmuwmfZ0+bvzB24eSC//bk1R1Zp3hM0OXYv/G2LIilg=
|
||||
github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs=
|
||||
github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA=
|
||||
github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg=
|
||||
@@ -1716,6 +1731,10 @@ go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3
|
||||
go.etcd.io/etcd/client/pkg/v3 v3.5.1/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
|
||||
go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
|
||||
go.etcd.io/etcd/client/v2 v2.305.1/go.mod h1:pMEacxZW7o8pg4CrFE7pquyCJJzZvkvdD2RibOCCCGs=
|
||||
go.mau.fi/libsignal v0.0.0-20220315232917-871a40435d3b h1:BGm0ceth6OtoXgBksEyeruiCL2ngZCwt86DUmUI6TmQ=
|
||||
go.mau.fi/libsignal v0.0.0-20220315232917-871a40435d3b/go.mod h1:XYWsswZT1LfDmguWKYDuj+OugtdGX6CP3iwTtOcAGt4=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220329131721-9f73bc00d158 h1:FLwtX7WD+SHGaSiHZwSiCCP155A7+oYdQ+6nr1Lvhms=
|
||||
go.mau.fi/whatsmeow v0.0.0-20220329131721-9f73bc00d158/go.mod h1:P7OA9XyJ/0dWHhUPKNESpC1wVOErnhY4pLEaMC1a8yg=
|
||||
go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM=
|
||||
go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8NzkI+yfU8=
|
||||
go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk=
|
||||
@@ -1791,13 +1810,14 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh
|
||||
golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871 h1:/pEO3GD/ABYAjuakUS6xSEmmlyVS4kxBNkeA9tLJiTI=
|
||||
golang.org/x/crypto v0.0.0-20211117183948-ae814b36b871/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220208233918-bba287dce954/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd h1:XcWmESyNjXJMLahc3mqVQJcgSTDxFxhETVlfk9uGc38=
|
||||
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
@@ -1825,8 +1845,9 @@ golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+o
|
||||
golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20210622092929-e6eecd499c2c/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ=
|
||||
golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867 h1:TcHcE0vrmgzNH1v3ppjcMGbhG5+9fMuvOmUYwNEF4q4=
|
||||
golang.org/x/image v0.0.0-20220302094943-723b81ca9867/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20181217174547-8f45f776aaf1/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
@@ -1854,6 +1875,7 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180530234432-1e491301e022/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -1924,18 +1946,19 @@ golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk=
|
||||
golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210505024714-0287a6fb4125/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210913180222-943fd674d43e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211008194852-3b03d305991f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211013171255-e13a2654a71e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/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-20211123203042-d83791d6bcd9 h1:0qxwC5n+ttVOINCBeRHO0nq9X7uy8SDsPoi5OaCdIEI=
|
||||
golang.org/x/net v0.0.0-20211123203042-d83791d6bcd9/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk=
|
||||
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/oauth2 v0.0.0-20180227000427-d7d64896b5ff/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
@@ -1958,8 +1981,9 @@ golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ
|
||||
golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
|
||||
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM=
|
||||
golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
|
||||
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
@@ -2076,6 +2100,7 @@ golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210326220804-49726bf1d181/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -2089,7 +2114,6 @@ golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816074244-15123e1e1f71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210818153620-00dd8d7831e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
@@ -2099,14 +2123,19 @@ golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBc
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211013075003-97ac67df715c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d h1:Bm7BNOQt2Qv7ZqysjeLjgCBanX+88Z/OtdvsrEv1Djc=
|
||||
golang.org/x/sys v0.0.0-20220207234003-57398862261d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 h1:JGgROgKl9N8DuW20oFS5gxc+lE67/N3FcwmBPMe7ArY=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
@@ -2211,7 +2240,9 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.9 h1:j9KsMiaP1c3B0OTQGth0/k+miLGTgLsAFUCrF2vLcF8=
|
||||
golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
@@ -2265,6 +2296,7 @@ google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqiv
|
||||
google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI=
|
||||
google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU=
|
||||
google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I=
|
||||
google.golang.org/api v0.62.0/go.mod h1:dKmwPCydfsad4qCH08MSdgWjfHOyfpd4VtDGgRFdavw=
|
||||
google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo=
|
||||
google.golang.org/appengine v1.0.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
@@ -2347,7 +2379,6 @@ google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKr
|
||||
google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48=
|
||||
google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w=
|
||||
google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210825212027-de86158e7fda/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY=
|
||||
@@ -2357,8 +2388,11 @@ google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ6
|
||||
google.golang.org/genproto v0.0.0-20211013025323-ce878158c4d4/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211129164237-f09f9a12af12/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211203200212-54befc351ae9/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
|
||||
google.golang.org/genproto v0.0.0-20220208230804-65c12eb4c068/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI=
|
||||
google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.8.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
|
||||
@@ -2398,6 +2432,7 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K
|
||||
google.golang.org/grpc v1.41.0/go.mod h1:U3l9uK9J0sini8mHphKoXyaqDA/8VyGnDee1zzIUK6k=
|
||||
google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU=
|
||||
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
@@ -2428,16 +2463,15 @@ gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMy
|
||||
gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s=
|
||||
gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
|
||||
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.64.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/ini.v1 v1.66.3 h1:jRskFVxYaMGAMUbN0UZ7niA9gzL9B49DOqE78vg0k3w=
|
||||
gopkg.in/ini.v1 v1.66.3/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mail.v2 v2.3.1/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||
gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
|
||||
@@ -2513,35 +2547,173 @@ k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
|
||||
layeh.com/gopus v0.0.0-20161224163843-0ebf989153aa/go.mod h1:AOef7vHz0+v4sWwJnr0jSyHiX/1NgsMoaxl+rEPz/I0=
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b h1:Kne6wkHqbqrygRsqs5XUNhSs84DFG5TYMeCkCbM56sY=
|
||||
layeh.com/gumble v0.0.0-20200818122324-146f9205029b/go.mod h1:tWPVA9ZAfImNwabjcd9uDE+Mtz0Hfs7a7G3vxrnrwyc=
|
||||
lukechampine.com/uint128 v1.1.1 h1:pnxCASz787iMf+02ssImqk6OLt+Z5QHMoZyUXR4z6JU=
|
||||
lukechampine.com/uint128 v1.1.1/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
|
||||
modernc.org/b v1.0.0/go.mod h1:uZWcZfRj1BpYzfN9JTerzlNUnnPsV9O2ZA8JsRcubNg=
|
||||
modernc.org/cc/v3 v3.32.4/go.mod h1:0R6jl1aZlIl2avnYfbfHBS1QB6/f+16mihBObaBC878=
|
||||
modernc.org/cc/v3 v3.33.6/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.33.9/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.33.11/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.34.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.0/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.4/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.5/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.7/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.8/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.10/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.15/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.16/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.17/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.18/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.20/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.22/go.mod h1:iPJg1pkwXqAV16SNgFBVYmggfMg6xhs+2oiO0vclK3g=
|
||||
modernc.org/cc/v3 v3.35.24 h1:vlCqjhVwX15t1uwlMPpOpNRC7JTjMZ9lT9DYHKQTFuA=
|
||||
modernc.org/cc/v3 v3.35.24/go.mod h1:NFUHyPn4ekoC/JHeZFfZurN6ixxawE1BnVonP/oahEI=
|
||||
modernc.org/ccgo/v3 v3.9.2/go.mod h1:gnJpy6NIVqkETT+L5zPsQFj7L2kkhfPMzOghRNv/CFo=
|
||||
modernc.org/ccgo/v3 v3.9.5/go.mod h1:umuo2EP2oDSBnD3ckjaVUXMrmeAw8C8OSICVa0iFf60=
|
||||
modernc.org/ccgo/v3 v3.10.0/go.mod h1:c0yBmkRFi7uW4J7fwx/JiijwOjeAeR2NoSaRVFPmjMw=
|
||||
modernc.org/ccgo/v3 v3.11.0/go.mod h1:dGNposbDp9TOZ/1KBxghxtUp/bzErD0/0QW4hhSaBMI=
|
||||
modernc.org/ccgo/v3 v3.11.1/go.mod h1:lWHxfsn13L3f7hgGsGlU28D9eUOf6y3ZYHKoPaKU0ag=
|
||||
modernc.org/ccgo/v3 v3.11.3/go.mod h1:0oHunRBMBiXOKdaglfMlRPBALQqsfrCKXgw9okQ3GEw=
|
||||
modernc.org/ccgo/v3 v3.12.4/go.mod h1:Bk+m6m2tsooJchP/Yk5ji56cClmN6R1cqc9o/YtbgBQ=
|
||||
modernc.org/ccgo/v3 v3.12.6/go.mod h1:0Ji3ruvpFPpz+yu+1m0wk68pdr/LENABhTrDkMDWH6c=
|
||||
modernc.org/ccgo/v3 v3.12.8/go.mod h1:Hq9keM4ZfjCDuDXxaHptpv9N24JhgBZmUG5q60iLgUo=
|
||||
modernc.org/ccgo/v3 v3.12.11/go.mod h1:0jVcmyDwDKDGWbcrzQ+xwJjbhZruHtouiBEvDfoIsdg=
|
||||
modernc.org/ccgo/v3 v3.12.14/go.mod h1:GhTu1k0YCpJSuWwtRAEHAol5W7g1/RRfS4/9hc9vF5I=
|
||||
modernc.org/ccgo/v3 v3.12.18/go.mod h1:jvg/xVdWWmZACSgOiAhpWpwHWylbJaSzayCqNOJKIhs=
|
||||
modernc.org/ccgo/v3 v3.12.20/go.mod h1:aKEdssiu7gVgSy/jjMastnv/q6wWGRbszbheXgWRHc8=
|
||||
modernc.org/ccgo/v3 v3.12.21/go.mod h1:ydgg2tEprnyMn159ZO/N4pLBqpL7NOkJ88GT5zNU2dE=
|
||||
modernc.org/ccgo/v3 v3.12.22/go.mod h1:nyDVFMmMWhMsgQw+5JH6B6o4MnZ+UQNw1pp52XYFPRk=
|
||||
modernc.org/ccgo/v3 v3.12.25/go.mod h1:UaLyWI26TwyIT4+ZFNjkyTbsPsY3plAEB6E7L/vZV3w=
|
||||
modernc.org/ccgo/v3 v3.12.29/go.mod h1:FXVjG7YLf9FetsS2OOYcwNhcdOLGt8S9bQ48+OP75cE=
|
||||
modernc.org/ccgo/v3 v3.12.36/go.mod h1:uP3/Fiezp/Ga8onfvMLpREq+KUjUmYMxXPO8tETHtA8=
|
||||
modernc.org/ccgo/v3 v3.12.38/go.mod h1:93O0G7baRST1vNj4wnZ49b1kLxt0xCW5Hsa2qRaZPqc=
|
||||
modernc.org/ccgo/v3 v3.12.43/go.mod h1:k+DqGXd3o7W+inNujK15S5ZYuPoWYLpF5PYougCmthU=
|
||||
modernc.org/ccgo/v3 v3.12.46/go.mod h1:UZe6EvMSqOxaJ4sznY7b23/k13R8XNlyWsO5bAmSgOE=
|
||||
modernc.org/ccgo/v3 v3.12.47/go.mod h1:m8d6p0zNps187fhBwzY/ii6gxfjob1VxWb919Nk1HUk=
|
||||
modernc.org/ccgo/v3 v3.12.50/go.mod h1:bu9YIwtg+HXQxBhsRDE+cJjQRuINuT9PUK4orOco/JI=
|
||||
modernc.org/ccgo/v3 v3.12.51/go.mod h1:gaIIlx4YpmGO2bLye04/yeblmvWEmE4BBBls4aJXFiE=
|
||||
modernc.org/ccgo/v3 v3.12.53/go.mod h1:8xWGGTFkdFEWBEsUmi+DBjwu/WLy3SSOrqEmKUjMeEg=
|
||||
modernc.org/ccgo/v3 v3.12.54/go.mod h1:yANKFTm9llTFVX1FqNKHE0aMcQb1fuPJx6p8AcUx+74=
|
||||
modernc.org/ccgo/v3 v3.12.55/go.mod h1:rsXiIyJi9psOwiBkplOaHye5L4MOOaCjHg1Fxkj7IeU=
|
||||
modernc.org/ccgo/v3 v3.12.56/go.mod h1:ljeFks3faDseCkr60JMpeDb2GSO3TKAmrzm7q9YOcMU=
|
||||
modernc.org/ccgo/v3 v3.12.57/go.mod h1:hNSF4DNVgBl8wYHpMvPqQWDQx8luqxDnNGCMM4NFNMc=
|
||||
modernc.org/ccgo/v3 v3.12.60/go.mod h1:k/Nn0zdO1xHVWjPYVshDeWKqbRWIfif5dtsIOCUVMqM=
|
||||
modernc.org/ccgo/v3 v3.12.66/go.mod h1:jUuxlCFZTUZLMV08s7B1ekHX5+LIAurKTTaugUr/EhQ=
|
||||
modernc.org/ccgo/v3 v3.12.67/go.mod h1:Bll3KwKvGROizP2Xj17GEGOTrlvB1XcVaBrC90ORO84=
|
||||
modernc.org/ccgo/v3 v3.12.73/go.mod h1:hngkB+nUUqzOf3iqsM48Gf1FZhY599qzVg1iX+BT3cQ=
|
||||
modernc.org/ccgo/v3 v3.12.81/go.mod h1:p2A1duHoBBg1mFtYvnhAnQyI6vL0uw5PGYLSIgF6rYY=
|
||||
modernc.org/ccgo/v3 v3.12.84/go.mod h1:ApbflUfa5BKadjHynCficldU1ghjen84tuM5jRynB7w=
|
||||
modernc.org/ccgo/v3 v3.12.86/go.mod h1:dN7S26DLTgVSni1PVA3KxxHTcykyDurf3OgUzNqTSrU=
|
||||
modernc.org/ccgo/v3 v3.12.90/go.mod h1:obhSc3CdivCRpYZmrvO88TXlW0NvoSVvdh/ccRjJYko=
|
||||
modernc.org/ccgo/v3 v3.12.92/go.mod h1:5yDdN7ti9KWPi5bRVWPl8UNhpEAtCjuEE7ayQnzzqHA=
|
||||
modernc.org/ccgo/v3 v3.13.1/go.mod h1:aBYVOUfIlcSnrsRVU8VRS35y2DIfpgkmVkYZ0tpIXi4=
|
||||
modernc.org/ccgo/v3 v3.15.9/go.mod h1:md59wBwDT2LznX/OTCPoVS6KIsdRgY8xqQwBV+hkTH0=
|
||||
modernc.org/ccgo/v3 v3.15.10/go.mod h1:wQKxoFn0ynxMuCLfFD09c8XPUCc8obfchoVR9Cn0fI8=
|
||||
modernc.org/ccgo/v3 v3.15.12/go.mod h1:VFePOWoCd8uDGRJpq/zfJ29D0EVzMSyID8LCMWYbX6I=
|
||||
modernc.org/ccgo/v3 v3.15.14/go.mod h1:144Sz2iBCKogb9OKwsu7hQEub3EVgOlyI8wMUPGKUXQ=
|
||||
modernc.org/ccgo/v3 v3.15.15/go.mod h1:z5qltXjU4PJl0pE5nhYQCvA9DhPHiWsl5GWl89+NSYE=
|
||||
modernc.org/ccgo/v3 v3.15.16/go.mod h1:XbKRMeMWMdq712Tr5ECgATYMrzJ+g9zAZEj2ktzBe24=
|
||||
modernc.org/ccgo/v3 v3.15.17/go.mod h1:bofnFkpRFf5gLY+mBZIyTW6FEcp26xi2lgOFk2Rlvs0=
|
||||
modernc.org/ccgo/v3 v3.15.18 h1:X5ym656Ye7/ubL+wox0SeF9aRX5od1UDFn1tAbQR+90=
|
||||
modernc.org/ccgo/v3 v3.15.18/go.mod h1:/2lv3WjHyanEr2sAPdGKRC38n6f0werut9BRXUjjX+A=
|
||||
modernc.org/ccorpus v1.11.1/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
|
||||
modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
|
||||
modernc.org/db v1.0.0/go.mod h1:kYD/cO29L/29RM0hXYl4i3+Q5VojL31kTUVpVJDw0s8=
|
||||
modernc.org/file v1.0.0/go.mod h1:uqEokAEn1u6e+J45e54dsEA/pw4o7zLrA2GwyntZzjw=
|
||||
modernc.org/fileutil v1.0.0/go.mod h1:JHsWpkrk/CnVV1H/eGlFf85BEpfkrp56ro8nojIq9Q8=
|
||||
modernc.org/golex v1.0.0/go.mod h1:b/QX9oBD/LhixY6NDh+IdGv17hgB+51fET1i2kPSmvk=
|
||||
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
|
||||
modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
|
||||
modernc.org/internal v1.0.0/go.mod h1:VUD/+JAkhCpvkUitlEOnhpVxCgsBI90oTzSCRcqQVSM=
|
||||
modernc.org/libc v1.7.13-0.20210308123627-12f642a52bb8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.5/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.8/go.mod h1:U1eq8YWr/Kc1RWCMFUWEdkTg8OTcfLw2kY8EDwl039w=
|
||||
modernc.org/libc v1.9.11/go.mod h1:NyF3tsA5ArIjJ83XB0JlqhjTabTCHm9aX4XMPHyQn0Q=
|
||||
modernc.org/libc v1.11.0/go.mod h1:2lOfPmj7cz+g1MrPNmX65QCzVxgNq2C5o0jdLY2gAYg=
|
||||
modernc.org/libc v1.11.2/go.mod h1:ioIyrl3ETkugDO3SGZ+6EOKvlP3zSOycUETe4XM4n8M=
|
||||
modernc.org/libc v1.11.5/go.mod h1:k3HDCP95A6U111Q5TmG3nAyUcp3kR5YFZTeDS9v8vSU=
|
||||
modernc.org/libc v1.11.6/go.mod h1:ddqmzR6p5i4jIGK1d/EiSw97LBcE3dK24QEwCFvgNgE=
|
||||
modernc.org/libc v1.11.11/go.mod h1:lXEp9QOOk4qAYOtL3BmMve99S5Owz7Qyowzvg6LiZso=
|
||||
modernc.org/libc v1.11.13/go.mod h1:ZYawJWlXIzXy2Pzghaf7YfM8OKacP3eZQI81PDLFdY8=
|
||||
modernc.org/libc v1.11.16/go.mod h1:+DJquzYi+DMRUtWI1YNxrlQO6TcA5+dRRiq8HWBWRC8=
|
||||
modernc.org/libc v1.11.19/go.mod h1:e0dgEame6mkydy19KKaVPBeEnyJB4LGNb0bBH1EtQ3I=
|
||||
modernc.org/libc v1.11.24/go.mod h1:FOSzE0UwookyT1TtCJrRkvsOrX2k38HoInhw+cSCUGk=
|
||||
modernc.org/libc v1.11.26/go.mod h1:SFjnYi9OSd2W7f4ct622o/PAYqk7KHv6GS8NZULIjKY=
|
||||
modernc.org/libc v1.11.27/go.mod h1:zmWm6kcFXt/jpzeCgfvUNswM0qke8qVwxqZrnddlDiE=
|
||||
modernc.org/libc v1.11.28/go.mod h1:Ii4V0fTFcbq3qrv3CNn+OGHAvzqMBvC7dBNyC4vHZlg=
|
||||
modernc.org/libc v1.11.31/go.mod h1:FpBncUkEAtopRNJj8aRo29qUiyx5AvAlAxzlx9GNaVM=
|
||||
modernc.org/libc v1.11.34/go.mod h1:+Tzc4hnb1iaX/SKAutJmfzES6awxfU1BPvrrJO0pYLg=
|
||||
modernc.org/libc v1.11.37/go.mod h1:dCQebOwoO1046yTrfUE5nX1f3YpGZQKNcITUYWlrAWo=
|
||||
modernc.org/libc v1.11.39/go.mod h1:mV8lJMo2S5A31uD0k1cMu7vrJbSA3J3waQJxpV4iqx8=
|
||||
modernc.org/libc v1.11.42/go.mod h1:yzrLDU+sSjLE+D4bIhS7q1L5UwXDOw99PLSX0BlZvSQ=
|
||||
modernc.org/libc v1.11.44/go.mod h1:KFq33jsma7F5WXiYelU8quMJasCCTnHK0mkri4yPHgA=
|
||||
modernc.org/libc v1.11.45/go.mod h1:Y192orvfVQQYFzCNsn+Xt0Hxt4DiO4USpLNXBlXg/tM=
|
||||
modernc.org/libc v1.11.47/go.mod h1:tPkE4PzCTW27E6AIKIR5IwHAQKCAtudEIeAV1/SiyBg=
|
||||
modernc.org/libc v1.11.49/go.mod h1:9JrJuK5WTtoTWIFQ7QjX2Mb/bagYdZdscI3xrvHbXjE=
|
||||
modernc.org/libc v1.11.51/go.mod h1:R9I8u9TS+meaWLdbfQhq2kFknTW0O3aw3kEMqDDxMaM=
|
||||
modernc.org/libc v1.11.53/go.mod h1:5ip5vWYPAoMulkQ5XlSJTy12Sz5U6blOQiYasilVPsU=
|
||||
modernc.org/libc v1.11.54/go.mod h1:S/FVnskbzVUrjfBqlGFIPA5m7UwB3n9fojHhCNfSsnw=
|
||||
modernc.org/libc v1.11.55/go.mod h1:j2A5YBRm6HjNkoSs/fzZrSxCuwWqcMYTDPLNx0URn3M=
|
||||
modernc.org/libc v1.11.56/go.mod h1:pakHkg5JdMLt2OgRadpPOTnyRXm/uzu+Yyg/LSLdi18=
|
||||
modernc.org/libc v1.11.58/go.mod h1:ns94Rxv0OWyoQrDqMFfWwka2BcaF6/61CqJRK9LP7S8=
|
||||
modernc.org/libc v1.11.71/go.mod h1:DUOmMYe+IvKi9n6Mycyx3DbjfzSKrdr/0Vgt3j7P5gw=
|
||||
modernc.org/libc v1.11.75/go.mod h1:dGRVugT6edz361wmD9gk6ax1AbDSe0x5vji0dGJiPT0=
|
||||
modernc.org/libc v1.11.82/go.mod h1:NF+Ek1BOl2jeC7lw3a7Jj5PWyHPwWD4aq3wVKxqV1fI=
|
||||
modernc.org/libc v1.11.86/go.mod h1:ePuYgoQLmvxdNT06RpGnaDKJmDNEkV7ZPKI2jnsvZoE=
|
||||
modernc.org/libc v1.11.87/go.mod h1:Qvd5iXTeLhI5PS0XSyqMY99282y+3euapQFxM7jYnpY=
|
||||
modernc.org/libc v1.11.88/go.mod h1:h3oIVe8dxmTcchcFuCcJ4nAWaoiwzKCdv82MM0oiIdQ=
|
||||
modernc.org/libc v1.11.98/go.mod h1:ynK5sbjsU77AP+nn61+k+wxUGRx9rOFcIqWYYMaDZ4c=
|
||||
modernc.org/libc v1.11.101/go.mod h1:wLLYgEiY2D17NbBOEp+mIJJJBGSiy7fLL4ZrGGZ+8jI=
|
||||
modernc.org/libc v1.12.0/go.mod h1:2MH3DaF/gCU8i/UBiVE1VFRos4o523M7zipmwH8SIgQ=
|
||||
modernc.org/libc v1.14.1/go.mod h1:npFeGWjmZTjFeWALQLrvklVmAxv4m80jnG3+xI8FdJk=
|
||||
modernc.org/libc v1.14.2/go.mod h1:MX1GBLnRLNdvmK9azU9LCxZ5lMyhrbEMK8rG3X/Fe34=
|
||||
modernc.org/libc v1.14.3/go.mod h1:GPIvQVOVPizzlqyRX3l756/3ppsAgg1QgPxjr5Q4agQ=
|
||||
modernc.org/libc v1.14.6/go.mod h1:2PJHINagVxO4QW/5OQdRrvMYo+bm5ClpUFfyXCYl9ak=
|
||||
modernc.org/libc v1.14.7/go.mod h1:f8xfWXW8LW41qb4X5+huVQo5dcfPlq7Cbny2TDheMv0=
|
||||
modernc.org/libc v1.14.8/go.mod h1:9+JCLb1MWSY23smyOpIPbd5ED+rSS/ieiDWUpdyO3mo=
|
||||
modernc.org/libc v1.14.10/go.mod h1:y1MtIWhwpJFpLYm6grAThtuXJKEsY6xkdZmXbRngIdo=
|
||||
modernc.org/libc v1.14.11/go.mod h1:l5/Mz/GrZwOqzwRHA3abgSCnSeJzzTl+Ify0bAwKbAw=
|
||||
modernc.org/libc v1.14.12 h1:pUBZTYoISfbb4pCf4PECENpbvwDBxeKc+/dS9LyOWFM=
|
||||
modernc.org/libc v1.14.12/go.mod h1:fJdoe23MHu2ruPQkFPPqCpToDi5cckzsbmkI6Ez0LqQ=
|
||||
modernc.org/lldb v1.0.0/go.mod h1:jcRvJGWfCGodDZz8BPwiKMJxGJngQ/5DrRapkQnLob8=
|
||||
modernc.org/mathutil v1.0.0/go.mod h1:wU0vUrJsVWBZ4P6e7xtFJEhFSNsfRLJ8H458uRjg03k=
|
||||
modernc.org/mathutil v1.1.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.2.2/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/mathutil v1.4.1 h1:ij3fYGe8zBF4Vu+g0oT7mB06r8sqGWKuJu1yXeR4by8=
|
||||
modernc.org/mathutil v1.4.1/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
|
||||
modernc.org/memory v1.0.4/go.mod h1:nV2OApxradM3/OVbs2/0OsP6nPfakXpi50C7dcoHXlc=
|
||||
modernc.org/memory v1.0.5/go.mod h1:B7OYswTRnfGg+4tDH1t1OeUNnsy2viGTdME4tzd+IjM=
|
||||
modernc.org/memory v1.0.6/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/memory v1.0.7 h1:UE3cxTRFa5tfUibAV7Jqq8P7zRY0OlJg+yWVIIaluEE=
|
||||
modernc.org/memory v1.0.7/go.mod h1:/0wo5ibyrQiaoUoH7f9D8dnglAmILJ5/cxZlRECf+Nw=
|
||||
modernc.org/opt v0.1.1 h1:/0RX92k9vwVeDXj+Xn23DKp2VJubL7k8qNffND6qn3A=
|
||||
modernc.org/opt v0.1.1/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
|
||||
modernc.org/ql v1.0.0/go.mod h1:xGVyrLIatPcO2C1JvI/Co8c0sr6y91HKFNy4pt9JXEY=
|
||||
modernc.org/sortutil v1.1.0/go.mod h1:ZyL98OQHJgH9IEfN71VsamvJgrtRX9Dj2gX+vH86L1k=
|
||||
modernc.org/sqlite v1.10.6/go.mod h1:Z9FEjUtZP4qFEg6/SiADg9XCER7aYy9a/j7Pg9P7CPs=
|
||||
modernc.org/sqlite v1.15.4 h1:pr3EA3Rety3j1c/9pCyGAe5d3vjF6wQwusHdgGCjIqc=
|
||||
modernc.org/sqlite v1.15.4/go.mod h1:Jwe13ItpESZ+78K5WS6+AjXsUg+JvirsjN3iIDO4C8k=
|
||||
modernc.org/strutil v1.1.0/go.mod h1:lstksw84oURvj9y3tn8lGvRxyRC1S2+g5uuIzNfIOBs=
|
||||
modernc.org/strutil v1.1.1 h1:xv+J1BXY3Opl2ALrBwyfEikFAj8pmqcpnfmuwUwcozs=
|
||||
modernc.org/strutil v1.1.1/go.mod h1:DE+MQQ/hjKBZS2zNInV5hhcipt5rLPWkmpbGeW5mmdw=
|
||||
modernc.org/tcl v1.5.2/go.mod h1:pmJYOLgpiys3oI4AeAafkcUfE+TKKilminxNyU/+Zlo=
|
||||
modernc.org/tcl v1.11.2 h1:mXpsx3AZqJt83uDiFu9UYQVBjNjaWKGCF1YDSlpCL6Y=
|
||||
modernc.org/tcl v1.11.2/go.mod h1:BRzgpajcGdS2qTxniOx9c/dcxjlbA7p12eJNmiriQYo=
|
||||
modernc.org/token v1.0.0 h1:a0jaWiNMDhDUtqOj09wvjWWAqd3q7WpBulmL9H2egsk=
|
||||
modernc.org/token v1.0.0/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
|
||||
modernc.org/z v1.0.1-0.20210308123920-1f282aa71362/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.0.1/go.mod h1:8/SRk5C/HgiQWCgXdfpb+1RvhORdkz5sw72d3jjtyqA=
|
||||
modernc.org/z v1.3.2 h1:4GWBVMa48UDC7KQ9tnaggN/yTlXg+CdCX9bhgHPQ9AM=
|
||||
modernc.org/z v1.3.2/go.mod h1:PEU2oK2OEA1CfzDTd+8E908qEXhC9s0MfyKp5LZsd+k=
|
||||
modernc.org/zappy v1.0.0/go.mod h1:hHe+oGahLVII/aTTyWK/b53VDHMAGCBYYeZ9sn83HC4=
|
||||
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
|
||||
rsc.io/goversion v1.2.0/go.mod h1:Eih9y/uIBS3ulggl7KNJ09xGSLcuNaLgmvvqa07sgfo=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
rsc.io/qr v0.2.0 h1:6vBLea5/NRMVTz8V66gipeLycZMl/+UlFmk8DvqQ6WY=
|
||||
rsc.io/qr v0.2.0/go.mod h1:IF+uZjkb9fqyeF/4tlBoynqmQxUoPfWEKh921coOuXs=
|
||||
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
|
||||
rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA=
|
||||
sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg=
|
||||
@@ -2554,4 +2726,3 @@ sourcegraph.com/sourcegraph/go-diff v0.5.0/go.mod h1:kuch7UrkMzY0X+p9CRK03kfuPQ2
|
||||
sourcegraph.com/sqs/pbtypes v0.0.0-20180604144634-d3ebe8f20ae4/go.mod h1:ketZ/q3QxT9HOBeFhu6RdvsftgpsbFHBF5Cas6cDKZ0=
|
||||
willnorris.com/go/gifresize v1.0.0/go.mod h1:eBM8gogBGCcaH603vxSpnfjwXIpq6nmnj/jauBDKtAk=
|
||||
willnorris.com/go/imageproxy v0.10.0/go.mod h1:2tWdKRneln3E9X/zwH1RINpQAQWPeUiNynZ7UQ9OROk=
|
||||
willnorris.com/go/imageproxy v0.11.2/go.mod h1:pyA05z6P0nLWX6QmeqMUyK6v9HnWE/bqnPnrzUST0KU=
|
||||
|
@@ -862,6 +862,10 @@ ShowUserTyping=false
|
||||
#Default "<clipped message>"
|
||||
MessageClipped="<clipped message>"
|
||||
|
||||
#If enabled use the slack "Real Name" as username.
|
||||
#OPTIONAL (default false)
|
||||
UseFullName=false
|
||||
|
||||
###################################################################
|
||||
#discord section
|
||||
###################################################################
|
||||
@@ -1036,6 +1040,12 @@ DisableWebPagePreview=false
|
||||
#OPTIONAL (default false)
|
||||
UseFirstName=false
|
||||
|
||||
#If enabled use the "Full Name" as username. If this is empty use the Username
|
||||
#If disabled use the "Username" as username. If this is empty use the First Name and Last Name as Full Name
|
||||
#If all names are empty, username will be "unknown"
|
||||
#OPTIONAL (default false)
|
||||
UseFullName=false
|
||||
|
||||
#WARNING! If enabled this will relay GIF/stickers/documents and other attachments as URLs
|
||||
#Those URLs will contain your bot-token. This may not be what you want.
|
||||
#For now there is no secure way to relay GIF/stickers/documents without seeing your token.
|
||||
@@ -1141,6 +1151,12 @@ StripNick=false
|
||||
#OPTIONAL (default false)
|
||||
ShowTopicChange=false
|
||||
|
||||
#Opportunistically preserve threaded replies between Telegram groups.
|
||||
#This only works if the parent message is still in the cache.
|
||||
#Cache is flushed between restarts.
|
||||
#OPTIONAL (default false)
|
||||
PreserveThreading=false
|
||||
|
||||
###################################################################
|
||||
#rocketchat section
|
||||
###################################################################
|
||||
|
27
vendor/filippo.io/edwards25519/LICENSE
generated
vendored
Normal file
27
vendor/filippo.io/edwards25519/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
Copyright (c) 2009 The Go Authors. All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above
|
||||
copyright notice, this list of conditions and the following disclaimer
|
||||
in the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of Google Inc. nor the names of its
|
||||
contributors may be used to endorse or promote products derived from
|
||||
this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
14
vendor/filippo.io/edwards25519/README.md
generated
vendored
Normal file
14
vendor/filippo.io/edwards25519/README.md
generated
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
# filippo.io/edwards25519
|
||||
|
||||
```
|
||||
import "filippo.io/edwards25519"
|
||||
```
|
||||
|
||||
This library implements the edwards25519 elliptic curve, exposing the necessary APIs to build a wide array of higher-level primitives.
|
||||
Read the docs at [pkg.go.dev/filippo.io/edwards25519](https://pkg.go.dev/filippo.io/edwards25519).
|
||||
|
||||
The code is originally derived from Adam Langley's internal implementation in the Go standard library, and includes George Tankersley's [performance improvements](https://golang.org/cl/71950). It was then further developed by Henry de Valence for use in ristretto255.
|
||||
|
||||
Most users don't need this package, and should instead use `crypto/ed25519` for signatures, `golang.org/x/crypto/curve25519` for Diffie-Hellman, or `github.com/gtank/ristretto255` for prime order group logic. However, for anyone currently using a fork of `crypto/ed25519/internal/edwards25519` or `github.com/agl/edwards25519`, this package should be a safer, faster, and more powerful alternative.
|
||||
|
||||
Since this package is meant to curb proliferation of edwards25519 implementations in the Go ecosystem, it welcomes requests for new APIs or reviewable performance improvements.
|
20
vendor/filippo.io/edwards25519/doc.go
generated
vendored
Normal file
20
vendor/filippo.io/edwards25519/doc.go
generated
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
// Package edwards25519 implements group logic for the twisted Edwards curve
|
||||
//
|
||||
// -x^2 + y^2 = 1 + -(121665/121666)*x^2*y^2
|
||||
//
|
||||
// This is better known as the Edwards curve equivalent to Curve25519, and is
|
||||
// the curve used by the Ed25519 signature scheme.
|
||||
//
|
||||
// Most users don't need this package, and should instead use crypto/ed25519 for
|
||||
// signatures, golang.org/x/crypto/curve25519 for Diffie-Hellman, or
|
||||
// github.com/gtank/ristretto255 for prime order group logic.
|
||||
//
|
||||
// However, developers who do need to interact with low-level edwards25519
|
||||
// operations can use this package, which is an extended version of
|
||||
// crypto/ed25519/internal/edwards25519 from the standard library repackaged as
|
||||
// an importable module.
|
||||
package edwards25519
|
428
vendor/filippo.io/edwards25519/edwards25519.go
generated
vendored
Normal file
428
vendor/filippo.io/edwards25519/edwards25519.go
generated
vendored
Normal file
@@ -0,0 +1,428 @@
|
||||
// Copyright (c) 2017 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.
|
||||
|
||||
package edwards25519
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"filippo.io/edwards25519/field"
|
||||
)
|
||||
|
||||
// Point types.
|
||||
|
||||
type projP1xP1 struct {
|
||||
X, Y, Z, T field.Element
|
||||
}
|
||||
|
||||
type projP2 struct {
|
||||
X, Y, Z field.Element
|
||||
}
|
||||
|
||||
// Point represents a point on the edwards25519 curve.
|
||||
//
|
||||
// This type works similarly to math/big.Int, and all arguments and receivers
|
||||
// are allowed to alias.
|
||||
//
|
||||
// The zero value is NOT valid, and it may be used only as a receiver.
|
||||
type Point struct {
|
||||
// The point is internally represented in extended coordinates (X, Y, Z, T)
|
||||
// where x = X/Z, y = Y/Z, and xy = T/Z per https://eprint.iacr.org/2008/522.
|
||||
x, y, z, t field.Element
|
||||
|
||||
// Make the type not comparable (i.e. used with == or as a map key), as
|
||||
// equivalent points can be represented by different Go values.
|
||||
_ incomparable
|
||||
}
|
||||
|
||||
type incomparable [0]func()
|
||||
|
||||
func checkInitialized(points ...*Point) {
|
||||
for _, p := range points {
|
||||
if p.x == (field.Element{}) && p.y == (field.Element{}) {
|
||||
panic("edwards25519: use of uninitialized Point")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
type projCached struct {
|
||||
YplusX, YminusX, Z, T2d field.Element
|
||||
}
|
||||
|
||||
type affineCached struct {
|
||||
YplusX, YminusX, T2d field.Element
|
||||
}
|
||||
|
||||
// Constructors.
|
||||
|
||||
func (v *projP2) Zero() *projP2 {
|
||||
v.X.Zero()
|
||||
v.Y.One()
|
||||
v.Z.One()
|
||||
return v
|
||||
}
|
||||
|
||||
// identity is the point at infinity.
|
||||
var identity, _ = new(Point).SetBytes([]byte{
|
||||
1, 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})
|
||||
|
||||
// NewIdentityPoint returns a new Point set to the identity.
|
||||
func NewIdentityPoint() *Point {
|
||||
return new(Point).Set(identity)
|
||||
}
|
||||
|
||||
// generator is the canonical curve basepoint. See TestGenerator for the
|
||||
// correspondence of this encoding with the values in RFC 8032.
|
||||
var generator, _ = new(Point).SetBytes([]byte{
|
||||
0x58, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
|
||||
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66})
|
||||
|
||||
// NewGeneratorPoint returns a new Point set to the canonical generator.
|
||||
func NewGeneratorPoint() *Point {
|
||||
return new(Point).Set(generator)
|
||||
}
|
||||
|
||||
func (v *projCached) Zero() *projCached {
|
||||
v.YplusX.One()
|
||||
v.YminusX.One()
|
||||
v.Z.One()
|
||||
v.T2d.Zero()
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *affineCached) Zero() *affineCached {
|
||||
v.YplusX.One()
|
||||
v.YminusX.One()
|
||||
v.T2d.Zero()
|
||||
return v
|
||||
}
|
||||
|
||||
// Assignments.
|
||||
|
||||
// Set sets v = u, and returns v.
|
||||
func (v *Point) Set(u *Point) *Point {
|
||||
*v = *u
|
||||
return v
|
||||
}
|
||||
|
||||
// Encoding.
|
||||
|
||||
// Bytes returns the canonical 32-byte encoding of v, according to RFC 8032,
|
||||
// Section 5.1.2.
|
||||
func (v *Point) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var buf [32]byte
|
||||
return v.bytes(&buf)
|
||||
}
|
||||
|
||||
func (v *Point) bytes(buf *[32]byte) []byte {
|
||||
checkInitialized(v)
|
||||
|
||||
var zInv, x, y field.Element
|
||||
zInv.Invert(&v.z) // zInv = 1 / Z
|
||||
x.Multiply(&v.x, &zInv) // x = X / Z
|
||||
y.Multiply(&v.y, &zInv) // y = Y / Z
|
||||
|
||||
out := copyFieldElement(buf, &y)
|
||||
out[31] |= byte(x.IsNegative() << 7)
|
||||
return out
|
||||
}
|
||||
|
||||
var feOne = new(field.Element).One()
|
||||
|
||||
// SetBytes sets v = x, where x is a 32-byte encoding of v. If x does not
|
||||
// represent a valid point on the curve, SetBytes returns nil and an error and
|
||||
// the receiver is unchanged. Otherwise, SetBytes returns v.
|
||||
//
|
||||
// Note that SetBytes accepts all non-canonical encodings of valid points.
|
||||
// That is, it follows decoding rules that match most implementations in
|
||||
// the ecosystem rather than RFC 8032.
|
||||
func (v *Point) SetBytes(x []byte) (*Point, error) {
|
||||
// Specifically, the non-canonical encodings that are accepted are
|
||||
// 1) the ones where the field element is not reduced (see the
|
||||
// (*field.Element).SetBytes docs) and
|
||||
// 2) the ones where the x-coordinate is zero and the sign bit is set.
|
||||
//
|
||||
// This is consistent with crypto/ed25519/internal/edwards25519. Read more
|
||||
// at https://hdevalence.ca/blog/2020-10-04-its-25519am, specifically the
|
||||
// "Canonical A, R" section.
|
||||
|
||||
y, err := new(field.Element).SetBytes(x)
|
||||
if err != nil {
|
||||
return nil, errors.New("edwards25519: invalid point encoding length")
|
||||
}
|
||||
|
||||
// -x² + y² = 1 + dx²y²
|
||||
// x² + dx²y² = x²(dy² + 1) = y² - 1
|
||||
// x² = (y² - 1) / (dy² + 1)
|
||||
|
||||
// u = y² - 1
|
||||
y2 := new(field.Element).Square(y)
|
||||
u := new(field.Element).Subtract(y2, feOne)
|
||||
|
||||
// v = dy² + 1
|
||||
vv := new(field.Element).Multiply(y2, d)
|
||||
vv = vv.Add(vv, feOne)
|
||||
|
||||
// x = +√(u/v)
|
||||
xx, wasSquare := new(field.Element).SqrtRatio(u, vv)
|
||||
if wasSquare == 0 {
|
||||
return nil, errors.New("edwards25519: invalid point encoding")
|
||||
}
|
||||
|
||||
// Select the negative square root if the sign bit is set.
|
||||
xxNeg := new(field.Element).Negate(xx)
|
||||
xx = xx.Select(xxNeg, xx, int(x[31]>>7))
|
||||
|
||||
v.x.Set(xx)
|
||||
v.y.Set(y)
|
||||
v.z.One()
|
||||
v.t.Multiply(xx, y) // xy = T / Z
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func copyFieldElement(buf *[32]byte, v *field.Element) []byte {
|
||||
copy(buf[:], v.Bytes())
|
||||
return buf[:]
|
||||
}
|
||||
|
||||
// Conversions.
|
||||
|
||||
func (v *projP2) FromP1xP1(p *projP1xP1) *projP2 {
|
||||
v.X.Multiply(&p.X, &p.T)
|
||||
v.Y.Multiply(&p.Y, &p.Z)
|
||||
v.Z.Multiply(&p.Z, &p.T)
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *projP2) FromP3(p *Point) *projP2 {
|
||||
v.X.Set(&p.x)
|
||||
v.Y.Set(&p.y)
|
||||
v.Z.Set(&p.z)
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *Point) fromP1xP1(p *projP1xP1) *Point {
|
||||
v.x.Multiply(&p.X, &p.T)
|
||||
v.y.Multiply(&p.Y, &p.Z)
|
||||
v.z.Multiply(&p.Z, &p.T)
|
||||
v.t.Multiply(&p.X, &p.Y)
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *Point) fromP2(p *projP2) *Point {
|
||||
v.x.Multiply(&p.X, &p.Z)
|
||||
v.y.Multiply(&p.Y, &p.Z)
|
||||
v.z.Square(&p.Z)
|
||||
v.t.Multiply(&p.X, &p.Y)
|
||||
return v
|
||||
}
|
||||
|
||||
// d is a constant in the curve equation.
|
||||
var d, _ = new(field.Element).SetBytes([]byte{
|
||||
0xa3, 0x78, 0x59, 0x13, 0xca, 0x4d, 0xeb, 0x75,
|
||||
0xab, 0xd8, 0x41, 0x41, 0x4d, 0x0a, 0x70, 0x00,
|
||||
0x98, 0xe8, 0x79, 0x77, 0x79, 0x40, 0xc7, 0x8c,
|
||||
0x73, 0xfe, 0x6f, 0x2b, 0xee, 0x6c, 0x03, 0x52})
|
||||
var d2 = new(field.Element).Add(d, d)
|
||||
|
||||
func (v *projCached) FromP3(p *Point) *projCached {
|
||||
v.YplusX.Add(&p.y, &p.x)
|
||||
v.YminusX.Subtract(&p.y, &p.x)
|
||||
v.Z.Set(&p.z)
|
||||
v.T2d.Multiply(&p.t, d2)
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *affineCached) FromP3(p *Point) *affineCached {
|
||||
v.YplusX.Add(&p.y, &p.x)
|
||||
v.YminusX.Subtract(&p.y, &p.x)
|
||||
v.T2d.Multiply(&p.t, d2)
|
||||
|
||||
var invZ field.Element
|
||||
invZ.Invert(&p.z)
|
||||
v.YplusX.Multiply(&v.YplusX, &invZ)
|
||||
v.YminusX.Multiply(&v.YminusX, &invZ)
|
||||
v.T2d.Multiply(&v.T2d, &invZ)
|
||||
return v
|
||||
}
|
||||
|
||||
// (Re)addition and subtraction.
|
||||
|
||||
// Add sets v = p + q, and returns v.
|
||||
func (v *Point) Add(p, q *Point) *Point {
|
||||
checkInitialized(p, q)
|
||||
qCached := new(projCached).FromP3(q)
|
||||
result := new(projP1xP1).Add(p, qCached)
|
||||
return v.fromP1xP1(result)
|
||||
}
|
||||
|
||||
// Subtract sets v = p - q, and returns v.
|
||||
func (v *Point) Subtract(p, q *Point) *Point {
|
||||
checkInitialized(p, q)
|
||||
qCached := new(projCached).FromP3(q)
|
||||
result := new(projP1xP1).Sub(p, qCached)
|
||||
return v.fromP1xP1(result)
|
||||
}
|
||||
|
||||
func (v *projP1xP1) Add(p *Point, q *projCached) *projP1xP1 {
|
||||
var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
|
||||
|
||||
YplusX.Add(&p.y, &p.x)
|
||||
YminusX.Subtract(&p.y, &p.x)
|
||||
|
||||
PP.Multiply(&YplusX, &q.YplusX)
|
||||
MM.Multiply(&YminusX, &q.YminusX)
|
||||
TT2d.Multiply(&p.t, &q.T2d)
|
||||
ZZ2.Multiply(&p.z, &q.Z)
|
||||
|
||||
ZZ2.Add(&ZZ2, &ZZ2)
|
||||
|
||||
v.X.Subtract(&PP, &MM)
|
||||
v.Y.Add(&PP, &MM)
|
||||
v.Z.Add(&ZZ2, &TT2d)
|
||||
v.T.Subtract(&ZZ2, &TT2d)
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *projP1xP1) Sub(p *Point, q *projCached) *projP1xP1 {
|
||||
var YplusX, YminusX, PP, MM, TT2d, ZZ2 field.Element
|
||||
|
||||
YplusX.Add(&p.y, &p.x)
|
||||
YminusX.Subtract(&p.y, &p.x)
|
||||
|
||||
PP.Multiply(&YplusX, &q.YminusX) // flipped sign
|
||||
MM.Multiply(&YminusX, &q.YplusX) // flipped sign
|
||||
TT2d.Multiply(&p.t, &q.T2d)
|
||||
ZZ2.Multiply(&p.z, &q.Z)
|
||||
|
||||
ZZ2.Add(&ZZ2, &ZZ2)
|
||||
|
||||
v.X.Subtract(&PP, &MM)
|
||||
v.Y.Add(&PP, &MM)
|
||||
v.Z.Subtract(&ZZ2, &TT2d) // flipped sign
|
||||
v.T.Add(&ZZ2, &TT2d) // flipped sign
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *projP1xP1) AddAffine(p *Point, q *affineCached) *projP1xP1 {
|
||||
var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
|
||||
|
||||
YplusX.Add(&p.y, &p.x)
|
||||
YminusX.Subtract(&p.y, &p.x)
|
||||
|
||||
PP.Multiply(&YplusX, &q.YplusX)
|
||||
MM.Multiply(&YminusX, &q.YminusX)
|
||||
TT2d.Multiply(&p.t, &q.T2d)
|
||||
|
||||
Z2.Add(&p.z, &p.z)
|
||||
|
||||
v.X.Subtract(&PP, &MM)
|
||||
v.Y.Add(&PP, &MM)
|
||||
v.Z.Add(&Z2, &TT2d)
|
||||
v.T.Subtract(&Z2, &TT2d)
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *projP1xP1) SubAffine(p *Point, q *affineCached) *projP1xP1 {
|
||||
var YplusX, YminusX, PP, MM, TT2d, Z2 field.Element
|
||||
|
||||
YplusX.Add(&p.y, &p.x)
|
||||
YminusX.Subtract(&p.y, &p.x)
|
||||
|
||||
PP.Multiply(&YplusX, &q.YminusX) // flipped sign
|
||||
MM.Multiply(&YminusX, &q.YplusX) // flipped sign
|
||||
TT2d.Multiply(&p.t, &q.T2d)
|
||||
|
||||
Z2.Add(&p.z, &p.z)
|
||||
|
||||
v.X.Subtract(&PP, &MM)
|
||||
v.Y.Add(&PP, &MM)
|
||||
v.Z.Subtract(&Z2, &TT2d) // flipped sign
|
||||
v.T.Add(&Z2, &TT2d) // flipped sign
|
||||
return v
|
||||
}
|
||||
|
||||
// Doubling.
|
||||
|
||||
func (v *projP1xP1) Double(p *projP2) *projP1xP1 {
|
||||
var XX, YY, ZZ2, XplusYsq field.Element
|
||||
|
||||
XX.Square(&p.X)
|
||||
YY.Square(&p.Y)
|
||||
ZZ2.Square(&p.Z)
|
||||
ZZ2.Add(&ZZ2, &ZZ2)
|
||||
XplusYsq.Add(&p.X, &p.Y)
|
||||
XplusYsq.Square(&XplusYsq)
|
||||
|
||||
v.Y.Add(&YY, &XX)
|
||||
v.Z.Subtract(&YY, &XX)
|
||||
|
||||
v.X.Subtract(&XplusYsq, &v.Y)
|
||||
v.T.Subtract(&ZZ2, &v.Z)
|
||||
return v
|
||||
}
|
||||
|
||||
// Negation.
|
||||
|
||||
// Negate sets v = -p, and returns v.
|
||||
func (v *Point) Negate(p *Point) *Point {
|
||||
checkInitialized(p)
|
||||
v.x.Negate(&p.x)
|
||||
v.y.Set(&p.y)
|
||||
v.z.Set(&p.z)
|
||||
v.t.Negate(&p.t)
|
||||
return v
|
||||
}
|
||||
|
||||
// Equal returns 1 if v is equivalent to u, and 0 otherwise.
|
||||
func (v *Point) Equal(u *Point) int {
|
||||
checkInitialized(v, u)
|
||||
|
||||
var t1, t2, t3, t4 field.Element
|
||||
t1.Multiply(&v.x, &u.z)
|
||||
t2.Multiply(&u.x, &v.z)
|
||||
t3.Multiply(&v.y, &u.z)
|
||||
t4.Multiply(&u.y, &v.z)
|
||||
|
||||
return t1.Equal(&t2) & t3.Equal(&t4)
|
||||
}
|
||||
|
||||
// Constant-time operations
|
||||
|
||||
// Select sets v to a if cond == 1 and to b if cond == 0.
|
||||
func (v *projCached) Select(a, b *projCached, cond int) *projCached {
|
||||
v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
|
||||
v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
|
||||
v.Z.Select(&a.Z, &b.Z, cond)
|
||||
v.T2d.Select(&a.T2d, &b.T2d, cond)
|
||||
return v
|
||||
}
|
||||
|
||||
// Select sets v to a if cond == 1 and to b if cond == 0.
|
||||
func (v *affineCached) Select(a, b *affineCached, cond int) *affineCached {
|
||||
v.YplusX.Select(&a.YplusX, &b.YplusX, cond)
|
||||
v.YminusX.Select(&a.YminusX, &b.YminusX, cond)
|
||||
v.T2d.Select(&a.T2d, &b.T2d, cond)
|
||||
return v
|
||||
}
|
||||
|
||||
// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
|
||||
func (v *projCached) CondNeg(cond int) *projCached {
|
||||
v.YplusX.Swap(&v.YminusX, cond)
|
||||
v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
|
||||
return v
|
||||
}
|
||||
|
||||
// CondNeg negates v if cond == 1 and leaves it unchanged if cond == 0.
|
||||
func (v *affineCached) CondNeg(cond int) *affineCached {
|
||||
v.YplusX.Swap(&v.YminusX, cond)
|
||||
v.T2d.Select(new(field.Element).Negate(&v.T2d), &v.T2d, cond)
|
||||
return v
|
||||
}
|
343
vendor/filippo.io/edwards25519/extra.go
generated
vendored
Normal file
343
vendor/filippo.io/edwards25519/extra.go
generated
vendored
Normal file
@@ -0,0 +1,343 @@
|
||||
// Copyright (c) 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.
|
||||
|
||||
package edwards25519
|
||||
|
||||
// This file contains additional functionality that is not included in the
|
||||
// upstream crypto/ed25519/internal/edwards25519 package.
|
||||
|
||||
import (
|
||||
"errors"
|
||||
|
||||
"filippo.io/edwards25519/field"
|
||||
)
|
||||
|
||||
// ExtendedCoordinates returns v in extended coordinates (X:Y:Z:T) where
|
||||
// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522.
|
||||
func (v *Point) ExtendedCoordinates() (X, Y, Z, T *field.Element) {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap. Don't change the style without making
|
||||
// sure it doesn't increase the inliner cost.
|
||||
var e [4]field.Element
|
||||
X, Y, Z, T = v.extendedCoordinates(&e)
|
||||
return
|
||||
}
|
||||
|
||||
func (v *Point) extendedCoordinates(e *[4]field.Element) (X, Y, Z, T *field.Element) {
|
||||
checkInitialized(v)
|
||||
X = e[0].Set(&v.x)
|
||||
Y = e[1].Set(&v.y)
|
||||
Z = e[2].Set(&v.z)
|
||||
T = e[3].Set(&v.t)
|
||||
return
|
||||
}
|
||||
|
||||
// SetExtendedCoordinates sets v = (X:Y:Z:T) in extended coordinates where
|
||||
// x = X/Z, y = Y/Z, and xy = T/Z as in https://eprint.iacr.org/2008/522.
|
||||
//
|
||||
// If the coordinates are invalid or don't represent a valid point on the curve,
|
||||
// SetExtendedCoordinates returns nil and an error and the receiver is
|
||||
// unchanged. Otherwise, SetExtendedCoordinates returns v.
|
||||
func (v *Point) SetExtendedCoordinates(X, Y, Z, T *field.Element) (*Point, error) {
|
||||
if !isOnCurve(X, Y, Z, T) {
|
||||
return nil, errors.New("edwards25519: invalid point coordinates")
|
||||
}
|
||||
v.x.Set(X)
|
||||
v.y.Set(Y)
|
||||
v.z.Set(Z)
|
||||
v.t.Set(T)
|
||||
return v, nil
|
||||
}
|
||||
|
||||
func isOnCurve(X, Y, Z, T *field.Element) bool {
|
||||
var lhs, rhs field.Element
|
||||
XX := new(field.Element).Square(X)
|
||||
YY := new(field.Element).Square(Y)
|
||||
ZZ := new(field.Element).Square(Z)
|
||||
TT := new(field.Element).Square(T)
|
||||
// -x² + y² = 1 + dx²y²
|
||||
// -(X/Z)² + (Y/Z)² = 1 + d(T/Z)²
|
||||
// -X² + Y² = Z² + dT²
|
||||
lhs.Subtract(YY, XX)
|
||||
rhs.Multiply(d, TT).Add(&rhs, ZZ)
|
||||
if lhs.Equal(&rhs) != 1 {
|
||||
return false
|
||||
}
|
||||
// xy = T/Z
|
||||
// XY/Z² = T/Z
|
||||
// XY = TZ
|
||||
lhs.Multiply(X, Y)
|
||||
rhs.Multiply(T, Z)
|
||||
return lhs.Equal(&rhs) == 1
|
||||
}
|
||||
|
||||
// BytesMontgomery converts v to a point on the birationally-equivalent
|
||||
// Curve25519 Montgomery curve, and returns its canonical 32 bytes encoding
|
||||
// according to RFC 7748.
|
||||
//
|
||||
// Note that BytesMontgomery only encodes the u-coordinate, so v and -v encode
|
||||
// to the same value. If v is the identity point, BytesMontgomery returns 32
|
||||
// zero bytes, analogously to the X25519 function.
|
||||
func (v *Point) BytesMontgomery() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var buf [32]byte
|
||||
return v.bytesMontgomery(&buf)
|
||||
}
|
||||
|
||||
func (v *Point) bytesMontgomery(buf *[32]byte) []byte {
|
||||
checkInitialized(v)
|
||||
|
||||
// RFC 7748, Section 4.1 provides the bilinear map to calculate the
|
||||
// Montgomery u-coordinate
|
||||
//
|
||||
// u = (1 + y) / (1 - y)
|
||||
//
|
||||
// where y = Y / Z.
|
||||
|
||||
var y, recip, u field.Element
|
||||
|
||||
y.Multiply(&v.y, y.Invert(&v.z)) // y = Y / Z
|
||||
recip.Invert(recip.Subtract(feOne, &y)) // r = 1/(1 - y)
|
||||
u.Multiply(u.Add(feOne, &y), &recip) // u = (1 + y)*r
|
||||
|
||||
return copyFieldElement(buf, &u)
|
||||
}
|
||||
|
||||
// MultByCofactor sets v = 8 * p, and returns v.
|
||||
func (v *Point) MultByCofactor(p *Point) *Point {
|
||||
checkInitialized(p)
|
||||
result := projP1xP1{}
|
||||
pp := (&projP2{}).FromP3(p)
|
||||
result.Double(pp)
|
||||
pp.FromP1xP1(&result)
|
||||
result.Double(pp)
|
||||
pp.FromP1xP1(&result)
|
||||
result.Double(pp)
|
||||
return v.fromP1xP1(&result)
|
||||
}
|
||||
|
||||
// Given k > 0, set s = s**(2*i).
|
||||
func (s *Scalar) pow2k(k int) {
|
||||
for i := 0; i < k; i++ {
|
||||
s.Multiply(s, s)
|
||||
}
|
||||
}
|
||||
|
||||
// Invert sets s to the inverse of a nonzero scalar v, and returns s.
|
||||
//
|
||||
// If t is zero, Invert returns zero.
|
||||
func (s *Scalar) Invert(t *Scalar) *Scalar {
|
||||
// Uses a hardcoded sliding window of width 4.
|
||||
var table [8]Scalar
|
||||
var tt Scalar
|
||||
tt.Multiply(t, t)
|
||||
table[0] = *t
|
||||
for i := 0; i < 7; i++ {
|
||||
table[i+1].Multiply(&table[i], &tt)
|
||||
}
|
||||
// Now table = [t**1, t**3, t**7, t**11, t**13, t**15]
|
||||
// so t**k = t[k/2] for odd k
|
||||
|
||||
// To compute the sliding window digits, use the following Sage script:
|
||||
|
||||
// sage: import itertools
|
||||
// sage: def sliding_window(w,k):
|
||||
// ....: digits = []
|
||||
// ....: while k > 0:
|
||||
// ....: if k % 2 == 1:
|
||||
// ....: kmod = k % (2**w)
|
||||
// ....: digits.append(kmod)
|
||||
// ....: k = k - kmod
|
||||
// ....: else:
|
||||
// ....: digits.append(0)
|
||||
// ....: k = k // 2
|
||||
// ....: return digits
|
||||
|
||||
// Now we can compute s roughly as follows:
|
||||
|
||||
// sage: s = 1
|
||||
// sage: for coeff in reversed(sliding_window(4,l-2)):
|
||||
// ....: s = s*s
|
||||
// ....: if coeff > 0 :
|
||||
// ....: s = s*t**coeff
|
||||
|
||||
// This works on one bit at a time, with many runs of zeros.
|
||||
// The digits can be collapsed into [(count, coeff)] as follows:
|
||||
|
||||
// sage: [(len(list(group)),d) for d,group in itertools.groupby(sliding_window(4,l-2))]
|
||||
|
||||
// Entries of the form (k, 0) turn into pow2k(k)
|
||||
// Entries of the form (1, coeff) turn into a squaring and then a table lookup.
|
||||
// We can fold the squaring into the previous pow2k(k) as pow2k(k+1).
|
||||
|
||||
*s = table[1/2]
|
||||
s.pow2k(127 + 1)
|
||||
s.Multiply(s, &table[1/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[9/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[11/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[13/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[15/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[7/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[15/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[5/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[1/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[15/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[15/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[7/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[3/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[11/2])
|
||||
s.pow2k(5 + 1)
|
||||
s.Multiply(s, &table[11/2])
|
||||
s.pow2k(9 + 1)
|
||||
s.Multiply(s, &table[9/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[3/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[3/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[3/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[9/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[7/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[3/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[13/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[7/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[9/2])
|
||||
s.pow2k(3 + 1)
|
||||
s.Multiply(s, &table[15/2])
|
||||
s.pow2k(4 + 1)
|
||||
s.Multiply(s, &table[11/2])
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// MultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v.
|
||||
//
|
||||
// Execution time depends only on the lengths of the two slices, which must match.
|
||||
func (v *Point) MultiScalarMult(scalars []*Scalar, points []*Point) *Point {
|
||||
if len(scalars) != len(points) {
|
||||
panic("edwards25519: called MultiScalarMult with different size inputs")
|
||||
}
|
||||
checkInitialized(points...)
|
||||
|
||||
// Proceed as in the single-base case, but share doublings
|
||||
// between each point in the multiscalar equation.
|
||||
|
||||
// Build lookup tables for each point
|
||||
tables := make([]projLookupTable, len(points))
|
||||
for i := range tables {
|
||||
tables[i].FromP3(points[i])
|
||||
}
|
||||
// Compute signed radix-16 digits for each scalar
|
||||
digits := make([][64]int8, len(scalars))
|
||||
for i := range digits {
|
||||
digits[i] = scalars[i].signedRadix16()
|
||||
}
|
||||
|
||||
// Unwrap first loop iteration to save computing 16*identity
|
||||
multiple := &projCached{}
|
||||
tmp1 := &projP1xP1{}
|
||||
tmp2 := &projP2{}
|
||||
// Lookup-and-add the appropriate multiple of each input point
|
||||
for j := range tables {
|
||||
tables[j].SelectInto(multiple, digits[j][63])
|
||||
tmp1.Add(v, multiple) // tmp1 = v + x_(j,63)*Q in P1xP1 coords
|
||||
v.fromP1xP1(tmp1) // update v
|
||||
}
|
||||
tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration
|
||||
for i := 62; i >= 0; i-- {
|
||||
tmp1.Double(tmp2) // tmp1 = 2*(prev) in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 2*(prev) in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 4*(prev) in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 4*(prev) in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 8*(prev) in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 8*(prev) in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 16*(prev) in P1xP1 coords
|
||||
v.fromP1xP1(tmp1) // v = 16*(prev) in P3 coords
|
||||
// Lookup-and-add the appropriate multiple of each input point
|
||||
for j := range tables {
|
||||
tables[j].SelectInto(multiple, digits[j][i])
|
||||
tmp1.Add(v, multiple) // tmp1 = v + x_(j,i)*Q in P1xP1 coords
|
||||
v.fromP1xP1(tmp1) // update v
|
||||
}
|
||||
tmp2.FromP3(v) // set up tmp2 = v in P2 coords for next iteration
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// VarTimeMultiScalarMult sets v = sum(scalars[i] * points[i]), and returns v.
|
||||
//
|
||||
// Execution time depends on the inputs.
|
||||
func (v *Point) VarTimeMultiScalarMult(scalars []*Scalar, points []*Point) *Point {
|
||||
if len(scalars) != len(points) {
|
||||
panic("edwards25519: called VarTimeMultiScalarMult with different size inputs")
|
||||
}
|
||||
checkInitialized(points...)
|
||||
|
||||
// Generalize double-base NAF computation to arbitrary sizes.
|
||||
// Here all the points are dynamic, so we only use the smaller
|
||||
// tables.
|
||||
|
||||
// Build lookup tables for each point
|
||||
tables := make([]nafLookupTable5, len(points))
|
||||
for i := range tables {
|
||||
tables[i].FromP3(points[i])
|
||||
}
|
||||
// Compute a NAF for each scalar
|
||||
nafs := make([][256]int8, len(scalars))
|
||||
for i := range nafs {
|
||||
nafs[i] = scalars[i].nonAdjacentForm(5)
|
||||
}
|
||||
|
||||
multiple := &projCached{}
|
||||
tmp1 := &projP1xP1{}
|
||||
tmp2 := &projP2{}
|
||||
tmp2.Zero()
|
||||
|
||||
// Move from high to low bits, doubling the accumulator
|
||||
// at each iteration and checking whether there is a nonzero
|
||||
// coefficient to look up a multiple of.
|
||||
//
|
||||
// Skip trying to find the first nonzero coefficent, because
|
||||
// searching might be more work than a few extra doublings.
|
||||
for i := 255; i >= 0; i-- {
|
||||
tmp1.Double(tmp2)
|
||||
|
||||
for j := range nafs {
|
||||
if nafs[j][i] > 0 {
|
||||
v.fromP1xP1(tmp1)
|
||||
tables[j].SelectInto(multiple, nafs[j][i])
|
||||
tmp1.Add(v, multiple)
|
||||
} else if nafs[j][i] < 0 {
|
||||
v.fromP1xP1(tmp1)
|
||||
tables[j].SelectInto(multiple, -nafs[j][i])
|
||||
tmp1.Sub(v, multiple)
|
||||
}
|
||||
}
|
||||
|
||||
tmp2.FromP1xP1(tmp1)
|
||||
}
|
||||
|
||||
v.fromP2(tmp2)
|
||||
return v
|
||||
}
|
419
vendor/filippo.io/edwards25519/field/fe.go
generated
vendored
Normal file
419
vendor/filippo.io/edwards25519/field/fe.go
generated
vendored
Normal file
@@ -0,0 +1,419 @@
|
||||
// Copyright (c) 2017 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.
|
||||
|
||||
// Package field implements fast arithmetic modulo 2^255-19.
|
||||
package field
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"math/bits"
|
||||
)
|
||||
|
||||
// Element represents an element of the field GF(2^255-19). Note that this
|
||||
// is not a cryptographically secure group, and should only be used to interact
|
||||
// with edwards25519.Point coordinates.
|
||||
//
|
||||
// This type works similarly to math/big.Int, and all arguments and receivers
|
||||
// are allowed to alias.
|
||||
//
|
||||
// The zero value is a valid zero element.
|
||||
type Element struct {
|
||||
// An element t represents the integer
|
||||
// t.l0 + t.l1*2^51 + t.l2*2^102 + t.l3*2^153 + t.l4*2^204
|
||||
//
|
||||
// Between operations, all limbs are expected to be lower than 2^52.
|
||||
l0 uint64
|
||||
l1 uint64
|
||||
l2 uint64
|
||||
l3 uint64
|
||||
l4 uint64
|
||||
}
|
||||
|
||||
const maskLow51Bits uint64 = (1 << 51) - 1
|
||||
|
||||
var feZero = &Element{0, 0, 0, 0, 0}
|
||||
|
||||
// Zero sets v = 0, and returns v.
|
||||
func (v *Element) Zero() *Element {
|
||||
*v = *feZero
|
||||
return v
|
||||
}
|
||||
|
||||
var feOne = &Element{1, 0, 0, 0, 0}
|
||||
|
||||
// One sets v = 1, and returns v.
|
||||
func (v *Element) One() *Element {
|
||||
*v = *feOne
|
||||
return v
|
||||
}
|
||||
|
||||
// reduce reduces v modulo 2^255 - 19 and returns it.
|
||||
func (v *Element) reduce() *Element {
|
||||
v.carryPropagate()
|
||||
|
||||
// After the light reduction we now have a field element representation
|
||||
// v < 2^255 + 2^13 * 19, but need v < 2^255 - 19.
|
||||
|
||||
// If v >= 2^255 - 19, then v + 19 >= 2^255, which would overflow 2^255 - 1,
|
||||
// generating a carry. That is, c will be 0 if v < 2^255 - 19, and 1 otherwise.
|
||||
c := (v.l0 + 19) >> 51
|
||||
c = (v.l1 + c) >> 51
|
||||
c = (v.l2 + c) >> 51
|
||||
c = (v.l3 + c) >> 51
|
||||
c = (v.l4 + c) >> 51
|
||||
|
||||
// If v < 2^255 - 19 and c = 0, this will be a no-op. Otherwise, it's
|
||||
// effectively applying the reduction identity to the carry.
|
||||
v.l0 += 19 * c
|
||||
|
||||
v.l1 += v.l0 >> 51
|
||||
v.l0 = v.l0 & maskLow51Bits
|
||||
v.l2 += v.l1 >> 51
|
||||
v.l1 = v.l1 & maskLow51Bits
|
||||
v.l3 += v.l2 >> 51
|
||||
v.l2 = v.l2 & maskLow51Bits
|
||||
v.l4 += v.l3 >> 51
|
||||
v.l3 = v.l3 & maskLow51Bits
|
||||
// no additional carry
|
||||
v.l4 = v.l4 & maskLow51Bits
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Add sets v = a + b, and returns v.
|
||||
func (v *Element) Add(a, b *Element) *Element {
|
||||
v.l0 = a.l0 + b.l0
|
||||
v.l1 = a.l1 + b.l1
|
||||
v.l2 = a.l2 + b.l2
|
||||
v.l3 = a.l3 + b.l3
|
||||
v.l4 = a.l4 + b.l4
|
||||
// Using the generic implementation here is actually faster than the
|
||||
// assembly. Probably because the body of this function is so simple that
|
||||
// the compiler can figure out better optimizations by inlining the carry
|
||||
// propagation.
|
||||
return v.carryPropagateGeneric()
|
||||
}
|
||||
|
||||
// Subtract sets v = a - b, and returns v.
|
||||
func (v *Element) Subtract(a, b *Element) *Element {
|
||||
// We first add 2 * p, to guarantee the subtraction won't underflow, and
|
||||
// then subtract b (which can be up to 2^255 + 2^13 * 19).
|
||||
v.l0 = (a.l0 + 0xFFFFFFFFFFFDA) - b.l0
|
||||
v.l1 = (a.l1 + 0xFFFFFFFFFFFFE) - b.l1
|
||||
v.l2 = (a.l2 + 0xFFFFFFFFFFFFE) - b.l2
|
||||
v.l3 = (a.l3 + 0xFFFFFFFFFFFFE) - b.l3
|
||||
v.l4 = (a.l4 + 0xFFFFFFFFFFFFE) - b.l4
|
||||
return v.carryPropagate()
|
||||
}
|
||||
|
||||
// Negate sets v = -a, and returns v.
|
||||
func (v *Element) Negate(a *Element) *Element {
|
||||
return v.Subtract(feZero, a)
|
||||
}
|
||||
|
||||
// Invert sets v = 1/z mod p, and returns v.
|
||||
//
|
||||
// If z == 0, Invert returns v = 0.
|
||||
func (v *Element) Invert(z *Element) *Element {
|
||||
// Inversion is implemented as exponentiation with exponent p − 2. It uses the
|
||||
// same sequence of 255 squarings and 11 multiplications as [Curve25519].
|
||||
var z2, z9, z11, z2_5_0, z2_10_0, z2_20_0, z2_50_0, z2_100_0, t Element
|
||||
|
||||
z2.Square(z) // 2
|
||||
t.Square(&z2) // 4
|
||||
t.Square(&t) // 8
|
||||
z9.Multiply(&t, z) // 9
|
||||
z11.Multiply(&z9, &z2) // 11
|
||||
t.Square(&z11) // 22
|
||||
z2_5_0.Multiply(&t, &z9) // 31 = 2^5 - 2^0
|
||||
|
||||
t.Square(&z2_5_0) // 2^6 - 2^1
|
||||
for i := 0; i < 4; i++ {
|
||||
t.Square(&t) // 2^10 - 2^5
|
||||
}
|
||||
z2_10_0.Multiply(&t, &z2_5_0) // 2^10 - 2^0
|
||||
|
||||
t.Square(&z2_10_0) // 2^11 - 2^1
|
||||
for i := 0; i < 9; i++ {
|
||||
t.Square(&t) // 2^20 - 2^10
|
||||
}
|
||||
z2_20_0.Multiply(&t, &z2_10_0) // 2^20 - 2^0
|
||||
|
||||
t.Square(&z2_20_0) // 2^21 - 2^1
|
||||
for i := 0; i < 19; i++ {
|
||||
t.Square(&t) // 2^40 - 2^20
|
||||
}
|
||||
t.Multiply(&t, &z2_20_0) // 2^40 - 2^0
|
||||
|
||||
t.Square(&t) // 2^41 - 2^1
|
||||
for i := 0; i < 9; i++ {
|
||||
t.Square(&t) // 2^50 - 2^10
|
||||
}
|
||||
z2_50_0.Multiply(&t, &z2_10_0) // 2^50 - 2^0
|
||||
|
||||
t.Square(&z2_50_0) // 2^51 - 2^1
|
||||
for i := 0; i < 49; i++ {
|
||||
t.Square(&t) // 2^100 - 2^50
|
||||
}
|
||||
z2_100_0.Multiply(&t, &z2_50_0) // 2^100 - 2^0
|
||||
|
||||
t.Square(&z2_100_0) // 2^101 - 2^1
|
||||
for i := 0; i < 99; i++ {
|
||||
t.Square(&t) // 2^200 - 2^100
|
||||
}
|
||||
t.Multiply(&t, &z2_100_0) // 2^200 - 2^0
|
||||
|
||||
t.Square(&t) // 2^201 - 2^1
|
||||
for i := 0; i < 49; i++ {
|
||||
t.Square(&t) // 2^250 - 2^50
|
||||
}
|
||||
t.Multiply(&t, &z2_50_0) // 2^250 - 2^0
|
||||
|
||||
t.Square(&t) // 2^251 - 2^1
|
||||
t.Square(&t) // 2^252 - 2^2
|
||||
t.Square(&t) // 2^253 - 2^3
|
||||
t.Square(&t) // 2^254 - 2^4
|
||||
t.Square(&t) // 2^255 - 2^5
|
||||
|
||||
return v.Multiply(&t, &z11) // 2^255 - 21
|
||||
}
|
||||
|
||||
// Set sets v = a, and returns v.
|
||||
func (v *Element) Set(a *Element) *Element {
|
||||
*v = *a
|
||||
return v
|
||||
}
|
||||
|
||||
// SetBytes sets v to x, where x is a 32-byte little-endian encoding. If x is
|
||||
// not of the right length, SetUniformBytes returns nil and an error, and the
|
||||
// receiver is unchanged.
|
||||
//
|
||||
// Consistent with RFC 7748, the most significant bit (the high bit of the
|
||||
// last byte) is ignored, and non-canonical values (2^255-19 through 2^255-1)
|
||||
// are accepted. Note that this is laxer than specified by RFC 8032.
|
||||
func (v *Element) SetBytes(x []byte) (*Element, error) {
|
||||
if len(x) != 32 {
|
||||
return nil, errors.New("edwards25519: invalid field element input size")
|
||||
}
|
||||
|
||||
// Bits 0:51 (bytes 0:8, bits 0:64, shift 0, mask 51).
|
||||
v.l0 = binary.LittleEndian.Uint64(x[0:8])
|
||||
v.l0 &= maskLow51Bits
|
||||
// Bits 51:102 (bytes 6:14, bits 48:112, shift 3, mask 51).
|
||||
v.l1 = binary.LittleEndian.Uint64(x[6:14]) >> 3
|
||||
v.l1 &= maskLow51Bits
|
||||
// Bits 102:153 (bytes 12:20, bits 96:160, shift 6, mask 51).
|
||||
v.l2 = binary.LittleEndian.Uint64(x[12:20]) >> 6
|
||||
v.l2 &= maskLow51Bits
|
||||
// Bits 153:204 (bytes 19:27, bits 152:216, shift 1, mask 51).
|
||||
v.l3 = binary.LittleEndian.Uint64(x[19:27]) >> 1
|
||||
v.l3 &= maskLow51Bits
|
||||
// Bits 204:251 (bytes 24:32, bits 192:256, shift 12, mask 51).
|
||||
// Note: not bytes 25:33, shift 4, to avoid overread.
|
||||
v.l4 = binary.LittleEndian.Uint64(x[24:32]) >> 12
|
||||
v.l4 &= maskLow51Bits
|
||||
|
||||
return v, nil
|
||||
}
|
||||
|
||||
// Bytes returns the canonical 32-byte little-endian encoding of v.
|
||||
func (v *Element) Bytes() []byte {
|
||||
// This function is outlined to make the allocations inline in the caller
|
||||
// rather than happen on the heap.
|
||||
var out [32]byte
|
||||
return v.bytes(&out)
|
||||
}
|
||||
|
||||
func (v *Element) bytes(out *[32]byte) []byte {
|
||||
t := *v
|
||||
t.reduce()
|
||||
|
||||
var buf [8]byte
|
||||
for i, l := range [5]uint64{t.l0, t.l1, t.l2, t.l3, t.l4} {
|
||||
bitsOffset := i * 51
|
||||
binary.LittleEndian.PutUint64(buf[:], l<<uint(bitsOffset%8))
|
||||
for i, bb := range buf {
|
||||
off := bitsOffset/8 + i
|
||||
if off >= len(out) {
|
||||
break
|
||||
}
|
||||
out[off] |= bb
|
||||
}
|
||||
}
|
||||
|
||||
return out[:]
|
||||
}
|
||||
|
||||
// Equal returns 1 if v and u are equal, and 0 otherwise.
|
||||
func (v *Element) Equal(u *Element) int {
|
||||
sa, sv := u.Bytes(), v.Bytes()
|
||||
return subtle.ConstantTimeCompare(sa, sv)
|
||||
}
|
||||
|
||||
// mask64Bits returns 0xffffffff if cond is 1, and 0 otherwise.
|
||||
func mask64Bits(cond int) uint64 { return ^(uint64(cond) - 1) }
|
||||
|
||||
// Select sets v to a if cond == 1, and to b if cond == 0.
|
||||
func (v *Element) Select(a, b *Element, cond int) *Element {
|
||||
m := mask64Bits(cond)
|
||||
v.l0 = (m & a.l0) | (^m & b.l0)
|
||||
v.l1 = (m & a.l1) | (^m & b.l1)
|
||||
v.l2 = (m & a.l2) | (^m & b.l2)
|
||||
v.l3 = (m & a.l3) | (^m & b.l3)
|
||||
v.l4 = (m & a.l4) | (^m & b.l4)
|
||||
return v
|
||||
}
|
||||
|
||||
// Swap swaps v and u if cond == 1 or leaves them unchanged if cond == 0, and returns v.
|
||||
func (v *Element) Swap(u *Element, cond int) {
|
||||
m := mask64Bits(cond)
|
||||
t := m & (v.l0 ^ u.l0)
|
||||
v.l0 ^= t
|
||||
u.l0 ^= t
|
||||
t = m & (v.l1 ^ u.l1)
|
||||
v.l1 ^= t
|
||||
u.l1 ^= t
|
||||
t = m & (v.l2 ^ u.l2)
|
||||
v.l2 ^= t
|
||||
u.l2 ^= t
|
||||
t = m & (v.l3 ^ u.l3)
|
||||
v.l3 ^= t
|
||||
u.l3 ^= t
|
||||
t = m & (v.l4 ^ u.l4)
|
||||
v.l4 ^= t
|
||||
u.l4 ^= t
|
||||
}
|
||||
|
||||
// IsNegative returns 1 if v is negative, and 0 otherwise.
|
||||
func (v *Element) IsNegative() int {
|
||||
return int(v.Bytes()[0] & 1)
|
||||
}
|
||||
|
||||
// Absolute sets v to |u|, and returns v.
|
||||
func (v *Element) Absolute(u *Element) *Element {
|
||||
return v.Select(new(Element).Negate(u), u, u.IsNegative())
|
||||
}
|
||||
|
||||
// Multiply sets v = x * y, and returns v.
|
||||
func (v *Element) Multiply(x, y *Element) *Element {
|
||||
feMul(v, x, y)
|
||||
return v
|
||||
}
|
||||
|
||||
// Square sets v = x * x, and returns v.
|
||||
func (v *Element) Square(x *Element) *Element {
|
||||
feSquare(v, x)
|
||||
return v
|
||||
}
|
||||
|
||||
// Mult32 sets v = x * y, and returns v.
|
||||
func (v *Element) Mult32(x *Element, y uint32) *Element {
|
||||
x0lo, x0hi := mul51(x.l0, y)
|
||||
x1lo, x1hi := mul51(x.l1, y)
|
||||
x2lo, x2hi := mul51(x.l2, y)
|
||||
x3lo, x3hi := mul51(x.l3, y)
|
||||
x4lo, x4hi := mul51(x.l4, y)
|
||||
v.l0 = x0lo + 19*x4hi // carried over per the reduction identity
|
||||
v.l1 = x1lo + x0hi
|
||||
v.l2 = x2lo + x1hi
|
||||
v.l3 = x3lo + x2hi
|
||||
v.l4 = x4lo + x3hi
|
||||
// The hi portions are going to be only 32 bits, plus any previous excess,
|
||||
// so we can skip the carry propagation.
|
||||
return v
|
||||
}
|
||||
|
||||
// mul51 returns lo + hi * 2⁵¹ = a * b.
|
||||
func mul51(a uint64, b uint32) (lo uint64, hi uint64) {
|
||||
mh, ml := bits.Mul64(a, uint64(b))
|
||||
lo = ml & maskLow51Bits
|
||||
hi = (mh << 13) | (ml >> 51)
|
||||
return
|
||||
}
|
||||
|
||||
// Pow22523 set v = x^((p-5)/8), and returns v. (p-5)/8 is 2^252-3.
|
||||
func (v *Element) Pow22523(x *Element) *Element {
|
||||
var t0, t1, t2 Element
|
||||
|
||||
t0.Square(x) // x^2
|
||||
t1.Square(&t0) // x^4
|
||||
t1.Square(&t1) // x^8
|
||||
t1.Multiply(x, &t1) // x^9
|
||||
t0.Multiply(&t0, &t1) // x^11
|
||||
t0.Square(&t0) // x^22
|
||||
t0.Multiply(&t1, &t0) // x^31
|
||||
t1.Square(&t0) // x^62
|
||||
for i := 1; i < 5; i++ { // x^992
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t0.Multiply(&t1, &t0) // x^1023 -> 1023 = 2^10 - 1
|
||||
t1.Square(&t0) // 2^11 - 2
|
||||
for i := 1; i < 10; i++ { // 2^20 - 2^10
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t1.Multiply(&t1, &t0) // 2^20 - 1
|
||||
t2.Square(&t1) // 2^21 - 2
|
||||
for i := 1; i < 20; i++ { // 2^40 - 2^20
|
||||
t2.Square(&t2)
|
||||
}
|
||||
t1.Multiply(&t2, &t1) // 2^40 - 1
|
||||
t1.Square(&t1) // 2^41 - 2
|
||||
for i := 1; i < 10; i++ { // 2^50 - 2^10
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t0.Multiply(&t1, &t0) // 2^50 - 1
|
||||
t1.Square(&t0) // 2^51 - 2
|
||||
for i := 1; i < 50; i++ { // 2^100 - 2^50
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t1.Multiply(&t1, &t0) // 2^100 - 1
|
||||
t2.Square(&t1) // 2^101 - 2
|
||||
for i := 1; i < 100; i++ { // 2^200 - 2^100
|
||||
t2.Square(&t2)
|
||||
}
|
||||
t1.Multiply(&t2, &t1) // 2^200 - 1
|
||||
t1.Square(&t1) // 2^201 - 2
|
||||
for i := 1; i < 50; i++ { // 2^250 - 2^50
|
||||
t1.Square(&t1)
|
||||
}
|
||||
t0.Multiply(&t1, &t0) // 2^250 - 1
|
||||
t0.Square(&t0) // 2^251 - 2
|
||||
t0.Square(&t0) // 2^252 - 4
|
||||
return v.Multiply(&t0, x) // 2^252 - 3 -> x^(2^252-3)
|
||||
}
|
||||
|
||||
// sqrtM1 is 2^((p-1)/4), which squared is equal to -1 by Euler's Criterion.
|
||||
var sqrtM1 = &Element{1718705420411056, 234908883556509,
|
||||
2233514472574048, 2117202627021982, 765476049583133}
|
||||
|
||||
// SqrtRatio sets r to the non-negative square root of the ratio of u and v.
|
||||
//
|
||||
// If u/v is square, SqrtRatio returns r and 1. If u/v is not square, SqrtRatio
|
||||
// sets r according to Section 4.3 of draft-irtf-cfrg-ristretto255-decaf448-00,
|
||||
// and returns r and 0.
|
||||
func (r *Element) SqrtRatio(u, v *Element) (rr *Element, wasSquare int) {
|
||||
var a, b Element
|
||||
|
||||
// r = (u * v3) * (u * v7)^((p-5)/8)
|
||||
v2 := a.Square(v)
|
||||
uv3 := b.Multiply(u, b.Multiply(v2, v))
|
||||
uv7 := a.Multiply(uv3, a.Square(v2))
|
||||
r.Multiply(uv3, r.Pow22523(uv7))
|
||||
|
||||
check := a.Multiply(v, a.Square(r)) // check = v * r^2
|
||||
|
||||
uNeg := b.Negate(u)
|
||||
correctSignSqrt := check.Equal(u)
|
||||
flippedSignSqrt := check.Equal(uNeg)
|
||||
flippedSignSqrtI := check.Equal(uNeg.Multiply(uNeg, sqrtM1))
|
||||
|
||||
rPrime := b.Multiply(r, sqrtM1) // r_prime = SQRT_M1 * r
|
||||
// r = CT_SELECT(r_prime IF flipped_sign_sqrt | flipped_sign_sqrt_i ELSE r)
|
||||
r.Select(rPrime, r, flippedSignSqrt|flippedSignSqrtI)
|
||||
|
||||
r.Absolute(r) // Choose the nonnegative square root.
|
||||
return r, correctSignSqrt | flippedSignSqrt
|
||||
}
|
13
vendor/filippo.io/edwards25519/field/fe_amd64.go
generated
vendored
Normal file
13
vendor/filippo.io/edwards25519/field/fe_amd64.go
generated
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
||||
|
||||
// +build amd64,gc,!purego
|
||||
|
||||
package field
|
||||
|
||||
// feMul sets out = a * b. It works like feMulGeneric.
|
||||
//go:noescape
|
||||
func feMul(out *Element, a *Element, b *Element)
|
||||
|
||||
// feSquare sets out = a * a. It works like feSquareGeneric.
|
||||
//go:noescape
|
||||
func feSquare(out *Element, a *Element)
|
378
vendor/filippo.io/edwards25519/field/fe_amd64.s
generated
vendored
Normal file
378
vendor/filippo.io/edwards25519/field/fe_amd64.s
generated
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
// Code generated by command: go run fe_amd64_asm.go -out ../fe_amd64.s -stubs ../fe_amd64.go -pkg field. DO NOT EDIT.
|
||||
|
||||
// +build amd64,gc,!purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// func feMul(out *Element, a *Element, b *Element)
|
||||
TEXT ·feMul(SB), NOSPLIT, $0-24
|
||||
MOVQ a+8(FP), CX
|
||||
MOVQ b+16(FP), BX
|
||||
|
||||
// r0 = a0×b0
|
||||
MOVQ (CX), AX
|
||||
MULQ (BX)
|
||||
MOVQ AX, DI
|
||||
MOVQ DX, SI
|
||||
|
||||
// r0 += 19×a1×b4
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r0 += 19×a2×b3
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r0 += 19×a3×b2
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r0 += 19×a4×b1
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, DI
|
||||
ADCQ DX, SI
|
||||
|
||||
// r1 = a0×b1
|
||||
MOVQ (CX), AX
|
||||
MULQ 8(BX)
|
||||
MOVQ AX, R9
|
||||
MOVQ DX, R8
|
||||
|
||||
// r1 += a1×b0
|
||||
MOVQ 8(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r1 += 19×a2×b4
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r1 += 19×a3×b3
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r1 += 19×a4×b2
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, R9
|
||||
ADCQ DX, R8
|
||||
|
||||
// r2 = a0×b2
|
||||
MOVQ (CX), AX
|
||||
MULQ 16(BX)
|
||||
MOVQ AX, R11
|
||||
MOVQ DX, R10
|
||||
|
||||
// r2 += a1×b1
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r2 += a2×b0
|
||||
MOVQ 16(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r2 += 19×a3×b4
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r2 += 19×a4×b3
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, R11
|
||||
ADCQ DX, R10
|
||||
|
||||
// r3 = a0×b3
|
||||
MOVQ (CX), AX
|
||||
MULQ 24(BX)
|
||||
MOVQ AX, R13
|
||||
MOVQ DX, R12
|
||||
|
||||
// r3 += a1×b2
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r3 += a2×b1
|
||||
MOVQ 16(CX), AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r3 += a3×b0
|
||||
MOVQ 24(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r3 += 19×a4×b4
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(BX)
|
||||
ADDQ AX, R13
|
||||
ADCQ DX, R12
|
||||
|
||||
// r4 = a0×b4
|
||||
MOVQ (CX), AX
|
||||
MULQ 32(BX)
|
||||
MOVQ AX, R15
|
||||
MOVQ DX, R14
|
||||
|
||||
// r4 += a1×b3
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 24(BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// r4 += a2×b2
|
||||
MOVQ 16(CX), AX
|
||||
MULQ 16(BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// r4 += a3×b1
|
||||
MOVQ 24(CX), AX
|
||||
MULQ 8(BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// r4 += a4×b0
|
||||
MOVQ 32(CX), AX
|
||||
MULQ (BX)
|
||||
ADDQ AX, R15
|
||||
ADCQ DX, R14
|
||||
|
||||
// First reduction chain
|
||||
MOVQ $0x0007ffffffffffff, AX
|
||||
SHLQ $0x0d, DI, SI
|
||||
SHLQ $0x0d, R9, R8
|
||||
SHLQ $0x0d, R11, R10
|
||||
SHLQ $0x0d, R13, R12
|
||||
SHLQ $0x0d, R15, R14
|
||||
ANDQ AX, DI
|
||||
IMUL3Q $0x13, R14, R14
|
||||
ADDQ R14, DI
|
||||
ANDQ AX, R9
|
||||
ADDQ SI, R9
|
||||
ANDQ AX, R11
|
||||
ADDQ R8, R11
|
||||
ANDQ AX, R13
|
||||
ADDQ R10, R13
|
||||
ANDQ AX, R15
|
||||
ADDQ R12, R15
|
||||
|
||||
// Second reduction chain (carryPropagate)
|
||||
MOVQ DI, SI
|
||||
SHRQ $0x33, SI
|
||||
MOVQ R9, R8
|
||||
SHRQ $0x33, R8
|
||||
MOVQ R11, R10
|
||||
SHRQ $0x33, R10
|
||||
MOVQ R13, R12
|
||||
SHRQ $0x33, R12
|
||||
MOVQ R15, R14
|
||||
SHRQ $0x33, R14
|
||||
ANDQ AX, DI
|
||||
IMUL3Q $0x13, R14, R14
|
||||
ADDQ R14, DI
|
||||
ANDQ AX, R9
|
||||
ADDQ SI, R9
|
||||
ANDQ AX, R11
|
||||
ADDQ R8, R11
|
||||
ANDQ AX, R13
|
||||
ADDQ R10, R13
|
||||
ANDQ AX, R15
|
||||
ADDQ R12, R15
|
||||
|
||||
// Store output
|
||||
MOVQ out+0(FP), AX
|
||||
MOVQ DI, (AX)
|
||||
MOVQ R9, 8(AX)
|
||||
MOVQ R11, 16(AX)
|
||||
MOVQ R13, 24(AX)
|
||||
MOVQ R15, 32(AX)
|
||||
RET
|
||||
|
||||
// func feSquare(out *Element, a *Element)
|
||||
TEXT ·feSquare(SB), NOSPLIT, $0-16
|
||||
MOVQ a+8(FP), CX
|
||||
|
||||
// r0 = l0×l0
|
||||
MOVQ (CX), AX
|
||||
MULQ (CX)
|
||||
MOVQ AX, SI
|
||||
MOVQ DX, BX
|
||||
|
||||
// r0 += 38×l1×l4
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, SI
|
||||
ADCQ DX, BX
|
||||
|
||||
// r0 += 38×l2×l3
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX, SI
|
||||
ADCQ DX, BX
|
||||
|
||||
// r1 = 2×l0×l1
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 8(CX)
|
||||
MOVQ AX, R8
|
||||
MOVQ DX, DI
|
||||
|
||||
// r1 += 38×l2×l4
|
||||
MOVQ 16(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, R8
|
||||
ADCQ DX, DI
|
||||
|
||||
// r1 += 19×l3×l3
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX, R8
|
||||
ADCQ DX, DI
|
||||
|
||||
// r2 = 2×l0×l2
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 16(CX)
|
||||
MOVQ AX, R10
|
||||
MOVQ DX, R9
|
||||
|
||||
// r2 += l1×l1
|
||||
MOVQ 8(CX), AX
|
||||
MULQ 8(CX)
|
||||
ADDQ AX, R10
|
||||
ADCQ DX, R9
|
||||
|
||||
// r2 += 38×l3×l4
|
||||
MOVQ 24(CX), AX
|
||||
IMUL3Q $0x26, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, R10
|
||||
ADCQ DX, R9
|
||||
|
||||
// r3 = 2×l0×l3
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 24(CX)
|
||||
MOVQ AX, R12
|
||||
MOVQ DX, R11
|
||||
|
||||
// r3 += 2×l1×l2
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x02, AX, AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX, R12
|
||||
ADCQ DX, R11
|
||||
|
||||
// r3 += 19×l4×l4
|
||||
MOVQ 32(CX), AX
|
||||
IMUL3Q $0x13, AX, AX
|
||||
MULQ 32(CX)
|
||||
ADDQ AX, R12
|
||||
ADCQ DX, R11
|
||||
|
||||
// r4 = 2×l0×l4
|
||||
MOVQ (CX), AX
|
||||
SHLQ $0x01, AX
|
||||
MULQ 32(CX)
|
||||
MOVQ AX, R14
|
||||
MOVQ DX, R13
|
||||
|
||||
// r4 += 2×l1×l3
|
||||
MOVQ 8(CX), AX
|
||||
IMUL3Q $0x02, AX, AX
|
||||
MULQ 24(CX)
|
||||
ADDQ AX, R14
|
||||
ADCQ DX, R13
|
||||
|
||||
// r4 += l2×l2
|
||||
MOVQ 16(CX), AX
|
||||
MULQ 16(CX)
|
||||
ADDQ AX, R14
|
||||
ADCQ DX, R13
|
||||
|
||||
// First reduction chain
|
||||
MOVQ $0x0007ffffffffffff, AX
|
||||
SHLQ $0x0d, SI, BX
|
||||
SHLQ $0x0d, R8, DI
|
||||
SHLQ $0x0d, R10, R9
|
||||
SHLQ $0x0d, R12, R11
|
||||
SHLQ $0x0d, R14, R13
|
||||
ANDQ AX, SI
|
||||
IMUL3Q $0x13, R13, R13
|
||||
ADDQ R13, SI
|
||||
ANDQ AX, R8
|
||||
ADDQ BX, R8
|
||||
ANDQ AX, R10
|
||||
ADDQ DI, R10
|
||||
ANDQ AX, R12
|
||||
ADDQ R9, R12
|
||||
ANDQ AX, R14
|
||||
ADDQ R11, R14
|
||||
|
||||
// Second reduction chain (carryPropagate)
|
||||
MOVQ SI, BX
|
||||
SHRQ $0x33, BX
|
||||
MOVQ R8, DI
|
||||
SHRQ $0x33, DI
|
||||
MOVQ R10, R9
|
||||
SHRQ $0x33, R9
|
||||
MOVQ R12, R11
|
||||
SHRQ $0x33, R11
|
||||
MOVQ R14, R13
|
||||
SHRQ $0x33, R13
|
||||
ANDQ AX, SI
|
||||
IMUL3Q $0x13, R13, R13
|
||||
ADDQ R13, SI
|
||||
ANDQ AX, R8
|
||||
ADDQ BX, R8
|
||||
ANDQ AX, R10
|
||||
ADDQ DI, R10
|
||||
ANDQ AX, R12
|
||||
ADDQ R9, R12
|
||||
ANDQ AX, R14
|
||||
ADDQ R11, R14
|
||||
|
||||
// Store output
|
||||
MOVQ out+0(FP), AX
|
||||
MOVQ SI, (AX)
|
||||
MOVQ R8, 8(AX)
|
||||
MOVQ R10, 16(AX)
|
||||
MOVQ R12, 24(AX)
|
||||
MOVQ R14, 32(AX)
|
||||
RET
|
12
vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go
generated
vendored
Normal file
12
vendor/filippo.io/edwards25519/field/fe_amd64_noasm.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) 2019 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 !amd64 || !gc || purego
|
||||
// +build !amd64 !gc purego
|
||||
|
||||
package field
|
||||
|
||||
func feMul(v, x, y *Element) { feMulGeneric(v, x, y) }
|
||||
|
||||
func feSquare(v, x *Element) { feSquareGeneric(v, x) }
|
16
vendor/filippo.io/edwards25519/field/fe_arm64.go
generated
vendored
Normal file
16
vendor/filippo.io/edwards25519/field/fe_arm64.go
generated
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright (c) 2020 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 arm64 && gc && !purego
|
||||
// +build arm64,gc,!purego
|
||||
|
||||
package field
|
||||
|
||||
//go:noescape
|
||||
func carryPropagate(v *Element)
|
||||
|
||||
func (v *Element) carryPropagate() *Element {
|
||||
carryPropagate(v)
|
||||
return v
|
||||
}
|
42
vendor/filippo.io/edwards25519/field/fe_arm64.s
generated
vendored
Normal file
42
vendor/filippo.io/edwards25519/field/fe_arm64.s
generated
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
// Copyright (c) 2020 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.
|
||||
|
||||
// +build arm64,gc,!purego
|
||||
|
||||
#include "textflag.h"
|
||||
|
||||
// carryPropagate works exactly like carryPropagateGeneric and uses the
|
||||
// same AND, ADD, and LSR+MADD instructions emitted by the compiler, but
|
||||
// avoids loading R0-R4 twice and uses LDP and STP.
|
||||
//
|
||||
// See https://golang.org/issues/43145 for the main compiler issue.
|
||||
//
|
||||
// func carryPropagate(v *Element)
|
||||
TEXT ·carryPropagate(SB),NOFRAME|NOSPLIT,$0-8
|
||||
MOVD v+0(FP), R20
|
||||
|
||||
LDP 0(R20), (R0, R1)
|
||||
LDP 16(R20), (R2, R3)
|
||||
MOVD 32(R20), R4
|
||||
|
||||
AND $0x7ffffffffffff, R0, R10
|
||||
AND $0x7ffffffffffff, R1, R11
|
||||
AND $0x7ffffffffffff, R2, R12
|
||||
AND $0x7ffffffffffff, R3, R13
|
||||
AND $0x7ffffffffffff, R4, R14
|
||||
|
||||
ADD R0>>51, R11, R11
|
||||
ADD R1>>51, R12, R12
|
||||
ADD R2>>51, R13, R13
|
||||
ADD R3>>51, R14, R14
|
||||
// R4>>51 * 19 + R10 -> R10
|
||||
LSR $51, R4, R21
|
||||
MOVD $19, R22
|
||||
MADD R22, R10, R21, R10
|
||||
|
||||
STP (R10, R11), 0(R20)
|
||||
STP (R12, R13), 16(R20)
|
||||
MOVD R14, 32(R20)
|
||||
|
||||
RET
|
12
vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go
generated
vendored
Normal file
12
vendor/filippo.io/edwards25519/field/fe_arm64_noasm.go
generated
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) 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 !arm64 || !gc || purego
|
||||
// +build !arm64 !gc purego
|
||||
|
||||
package field
|
||||
|
||||
func (v *Element) carryPropagate() *Element {
|
||||
return v.carryPropagateGeneric()
|
||||
}
|
264
vendor/filippo.io/edwards25519/field/fe_generic.go
generated
vendored
Normal file
264
vendor/filippo.io/edwards25519/field/fe_generic.go
generated
vendored
Normal file
@@ -0,0 +1,264 @@
|
||||
// Copyright (c) 2017 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.
|
||||
|
||||
package field
|
||||
|
||||
import "math/bits"
|
||||
|
||||
// uint128 holds a 128-bit number as two 64-bit limbs, for use with the
|
||||
// bits.Mul64 and bits.Add64 intrinsics.
|
||||
type uint128 struct {
|
||||
lo, hi uint64
|
||||
}
|
||||
|
||||
// mul64 returns a * b.
|
||||
func mul64(a, b uint64) uint128 {
|
||||
hi, lo := bits.Mul64(a, b)
|
||||
return uint128{lo, hi}
|
||||
}
|
||||
|
||||
// addMul64 returns v + a * b.
|
||||
func addMul64(v uint128, a, b uint64) uint128 {
|
||||
hi, lo := bits.Mul64(a, b)
|
||||
lo, c := bits.Add64(lo, v.lo, 0)
|
||||
hi, _ = bits.Add64(hi, v.hi, c)
|
||||
return uint128{lo, hi}
|
||||
}
|
||||
|
||||
// shiftRightBy51 returns a >> 51. a is assumed to be at most 115 bits.
|
||||
func shiftRightBy51(a uint128) uint64 {
|
||||
return (a.hi << (64 - 51)) | (a.lo >> 51)
|
||||
}
|
||||
|
||||
func feMulGeneric(v, a, b *Element) {
|
||||
a0 := a.l0
|
||||
a1 := a.l1
|
||||
a2 := a.l2
|
||||
a3 := a.l3
|
||||
a4 := a.l4
|
||||
|
||||
b0 := b.l0
|
||||
b1 := b.l1
|
||||
b2 := b.l2
|
||||
b3 := b.l3
|
||||
b4 := b.l4
|
||||
|
||||
// Limb multiplication works like pen-and-paper columnar multiplication, but
|
||||
// with 51-bit limbs instead of digits.
|
||||
//
|
||||
// a4 a3 a2 a1 a0 x
|
||||
// b4 b3 b2 b1 b0 =
|
||||
// ------------------------
|
||||
// a4b0 a3b0 a2b0 a1b0 a0b0 +
|
||||
// a4b1 a3b1 a2b1 a1b1 a0b1 +
|
||||
// a4b2 a3b2 a2b2 a1b2 a0b2 +
|
||||
// a4b3 a3b3 a2b3 a1b3 a0b3 +
|
||||
// a4b4 a3b4 a2b4 a1b4 a0b4 =
|
||||
// ----------------------------------------------
|
||||
// r8 r7 r6 r5 r4 r3 r2 r1 r0
|
||||
//
|
||||
// We can then use the reduction identity (a * 2²⁵⁵ + b = a * 19 + b) to
|
||||
// reduce the limbs that would overflow 255 bits. r5 * 2²⁵⁵ becomes 19 * r5,
|
||||
// r6 * 2³⁰⁶ becomes 19 * r6 * 2⁵¹, etc.
|
||||
//
|
||||
// Reduction can be carried out simultaneously to multiplication. For
|
||||
// example, we do not compute r5: whenever the result of a multiplication
|
||||
// belongs to r5, like a1b4, we multiply it by 19 and add the result to r0.
|
||||
//
|
||||
// a4b0 a3b0 a2b0 a1b0 a0b0 +
|
||||
// a3b1 a2b1 a1b1 a0b1 19×a4b1 +
|
||||
// a2b2 a1b2 a0b2 19×a4b2 19×a3b2 +
|
||||
// a1b3 a0b3 19×a4b3 19×a3b3 19×a2b3 +
|
||||
// a0b4 19×a4b4 19×a3b4 19×a2b4 19×a1b4 =
|
||||
// --------------------------------------
|
||||
// r4 r3 r2 r1 r0
|
||||
//
|
||||
// Finally we add up the columns into wide, overlapping limbs.
|
||||
|
||||
a1_19 := a1 * 19
|
||||
a2_19 := a2 * 19
|
||||
a3_19 := a3 * 19
|
||||
a4_19 := a4 * 19
|
||||
|
||||
// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
|
||||
r0 := mul64(a0, b0)
|
||||
r0 = addMul64(r0, a1_19, b4)
|
||||
r0 = addMul64(r0, a2_19, b3)
|
||||
r0 = addMul64(r0, a3_19, b2)
|
||||
r0 = addMul64(r0, a4_19, b1)
|
||||
|
||||
// r1 = a0×b1 + a1×b0 + 19×(a2×b4 + a3×b3 + a4×b2)
|
||||
r1 := mul64(a0, b1)
|
||||
r1 = addMul64(r1, a1, b0)
|
||||
r1 = addMul64(r1, a2_19, b4)
|
||||
r1 = addMul64(r1, a3_19, b3)
|
||||
r1 = addMul64(r1, a4_19, b2)
|
||||
|
||||
// r2 = a0×b2 + a1×b1 + a2×b0 + 19×(a3×b4 + a4×b3)
|
||||
r2 := mul64(a0, b2)
|
||||
r2 = addMul64(r2, a1, b1)
|
||||
r2 = addMul64(r2, a2, b0)
|
||||
r2 = addMul64(r2, a3_19, b4)
|
||||
r2 = addMul64(r2, a4_19, b3)
|
||||
|
||||
// r3 = a0×b3 + a1×b2 + a2×b1 + a3×b0 + 19×a4×b4
|
||||
r3 := mul64(a0, b3)
|
||||
r3 = addMul64(r3, a1, b2)
|
||||
r3 = addMul64(r3, a2, b1)
|
||||
r3 = addMul64(r3, a3, b0)
|
||||
r3 = addMul64(r3, a4_19, b4)
|
||||
|
||||
// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
|
||||
r4 := mul64(a0, b4)
|
||||
r4 = addMul64(r4, a1, b3)
|
||||
r4 = addMul64(r4, a2, b2)
|
||||
r4 = addMul64(r4, a3, b1)
|
||||
r4 = addMul64(r4, a4, b0)
|
||||
|
||||
// After the multiplication, we need to reduce (carry) the five coefficients
|
||||
// to obtain a result with limbs that are at most slightly larger than 2⁵¹,
|
||||
// to respect the Element invariant.
|
||||
//
|
||||
// Overall, the reduction works the same as carryPropagate, except with
|
||||
// wider inputs: we take the carry for each coefficient by shifting it right
|
||||
// by 51, and add it to the limb above it. The top carry is multiplied by 19
|
||||
// according to the reduction identity and added to the lowest limb.
|
||||
//
|
||||
// The largest coefficient (r0) will be at most 111 bits, which guarantees
|
||||
// that all carries are at most 111 - 51 = 60 bits, which fits in a uint64.
|
||||
//
|
||||
// r0 = a0×b0 + 19×(a1×b4 + a2×b3 + a3×b2 + a4×b1)
|
||||
// r0 < 2⁵²×2⁵² + 19×(2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵² + 2⁵²×2⁵²)
|
||||
// r0 < (1 + 19 × 4) × 2⁵² × 2⁵²
|
||||
// r0 < 2⁷ × 2⁵² × 2⁵²
|
||||
// r0 < 2¹¹¹
|
||||
//
|
||||
// Moreover, the top coefficient (r4) is at most 107 bits, so c4 is at most
|
||||
// 56 bits, and c4 * 19 is at most 61 bits, which again fits in a uint64 and
|
||||
// allows us to easily apply the reduction identity.
|
||||
//
|
||||
// r4 = a0×b4 + a1×b3 + a2×b2 + a3×b1 + a4×b0
|
||||
// r4 < 5 × 2⁵² × 2⁵²
|
||||
// r4 < 2¹⁰⁷
|
||||
//
|
||||
|
||||
c0 := shiftRightBy51(r0)
|
||||
c1 := shiftRightBy51(r1)
|
||||
c2 := shiftRightBy51(r2)
|
||||
c3 := shiftRightBy51(r3)
|
||||
c4 := shiftRightBy51(r4)
|
||||
|
||||
rr0 := r0.lo&maskLow51Bits + c4*19
|
||||
rr1 := r1.lo&maskLow51Bits + c0
|
||||
rr2 := r2.lo&maskLow51Bits + c1
|
||||
rr3 := r3.lo&maskLow51Bits + c2
|
||||
rr4 := r4.lo&maskLow51Bits + c3
|
||||
|
||||
// Now all coefficients fit into 64-bit registers but are still too large to
|
||||
// be passed around as a Element. We therefore do one last carry chain,
|
||||
// where the carries will be small enough to fit in the wiggle room above 2⁵¹.
|
||||
*v = Element{rr0, rr1, rr2, rr3, rr4}
|
||||
v.carryPropagate()
|
||||
}
|
||||
|
||||
func feSquareGeneric(v, a *Element) {
|
||||
l0 := a.l0
|
||||
l1 := a.l1
|
||||
l2 := a.l2
|
||||
l3 := a.l3
|
||||
l4 := a.l4
|
||||
|
||||
// Squaring works precisely like multiplication above, but thanks to its
|
||||
// symmetry we get to group a few terms together.
|
||||
//
|
||||
// l4 l3 l2 l1 l0 x
|
||||
// l4 l3 l2 l1 l0 =
|
||||
// ------------------------
|
||||
// l4l0 l3l0 l2l0 l1l0 l0l0 +
|
||||
// l4l1 l3l1 l2l1 l1l1 l0l1 +
|
||||
// l4l2 l3l2 l2l2 l1l2 l0l2 +
|
||||
// l4l3 l3l3 l2l3 l1l3 l0l3 +
|
||||
// l4l4 l3l4 l2l4 l1l4 l0l4 =
|
||||
// ----------------------------------------------
|
||||
// r8 r7 r6 r5 r4 r3 r2 r1 r0
|
||||
//
|
||||
// l4l0 l3l0 l2l0 l1l0 l0l0 +
|
||||
// l3l1 l2l1 l1l1 l0l1 19×l4l1 +
|
||||
// l2l2 l1l2 l0l2 19×l4l2 19×l3l2 +
|
||||
// l1l3 l0l3 19×l4l3 19×l3l3 19×l2l3 +
|
||||
// l0l4 19×l4l4 19×l3l4 19×l2l4 19×l1l4 =
|
||||
// --------------------------------------
|
||||
// r4 r3 r2 r1 r0
|
||||
//
|
||||
// With precomputed 2×, 19×, and 2×19× terms, we can compute each limb with
|
||||
// only three Mul64 and four Add64, instead of five and eight.
|
||||
|
||||
l0_2 := l0 * 2
|
||||
l1_2 := l1 * 2
|
||||
|
||||
l1_38 := l1 * 38
|
||||
l2_38 := l2 * 38
|
||||
l3_38 := l3 * 38
|
||||
|
||||
l3_19 := l3 * 19
|
||||
l4_19 := l4 * 19
|
||||
|
||||
// r0 = l0×l0 + 19×(l1×l4 + l2×l3 + l3×l2 + l4×l1) = l0×l0 + 19×2×(l1×l4 + l2×l3)
|
||||
r0 := mul64(l0, l0)
|
||||
r0 = addMul64(r0, l1_38, l4)
|
||||
r0 = addMul64(r0, l2_38, l3)
|
||||
|
||||
// r1 = l0×l1 + l1×l0 + 19×(l2×l4 + l3×l3 + l4×l2) = 2×l0×l1 + 19×2×l2×l4 + 19×l3×l3
|
||||
r1 := mul64(l0_2, l1)
|
||||
r1 = addMul64(r1, l2_38, l4)
|
||||
r1 = addMul64(r1, l3_19, l3)
|
||||
|
||||
// r2 = l0×l2 + l1×l1 + l2×l0 + 19×(l3×l4 + l4×l3) = 2×l0×l2 + l1×l1 + 19×2×l3×l4
|
||||
r2 := mul64(l0_2, l2)
|
||||
r2 = addMul64(r2, l1, l1)
|
||||
r2 = addMul64(r2, l3_38, l4)
|
||||
|
||||
// r3 = l0×l3 + l1×l2 + l2×l1 + l3×l0 + 19×l4×l4 = 2×l0×l3 + 2×l1×l2 + 19×l4×l4
|
||||
r3 := mul64(l0_2, l3)
|
||||
r3 = addMul64(r3, l1_2, l2)
|
||||
r3 = addMul64(r3, l4_19, l4)
|
||||
|
||||
// r4 = l0×l4 + l1×l3 + l2×l2 + l3×l1 + l4×l0 = 2×l0×l4 + 2×l1×l3 + l2×l2
|
||||
r4 := mul64(l0_2, l4)
|
||||
r4 = addMul64(r4, l1_2, l3)
|
||||
r4 = addMul64(r4, l2, l2)
|
||||
|
||||
c0 := shiftRightBy51(r0)
|
||||
c1 := shiftRightBy51(r1)
|
||||
c2 := shiftRightBy51(r2)
|
||||
c3 := shiftRightBy51(r3)
|
||||
c4 := shiftRightBy51(r4)
|
||||
|
||||
rr0 := r0.lo&maskLow51Bits + c4*19
|
||||
rr1 := r1.lo&maskLow51Bits + c0
|
||||
rr2 := r2.lo&maskLow51Bits + c1
|
||||
rr3 := r3.lo&maskLow51Bits + c2
|
||||
rr4 := r4.lo&maskLow51Bits + c3
|
||||
|
||||
*v = Element{rr0, rr1, rr2, rr3, rr4}
|
||||
v.carryPropagate()
|
||||
}
|
||||
|
||||
// carryPropagate brings the limbs below 52 bits by applying the reduction
|
||||
// identity (a * 2²⁵⁵ + b = a * 19 + b) to the l4 carry.
|
||||
func (v *Element) carryPropagateGeneric() *Element {
|
||||
c0 := v.l0 >> 51
|
||||
c1 := v.l1 >> 51
|
||||
c2 := v.l2 >> 51
|
||||
c3 := v.l3 >> 51
|
||||
c4 := v.l4 >> 51
|
||||
|
||||
v.l0 = v.l0&maskLow51Bits + c4*19
|
||||
v.l1 = v.l1&maskLow51Bits + c0
|
||||
v.l2 = v.l2&maskLow51Bits + c1
|
||||
v.l3 = v.l3&maskLow51Bits + c2
|
||||
v.l4 = v.l4&maskLow51Bits + c3
|
||||
|
||||
return v
|
||||
}
|
1027
vendor/filippo.io/edwards25519/scalar.go
generated
vendored
Normal file
1027
vendor/filippo.io/edwards25519/scalar.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
214
vendor/filippo.io/edwards25519/scalarmult.go
generated
vendored
Normal file
214
vendor/filippo.io/edwards25519/scalarmult.go
generated
vendored
Normal file
@@ -0,0 +1,214 @@
|
||||
// Copyright (c) 2019 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.
|
||||
|
||||
package edwards25519
|
||||
|
||||
import "sync"
|
||||
|
||||
// basepointTable is a set of 32 affineLookupTables, where table i is generated
|
||||
// from 256i * basepoint. It is precomputed the first time it's used.
|
||||
func basepointTable() *[32]affineLookupTable {
|
||||
basepointTablePrecomp.initOnce.Do(func() {
|
||||
p := NewGeneratorPoint()
|
||||
for i := 0; i < 32; i++ {
|
||||
basepointTablePrecomp.table[i].FromP3(p)
|
||||
for j := 0; j < 8; j++ {
|
||||
p.Add(p, p)
|
||||
}
|
||||
}
|
||||
})
|
||||
return &basepointTablePrecomp.table
|
||||
}
|
||||
|
||||
var basepointTablePrecomp struct {
|
||||
table [32]affineLookupTable
|
||||
initOnce sync.Once
|
||||
}
|
||||
|
||||
// ScalarBaseMult sets v = x * B, where B is the canonical generator, and
|
||||
// returns v.
|
||||
//
|
||||
// The scalar multiplication is done in constant time.
|
||||
func (v *Point) ScalarBaseMult(x *Scalar) *Point {
|
||||
basepointTable := basepointTable()
|
||||
|
||||
// Write x = sum(x_i * 16^i) so x*B = sum( B*x_i*16^i )
|
||||
// as described in the Ed25519 paper
|
||||
//
|
||||
// Group even and odd coefficients
|
||||
// x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
|
||||
// + x_1*16^1*B + x_3*16^3*B + ... + x_63*16^63*B
|
||||
// x*B = x_0*16^0*B + x_2*16^2*B + ... + x_62*16^62*B
|
||||
// + 16*( x_1*16^0*B + x_3*16^2*B + ... + x_63*16^62*B)
|
||||
//
|
||||
// We use a lookup table for each i to get x_i*16^(2*i)*B
|
||||
// and do four doublings to multiply by 16.
|
||||
digits := x.signedRadix16()
|
||||
|
||||
multiple := &affineCached{}
|
||||
tmp1 := &projP1xP1{}
|
||||
tmp2 := &projP2{}
|
||||
|
||||
// Accumulate the odd components first
|
||||
v.Set(NewIdentityPoint())
|
||||
for i := 1; i < 64; i += 2 {
|
||||
basepointTable[i/2].SelectInto(multiple, digits[i])
|
||||
tmp1.AddAffine(v, multiple)
|
||||
v.fromP1xP1(tmp1)
|
||||
}
|
||||
|
||||
// Multiply by 16
|
||||
tmp2.FromP3(v) // tmp2 = v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 2*v in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 2*v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 4*v in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 4*v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 8*v in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 8*v in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 16*v in P1xP1 coords
|
||||
v.fromP1xP1(tmp1) // now v = 16*(odd components)
|
||||
|
||||
// Accumulate the even components
|
||||
for i := 0; i < 64; i += 2 {
|
||||
basepointTable[i/2].SelectInto(multiple, digits[i])
|
||||
tmp1.AddAffine(v, multiple)
|
||||
v.fromP1xP1(tmp1)
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// ScalarMult sets v = x * q, and returns v.
|
||||
//
|
||||
// The scalar multiplication is done in constant time.
|
||||
func (v *Point) ScalarMult(x *Scalar, q *Point) *Point {
|
||||
checkInitialized(q)
|
||||
|
||||
var table projLookupTable
|
||||
table.FromP3(q)
|
||||
|
||||
// Write x = sum(x_i * 16^i)
|
||||
// so x*Q = sum( Q*x_i*16^i )
|
||||
// = Q*x_0 + 16*(Q*x_1 + 16*( ... + Q*x_63) ... )
|
||||
// <------compute inside out---------
|
||||
//
|
||||
// We use the lookup table to get the x_i*Q values
|
||||
// and do four doublings to compute 16*Q
|
||||
digits := x.signedRadix16()
|
||||
|
||||
// Unwrap first loop iteration to save computing 16*identity
|
||||
multiple := &projCached{}
|
||||
tmp1 := &projP1xP1{}
|
||||
tmp2 := &projP2{}
|
||||
table.SelectInto(multiple, digits[63])
|
||||
|
||||
v.Set(NewIdentityPoint())
|
||||
tmp1.Add(v, multiple) // tmp1 = x_63*Q in P1xP1 coords
|
||||
for i := 62; i >= 0; i-- {
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = (prev) in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 2*(prev) in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 2*(prev) in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 4*(prev) in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 4*(prev) in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 8*(prev) in P1xP1 coords
|
||||
tmp2.FromP1xP1(tmp1) // tmp2 = 8*(prev) in P2 coords
|
||||
tmp1.Double(tmp2) // tmp1 = 16*(prev) in P1xP1 coords
|
||||
v.fromP1xP1(tmp1) // v = 16*(prev) in P3 coords
|
||||
table.SelectInto(multiple, digits[i])
|
||||
tmp1.Add(v, multiple) // tmp1 = x_i*Q + 16*(prev) in P1xP1 coords
|
||||
}
|
||||
v.fromP1xP1(tmp1)
|
||||
return v
|
||||
}
|
||||
|
||||
// basepointNafTable is the nafLookupTable8 for the basepoint.
|
||||
// It is precomputed the first time it's used.
|
||||
func basepointNafTable() *nafLookupTable8 {
|
||||
basepointNafTablePrecomp.initOnce.Do(func() {
|
||||
basepointNafTablePrecomp.table.FromP3(NewGeneratorPoint())
|
||||
})
|
||||
return &basepointNafTablePrecomp.table
|
||||
}
|
||||
|
||||
var basepointNafTablePrecomp struct {
|
||||
table nafLookupTable8
|
||||
initOnce sync.Once
|
||||
}
|
||||
|
||||
// VarTimeDoubleScalarBaseMult sets v = a * A + b * B, where B is the canonical
|
||||
// generator, and returns v.
|
||||
//
|
||||
// Execution time depends on the inputs.
|
||||
func (v *Point) VarTimeDoubleScalarBaseMult(a *Scalar, A *Point, b *Scalar) *Point {
|
||||
checkInitialized(A)
|
||||
|
||||
// Similarly to the single variable-base approach, we compute
|
||||
// digits and use them with a lookup table. However, because
|
||||
// we are allowed to do variable-time operations, we don't
|
||||
// need constant-time lookups or constant-time digit
|
||||
// computations.
|
||||
//
|
||||
// So we use a non-adjacent form of some width w instead of
|
||||
// radix 16. This is like a binary representation (one digit
|
||||
// for each binary place) but we allow the digits to grow in
|
||||
// magnitude up to 2^{w-1} so that the nonzero digits are as
|
||||
// sparse as possible. Intuitively, this "condenses" the
|
||||
// "mass" of the scalar onto sparse coefficients (meaning
|
||||
// fewer additions).
|
||||
|
||||
basepointNafTable := basepointNafTable()
|
||||
var aTable nafLookupTable5
|
||||
aTable.FromP3(A)
|
||||
// Because the basepoint is fixed, we can use a wider NAF
|
||||
// corresponding to a bigger table.
|
||||
aNaf := a.nonAdjacentForm(5)
|
||||
bNaf := b.nonAdjacentForm(8)
|
||||
|
||||
// Find the first nonzero coefficient.
|
||||
i := 255
|
||||
for j := i; j >= 0; j-- {
|
||||
if aNaf[j] != 0 || bNaf[j] != 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
multA := &projCached{}
|
||||
multB := &affineCached{}
|
||||
tmp1 := &projP1xP1{}
|
||||
tmp2 := &projP2{}
|
||||
tmp2.Zero()
|
||||
|
||||
// Move from high to low bits, doubling the accumulator
|
||||
// at each iteration and checking whether there is a nonzero
|
||||
// coefficient to look up a multiple of.
|
||||
for ; i >= 0; i-- {
|
||||
tmp1.Double(tmp2)
|
||||
|
||||
// Only update v if we have a nonzero coeff to add in.
|
||||
if aNaf[i] > 0 {
|
||||
v.fromP1xP1(tmp1)
|
||||
aTable.SelectInto(multA, aNaf[i])
|
||||
tmp1.Add(v, multA)
|
||||
} else if aNaf[i] < 0 {
|
||||
v.fromP1xP1(tmp1)
|
||||
aTable.SelectInto(multA, -aNaf[i])
|
||||
tmp1.Sub(v, multA)
|
||||
}
|
||||
|
||||
if bNaf[i] > 0 {
|
||||
v.fromP1xP1(tmp1)
|
||||
basepointNafTable.SelectInto(multB, bNaf[i])
|
||||
tmp1.AddAffine(v, multB)
|
||||
} else if bNaf[i] < 0 {
|
||||
v.fromP1xP1(tmp1)
|
||||
basepointNafTable.SelectInto(multB, -bNaf[i])
|
||||
tmp1.SubAffine(v, multB)
|
||||
}
|
||||
|
||||
tmp2.FromP1xP1(tmp1)
|
||||
}
|
||||
|
||||
v.fromP2(tmp2)
|
||||
return v
|
||||
}
|
129
vendor/filippo.io/edwards25519/tables.go
generated
vendored
Normal file
129
vendor/filippo.io/edwards25519/tables.go
generated
vendored
Normal file
@@ -0,0 +1,129 @@
|
||||
// Copyright (c) 2019 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.
|
||||
|
||||
package edwards25519
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
)
|
||||
|
||||
// A dynamic lookup table for variable-base, constant-time scalar muls.
|
||||
type projLookupTable struct {
|
||||
points [8]projCached
|
||||
}
|
||||
|
||||
// A precomputed lookup table for fixed-base, constant-time scalar muls.
|
||||
type affineLookupTable struct {
|
||||
points [8]affineCached
|
||||
}
|
||||
|
||||
// A dynamic lookup table for variable-base, variable-time scalar muls.
|
||||
type nafLookupTable5 struct {
|
||||
points [8]projCached
|
||||
}
|
||||
|
||||
// A precomputed lookup table for fixed-base, variable-time scalar muls.
|
||||
type nafLookupTable8 struct {
|
||||
points [64]affineCached
|
||||
}
|
||||
|
||||
// Constructors.
|
||||
|
||||
// Builds a lookup table at runtime. Fast.
|
||||
func (v *projLookupTable) FromP3(q *Point) {
|
||||
// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
|
||||
// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
|
||||
v.points[0].FromP3(q)
|
||||
tmpP3 := Point{}
|
||||
tmpP1xP1 := projP1xP1{}
|
||||
for i := 0; i < 7; i++ {
|
||||
// Compute (i+1)*Q as Q + i*Q and convert to a ProjCached
|
||||
// This is needlessly complicated because the API has explicit
|
||||
// recievers instead of creating stack objects and relying on RVO
|
||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(q, &v.points[i])))
|
||||
}
|
||||
}
|
||||
|
||||
// This is not optimised for speed; fixed-base tables should be precomputed.
|
||||
func (v *affineLookupTable) FromP3(q *Point) {
|
||||
// Goal: v.points[i] = (i+1)*Q, i.e., Q, 2Q, ..., 8Q
|
||||
// This allows lookup of -8Q, ..., -Q, 0, Q, ..., 8Q
|
||||
v.points[0].FromP3(q)
|
||||
tmpP3 := Point{}
|
||||
tmpP1xP1 := projP1xP1{}
|
||||
for i := 0; i < 7; i++ {
|
||||
// Compute (i+1)*Q as Q + i*Q and convert to AffineCached
|
||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(q, &v.points[i])))
|
||||
}
|
||||
}
|
||||
|
||||
// Builds a lookup table at runtime. Fast.
|
||||
func (v *nafLookupTable5) FromP3(q *Point) {
|
||||
// Goal: v.points[i] = (2*i+1)*Q, i.e., Q, 3Q, 5Q, ..., 15Q
|
||||
// This allows lookup of -15Q, ..., -3Q, -Q, 0, Q, 3Q, ..., 15Q
|
||||
v.points[0].FromP3(q)
|
||||
q2 := Point{}
|
||||
q2.Add(q, q)
|
||||
tmpP3 := Point{}
|
||||
tmpP1xP1 := projP1xP1{}
|
||||
for i := 0; i < 7; i++ {
|
||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.Add(&q2, &v.points[i])))
|
||||
}
|
||||
}
|
||||
|
||||
// This is not optimised for speed; fixed-base tables should be precomputed.
|
||||
func (v *nafLookupTable8) FromP3(q *Point) {
|
||||
v.points[0].FromP3(q)
|
||||
q2 := Point{}
|
||||
q2.Add(q, q)
|
||||
tmpP3 := Point{}
|
||||
tmpP1xP1 := projP1xP1{}
|
||||
for i := 0; i < 63; i++ {
|
||||
v.points[i+1].FromP3(tmpP3.fromP1xP1(tmpP1xP1.AddAffine(&q2, &v.points[i])))
|
||||
}
|
||||
}
|
||||
|
||||
// Selectors.
|
||||
|
||||
// Set dest to x*Q, where -8 <= x <= 8, in constant time.
|
||||
func (v *projLookupTable) SelectInto(dest *projCached, x int8) {
|
||||
// Compute xabs = |x|
|
||||
xmask := x >> 7
|
||||
xabs := uint8((x + xmask) ^ xmask)
|
||||
|
||||
dest.Zero()
|
||||
for j := 1; j <= 8; j++ {
|
||||
// Set dest = j*Q if |x| = j
|
||||
cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
|
||||
dest.Select(&v.points[j-1], dest, cond)
|
||||
}
|
||||
// Now dest = |x|*Q, conditionally negate to get x*Q
|
||||
dest.CondNeg(int(xmask & 1))
|
||||
}
|
||||
|
||||
// Set dest to x*Q, where -8 <= x <= 8, in constant time.
|
||||
func (v *affineLookupTable) SelectInto(dest *affineCached, x int8) {
|
||||
// Compute xabs = |x|
|
||||
xmask := x >> 7
|
||||
xabs := uint8((x + xmask) ^ xmask)
|
||||
|
||||
dest.Zero()
|
||||
for j := 1; j <= 8; j++ {
|
||||
// Set dest = j*Q if |x| = j
|
||||
cond := subtle.ConstantTimeByteEq(xabs, uint8(j))
|
||||
dest.Select(&v.points[j-1], dest, cond)
|
||||
}
|
||||
// Now dest = |x|*Q, conditionally negate to get x*Q
|
||||
dest.CondNeg(int(xmask & 1))
|
||||
}
|
||||
|
||||
// Given odd x with 0 < x < 2^4, return x*Q (in variable time).
|
||||
func (v *nafLookupTable5) SelectInto(dest *projCached, x int8) {
|
||||
*dest = v.points[x/2]
|
||||
}
|
||||
|
||||
// Given odd x with 0 < x < 2^7, return x*Q (in variable time).
|
||||
func (v *nafLookupTable8) SelectInto(dest *affineCached, x int8) {
|
||||
*dest = v.points[x/2]
|
||||
}
|
5
vendor/github.com/bwmarrin/discordgo/.gitignore
generated
vendored
Normal file
5
vendor/github.com/bwmarrin/discordgo/.gitignore
generated
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# IDE-specific metadata
|
||||
.idea/
|
||||
|
||||
# Environment variables. Useful for examples.
|
||||
.env
|
19
vendor/github.com/bwmarrin/discordgo/.golangci.yml
generated
vendored
Normal file
19
vendor/github.com/bwmarrin/discordgo/.golangci.yml
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
linters:
|
||||
disable-all: true
|
||||
enable:
|
||||
# - staticcheck
|
||||
# - unused
|
||||
- golint
|
||||
|
||||
linters-settings:
|
||||
staticcheck:
|
||||
go: "1.13"
|
||||
|
||||
checks: ["all"]
|
||||
|
||||
unused:
|
||||
go: "1.13"
|
||||
|
||||
issues:
|
||||
include:
|
||||
- EXC0002
|
@@ -3,6 +3,7 @@ go:
|
||||
- 1.13.x
|
||||
- 1.14.x
|
||||
- 1.15.x
|
||||
- 1.16.x
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
install:
|
@@ -1,8 +1,8 @@
|
||||
# DiscordGo
|
||||
|
||||
[](https://godoc.org/github.com/bwmarrin/discordgo) [](http://goreportcard.com/report/bwmarrin/discordgo) [](https://travis-ci.org/bwmarrin/discordgo) [](https://discord.gg/0f1SbxBZjYoCtNPP) [](https://discord.com/invite/discord-api)
|
||||
[](https://pkg.go.dev/github.com/bwmarrin/discordgo) [](https://goreportcard.com/report/github.com/bwmarrin/discordgo) [](https://travis-ci.com/bwmarrin/discordgo) [](https://discord.gg/golang) [](https://discord.com/invite/discord-api)
|
||||
|
||||
<img align="right" src="http://bwmarrin.github.io/discordgo/img/discordgo.png">
|
||||
<img align="right" alt="DiscordGo logo" src="docs/img/discordgo.svg" width="400">
|
||||
|
||||
DiscordGo is a [Go](https://golang.org/) package that provides low level
|
||||
bindings to the [Discord](https://discord.com/) chat client API. DiscordGo
|
||||
@@ -22,7 +22,7 @@ tool that wraps `ffmpeg` to create opus encoded audio appropriate for use with
|
||||
Discord (and DiscordGo).
|
||||
|
||||
**For help with this package or general Go discussion, please join the [Discord
|
||||
Gophers](https://discord.gg/0f1SbxBZjYq9jLBk) chat server.**
|
||||
Gophers](https://discord.gg/golang) chat server.**
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -64,8 +64,8 @@ The DiscordGo code is fairly well documented at this point and is currently
|
||||
the only documentation available. Both GoDoc and GoWalker (below) present
|
||||
that information in a nice format.
|
||||
|
||||
- [](https://godoc.org/github.com/bwmarrin/discordgo)
|
||||
- [](https://gowalker.org/github.com/bwmarrin/discordgo)
|
||||
- [](https://pkg.go.dev/github.com/bwmarrin/discordgo)
|
||||
- [](https://gowalker.org/github.com/bwmarrin/discordgo)
|
||||
- Hand crafted documentation coming eventually.
|
||||
|
||||
|
241
vendor/github.com/bwmarrin/discordgo/components.go
generated
vendored
Normal file
241
vendor/github.com/bwmarrin/discordgo/components.go
generated
vendored
Normal file
@@ -0,0 +1,241 @@
|
||||
package discordgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// ComponentType is type of component.
|
||||
type ComponentType uint
|
||||
|
||||
// MessageComponent types.
|
||||
const (
|
||||
ActionsRowComponent ComponentType = 1
|
||||
ButtonComponent ComponentType = 2
|
||||
SelectMenuComponent ComponentType = 3
|
||||
TextInputComponent ComponentType = 4
|
||||
)
|
||||
|
||||
// MessageComponent is a base interface for all message components.
|
||||
type MessageComponent interface {
|
||||
json.Marshaler
|
||||
Type() ComponentType
|
||||
}
|
||||
|
||||
type unmarshalableMessageComponent struct {
|
||||
MessageComponent
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to unmarshal MessageComponent object.
|
||||
func (umc *unmarshalableMessageComponent) UnmarshalJSON(src []byte) error {
|
||||
var v struct {
|
||||
Type ComponentType `json:"type"`
|
||||
}
|
||||
err := json.Unmarshal(src, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v.Type {
|
||||
case ActionsRowComponent:
|
||||
umc.MessageComponent = &ActionsRow{}
|
||||
case ButtonComponent:
|
||||
umc.MessageComponent = &Button{}
|
||||
case SelectMenuComponent:
|
||||
umc.MessageComponent = &SelectMenu{}
|
||||
case TextInputComponent:
|
||||
umc.MessageComponent = &TextInput{}
|
||||
default:
|
||||
return fmt.Errorf("unknown component type: %d", v.Type)
|
||||
}
|
||||
return json.Unmarshal(src, umc.MessageComponent)
|
||||
}
|
||||
|
||||
// MessageComponentFromJSON is a helper function for unmarshaling message components
|
||||
func MessageComponentFromJSON(b []byte) (MessageComponent, error) {
|
||||
var u unmarshalableMessageComponent
|
||||
err := u.UnmarshalJSON(b)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to unmarshal into MessageComponent: %w", err)
|
||||
}
|
||||
return u.MessageComponent, nil
|
||||
}
|
||||
|
||||
// ActionsRow is a container for components within one row.
|
||||
type ActionsRow struct {
|
||||
Components []MessageComponent `json:"components"`
|
||||
}
|
||||
|
||||
// MarshalJSON is a method for marshaling ActionsRow to a JSON object.
|
||||
func (r ActionsRow) MarshalJSON() ([]byte, error) {
|
||||
type actionsRow ActionsRow
|
||||
|
||||
return json.Marshal(struct {
|
||||
actionsRow
|
||||
Type ComponentType `json:"type"`
|
||||
}{
|
||||
actionsRow: actionsRow(r),
|
||||
Type: r.Type(),
|
||||
})
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to unmarshal Actions Row.
|
||||
func (r *ActionsRow) UnmarshalJSON(data []byte) error {
|
||||
var v struct {
|
||||
RawComponents []unmarshalableMessageComponent `json:"components"`
|
||||
}
|
||||
err := json.Unmarshal(data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.Components = make([]MessageComponent, len(v.RawComponents))
|
||||
for i, v := range v.RawComponents {
|
||||
r.Components[i] = v.MessageComponent
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// Type is a method to get the type of a component.
|
||||
func (r ActionsRow) Type() ComponentType {
|
||||
return ActionsRowComponent
|
||||
}
|
||||
|
||||
// ButtonStyle is style of button.
|
||||
type ButtonStyle uint
|
||||
|
||||
// Button styles.
|
||||
const (
|
||||
// PrimaryButton is a button with blurple color.
|
||||
PrimaryButton ButtonStyle = 1
|
||||
// SecondaryButton is a button with grey color.
|
||||
SecondaryButton ButtonStyle = 2
|
||||
// SuccessButton is a button with green color.
|
||||
SuccessButton ButtonStyle = 3
|
||||
// DangerButton is a button with red color.
|
||||
DangerButton ButtonStyle = 4
|
||||
// LinkButton is a special type of button which navigates to a URL. Has grey color.
|
||||
LinkButton ButtonStyle = 5
|
||||
)
|
||||
|
||||
// ComponentEmoji represents button emoji, if it does have one.
|
||||
type ComponentEmoji struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
ID string `json:"id,omitempty"`
|
||||
Animated bool `json:"animated,omitempty"`
|
||||
}
|
||||
|
||||
// Button represents button component.
|
||||
type Button struct {
|
||||
Label string `json:"label"`
|
||||
Style ButtonStyle `json:"style"`
|
||||
Disabled bool `json:"disabled"`
|
||||
Emoji ComponentEmoji `json:"emoji"`
|
||||
|
||||
// NOTE: Only button with LinkButton style can have link. Also, URL is mutually exclusive with CustomID.
|
||||
URL string `json:"url,omitempty"`
|
||||
CustomID string `json:"custom_id,omitempty"`
|
||||
}
|
||||
|
||||
// MarshalJSON is a method for marshaling Button to a JSON object.
|
||||
func (b Button) MarshalJSON() ([]byte, error) {
|
||||
type button Button
|
||||
|
||||
if b.Style == 0 {
|
||||
b.Style = PrimaryButton
|
||||
}
|
||||
|
||||
return json.Marshal(struct {
|
||||
button
|
||||
Type ComponentType `json:"type"`
|
||||
}{
|
||||
button: button(b),
|
||||
Type: b.Type(),
|
||||
})
|
||||
}
|
||||
|
||||
// Type is a method to get the type of a component.
|
||||
func (Button) Type() ComponentType {
|
||||
return ButtonComponent
|
||||
}
|
||||
|
||||
// SelectMenuOption represents an option for a select menu.
|
||||
type SelectMenuOption struct {
|
||||
Label string `json:"label,omitempty"`
|
||||
Value string `json:"value"`
|
||||
Description string `json:"description"`
|
||||
Emoji ComponentEmoji `json:"emoji"`
|
||||
// Determines whenever option is selected by default or not.
|
||||
Default bool `json:"default"`
|
||||
}
|
||||
|
||||
// SelectMenu represents select menu component.
|
||||
type SelectMenu struct {
|
||||
CustomID string `json:"custom_id,omitempty"`
|
||||
// The text which will be shown in the menu if there's no default options or all options was deselected and component was closed.
|
||||
Placeholder string `json:"placeholder"`
|
||||
// This value determines the minimal amount of selected items in the menu.
|
||||
MinValues *int `json:"min_values,omitempty"`
|
||||
// This value determines the maximal amount of selected items in the menu.
|
||||
// If MaxValues or MinValues are greater than one then the user can select multiple items in the component.
|
||||
MaxValues int `json:"max_values,omitempty"`
|
||||
Options []SelectMenuOption `json:"options"`
|
||||
Disabled bool `json:"disabled"`
|
||||
}
|
||||
|
||||
// Type is a method to get the type of a component.
|
||||
func (SelectMenu) Type() ComponentType {
|
||||
return SelectMenuComponent
|
||||
}
|
||||
|
||||
// MarshalJSON is a method for marshaling SelectMenu to a JSON object.
|
||||
func (m SelectMenu) MarshalJSON() ([]byte, error) {
|
||||
type selectMenu SelectMenu
|
||||
|
||||
return json.Marshal(struct {
|
||||
selectMenu
|
||||
Type ComponentType `json:"type"`
|
||||
}{
|
||||
selectMenu: selectMenu(m),
|
||||
Type: m.Type(),
|
||||
})
|
||||
}
|
||||
|
||||
// TextInput represents text input component.
|
||||
type TextInput struct {
|
||||
CustomID string `json:"custom_id"`
|
||||
Label string `json:"label"`
|
||||
Style TextInputStyle `json:"style"`
|
||||
Placeholder string `json:"placeholder,omitempty"`
|
||||
Value string `json:"value,omitempty"`
|
||||
Required bool `json:"required,omitempty"`
|
||||
MinLength int `json:"min_length,omitempty"`
|
||||
MaxLength int `json:"max_length,omitempty"`
|
||||
}
|
||||
|
||||
// Type is a method to get the type of a component.
|
||||
func (TextInput) Type() ComponentType {
|
||||
return TextInputComponent
|
||||
}
|
||||
|
||||
// MarshalJSON is a method for marshaling TextInput to a JSON object.
|
||||
func (m TextInput) MarshalJSON() ([]byte, error) {
|
||||
type inputText TextInput
|
||||
|
||||
return json.Marshal(struct {
|
||||
inputText
|
||||
Type ComponentType `json:"type"`
|
||||
}{
|
||||
inputText: inputText(m),
|
||||
Type: m.Type(),
|
||||
})
|
||||
}
|
||||
|
||||
// TextInputStyle is style of text in TextInput component.
|
||||
type TextInputStyle uint
|
||||
|
||||
// Text styles
|
||||
const (
|
||||
TextInputShort TextInputStyle = 1
|
||||
TextInputParagraph TextInputStyle = 2
|
||||
)
|
60
vendor/github.com/bwmarrin/discordgo/discord.go
generated
vendored
Normal file
60
vendor/github.com/bwmarrin/discordgo/discord.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
// Discordgo - Discord bindings for Go
|
||||
// Available at https://github.com/bwmarrin/discordgo
|
||||
|
||||
// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file contains high level helper functions and easy entry points for the
|
||||
// entire discordgo package. These functions are being developed and are very
|
||||
// experimental at this point. They will most likely change so please use the
|
||||
// low level functions if that's a problem.
|
||||
|
||||
// Package discordgo provides Discord binding for Go
|
||||
package discordgo
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
// VERSION of DiscordGo, follows Semantic Versioning. (http://semver.org/)
|
||||
const VERSION = "0.24.0"
|
||||
|
||||
// New creates a new Discord session with provided token.
|
||||
// If the token is for a bot, it must be prefixed with "Bot "
|
||||
// e.g. "Bot ..."
|
||||
// Or if it is an OAuth2 token, it must be prefixed with "Bearer "
|
||||
// e.g. "Bearer ..."
|
||||
func New(token string) (s *Session, err error) {
|
||||
|
||||
// Create an empty Session interface.
|
||||
s = &Session{
|
||||
State: NewState(),
|
||||
Ratelimiter: NewRatelimiter(),
|
||||
StateEnabled: true,
|
||||
Compress: true,
|
||||
ShouldReconnectOnError: true,
|
||||
ShardID: 0,
|
||||
ShardCount: 1,
|
||||
MaxRestRetries: 3,
|
||||
Client: &http.Client{Timeout: (20 * time.Second)},
|
||||
UserAgent: "DiscordBot (https://github.com/bwmarrin/discordgo, v" + VERSION + ")",
|
||||
sequence: new(int64),
|
||||
LastHeartbeatAck: time.Now().UTC(),
|
||||
}
|
||||
|
||||
// Initilize the Identify Package with defaults
|
||||
// These can be modified prior to calling Open()
|
||||
s.Identify.Compress = true
|
||||
s.Identify.LargeThreshold = 250
|
||||
s.Identify.GuildSubscriptions = true
|
||||
s.Identify.Properties.OS = runtime.GOOS
|
||||
s.Identify.Properties.Browser = "DiscordGo v" + VERSION
|
||||
s.Identify.Intents = IntentsAllWithoutPrivileged
|
||||
s.Identify.Token = token
|
||||
s.Token = token
|
||||
|
||||
return
|
||||
}
|
210
vendor/github.com/bwmarrin/discordgo/endpoints.go
generated
vendored
Normal file
210
vendor/github.com/bwmarrin/discordgo/endpoints.go
generated
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
// Discordgo - Discord bindings for Go
|
||||
// Available at https://github.com/bwmarrin/discordgo
|
||||
|
||||
// Copyright 2015-2016 Bruce Marriner <bruce@sqls.net>. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// This file contains variables for all known Discord end points. All functions
|
||||
// throughout the Discordgo package use these variables for all connections
|
||||
// to Discord. These are all exported and you may modify them if needed.
|
||||
|
||||
package discordgo
|
||||
|
||||
import "strconv"
|
||||
|
||||
// APIVersion is the Discord API version used for the REST and Websocket API.
|
||||
var APIVersion = "9"
|
||||
|
||||
// Known Discord API Endpoints.
|
||||
var (
|
||||
EndpointStatus = "https://status.discord.com/api/v2/"
|
||||
EndpointSm = EndpointStatus + "scheduled-maintenances/"
|
||||
EndpointSmActive = EndpointSm + "active.json"
|
||||
EndpointSmUpcoming = EndpointSm + "upcoming.json"
|
||||
|
||||
EndpointDiscord = "https://discord.com/"
|
||||
EndpointAPI = EndpointDiscord + "api/v" + APIVersion + "/"
|
||||
EndpointGuilds = EndpointAPI + "guilds/"
|
||||
EndpointChannels = EndpointAPI + "channels/"
|
||||
EndpointUsers = EndpointAPI + "users/"
|
||||
EndpointGateway = EndpointAPI + "gateway"
|
||||
EndpointGatewayBot = EndpointGateway + "/bot"
|
||||
EndpointWebhooks = EndpointAPI + "webhooks/"
|
||||
EndpointStickers = EndpointAPI + "stickers/"
|
||||
|
||||
EndpointCDN = "https://cdn.discordapp.com/"
|
||||
EndpointCDNAttachments = EndpointCDN + "attachments/"
|
||||
EndpointCDNAvatars = EndpointCDN + "avatars/"
|
||||
EndpointCDNIcons = EndpointCDN + "icons/"
|
||||
EndpointCDNSplashes = EndpointCDN + "splashes/"
|
||||
EndpointCDNChannelIcons = EndpointCDN + "channel-icons/"
|
||||
EndpointCDNBanners = EndpointCDN + "banners/"
|
||||
EndpointCDNGuilds = EndpointCDN + "guilds/"
|
||||
|
||||
EndpointVoice = EndpointAPI + "/voice/"
|
||||
EndpointVoiceRegions = EndpointVoice + "regions"
|
||||
|
||||
// TODO: EndpointUserGuildMember
|
||||
|
||||
EndpointUser = func(uID string) string { return EndpointUsers + uID }
|
||||
EndpointUserAvatar = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".png" }
|
||||
EndpointUserAvatarAnimated = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".gif" }
|
||||
EndpointDefaultUserAvatar = func(uDiscriminator string) string {
|
||||
uDiscriminatorInt, _ := strconv.Atoi(uDiscriminator)
|
||||
return EndpointCDN + "embed/avatars/" + strconv.Itoa(uDiscriminatorInt%5) + ".png"
|
||||
}
|
||||
EndpointUserBanner = func(uID, cID string) string {
|
||||
return EndpointCDNBanners + uID + "/" + cID + ".png"
|
||||
}
|
||||
EndpointUserBannerAnimated = func(uID, cID string) string {
|
||||
return EndpointCDNBanners + uID + "/" + cID + ".gif"
|
||||
}
|
||||
|
||||
EndpointUserGuilds = func(uID string) string { return EndpointUsers + uID + "/guilds" }
|
||||
EndpointUserGuild = func(uID, gID string) string { return EndpointUsers + uID + "/guilds/" + gID }
|
||||
EndpointUserChannels = func(uID string) string { return EndpointUsers + uID + "/channels" }
|
||||
EndpointUserConnections = func(uID string) string { return EndpointUsers + uID + "/connections" }
|
||||
|
||||
EndpointGuild = func(gID string) string { return EndpointGuilds + gID }
|
||||
EndpointGuildThreads = func(gID string) string { return EndpointGuild(gID) + "/threads" }
|
||||
EndpointGuildActiveThreads = func(gID string) string { return EndpointGuildThreads(gID) + "/active" }
|
||||
EndpointGuildPreview = func(gID string) string { return EndpointGuilds + gID + "/preview" }
|
||||
EndpointGuildChannels = func(gID string) string { return EndpointGuilds + gID + "/channels" }
|
||||
EndpointGuildMembers = func(gID string) string { return EndpointGuilds + gID + "/members" }
|
||||
EndpointGuildMember = func(gID, uID string) string { return EndpointGuilds + gID + "/members/" + uID }
|
||||
EndpointGuildMemberRole = func(gID, uID, rID string) string { return EndpointGuilds + gID + "/members/" + uID + "/roles/" + rID }
|
||||
EndpointGuildBans = func(gID string) string { return EndpointGuilds + gID + "/bans" }
|
||||
EndpointGuildBan = func(gID, uID string) string { return EndpointGuilds + gID + "/bans/" + uID }
|
||||
EndpointGuildIntegrations = func(gID string) string { return EndpointGuilds + gID + "/integrations" }
|
||||
EndpointGuildIntegration = func(gID, iID string) string { return EndpointGuilds + gID + "/integrations/" + iID }
|
||||
EndpointGuildRoles = func(gID string) string { return EndpointGuilds + gID + "/roles" }
|
||||
EndpointGuildRole = func(gID, rID string) string { return EndpointGuilds + gID + "/roles/" + rID }
|
||||
EndpointGuildInvites = func(gID string) string { return EndpointGuilds + gID + "/invites" }
|
||||
EndpointGuildWidget = func(gID string) string { return EndpointGuilds + gID + "/widget" }
|
||||
EndpointGuildEmbed = EndpointGuildWidget
|
||||
EndpointGuildPrune = func(gID string) string { return EndpointGuilds + gID + "/prune" }
|
||||
EndpointGuildIcon = func(gID, hash string) string { return EndpointCDNIcons + gID + "/" + hash + ".png" }
|
||||
EndpointGuildIconAnimated = func(gID, hash string) string { return EndpointCDNIcons + gID + "/" + hash + ".gif" }
|
||||
EndpointGuildSplash = func(gID, hash string) string { return EndpointCDNSplashes + gID + "/" + hash + ".png" }
|
||||
EndpointGuildWebhooks = func(gID string) string { return EndpointGuilds + gID + "/webhooks" }
|
||||
EndpointGuildAuditLogs = func(gID string) string { return EndpointGuilds + gID + "/audit-logs" }
|
||||
EndpointGuildEmojis = func(gID string) string { return EndpointGuilds + gID + "/emojis" }
|
||||
EndpointGuildEmoji = func(gID, eID string) string { return EndpointGuilds + gID + "/emojis/" + eID }
|
||||
EndpointGuildBanner = func(gID, hash string) string { return EndpointCDNBanners + gID + "/" + hash + ".png" }
|
||||
EndpointGuildStickers = func(gID string) string { return EndpointGuilds + gID + "/stickers" }
|
||||
EndpointGuildSticker = func(gID, sID string) string { return EndpointGuilds + gID + "/stickers/" + sID }
|
||||
EndpointGuildScheduledEvents = func(gID string) string { return EndpointGuilds + gID + "/scheduled-events" }
|
||||
EndpointGuildScheduledEvent = func(gID, eID string) string { return EndpointGuilds + gID + "/scheduled-events/" + eID }
|
||||
EndpointGuildScheduledEventUsers = func(gID, eID string) string { return EndpointGuildScheduledEvent(gID, eID) + "/users" }
|
||||
EndpointGuildTemplate = func(tID string) string { return EndpointGuilds + "/templates/" + tID }
|
||||
EndpointGuildTemplates = func(gID string) string { return EndpointGuilds + gID + "/templates" }
|
||||
EndpointGuildTemplateSync = func(gID, tID string) string { return EndpointGuilds + gID + "/templates/" + tID }
|
||||
EndpointGuildMemberAvatar = func(gId, uID, aID string) string {
|
||||
return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".png"
|
||||
}
|
||||
EndpointGuildMemberAvatarAnimated = func(gId, uID, aID string) string {
|
||||
return EndpointCDNGuilds + gId + "/users/" + uID + "/avatars/" + aID + ".gif"
|
||||
}
|
||||
|
||||
EndpointChannel = func(cID string) string { return EndpointChannels + cID }
|
||||
EndpointChannelThreads = func(cID string) string { return EndpointChannel(cID) + "/threads" }
|
||||
EndpointChannelActiveThreads = func(cID string) string { return EndpointChannelThreads(cID) + "/active" }
|
||||
EndpointChannelPublicArchivedThreads = func(cID string) string { return EndpointChannelThreads(cID) + "/archived/public" }
|
||||
EndpointChannelPrivateArchivedThreads = func(cID string) string { return EndpointChannelThreads(cID) + "/archived/private" }
|
||||
EndpointChannelJoinedPrivateArchivedThreads = func(cID string) string { return EndpointChannel(cID) + "/users/@me/threads/archived/private" }
|
||||
EndpointChannelPermissions = func(cID string) string { return EndpointChannels + cID + "/permissions" }
|
||||
EndpointChannelPermission = func(cID, tID string) string { return EndpointChannels + cID + "/permissions/" + tID }
|
||||
EndpointChannelInvites = func(cID string) string { return EndpointChannels + cID + "/invites" }
|
||||
EndpointChannelTyping = func(cID string) string { return EndpointChannels + cID + "/typing" }
|
||||
EndpointChannelMessages = func(cID string) string { return EndpointChannels + cID + "/messages" }
|
||||
EndpointChannelMessage = func(cID, mID string) string { return EndpointChannels + cID + "/messages/" + mID }
|
||||
EndpointChannelMessageThread = func(cID, mID string) string { return EndpointChannelMessage(cID, mID) + "/threads" }
|
||||
EndpointChannelMessagesBulkDelete = func(cID string) string { return EndpointChannel(cID) + "/messages/bulk-delete" }
|
||||
EndpointChannelMessagesPins = func(cID string) string { return EndpointChannel(cID) + "/pins" }
|
||||
EndpointChannelMessagePin = func(cID, mID string) string { return EndpointChannel(cID) + "/pins/" + mID }
|
||||
EndpointChannelMessageCrosspost = func(cID, mID string) string { return EndpointChannel(cID) + "/messages/" + mID + "/crosspost" }
|
||||
EndpointChannelFollow = func(cID string) string { return EndpointChannel(cID) + "/followers" }
|
||||
EndpointThreadMembers = func(tID string) string { return EndpointChannel(tID) + "/thread-members" }
|
||||
EndpointThreadMember = func(tID, mID string) string { return EndpointThreadMembers(tID) + "/" + mID }
|
||||
|
||||
EndpointGroupIcon = func(cID, hash string) string { return EndpointCDNChannelIcons + cID + "/" + hash + ".png" }
|
||||
|
||||
EndpointSticker = func(sID string) string { return EndpointStickers + sID }
|
||||
EndpointNitroStickersPacks = EndpointAPI + "/sticker-packs"
|
||||
|
||||
EndpointChannelWebhooks = func(cID string) string { return EndpointChannel(cID) + "/webhooks" }
|
||||
EndpointWebhook = func(wID string) string { return EndpointWebhooks + wID }
|
||||
EndpointWebhookToken = func(wID, token string) string { return EndpointWebhooks + wID + "/" + token }
|
||||
EndpointWebhookMessage = func(wID, token, messageID string) string {
|
||||
return EndpointWebhookToken(wID, token) + "/messages/" + messageID
|
||||
}
|
||||
|
||||
EndpointMessageReactionsAll = func(cID, mID string) string {
|
||||
return EndpointChannelMessage(cID, mID) + "/reactions"
|
||||
}
|
||||
EndpointMessageReactions = func(cID, mID, eID string) string {
|
||||
return EndpointChannelMessage(cID, mID) + "/reactions/" + eID
|
||||
}
|
||||
EndpointMessageReaction = func(cID, mID, eID, uID string) string {
|
||||
return EndpointMessageReactions(cID, mID, eID) + "/" + uID
|
||||
}
|
||||
|
||||
EndpointApplicationGlobalCommands = func(aID string) string {
|
||||
return EndpointApplication(aID) + "/commands"
|
||||
}
|
||||
EndpointApplicationGlobalCommand = func(aID, cID string) string {
|
||||
return EndpointApplicationGlobalCommands(aID) + "/" + cID
|
||||
}
|
||||
|
||||
EndpointApplicationGuildCommands = func(aID, gID string) string {
|
||||
return EndpointApplication(aID) + "/guilds/" + gID + "/commands"
|
||||
}
|
||||
EndpointApplicationGuildCommand = func(aID, gID, cID string) string {
|
||||
return EndpointApplicationGuildCommands(aID, gID) + "/" + cID
|
||||
}
|
||||
EndpointApplicationCommandPermissions = func(aID, gID, cID string) string {
|
||||
return EndpointApplicationGuildCommand(aID, gID, cID) + "/permissions"
|
||||
}
|
||||
EndpointApplicationCommandsGuildPermissions = func(aID, gID string) string {
|
||||
return EndpointApplicationGuildCommands(aID, gID) + "/permissions"
|
||||
}
|
||||
EndpointInteraction = func(aID, iToken string) string {
|
||||
return EndpointAPI + "interactions/" + aID + "/" + iToken
|
||||
}
|
||||
EndpointInteractionResponse = func(iID, iToken string) string {
|
||||
return EndpointInteraction(iID, iToken) + "/callback"
|
||||
}
|
||||
EndpointInteractionResponseActions = func(aID, iToken string) string {
|
||||
return EndpointWebhookMessage(aID, iToken, "@original")
|
||||
}
|
||||
EndpointFollowupMessage = func(aID, iToken string) string {
|
||||
return EndpointWebhookToken(aID, iToken)
|
||||
}
|
||||
EndpointFollowupMessageActions = func(aID, iToken, mID string) string {
|
||||
return EndpointWebhookMessage(aID, iToken, mID)
|
||||
}
|
||||
|
||||
EndpointGuildCreate = EndpointAPI + "guilds"
|
||||
|
||||
EndpointInvite = func(iID string) string { return EndpointAPI + "invites/" + iID }
|
||||
|
||||
EndpointEmoji = func(eID string) string { return EndpointCDN + "emojis/" + eID + ".png" }
|
||||
EndpointEmojiAnimated = func(eID string) string { return EndpointCDN + "emojis/" + eID + ".gif" }
|
||||
|
||||
EndpointApplications = EndpointAPI + "applications"
|
||||
EndpointApplication = func(aID string) string { return EndpointApplications + "/" + aID }
|
||||
|
||||
EndpointOAuth2 = EndpointAPI + "oauth2/"
|
||||
EndpointOAuth2Applications = EndpointOAuth2 + "applications"
|
||||
EndpointOAuth2Application = func(aID string) string { return EndpointOAuth2Applications + "/" + aID }
|
||||
EndpointOAuth2ApplicationsBot = func(aID string) string { return EndpointOAuth2Applications + "/" + aID + "/bot" }
|
||||
EndpointOAuth2ApplicationAssets = func(aID string) string { return EndpointOAuth2Applications + "/" + aID + "/assets" }
|
||||
|
||||
// TODO: Deprecated, remove in the next release
|
||||
EndpointOauth2 = EndpointOAuth2
|
||||
EndpointOauth2Applications = EndpointOAuth2Applications
|
||||
EndpointOauth2Application = EndpointOAuth2Application
|
||||
EndpointOauth2ApplicationsBot = EndpointOAuth2ApplicationsBot
|
||||
EndpointOauth2ApplicationAssets = EndpointOAuth2ApplicationAssets
|
||||
)
|
@@ -157,7 +157,7 @@ func (s *Session) removeEventHandlerInstance(t string, ehi *eventHandlerInstance
|
||||
onceHandlers := s.onceHandlers[t]
|
||||
for i := range onceHandlers {
|
||||
if onceHandlers[i] == ehi {
|
||||
s.onceHandlers[t] = append(onceHandlers[:i], handlers[i+1:]...)
|
||||
s.onceHandlers[t] = append(onceHandlers[:i], onceHandlers[i+1:]...)
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,50 +7,62 @@ package discordgo
|
||||
// Event type values are used to match the events returned by Discord.
|
||||
// EventTypes surrounded by __ are synthetic and are internal to DiscordGo.
|
||||
const (
|
||||
channelCreateEventType = "CHANNEL_CREATE"
|
||||
channelDeleteEventType = "CHANNEL_DELETE"
|
||||
channelPinsUpdateEventType = "CHANNEL_PINS_UPDATE"
|
||||
channelUpdateEventType = "CHANNEL_UPDATE"
|
||||
connectEventType = "__CONNECT__"
|
||||
disconnectEventType = "__DISCONNECT__"
|
||||
eventEventType = "__EVENT__"
|
||||
guildBanAddEventType = "GUILD_BAN_ADD"
|
||||
guildBanRemoveEventType = "GUILD_BAN_REMOVE"
|
||||
guildCreateEventType = "GUILD_CREATE"
|
||||
guildDeleteEventType = "GUILD_DELETE"
|
||||
guildEmojisUpdateEventType = "GUILD_EMOJIS_UPDATE"
|
||||
guildIntegrationsUpdateEventType = "GUILD_INTEGRATIONS_UPDATE"
|
||||
guildMemberAddEventType = "GUILD_MEMBER_ADD"
|
||||
guildMemberRemoveEventType = "GUILD_MEMBER_REMOVE"
|
||||
guildMemberUpdateEventType = "GUILD_MEMBER_UPDATE"
|
||||
guildMembersChunkEventType = "GUILD_MEMBERS_CHUNK"
|
||||
guildRoleCreateEventType = "GUILD_ROLE_CREATE"
|
||||
guildRoleDeleteEventType = "GUILD_ROLE_DELETE"
|
||||
guildRoleUpdateEventType = "GUILD_ROLE_UPDATE"
|
||||
guildUpdateEventType = "GUILD_UPDATE"
|
||||
messageAckEventType = "MESSAGE_ACK"
|
||||
messageCreateEventType = "MESSAGE_CREATE"
|
||||
messageDeleteEventType = "MESSAGE_DELETE"
|
||||
messageDeleteBulkEventType = "MESSAGE_DELETE_BULK"
|
||||
messageReactionAddEventType = "MESSAGE_REACTION_ADD"
|
||||
messageReactionRemoveEventType = "MESSAGE_REACTION_REMOVE"
|
||||
messageReactionRemoveAllEventType = "MESSAGE_REACTION_REMOVE_ALL"
|
||||
messageUpdateEventType = "MESSAGE_UPDATE"
|
||||
presenceUpdateEventType = "PRESENCE_UPDATE"
|
||||
presencesReplaceEventType = "PRESENCES_REPLACE"
|
||||
rateLimitEventType = "__RATE_LIMIT__"
|
||||
readyEventType = "READY"
|
||||
relationshipAddEventType = "RELATIONSHIP_ADD"
|
||||
relationshipRemoveEventType = "RELATIONSHIP_REMOVE"
|
||||
resumedEventType = "RESUMED"
|
||||
typingStartEventType = "TYPING_START"
|
||||
userGuildSettingsUpdateEventType = "USER_GUILD_SETTINGS_UPDATE"
|
||||
userNoteUpdateEventType = "USER_NOTE_UPDATE"
|
||||
userSettingsUpdateEventType = "USER_SETTINGS_UPDATE"
|
||||
userUpdateEventType = "USER_UPDATE"
|
||||
voiceServerUpdateEventType = "VOICE_SERVER_UPDATE"
|
||||
voiceStateUpdateEventType = "VOICE_STATE_UPDATE"
|
||||
webhooksUpdateEventType = "WEBHOOKS_UPDATE"
|
||||
channelCreateEventType = "CHANNEL_CREATE"
|
||||
channelDeleteEventType = "CHANNEL_DELETE"
|
||||
channelPinsUpdateEventType = "CHANNEL_PINS_UPDATE"
|
||||
channelUpdateEventType = "CHANNEL_UPDATE"
|
||||
connectEventType = "__CONNECT__"
|
||||
disconnectEventType = "__DISCONNECT__"
|
||||
eventEventType = "__EVENT__"
|
||||
guildBanAddEventType = "GUILD_BAN_ADD"
|
||||
guildBanRemoveEventType = "GUILD_BAN_REMOVE"
|
||||
guildCreateEventType = "GUILD_CREATE"
|
||||
guildDeleteEventType = "GUILD_DELETE"
|
||||
guildEmojisUpdateEventType = "GUILD_EMOJIS_UPDATE"
|
||||
guildIntegrationsUpdateEventType = "GUILD_INTEGRATIONS_UPDATE"
|
||||
guildMemberAddEventType = "GUILD_MEMBER_ADD"
|
||||
guildMemberRemoveEventType = "GUILD_MEMBER_REMOVE"
|
||||
guildMemberUpdateEventType = "GUILD_MEMBER_UPDATE"
|
||||
guildMembersChunkEventType = "GUILD_MEMBERS_CHUNK"
|
||||
guildRoleCreateEventType = "GUILD_ROLE_CREATE"
|
||||
guildRoleDeleteEventType = "GUILD_ROLE_DELETE"
|
||||
guildRoleUpdateEventType = "GUILD_ROLE_UPDATE"
|
||||
guildUpdateEventType = "GUILD_UPDATE"
|
||||
guildScheduledEventCreateEventType = "GUILD_SCHEDULED_EVENT_CREATE"
|
||||
guildScheduledEventUpdateEventType = "GUILD_SCHEDULED_EVENT_UPDATE"
|
||||
guildScheduledEventDeleteEventType = "GUILD_SCHEDULED_EVENT_DELETE"
|
||||
interactionCreateEventType = "INTERACTION_CREATE"
|
||||
inviteCreateEventType = "INVITE_CREATE"
|
||||
inviteDeleteEventType = "INVITE_DELETE"
|
||||
messageAckEventType = "MESSAGE_ACK"
|
||||
messageCreateEventType = "MESSAGE_CREATE"
|
||||
messageDeleteEventType = "MESSAGE_DELETE"
|
||||
messageDeleteBulkEventType = "MESSAGE_DELETE_BULK"
|
||||
messageReactionAddEventType = "MESSAGE_REACTION_ADD"
|
||||
messageReactionRemoveEventType = "MESSAGE_REACTION_REMOVE"
|
||||
messageReactionRemoveAllEventType = "MESSAGE_REACTION_REMOVE_ALL"
|
||||
messageUpdateEventType = "MESSAGE_UPDATE"
|
||||
presenceUpdateEventType = "PRESENCE_UPDATE"
|
||||
presencesReplaceEventType = "PRESENCES_REPLACE"
|
||||
rateLimitEventType = "__RATE_LIMIT__"
|
||||
readyEventType = "READY"
|
||||
relationshipAddEventType = "RELATIONSHIP_ADD"
|
||||
relationshipRemoveEventType = "RELATIONSHIP_REMOVE"
|
||||
resumedEventType = "RESUMED"
|
||||
threadCreateEventType = "THREAD_CREATE"
|
||||
threadDeleteEventType = "THREAD_DELETE"
|
||||
threadListSyncEventType = "THREAD_LIST_SYNC"
|
||||
threadMemberUpdateEventType = "THREAD_MEMBER_UPDATE"
|
||||
threadMembersUpdateEventType = "THREAD_MEMBERS_UPDATE"
|
||||
threadUpdateEventType = "THREAD_UPDATE"
|
||||
typingStartEventType = "TYPING_START"
|
||||
userGuildSettingsUpdateEventType = "USER_GUILD_SETTINGS_UPDATE"
|
||||
userNoteUpdateEventType = "USER_NOTE_UPDATE"
|
||||
userSettingsUpdateEventType = "USER_SETTINGS_UPDATE"
|
||||
userUpdateEventType = "USER_UPDATE"
|
||||
voiceServerUpdateEventType = "VOICE_SERVER_UPDATE"
|
||||
voiceStateUpdateEventType = "VOICE_STATE_UPDATE"
|
||||
webhooksUpdateEventType = "WEBHOOKS_UPDATE"
|
||||
)
|
||||
|
||||
// channelCreateEventHandler is an event handler for ChannelCreate events.
|
||||
@@ -298,6 +310,66 @@ func (eh guildIntegrationsUpdateEventHandler) Handle(s *Session, i interface{})
|
||||
}
|
||||
}
|
||||
|
||||
// guildScheduledEventCreateEventHandler is an event handler for GuildScheduledEventCreate events.
|
||||
type guildScheduledEventCreateEventHandler func(*Session, *GuildScheduledEventCreate)
|
||||
|
||||
// Type returns the event type for GuildScheduledEventCreate events.
|
||||
func (eh guildScheduledEventCreateEventHandler) Type() string {
|
||||
return guildScheduledEventCreateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of GuildScheduledEventCreate.
|
||||
func (eh guildScheduledEventCreateEventHandler) New() interface{} {
|
||||
return &GuildScheduledEventCreate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for GuildScheduledEventCreate events.
|
||||
func (eh guildScheduledEventCreateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*GuildScheduledEventCreate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// guildScheduledEventUpdateEventHandler is an event handler for GuildScheduledEventUpdate events.
|
||||
type guildScheduledEventUpdateEventHandler func(*Session, *GuildScheduledEventUpdate)
|
||||
|
||||
// Type returns the event type for GuildScheduledEventUpdate events.
|
||||
func (eh guildScheduledEventUpdateEventHandler) Type() string {
|
||||
return guildScheduledEventUpdateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of GuildScheduledEventUpdate.
|
||||
func (eh guildScheduledEventUpdateEventHandler) New() interface{} {
|
||||
return &GuildScheduledEventUpdate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for GuildScheduledEventUpdate events.
|
||||
func (eh guildScheduledEventUpdateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*GuildScheduledEventUpdate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// guildScheduledEventDeleteEventHandler is an event handler for GuildScheduledEventDelete events.
|
||||
type guildScheduledEventDeleteEventHandler func(*Session, *GuildScheduledEventDelete)
|
||||
|
||||
// Type returns the event type for GuildScheduledEventDelete events.
|
||||
func (eh guildScheduledEventDeleteEventHandler) Type() string {
|
||||
return guildScheduledEventDeleteEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of GuildScheduledEventDelete.
|
||||
func (eh guildScheduledEventDeleteEventHandler) New() interface{} {
|
||||
return &GuildScheduledEventDelete{}
|
||||
}
|
||||
|
||||
// Handle is the handler for GuildScheduledEventDelete events.
|
||||
func (eh guildScheduledEventDeleteEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*GuildScheduledEventDelete); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// guildMemberAddEventHandler is an event handler for GuildMemberAdd events.
|
||||
type guildMemberAddEventHandler func(*Session, *GuildMemberAdd)
|
||||
|
||||
@@ -458,6 +530,66 @@ func (eh guildUpdateEventHandler) Handle(s *Session, i interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// interactionCreateEventHandler is an event handler for InteractionCreate events.
|
||||
type interactionCreateEventHandler func(*Session, *InteractionCreate)
|
||||
|
||||
// Type returns the event type for InteractionCreate events.
|
||||
func (eh interactionCreateEventHandler) Type() string {
|
||||
return interactionCreateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of InteractionCreate.
|
||||
func (eh interactionCreateEventHandler) New() interface{} {
|
||||
return &InteractionCreate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for InteractionCreate events.
|
||||
func (eh interactionCreateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*InteractionCreate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// inviteCreateEventHandler is an event handler for InviteCreate events.
|
||||
type inviteCreateEventHandler func(*Session, *InviteCreate)
|
||||
|
||||
// Type returns the event type for InviteCreate events.
|
||||
func (eh inviteCreateEventHandler) Type() string {
|
||||
return inviteCreateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of InviteCreate.
|
||||
func (eh inviteCreateEventHandler) New() interface{} {
|
||||
return &InviteCreate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for InviteCreate events.
|
||||
func (eh inviteCreateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*InviteCreate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// inviteDeleteEventHandler is an event handler for InviteDelete events.
|
||||
type inviteDeleteEventHandler func(*Session, *InviteDelete)
|
||||
|
||||
// Type returns the event type for InviteDelete events.
|
||||
func (eh inviteDeleteEventHandler) Type() string {
|
||||
return inviteDeleteEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of InviteDelete.
|
||||
func (eh inviteDeleteEventHandler) New() interface{} {
|
||||
return &InviteDelete{}
|
||||
}
|
||||
|
||||
// Handle is the handler for InviteDelete events.
|
||||
func (eh inviteDeleteEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*InviteDelete); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// messageAckEventHandler is an event handler for MessageAck events.
|
||||
type messageAckEventHandler func(*Session, *MessageAck)
|
||||
|
||||
@@ -753,6 +885,126 @@ func (eh resumedEventHandler) Handle(s *Session, i interface{}) {
|
||||
}
|
||||
}
|
||||
|
||||
// threadCreateEventHandler is an event handler for ThreadCreate events.
|
||||
type threadCreateEventHandler func(*Session, *ThreadCreate)
|
||||
|
||||
// Type returns the event type for ThreadCreate events.
|
||||
func (eh threadCreateEventHandler) Type() string {
|
||||
return threadCreateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of ThreadCreate.
|
||||
func (eh threadCreateEventHandler) New() interface{} {
|
||||
return &ThreadCreate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for ThreadCreate events.
|
||||
func (eh threadCreateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*ThreadCreate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// threadDeleteEventHandler is an event handler for ThreadDelete events.
|
||||
type threadDeleteEventHandler func(*Session, *ThreadDelete)
|
||||
|
||||
// Type returns the event type for ThreadDelete events.
|
||||
func (eh threadDeleteEventHandler) Type() string {
|
||||
return threadDeleteEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of ThreadDelete.
|
||||
func (eh threadDeleteEventHandler) New() interface{} {
|
||||
return &ThreadDelete{}
|
||||
}
|
||||
|
||||
// Handle is the handler for ThreadDelete events.
|
||||
func (eh threadDeleteEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*ThreadDelete); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// threadListSyncEventHandler is an event handler for ThreadListSync events.
|
||||
type threadListSyncEventHandler func(*Session, *ThreadListSync)
|
||||
|
||||
// Type returns the event type for ThreadListSync events.
|
||||
func (eh threadListSyncEventHandler) Type() string {
|
||||
return threadListSyncEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of ThreadListSync.
|
||||
func (eh threadListSyncEventHandler) New() interface{} {
|
||||
return &ThreadListSync{}
|
||||
}
|
||||
|
||||
// Handle is the handler for ThreadListSync events.
|
||||
func (eh threadListSyncEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*ThreadListSync); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// threadMemberUpdateEventHandler is an event handler for ThreadMemberUpdate events.
|
||||
type threadMemberUpdateEventHandler func(*Session, *ThreadMemberUpdate)
|
||||
|
||||
// Type returns the event type for ThreadMemberUpdate events.
|
||||
func (eh threadMemberUpdateEventHandler) Type() string {
|
||||
return threadMemberUpdateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of ThreadMemberUpdate.
|
||||
func (eh threadMemberUpdateEventHandler) New() interface{} {
|
||||
return &ThreadMemberUpdate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for ThreadMemberUpdate events.
|
||||
func (eh threadMemberUpdateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*ThreadMemberUpdate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// threadMembersUpdateEventHandler is an event handler for ThreadMembersUpdate events.
|
||||
type threadMembersUpdateEventHandler func(*Session, *ThreadMembersUpdate)
|
||||
|
||||
// Type returns the event type for ThreadMembersUpdate events.
|
||||
func (eh threadMembersUpdateEventHandler) Type() string {
|
||||
return threadMembersUpdateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of ThreadMembersUpdate.
|
||||
func (eh threadMembersUpdateEventHandler) New() interface{} {
|
||||
return &ThreadMembersUpdate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for ThreadMembersUpdate events.
|
||||
func (eh threadMembersUpdateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*ThreadMembersUpdate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// threadUpdateEventHandler is an event handler for ThreadUpdate events.
|
||||
type threadUpdateEventHandler func(*Session, *ThreadUpdate)
|
||||
|
||||
// Type returns the event type for ThreadUpdate events.
|
||||
func (eh threadUpdateEventHandler) Type() string {
|
||||
return threadUpdateEventType
|
||||
}
|
||||
|
||||
// New returns a new instance of ThreadUpdate.
|
||||
func (eh threadUpdateEventHandler) New() interface{} {
|
||||
return &ThreadUpdate{}
|
||||
}
|
||||
|
||||
// Handle is the handler for ThreadUpdate events.
|
||||
func (eh threadUpdateEventHandler) Handle(s *Session, i interface{}) {
|
||||
if t, ok := i.(*ThreadUpdate); ok {
|
||||
eh(s, t)
|
||||
}
|
||||
}
|
||||
|
||||
// typingStartEventHandler is an event handler for TypingStart events.
|
||||
type typingStartEventHandler func(*Session, *TypingStart)
|
||||
|
||||
@@ -943,6 +1195,12 @@ func handlerForInterface(handler interface{}) EventHandler {
|
||||
return guildEmojisUpdateEventHandler(v)
|
||||
case func(*Session, *GuildIntegrationsUpdate):
|
||||
return guildIntegrationsUpdateEventHandler(v)
|
||||
case func(*Session, *GuildScheduledEventCreate):
|
||||
return guildScheduledEventCreateEventHandler(v)
|
||||
case func(*Session, *GuildScheduledEventUpdate):
|
||||
return guildScheduledEventUpdateEventHandler(v)
|
||||
case func(*Session, *GuildScheduledEventDelete):
|
||||
return guildScheduledEventDeleteEventHandler(v)
|
||||
case func(*Session, *GuildMemberAdd):
|
||||
return guildMemberAddEventHandler(v)
|
||||
case func(*Session, *GuildMemberRemove):
|
||||
@@ -959,6 +1217,12 @@ func handlerForInterface(handler interface{}) EventHandler {
|
||||
return guildRoleUpdateEventHandler(v)
|
||||
case func(*Session, *GuildUpdate):
|
||||
return guildUpdateEventHandler(v)
|
||||
case func(*Session, *InteractionCreate):
|
||||
return interactionCreateEventHandler(v)
|
||||
case func(*Session, *InviteCreate):
|
||||
return inviteCreateEventHandler(v)
|
||||
case func(*Session, *InviteDelete):
|
||||
return inviteDeleteEventHandler(v)
|
||||
case func(*Session, *MessageAck):
|
||||
return messageAckEventHandler(v)
|
||||
case func(*Session, *MessageCreate):
|
||||
@@ -989,6 +1253,18 @@ func handlerForInterface(handler interface{}) EventHandler {
|
||||
return relationshipRemoveEventHandler(v)
|
||||
case func(*Session, *Resumed):
|
||||
return resumedEventHandler(v)
|
||||
case func(*Session, *ThreadCreate):
|
||||
return threadCreateEventHandler(v)
|
||||
case func(*Session, *ThreadDelete):
|
||||
return threadDeleteEventHandler(v)
|
||||
case func(*Session, *ThreadListSync):
|
||||
return threadListSyncEventHandler(v)
|
||||
case func(*Session, *ThreadMemberUpdate):
|
||||
return threadMemberUpdateEventHandler(v)
|
||||
case func(*Session, *ThreadMembersUpdate):
|
||||
return threadMembersUpdateEventHandler(v)
|
||||
case func(*Session, *ThreadUpdate):
|
||||
return threadUpdateEventHandler(v)
|
||||
case func(*Session, *TypingStart):
|
||||
return typingStartEventHandler(v)
|
||||
case func(*Session, *UserGuildSettingsUpdate):
|
||||
@@ -1021,6 +1297,9 @@ func init() {
|
||||
registerInterfaceProvider(guildDeleteEventHandler(nil))
|
||||
registerInterfaceProvider(guildEmojisUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(guildIntegrationsUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(guildScheduledEventCreateEventHandler(nil))
|
||||
registerInterfaceProvider(guildScheduledEventUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(guildScheduledEventDeleteEventHandler(nil))
|
||||
registerInterfaceProvider(guildMemberAddEventHandler(nil))
|
||||
registerInterfaceProvider(guildMemberRemoveEventHandler(nil))
|
||||
registerInterfaceProvider(guildMemberUpdateEventHandler(nil))
|
||||
@@ -1029,6 +1308,9 @@ func init() {
|
||||
registerInterfaceProvider(guildRoleDeleteEventHandler(nil))
|
||||
registerInterfaceProvider(guildRoleUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(guildUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(interactionCreateEventHandler(nil))
|
||||
registerInterfaceProvider(inviteCreateEventHandler(nil))
|
||||
registerInterfaceProvider(inviteDeleteEventHandler(nil))
|
||||
registerInterfaceProvider(messageAckEventHandler(nil))
|
||||
registerInterfaceProvider(messageCreateEventHandler(nil))
|
||||
registerInterfaceProvider(messageDeleteEventHandler(nil))
|
||||
@@ -1043,6 +1325,12 @@ func init() {
|
||||
registerInterfaceProvider(relationshipAddEventHandler(nil))
|
||||
registerInterfaceProvider(relationshipRemoveEventHandler(nil))
|
||||
registerInterfaceProvider(resumedEventHandler(nil))
|
||||
registerInterfaceProvider(threadCreateEventHandler(nil))
|
||||
registerInterfaceProvider(threadDeleteEventHandler(nil))
|
||||
registerInterfaceProvider(threadListSyncEventHandler(nil))
|
||||
registerInterfaceProvider(threadMemberUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(threadMembersUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(threadUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(typingStartEventHandler(nil))
|
||||
registerInterfaceProvider(userGuildSettingsUpdateEventHandler(nil))
|
||||
registerInterfaceProvider(userNoteUpdateEventHandler(nil))
|
@@ -73,6 +73,53 @@ type ChannelPinsUpdate struct {
|
||||
GuildID string `json:"guild_id,omitempty"`
|
||||
}
|
||||
|
||||
// ThreadCreate is the data for a ThreadCreate event.
|
||||
type ThreadCreate struct {
|
||||
*Channel
|
||||
NewlyCreated bool `json:"newly_created"`
|
||||
}
|
||||
|
||||
// ThreadUpdate is the data for a ThreadUpdate event.
|
||||
type ThreadUpdate struct {
|
||||
*Channel
|
||||
BeforeUpdate *Channel `json:"-"`
|
||||
}
|
||||
|
||||
// ThreadDelete is the data for a ThreadDelete event.
|
||||
type ThreadDelete struct {
|
||||
*Channel
|
||||
}
|
||||
|
||||
// ThreadListSync is the data for a ThreadListSync event.
|
||||
type ThreadListSync struct {
|
||||
// The id of the guild
|
||||
GuildID string `json:"guild_id"`
|
||||
// The parent channel ids whose threads are being synced.
|
||||
// If omitted, then threads were synced for the entire guild.
|
||||
// This array may contain channel_ids that have no active threads as well, so you know to clear that data.
|
||||
ChannelIDs []string `json:"channel_ids"`
|
||||
// All active threads in the given channels that the current user can access
|
||||
Threads []*Channel `json:"threads"`
|
||||
// All thread member objects from the synced threads for the current user,
|
||||
// indicating which threads the current user has been added to
|
||||
Members []*ThreadMember `json:"members"`
|
||||
}
|
||||
|
||||
// ThreadMemberUpdate is the data for a ThreadMemberUpdate event.
|
||||
type ThreadMemberUpdate struct {
|
||||
*ThreadMember
|
||||
GuildID string `json:"guild_id"`
|
||||
}
|
||||
|
||||
// ThreadMembersUpdate is the data for a ThreadMembersUpdate event.
|
||||
type ThreadMembersUpdate struct {
|
||||
ID string `json:"id"`
|
||||
GuildID string `json:"guild_id"`
|
||||
MemberCount int `json:"member_count"`
|
||||
AddedMembers []AddedThreadMember `json:"added_members"`
|
||||
RemovedMembers []string `json:"removed_member_ids"`
|
||||
}
|
||||
|
||||
// GuildCreate is the data for a GuildCreate event.
|
||||
type GuildCreate struct {
|
||||
*Guild
|
||||
@@ -86,6 +133,7 @@ type GuildUpdate struct {
|
||||
// GuildDelete is the data for a GuildDelete event.
|
||||
type GuildDelete struct {
|
||||
*Guild
|
||||
BeforeDelete *Guild `json:"-"`
|
||||
}
|
||||
|
||||
// GuildBanAdd is the data for a GuildBanAdd event.
|
||||
@@ -151,6 +199,21 @@ type GuildIntegrationsUpdate struct {
|
||||
GuildID string `json:"guild_id"`
|
||||
}
|
||||
|
||||
// GuildScheduledEventCreate is the data for a GuildScheduledEventCreate event.
|
||||
type GuildScheduledEventCreate struct {
|
||||
*GuildScheduledEvent
|
||||
}
|
||||
|
||||
// GuildScheduledEventUpdate is the data for a GuildScheduledEventUpdate event.
|
||||
type GuildScheduledEventUpdate struct {
|
||||
*GuildScheduledEvent
|
||||
}
|
||||
|
||||
// GuildScheduledEventDelete is the data for a GuildScheduledEventDelete event.
|
||||
type GuildScheduledEventDelete struct {
|
||||
*GuildScheduledEvent
|
||||
}
|
||||
|
||||
// MessageAck is the data for a MessageAck event.
|
||||
type MessageAck struct {
|
||||
MessageID string `json:"message_id"`
|
||||
@@ -162,6 +225,11 @@ type MessageCreate struct {
|
||||
*Message
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to unmarshal MessageCreate object.
|
||||
func (m *MessageCreate) UnmarshalJSON(b []byte) error {
|
||||
return json.Unmarshal(b, &m.Message)
|
||||
}
|
||||
|
||||
// MessageUpdate is the data for a MessageUpdate event.
|
||||
type MessageUpdate struct {
|
||||
*Message
|
||||
@@ -169,15 +237,26 @@ type MessageUpdate struct {
|
||||
BeforeUpdate *Message `json:"-"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to unmarshal MessageUpdate object.
|
||||
func (m *MessageUpdate) UnmarshalJSON(b []byte) error {
|
||||
return json.Unmarshal(b, &m.Message)
|
||||
}
|
||||
|
||||
// MessageDelete is the data for a MessageDelete event.
|
||||
type MessageDelete struct {
|
||||
*Message
|
||||
BeforeDelete *Message `json:"-"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to unmarshal MessageDelete object.
|
||||
func (m *MessageDelete) UnmarshalJSON(b []byte) error {
|
||||
return json.Unmarshal(b, &m.Message)
|
||||
}
|
||||
|
||||
// MessageReactionAdd is the data for a MessageReactionAdd event.
|
||||
type MessageReactionAdd struct {
|
||||
*MessageReaction
|
||||
Member *Member `json:"member,omitempty"`
|
||||
}
|
||||
|
||||
// MessageReactionRemove is the data for a MessageReactionRemove event.
|
||||
@@ -267,3 +346,27 @@ type WebhooksUpdate struct {
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
}
|
||||
|
||||
// InteractionCreate is the data for a InteractionCreate event
|
||||
type InteractionCreate struct {
|
||||
*Interaction
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to unmarshal Interaction object.
|
||||
func (i *InteractionCreate) UnmarshalJSON(b []byte) error {
|
||||
return json.Unmarshal(b, &i.Interaction)
|
||||
}
|
||||
|
||||
// InviteCreate is the data for a InviteCreate event
|
||||
type InviteCreate struct {
|
||||
*Invite
|
||||
ChannelID string `json:"channel_id"`
|
||||
GuildID string `json:"guild_id"`
|
||||
}
|
||||
|
||||
// InviteDelete is the data for a InviteDelete event
|
||||
type InviteDelete struct {
|
||||
ChannelID string `json:"channel_id"`
|
||||
GuildID string `json:"guild_id"`
|
||||
Code string `json:"code"`
|
||||
}
|
568
vendor/github.com/bwmarrin/discordgo/interactions.go
generated
vendored
Normal file
568
vendor/github.com/bwmarrin/discordgo/interactions.go
generated
vendored
Normal file
@@ -0,0 +1,568 @@
|
||||
package discordgo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"crypto/ed25519"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// InteractionDeadline is the time allowed to respond to an interaction.
|
||||
const InteractionDeadline = time.Second * 3
|
||||
|
||||
// ApplicationCommandType represents the type of application command.
|
||||
type ApplicationCommandType uint8
|
||||
|
||||
// Application command types
|
||||
const (
|
||||
// ChatApplicationCommand is default command type. They are slash commands (i.e. called directly from the chat).
|
||||
ChatApplicationCommand ApplicationCommandType = 1
|
||||
// UserApplicationCommand adds command to user context menu.
|
||||
UserApplicationCommand ApplicationCommandType = 2
|
||||
// MessageApplicationCommand adds command to message context menu.
|
||||
MessageApplicationCommand ApplicationCommandType = 3
|
||||
)
|
||||
|
||||
// ApplicationCommand represents an application's slash command.
|
||||
type ApplicationCommand struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
ApplicationID string `json:"application_id,omitempty"`
|
||||
Version string `json:"version,omitempty"`
|
||||
Type ApplicationCommandType `json:"type,omitempty"`
|
||||
Name string `json:"name"`
|
||||
DefaultPermission *bool `json:"default_permission,omitempty"`
|
||||
|
||||
// NOTE: Chat commands only. Otherwise it mustn't be set.
|
||||
|
||||
Description string `json:"description,omitempty"`
|
||||
Options []*ApplicationCommandOption `json:"options"`
|
||||
}
|
||||
|
||||
// ApplicationCommandOptionType indicates the type of a slash command's option.
|
||||
type ApplicationCommandOptionType uint8
|
||||
|
||||
// Application command option types.
|
||||
const (
|
||||
ApplicationCommandOptionSubCommand ApplicationCommandOptionType = 1
|
||||
ApplicationCommandOptionSubCommandGroup ApplicationCommandOptionType = 2
|
||||
ApplicationCommandOptionString ApplicationCommandOptionType = 3
|
||||
ApplicationCommandOptionInteger ApplicationCommandOptionType = 4
|
||||
ApplicationCommandOptionBoolean ApplicationCommandOptionType = 5
|
||||
ApplicationCommandOptionUser ApplicationCommandOptionType = 6
|
||||
ApplicationCommandOptionChannel ApplicationCommandOptionType = 7
|
||||
ApplicationCommandOptionRole ApplicationCommandOptionType = 8
|
||||
ApplicationCommandOptionMentionable ApplicationCommandOptionType = 9
|
||||
ApplicationCommandOptionNumber ApplicationCommandOptionType = 10
|
||||
ApplicationCommandOptionAttachment ApplicationCommandOptionType = 11
|
||||
)
|
||||
|
||||
func (t ApplicationCommandOptionType) String() string {
|
||||
switch t {
|
||||
case ApplicationCommandOptionSubCommand:
|
||||
return "SubCommand"
|
||||
case ApplicationCommandOptionSubCommandGroup:
|
||||
return "SubCommandGroup"
|
||||
case ApplicationCommandOptionString:
|
||||
return "String"
|
||||
case ApplicationCommandOptionInteger:
|
||||
return "Integer"
|
||||
case ApplicationCommandOptionBoolean:
|
||||
return "Boolean"
|
||||
case ApplicationCommandOptionUser:
|
||||
return "User"
|
||||
case ApplicationCommandOptionChannel:
|
||||
return "Channel"
|
||||
case ApplicationCommandOptionRole:
|
||||
return "Role"
|
||||
case ApplicationCommandOptionMentionable:
|
||||
return "Mentionable"
|
||||
case ApplicationCommandOptionNumber:
|
||||
return "Number"
|
||||
case ApplicationCommandOptionAttachment:
|
||||
return "Attachment"
|
||||
}
|
||||
return fmt.Sprintf("ApplicationCommandOptionType(%d)", t)
|
||||
}
|
||||
|
||||
// ApplicationCommandOption represents an option/subcommand/subcommands group.
|
||||
type ApplicationCommandOption struct {
|
||||
Type ApplicationCommandOptionType `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
// NOTE: This feature was on the API, but at some point developers decided to remove it.
|
||||
// So I commented it, until it will be officially on the docs.
|
||||
// Default bool `json:"default"`
|
||||
|
||||
ChannelTypes []ChannelType `json:"channel_types"`
|
||||
Required bool `json:"required"`
|
||||
Options []*ApplicationCommandOption `json:"options"`
|
||||
|
||||
// NOTE: mutually exclusive with Choices.
|
||||
Autocomplete bool `json:"autocomplete"`
|
||||
Choices []*ApplicationCommandOptionChoice `json:"choices"`
|
||||
// Minimal value of number/integer option.
|
||||
MinValue *float64 `json:"min_value,omitempty"`
|
||||
// Maximum value of number/integer option.
|
||||
MaxValue float64 `json:"max_value,omitempty"`
|
||||
}
|
||||
|
||||
// ApplicationCommandOptionChoice represents a slash command option choice.
|
||||
type ApplicationCommandOptionChoice struct {
|
||||
Name string `json:"name"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
// ApplicationCommandPermissions represents a single user or role permission for a command.
|
||||
type ApplicationCommandPermissions struct {
|
||||
ID string `json:"id"`
|
||||
Type ApplicationCommandPermissionType `json:"type"`
|
||||
Permission bool `json:"permission"`
|
||||
}
|
||||
|
||||
// ApplicationCommandPermissionsList represents a list of ApplicationCommandPermissions, needed for serializing to JSON.
|
||||
type ApplicationCommandPermissionsList struct {
|
||||
Permissions []*ApplicationCommandPermissions `json:"permissions"`
|
||||
}
|
||||
|
||||
// GuildApplicationCommandPermissions represents all permissions for a single guild command.
|
||||
type GuildApplicationCommandPermissions struct {
|
||||
ID string `json:"id"`
|
||||
ApplicationID string `json:"application_id"`
|
||||
GuildID string `json:"guild_id"`
|
||||
Permissions []*ApplicationCommandPermissions `json:"permissions"`
|
||||
}
|
||||
|
||||
// ApplicationCommandPermissionType indicates whether a permission is user or role based.
|
||||
type ApplicationCommandPermissionType uint8
|
||||
|
||||
// Application command permission types.
|
||||
const (
|
||||
ApplicationCommandPermissionTypeRole ApplicationCommandPermissionType = 1
|
||||
ApplicationCommandPermissionTypeUser ApplicationCommandPermissionType = 2
|
||||
)
|
||||
|
||||
// InteractionType indicates the type of an interaction event.
|
||||
type InteractionType uint8
|
||||
|
||||
// Interaction types
|
||||
const (
|
||||
InteractionPing InteractionType = 1
|
||||
InteractionApplicationCommand InteractionType = 2
|
||||
InteractionMessageComponent InteractionType = 3
|
||||
InteractionApplicationCommandAutocomplete InteractionType = 4
|
||||
InteractionModalSubmit InteractionType = 5
|
||||
)
|
||||
|
||||
func (t InteractionType) String() string {
|
||||
switch t {
|
||||
case InteractionPing:
|
||||
return "Ping"
|
||||
case InteractionApplicationCommand:
|
||||
return "ApplicationCommand"
|
||||
case InteractionMessageComponent:
|
||||
return "MessageComponent"
|
||||
case InteractionModalSubmit:
|
||||
return "ModalSubmit"
|
||||
}
|
||||
return fmt.Sprintf("InteractionType(%d)", t)
|
||||
}
|
||||
|
||||
// Interaction represents data of an interaction.
|
||||
type Interaction struct {
|
||||
ID string `json:"id"`
|
||||
Type InteractionType `json:"type"`
|
||||
Data InteractionData `json:"data"`
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
|
||||
// The message on which interaction was used.
|
||||
// NOTE: this field is only filled when a button click triggered the interaction. Otherwise it will be nil.
|
||||
Message *Message `json:"message"`
|
||||
|
||||
// The member who invoked this interaction.
|
||||
// NOTE: this field is only filled when the slash command was invoked in a guild;
|
||||
// if it was invoked in a DM, the `User` field will be filled instead.
|
||||
// Make sure to check for `nil` before using this field.
|
||||
Member *Member `json:"member"`
|
||||
// The user who invoked this interaction.
|
||||
// NOTE: this field is only filled when the slash command was invoked in a DM;
|
||||
// if it was invoked in a guild, the `Member` field will be filled instead.
|
||||
// Make sure to check for `nil` before using this field.
|
||||
User *User `json:"user"`
|
||||
|
||||
// The user's discord client locale.
|
||||
Locale Locale `json:"locale"`
|
||||
// The guild's locale. This defaults to EnglishUS
|
||||
// NOTE: this field is only filled when the interaction was invoked in a guild.
|
||||
GuildLocale *Locale `json:"guild_locale"`
|
||||
|
||||
Token string `json:"token"`
|
||||
Version int `json:"version"`
|
||||
}
|
||||
|
||||
type interaction Interaction
|
||||
|
||||
type rawInteraction struct {
|
||||
interaction
|
||||
Data json.RawMessage `json:"data"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a method for unmarshalling JSON object to Interaction.
|
||||
func (i *Interaction) UnmarshalJSON(raw []byte) error {
|
||||
var tmp rawInteraction
|
||||
err := json.Unmarshal(raw, &tmp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
*i = Interaction(tmp.interaction)
|
||||
|
||||
switch tmp.Type {
|
||||
case InteractionApplicationCommand, InteractionApplicationCommandAutocomplete:
|
||||
v := ApplicationCommandInteractionData{}
|
||||
err = json.Unmarshal(tmp.Data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Data = v
|
||||
case InteractionMessageComponent:
|
||||
v := MessageComponentInteractionData{}
|
||||
err = json.Unmarshal(tmp.Data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Data = v
|
||||
case InteractionModalSubmit:
|
||||
v := ModalSubmitInteractionData{}
|
||||
err = json.Unmarshal(tmp.Data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
i.Data = v
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MessageComponentData is helper function to assert the inner InteractionData to MessageComponentInteractionData.
|
||||
// Make sure to check that the Type of the interaction is InteractionMessageComponent before calling.
|
||||
func (i Interaction) MessageComponentData() (data MessageComponentInteractionData) {
|
||||
if i.Type != InteractionMessageComponent {
|
||||
panic("MessageComponentData called on interaction of type " + i.Type.String())
|
||||
}
|
||||
return i.Data.(MessageComponentInteractionData)
|
||||
}
|
||||
|
||||
// ApplicationCommandData is helper function to assert the inner InteractionData to ApplicationCommandInteractionData.
|
||||
// Make sure to check that the Type of the interaction is InteractionApplicationCommand before calling.
|
||||
func (i Interaction) ApplicationCommandData() (data ApplicationCommandInteractionData) {
|
||||
if i.Type != InteractionApplicationCommand && i.Type != InteractionApplicationCommandAutocomplete {
|
||||
panic("ApplicationCommandData called on interaction of type " + i.Type.String())
|
||||
}
|
||||
return i.Data.(ApplicationCommandInteractionData)
|
||||
}
|
||||
|
||||
// ModalSubmitData is helper function to assert the inner InteractionData to ModalSubmitInteractionData.
|
||||
// Make sure to check that the Type of the interaction is InteractionModalSubmit before calling.
|
||||
func (i Interaction) ModalSubmitData() (data ModalSubmitInteractionData) {
|
||||
if i.Type != InteractionModalSubmit {
|
||||
panic("ModalSubmitData called on interaction of type " + i.Type.String())
|
||||
}
|
||||
return i.Data.(ModalSubmitInteractionData)
|
||||
}
|
||||
|
||||
// InteractionData is a common interface for all types of interaction data.
|
||||
type InteractionData interface {
|
||||
Type() InteractionType
|
||||
}
|
||||
|
||||
// ApplicationCommandInteractionData contains the data of application command interaction.
|
||||
type ApplicationCommandInteractionData struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Resolved *ApplicationCommandInteractionDataResolved `json:"resolved"`
|
||||
|
||||
// Slash command options
|
||||
Options []*ApplicationCommandInteractionDataOption `json:"options"`
|
||||
// Target (user/message) id on which context menu command was called.
|
||||
// The details are stored in Resolved according to command type.
|
||||
TargetID string `json:"target_id"`
|
||||
}
|
||||
|
||||
// ApplicationCommandInteractionDataResolved contains resolved data of command execution.
|
||||
// Partial Member objects are missing user, deaf and mute fields.
|
||||
// Partial Channel objects only have id, name, type and permissions fields.
|
||||
type ApplicationCommandInteractionDataResolved struct {
|
||||
Users map[string]*User `json:"users"`
|
||||
Members map[string]*Member `json:"members"`
|
||||
Roles map[string]*Role `json:"roles"`
|
||||
Channels map[string]*Channel `json:"channels"`
|
||||
Messages map[string]*Message `json:"messages"`
|
||||
Attachments map[string]*MessageAttachment `json:"attachments"`
|
||||
}
|
||||
|
||||
// Type returns the type of interaction data.
|
||||
func (ApplicationCommandInteractionData) Type() InteractionType {
|
||||
return InteractionApplicationCommand
|
||||
}
|
||||
|
||||
// MessageComponentInteractionData contains the data of message component interaction.
|
||||
type MessageComponentInteractionData struct {
|
||||
CustomID string `json:"custom_id"`
|
||||
ComponentType ComponentType `json:"component_type"`
|
||||
|
||||
// NOTE: Only filled when ComponentType is SelectMenuComponent (3). Otherwise is nil.
|
||||
Values []string `json:"values"`
|
||||
}
|
||||
|
||||
// Type returns the type of interaction data.
|
||||
func (MessageComponentInteractionData) Type() InteractionType {
|
||||
return InteractionMessageComponent
|
||||
}
|
||||
|
||||
// ModalSubmitInteractionData contains the data of modal submit interaction.
|
||||
type ModalSubmitInteractionData struct {
|
||||
CustomID string `json:"custom_id"`
|
||||
Components []MessageComponent `json:"-"`
|
||||
}
|
||||
|
||||
// Type returns the type of interaction data.
|
||||
func (ModalSubmitInteractionData) Type() InteractionType {
|
||||
return InteractionModalSubmit
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to correctly unmarshal Components.
|
||||
func (d *ModalSubmitInteractionData) UnmarshalJSON(data []byte) error {
|
||||
type modalSubmitInteractionData ModalSubmitInteractionData
|
||||
var v struct {
|
||||
modalSubmitInteractionData
|
||||
RawComponents []unmarshalableMessageComponent `json:"components"`
|
||||
}
|
||||
err := json.Unmarshal(data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*d = ModalSubmitInteractionData(v.modalSubmitInteractionData)
|
||||
d.Components = make([]MessageComponent, len(v.RawComponents))
|
||||
for i, v := range v.RawComponents {
|
||||
d.Components[i] = v.MessageComponent
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// ApplicationCommandInteractionDataOption represents an option of a slash command.
|
||||
type ApplicationCommandInteractionDataOption struct {
|
||||
Name string `json:"name"`
|
||||
Type ApplicationCommandOptionType `json:"type"`
|
||||
// NOTE: Contains the value specified by Type.
|
||||
Value interface{} `json:"value,omitempty"`
|
||||
Options []*ApplicationCommandInteractionDataOption `json:"options,omitempty"`
|
||||
|
||||
// NOTE: autocomplete interaction only.
|
||||
Focused bool `json:"focused,omitempty"`
|
||||
}
|
||||
|
||||
// IntValue is a utility function for casting option value to integer
|
||||
func (o ApplicationCommandInteractionDataOption) IntValue() int64 {
|
||||
if o.Type != ApplicationCommandOptionInteger {
|
||||
panic("IntValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
return int64(o.Value.(float64))
|
||||
}
|
||||
|
||||
// UintValue is a utility function for casting option value to unsigned integer
|
||||
func (o ApplicationCommandInteractionDataOption) UintValue() uint64 {
|
||||
if o.Type != ApplicationCommandOptionInteger {
|
||||
panic("UintValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
return uint64(o.Value.(float64))
|
||||
}
|
||||
|
||||
// FloatValue is a utility function for casting option value to float
|
||||
func (o ApplicationCommandInteractionDataOption) FloatValue() float64 {
|
||||
if o.Type != ApplicationCommandOptionNumber {
|
||||
panic("FloatValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
return o.Value.(float64)
|
||||
}
|
||||
|
||||
// StringValue is a utility function for casting option value to string
|
||||
func (o ApplicationCommandInteractionDataOption) StringValue() string {
|
||||
if o.Type != ApplicationCommandOptionString {
|
||||
panic("StringValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
return o.Value.(string)
|
||||
}
|
||||
|
||||
// BoolValue is a utility function for casting option value to bool
|
||||
func (o ApplicationCommandInteractionDataOption) BoolValue() bool {
|
||||
if o.Type != ApplicationCommandOptionBoolean {
|
||||
panic("BoolValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
return o.Value.(bool)
|
||||
}
|
||||
|
||||
// ChannelValue is a utility function for casting option value to channel object.
|
||||
// s : Session object, if not nil, function additionally fetches all channel's data
|
||||
func (o ApplicationCommandInteractionDataOption) ChannelValue(s *Session) *Channel {
|
||||
if o.Type != ApplicationCommandOptionChannel {
|
||||
panic("ChannelValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
chanID := o.Value.(string)
|
||||
|
||||
if s == nil {
|
||||
return &Channel{ID: chanID}
|
||||
}
|
||||
|
||||
ch, err := s.State.Channel(chanID)
|
||||
if err != nil {
|
||||
ch, err = s.Channel(chanID)
|
||||
if err != nil {
|
||||
return &Channel{ID: chanID}
|
||||
}
|
||||
}
|
||||
|
||||
return ch
|
||||
}
|
||||
|
||||
// RoleValue is a utility function for casting option value to role object.
|
||||
// s : Session object, if not nil, function additionally fetches all role's data
|
||||
func (o ApplicationCommandInteractionDataOption) RoleValue(s *Session, gID string) *Role {
|
||||
if o.Type != ApplicationCommandOptionRole && o.Type != ApplicationCommandOptionMentionable {
|
||||
panic("RoleValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
roleID := o.Value.(string)
|
||||
|
||||
if s == nil || gID == "" {
|
||||
return &Role{ID: roleID}
|
||||
}
|
||||
|
||||
r, err := s.State.Role(roleID, gID)
|
||||
if err != nil {
|
||||
roles, err := s.GuildRoles(gID)
|
||||
if err == nil {
|
||||
for _, r = range roles {
|
||||
if r.ID == roleID {
|
||||
return r
|
||||
}
|
||||
}
|
||||
}
|
||||
return &Role{ID: roleID}
|
||||
}
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
// UserValue is a utility function for casting option value to user object.
|
||||
// s : Session object, if not nil, function additionally fetches all user's data
|
||||
func (o ApplicationCommandInteractionDataOption) UserValue(s *Session) *User {
|
||||
if o.Type != ApplicationCommandOptionUser && o.Type != ApplicationCommandOptionMentionable {
|
||||
panic("UserValue called on data option of type " + o.Type.String())
|
||||
}
|
||||
userID := o.Value.(string)
|
||||
|
||||
if s == nil {
|
||||
return &User{ID: userID}
|
||||
}
|
||||
|
||||
u, err := s.User(userID)
|
||||
if err != nil {
|
||||
return &User{ID: userID}
|
||||
}
|
||||
|
||||
return u
|
||||
}
|
||||
|
||||
// InteractionResponseType is type of interaction response.
|
||||
type InteractionResponseType uint8
|
||||
|
||||
// Interaction response types.
|
||||
const (
|
||||
// InteractionResponsePong is for ACK ping event.
|
||||
InteractionResponsePong InteractionResponseType = 1
|
||||
// InteractionResponseChannelMessageWithSource is for responding with a message, showing the user's input.
|
||||
InteractionResponseChannelMessageWithSource InteractionResponseType = 4
|
||||
// InteractionResponseDeferredChannelMessageWithSource acknowledges that the event was received, and that a follow-up will come later.
|
||||
InteractionResponseDeferredChannelMessageWithSource InteractionResponseType = 5
|
||||
// InteractionResponseDeferredMessageUpdate acknowledges that the message component interaction event was received, and message will be updated later.
|
||||
InteractionResponseDeferredMessageUpdate InteractionResponseType = 6
|
||||
// InteractionResponseUpdateMessage is for updating the message to which message component was attached.
|
||||
InteractionResponseUpdateMessage InteractionResponseType = 7
|
||||
// InteractionApplicationCommandAutocompleteResult shows autocompletion results. Autocomplete interaction only.
|
||||
InteractionApplicationCommandAutocompleteResult InteractionResponseType = 8
|
||||
// InteractionResponseModal is for responding to an interaction with a modal window.
|
||||
InteractionResponseModal InteractionResponseType = 9
|
||||
)
|
||||
|
||||
// InteractionResponse represents a response for an interaction event.
|
||||
type InteractionResponse struct {
|
||||
Type InteractionResponseType `json:"type,omitempty"`
|
||||
Data *InteractionResponseData `json:"data,omitempty"`
|
||||
}
|
||||
|
||||
// InteractionResponseData is response data for an interaction.
|
||||
type InteractionResponseData struct {
|
||||
TTS bool `json:"tts"`
|
||||
Content string `json:"content"`
|
||||
Components []MessageComponent `json:"components"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
Flags uint64 `json:"flags,omitempty"`
|
||||
Files []*File `json:"-"`
|
||||
|
||||
// NOTE: autocomplete interaction only.
|
||||
Choices []*ApplicationCommandOptionChoice `json:"choices,omitempty"`
|
||||
|
||||
// NOTE: modal interaction only.
|
||||
|
||||
CustomID string `json:"custom_id,omitempty"`
|
||||
Title string `json:"title,omitempty"`
|
||||
}
|
||||
|
||||
// VerifyInteraction implements message verification of the discord interactions api
|
||||
// signing algorithm, as documented here:
|
||||
// https://discord.com/developers/docs/interactions/receiving-and-responding#security-and-authorization
|
||||
func VerifyInteraction(r *http.Request, key ed25519.PublicKey) bool {
|
||||
var msg bytes.Buffer
|
||||
|
||||
signature := r.Header.Get("X-Signature-Ed25519")
|
||||
if signature == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
sig, err := hex.DecodeString(signature)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if len(sig) != ed25519.SignatureSize {
|
||||
return false
|
||||
}
|
||||
|
||||
timestamp := r.Header.Get("X-Signature-Timestamp")
|
||||
if timestamp == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
msg.WriteString(timestamp)
|
||||
|
||||
defer r.Body.Close()
|
||||
var body bytes.Buffer
|
||||
|
||||
// at the end of the function, copy the original body back into the request
|
||||
defer func() {
|
||||
r.Body = ioutil.NopCloser(&body)
|
||||
}()
|
||||
|
||||
// copy body into buffers
|
||||
_, err = io.Copy(&msg, io.TeeReader(r.Body, &body))
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return ed25519.Verify(key, msg.Bytes(), sig)
|
||||
}
|
83
vendor/github.com/bwmarrin/discordgo/locales.go
generated
vendored
Normal file
83
vendor/github.com/bwmarrin/discordgo/locales.go
generated
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
package discordgo
|
||||
|
||||
// Locale represents the accepted languages for Discord.
|
||||
// https://discord.com/developers/docs/reference#locales
|
||||
type Locale string
|
||||
|
||||
// String returns the human-readable string of the locale
|
||||
func (l Locale) String() string {
|
||||
if name, ok := Locales[l]; ok {
|
||||
return name
|
||||
}
|
||||
return Unknown.String()
|
||||
}
|
||||
|
||||
// All defined locales in Discord
|
||||
const (
|
||||
EnglishUS Locale = "en-US"
|
||||
EnglishGB Locale = "en-GB"
|
||||
Bulgarian Locale = "bg"
|
||||
ChineseCN Locale = "zh-CN"
|
||||
ChineseTW Locale = "zh-TW"
|
||||
Croatian Locale = "hr"
|
||||
Czech Locale = "cs"
|
||||
Danish Locale = "da"
|
||||
Dutch Locale = "nl"
|
||||
Finnish Locale = "fi"
|
||||
French Locale = "fr"
|
||||
German Locale = "de"
|
||||
Greek Locale = "el"
|
||||
Hindi Locale = "hi"
|
||||
Hungarian Locale = "hu"
|
||||
Italian Locale = "it"
|
||||
Japanese Locale = "ja"
|
||||
Korean Locale = "ko"
|
||||
Lithuanian Locale = "lt"
|
||||
Norwegian Locale = "no"
|
||||
Polish Locale = "pl"
|
||||
PortugueseBR Locale = "pt-BR"
|
||||
Romanian Locale = "ro"
|
||||
Russian Locale = "ru"
|
||||
SpanishES Locale = "es-ES"
|
||||
Swedish Locale = "sv-SE"
|
||||
Thai Locale = "th"
|
||||
Turkish Locale = "tr"
|
||||
Ukrainian Locale = "uk"
|
||||
Vietnamese Locale = "vi"
|
||||
Unknown Locale = ""
|
||||
)
|
||||
|
||||
// Locales is a map of all the languages codes to their names.
|
||||
var Locales = map[Locale]string{
|
||||
EnglishUS: "English (United States)",
|
||||
EnglishGB: "English (Great Britain)",
|
||||
Bulgarian: "Bulgarian",
|
||||
ChineseCN: "Chinese (China)",
|
||||
ChineseTW: "Chinese (Taiwan)",
|
||||
Croatian: "Croatian",
|
||||
Czech: "Czech",
|
||||
Danish: "Danish",
|
||||
Dutch: "Dutch",
|
||||
Finnish: "Finnish",
|
||||
French: "French",
|
||||
German: "German",
|
||||
Greek: "Greek",
|
||||
Hindi: "Hindi",
|
||||
Hungarian: "Hungarian",
|
||||
Italian: "Italian",
|
||||
Japanese: "Japanese",
|
||||
Korean: "Korean",
|
||||
Lithuanian: "Lithuanian",
|
||||
Norwegian: "Norwegian",
|
||||
Polish: "Polish",
|
||||
PortugueseBR: "Portuguese (Brazil)",
|
||||
Romanian: "Romanian",
|
||||
Russian: "Russian",
|
||||
SpanishES: "Spanish (Spain)",
|
||||
Swedish: "Swedish",
|
||||
Thai: "Thai",
|
||||
Turkish: "Turkish",
|
||||
Ukrainian: "Ukrainian",
|
||||
Vietnamese: "Vietnamese",
|
||||
Unknown: "unknown",
|
||||
}
|
@@ -10,9 +10,11 @@
|
||||
package discordgo
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MessageType is the type of Message
|
||||
@@ -21,23 +23,26 @@ type MessageType int
|
||||
|
||||
// Block contains the valid known MessageType values
|
||||
const (
|
||||
MessageTypeDefault MessageType = iota
|
||||
MessageTypeRecipientAdd
|
||||
MessageTypeRecipientRemove
|
||||
MessageTypeCall
|
||||
MessageTypeChannelNameChange
|
||||
MessageTypeChannelIconChange
|
||||
MessageTypeChannelPinnedMessage
|
||||
MessageTypeGuildMemberJoin
|
||||
MessageTypeUserPremiumGuildSubscription
|
||||
MessageTypeUserPremiumGuildSubscriptionTierOne
|
||||
MessageTypeUserPremiumGuildSubscriptionTierTwo
|
||||
MessageTypeUserPremiumGuildSubscriptionTierThree
|
||||
MessageTypeChannelFollowAdd
|
||||
MessageTypeGuildDiscoveryDisqualified = iota + 1
|
||||
MessageTypeGuildDiscoveryRequalified
|
||||
MessageTypeReply = iota + 4
|
||||
MessageTypeApplicationCommand
|
||||
MessageTypeDefault MessageType = 0
|
||||
MessageTypeRecipientAdd MessageType = 1
|
||||
MessageTypeRecipientRemove MessageType = 2
|
||||
MessageTypeCall MessageType = 3
|
||||
MessageTypeChannelNameChange MessageType = 4
|
||||
MessageTypeChannelIconChange MessageType = 5
|
||||
MessageTypeChannelPinnedMessage MessageType = 6
|
||||
MessageTypeGuildMemberJoin MessageType = 7
|
||||
MessageTypeUserPremiumGuildSubscription MessageType = 8
|
||||
MessageTypeUserPremiumGuildSubscriptionTierOne MessageType = 9
|
||||
MessageTypeUserPremiumGuildSubscriptionTierTwo MessageType = 10
|
||||
MessageTypeUserPremiumGuildSubscriptionTierThree MessageType = 11
|
||||
MessageTypeChannelFollowAdd MessageType = 12
|
||||
MessageTypeGuildDiscoveryDisqualified MessageType = 14
|
||||
MessageTypeGuildDiscoveryRequalified MessageType = 15
|
||||
MessageTypeThreadCreated MessageType = 18
|
||||
MessageTypeReply MessageType = 19
|
||||
MessageTypeChatInputCommand MessageType = 20
|
||||
MessageTypeThreadStarterMessage MessageType = 21
|
||||
MessageTypeContextMenuCommand MessageType = 23
|
||||
)
|
||||
|
||||
// A Message stores all data related to a specific Discord message.
|
||||
@@ -58,11 +63,11 @@ type Message struct {
|
||||
// CAUTION: this field may be removed in a
|
||||
// future API version; it is safer to calculate
|
||||
// the creation time via the ID.
|
||||
Timestamp Timestamp `json:"timestamp"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
|
||||
// The time at which the last edit of the message
|
||||
// occurred, if it has been edited.
|
||||
EditedTimestamp Timestamp `json:"edited_timestamp"`
|
||||
EditedTimestamp *time.Time `json:"edited_timestamp"`
|
||||
|
||||
// The roles mentioned in the message.
|
||||
MentionRoles []string `json:"mention_roles"`
|
||||
@@ -80,8 +85,10 @@ type Message struct {
|
||||
// A list of attachments present in the message.
|
||||
Attachments []*MessageAttachment `json:"attachments"`
|
||||
|
||||
// A list of embeds present in the message. Multiple
|
||||
// embeds can currently only be sent by webhooks.
|
||||
// A list of components attached to the message.
|
||||
Components []MessageComponent `json:"-"`
|
||||
|
||||
// A list of embeds present in the message.
|
||||
Embeds []*MessageEmbed `json:"embeds"`
|
||||
|
||||
// A list of users mentioned in the message.
|
||||
@@ -116,13 +123,70 @@ type Message struct {
|
||||
// Is sent with Rich Presence-related chat embeds
|
||||
Application *MessageApplication `json:"application"`
|
||||
|
||||
// MessageReference contains reference data sent with crossposted messages
|
||||
// MessageReference contains reference data sent with crossposted or reply messages.
|
||||
// This does not contain the reference *to* this message; this is for when *this* message references another.
|
||||
// To generate a reference to this message, use (*Message).Reference().
|
||||
MessageReference *MessageReference `json:"message_reference"`
|
||||
|
||||
// The message associated with the message_reference
|
||||
// NOTE: This field is only returned for messages with a type of 19 (REPLY) or 21 (THREAD_STARTER_MESSAGE).
|
||||
// If the message is a reply but the referenced_message field is not present,
|
||||
// the backend did not attempt to fetch the message that was being replied to, so its state is unknown.
|
||||
// If the field exists but is null, the referenced message was deleted.
|
||||
ReferencedMessage *Message `json:"referenced_message"`
|
||||
|
||||
// Is sent when the message is a response to an Interaction, without an existing message.
|
||||
// This means responses to message component interactions do not include this property,
|
||||
// instead including a MessageReference, as components exist on preexisting messages.
|
||||
Interaction *MessageInteraction `json:"interaction"`
|
||||
|
||||
// The flags of the message, which describe extra features of a message.
|
||||
// This is a combination of bit masks; the presence of a certain permission can
|
||||
// be checked by performing a bitwise AND between this int and the flag.
|
||||
Flags MessageFlags `json:"flags"`
|
||||
|
||||
// The thread that was started from this message, includes thread member object
|
||||
Thread *Channel `json:"thread,omitempty"`
|
||||
|
||||
// An array of Sticker objects, if any were sent.
|
||||
StickerItems []*Sticker `json:"sticker_items"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON is a helper function to unmarshal the Message.
|
||||
func (m *Message) UnmarshalJSON(data []byte) error {
|
||||
type message Message
|
||||
var v struct {
|
||||
message
|
||||
RawComponents []unmarshalableMessageComponent `json:"components"`
|
||||
}
|
||||
err := json.Unmarshal(data, &v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*m = Message(v.message)
|
||||
m.Components = make([]MessageComponent, len(v.RawComponents))
|
||||
for i, v := range v.RawComponents {
|
||||
m.Components[i] = v.MessageComponent
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// GetCustomEmojis pulls out all the custom (Non-unicode) emojis from a message and returns a Slice of the Emoji struct.
|
||||
func (m *Message) GetCustomEmojis() []*Emoji {
|
||||
var toReturn []*Emoji
|
||||
emojis := EmojiRegex.FindAllString(m.Content, -1)
|
||||
if len(emojis) < 1 {
|
||||
return toReturn
|
||||
}
|
||||
for _, em := range emojis {
|
||||
parts := strings.Split(em, ":")
|
||||
toReturn = append(toReturn, &Emoji{
|
||||
ID: parts[2][:len(parts[2])-1],
|
||||
Name: parts[1],
|
||||
Animated: strings.HasPrefix(em, "<a:"),
|
||||
})
|
||||
}
|
||||
return toReturn
|
||||
}
|
||||
|
||||
// MessageFlags is the flags of "message" (see MessageFlags* consts)
|
||||
@@ -131,11 +195,24 @@ type MessageFlags int
|
||||
|
||||
// Valid MessageFlags values
|
||||
const (
|
||||
MessageFlagsCrossPosted MessageFlags = 1 << iota
|
||||
MessageFlagsIsCrossPosted
|
||||
MessageFlagsSupressEmbeds
|
||||
MessageFlagsSourceMessageDeleted
|
||||
MessageFlagsUrgent
|
||||
// MessageFlagsCrossPosted This message has been published to subscribed channels (via Channel Following).
|
||||
MessageFlagsCrossPosted MessageFlags = 1 << 0
|
||||
// MessageFlagsIsCrossPosted this message originated from a message in another channel (via Channel Following).
|
||||
MessageFlagsIsCrossPosted MessageFlags = 1 << 1
|
||||
// MessageFlagsSupressEmbeds do not include any embeds when serializing this message.
|
||||
MessageFlagsSupressEmbeds MessageFlags = 1 << 2
|
||||
// MessageFlagsSourceMessageDeleted the source message for this crosspost has been deleted (via Channel Following).
|
||||
MessageFlagsSourceMessageDeleted MessageFlags = 1 << 3
|
||||
// MessageFlagsUrgent this message came from the urgent message system.
|
||||
MessageFlagsUrgent MessageFlags = 1 << 4
|
||||
// MessageFlagsHasThread this message has an associated thread, with the same id as the message.
|
||||
MessageFlagsHasThread MessageFlags = 1 << 5
|
||||
// MessageFlagsEphemeral this message is only visible to the user who invoked the Interaction.
|
||||
MessageFlagsEphemeral MessageFlags = 1 << 6
|
||||
// MessageFlagsLoading this message is an Interaction Response and the bot is "thinking".
|
||||
MessageFlagsLoading MessageFlags = 1 << 7
|
||||
// MessageFlagsFailedToMentionSomeRolesInThread this message failed to mention some roles and add their members to the thread.
|
||||
MessageFlagsFailedToMentionSomeRolesInThread MessageFlags = 1 << 8
|
||||
)
|
||||
|
||||
// File stores info about files you e.g. send in messages.
|
||||
@@ -148,25 +225,33 @@ type File struct {
|
||||
// MessageSend stores all parameters you can send with ChannelMessageSendComplex.
|
||||
type MessageSend struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
Embed *MessageEmbed `json:"embed,omitempty"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
TTS bool `json:"tts"`
|
||||
Components []MessageComponent `json:"components"`
|
||||
Files []*File `json:"-"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
Reference *MessageReference `json:"message_reference,omitempty"`
|
||||
|
||||
// TODO: Remove this when compatibility is not required.
|
||||
File *File `json:"-"`
|
||||
|
||||
// TODO: Remove this when compatibility is not required.
|
||||
Embed *MessageEmbed `json:"-"`
|
||||
}
|
||||
|
||||
// MessageEdit is used to chain parameters via ChannelMessageEditComplex, which
|
||||
// is also where you should get the instance from.
|
||||
type MessageEdit struct {
|
||||
Content *string `json:"content,omitempty"`
|
||||
Embed *MessageEmbed `json:"embed,omitempty"`
|
||||
Components []MessageComponent `json:"components"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
|
||||
ID string
|
||||
Channel string
|
||||
|
||||
// TODO: Remove this when compatibility is not required.
|
||||
Embed *MessageEmbed `json:"-"`
|
||||
}
|
||||
|
||||
// NewMessageEdit returns a MessageEdit struct, initialized
|
||||
@@ -188,7 +273,14 @@ func (m *MessageEdit) SetContent(str string) *MessageEdit {
|
||||
// SetEmbed is a convenience function for setting the embed,
|
||||
// so you can chain commands.
|
||||
func (m *MessageEdit) SetEmbed(embed *MessageEmbed) *MessageEdit {
|
||||
m.Embed = embed
|
||||
m.Embeds = []*MessageEmbed{embed}
|
||||
return m
|
||||
}
|
||||
|
||||
// SetEmbeds is a convenience function for setting the embeds,
|
||||
// so you can chain commands.
|
||||
func (m *MessageEdit) SetEmbeds(embeds []*MessageEmbed) *MessageEdit {
|
||||
m.Embeds = embeds
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -230,13 +322,15 @@ type MessageAllowedMentions struct {
|
||||
|
||||
// A MessageAttachment stores data for message attachments.
|
||||
type MessageAttachment struct {
|
||||
ID string `json:"id"`
|
||||
URL string `json:"url"`
|
||||
ProxyURL string `json:"proxy_url"`
|
||||
Filename string `json:"filename"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Size int `json:"size"`
|
||||
ID string `json:"id"`
|
||||
URL string `json:"url"`
|
||||
ProxyURL string `json:"proxy_url"`
|
||||
Filename string `json:"filename"`
|
||||
ContentType string `json:"content_type"`
|
||||
Width int `json:"width"`
|
||||
Height int `json:"height"`
|
||||
Size int `json:"size"`
|
||||
Ephemeral bool `json:"ephemeral"`
|
||||
}
|
||||
|
||||
// MessageEmbedFooter is a part of a MessageEmbed struct.
|
||||
@@ -339,23 +433,10 @@ type MessageActivityType int
|
||||
|
||||
// Constants for the different types of Message Activity
|
||||
const (
|
||||
MessageActivityTypeJoin MessageActivityType = iota + 1
|
||||
MessageActivityTypeSpectate
|
||||
MessageActivityTypeListen
|
||||
MessageActivityTypeJoinRequest
|
||||
)
|
||||
|
||||
// MessageFlag describes an extra feature of the message
|
||||
type MessageFlag int
|
||||
|
||||
// Constants for the different bit offsets of Message Flags
|
||||
const (
|
||||
// This message has been published to subscribed channels (via Channel Following)
|
||||
MessageFlagCrossposted MessageFlag = 1 << iota
|
||||
// This message originated from a message in another channel (via Channel Following)
|
||||
MessageFlagIsCrosspost
|
||||
// Do not include any embeds when serializing this message
|
||||
MessageFlagSuppressEmbeds
|
||||
MessageActivityTypeJoin MessageActivityType = 1
|
||||
MessageActivityTypeSpectate MessageActivityType = 2
|
||||
MessageActivityTypeListen MessageActivityType = 3
|
||||
MessageActivityTypeJoinRequest MessageActivityType = 5
|
||||
)
|
||||
|
||||
// MessageApplication is sent with Rich Presence-related chat embeds
|
||||
@@ -447,3 +528,14 @@ func (m *Message) ContentWithMoreMentionsReplaced(s *Session) (content string, e
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// MessageInteraction contains information about the application command interaction which generated the message.
|
||||
type MessageInteraction struct {
|
||||
ID string `json:"id"`
|
||||
Type InteractionType `json:"type"`
|
||||
Name string `json:"name"`
|
||||
User *User `json:"user"`
|
||||
|
||||
// Member is only present when the interaction is from a guild.
|
||||
Member *Member `json:"member"`
|
||||
}
|
@@ -18,8 +18,8 @@ type MembershipState int
|
||||
|
||||
// Constants for the different stages of the MembershipState
|
||||
const (
|
||||
MembershipStateInvited MembershipState = iota + 1
|
||||
MembershipStateAccepted
|
||||
MembershipStateInvited MembershipState = 1
|
||||
MembershipStateAccepted MembershipState = 2
|
||||
)
|
||||
|
||||
// A TeamMember struct stores values for a single Team Member, extending the normal User data - note that the user field is partial
|
||||
@@ -40,28 +40,11 @@ type Team struct {
|
||||
Members []*TeamMember `json:"members"`
|
||||
}
|
||||
|
||||
// An Application struct stores values for a Discord OAuth2 Application
|
||||
type Application struct {
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description,omitempty"`
|
||||
Icon string `json:"icon,omitempty"`
|
||||
Secret string `json:"secret,omitempty"`
|
||||
RedirectURIs *[]string `json:"redirect_uris,omitempty"`
|
||||
BotRequireCodeGrant bool `json:"bot_require_code_grant,omitempty"`
|
||||
BotPublic bool `json:"bot_public,omitempty"`
|
||||
RPCApplicationState int `json:"rpc_application_state,omitempty"`
|
||||
Flags int `json:"flags,omitempty"`
|
||||
Owner *User `json:"owner"`
|
||||
Bot *User `json:"bot"`
|
||||
Team *Team `json:"team"`
|
||||
}
|
||||
|
||||
// Application returns an Application structure of a specific Application
|
||||
// appID : The ID of an Application
|
||||
func (s *Session) Application(appID string) (st *Application, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", EndpointApplication(appID), nil, EndpointApplication(""))
|
||||
body, err := s.RequestWithBucketID("GET", EndpointOAuth2Application(appID), nil, EndpointOAuth2Application(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -73,7 +56,7 @@ func (s *Session) Application(appID string) (st *Application, err error) {
|
||||
// Applications returns all applications for the authenticated user
|
||||
func (s *Session) Applications() (st []*Application, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", EndpointApplications, nil, EndpointApplications)
|
||||
body, err := s.RequestWithBucketID("GET", EndpointOAuth2Applications, nil, EndpointOAuth2Applications)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -88,12 +71,11 @@ func (s *Session) Applications() (st []*Application, err error) {
|
||||
func (s *Session) ApplicationCreate(ap *Application) (st *Application, err error) {
|
||||
|
||||
data := struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
RedirectURIs *[]string `json:"redirect_uris,omitempty"`
|
||||
}{ap.Name, ap.Description, ap.RedirectURIs}
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}{ap.Name, ap.Description}
|
||||
|
||||
body, err := s.RequestWithBucketID("POST", EndpointApplications, data, EndpointApplications)
|
||||
body, err := s.RequestWithBucketID("POST", EndpointOAuth2Applications, data, EndpointOAuth2Applications)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -107,12 +89,11 @@ func (s *Session) ApplicationCreate(ap *Application) (st *Application, err error
|
||||
func (s *Session) ApplicationUpdate(appID string, ap *Application) (st *Application, err error) {
|
||||
|
||||
data := struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
RedirectURIs *[]string `json:"redirect_uris,omitempty"`
|
||||
}{ap.Name, ap.Description, ap.RedirectURIs}
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
}{ap.Name, ap.Description}
|
||||
|
||||
body, err := s.RequestWithBucketID("PUT", EndpointApplication(appID), data, EndpointApplication(""))
|
||||
body, err := s.RequestWithBucketID("PUT", EndpointOAuth2Application(appID), data, EndpointOAuth2Application(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -125,7 +106,7 @@ func (s *Session) ApplicationUpdate(appID string, ap *Application) (st *Applicat
|
||||
// appID : The ID of an Application
|
||||
func (s *Session) ApplicationDelete(appID string) (err error) {
|
||||
|
||||
_, err = s.RequestWithBucketID("DELETE", EndpointApplication(appID), nil, EndpointApplication(""))
|
||||
_, err = s.RequestWithBucketID("DELETE", EndpointOAuth2Application(appID), nil, EndpointOAuth2Application(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -143,7 +124,7 @@ type Asset struct {
|
||||
// ApplicationAssets returns an application's assets
|
||||
func (s *Session) ApplicationAssets(appID string) (ass []*Asset, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("GET", EndpointApplicationAssets(appID), nil, EndpointApplicationAssets(""))
|
||||
body, err := s.RequestWithBucketID("GET", EndpointOAuth2ApplicationAssets(appID), nil, EndpointOAuth2ApplicationAssets(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@@ -163,7 +144,7 @@ func (s *Session) ApplicationAssets(appID string) (ass []*Asset, err error) {
|
||||
// NOTE: func name may change, if I can think up something better.
|
||||
func (s *Session) ApplicationBotCreate(appID string) (st *User, err error) {
|
||||
|
||||
body, err := s.RequestWithBucketID("POST", EndpointApplicationsBot(appID), nil, EndpointApplicationsBot(""))
|
||||
body, err := s.RequestWithBucketID("POST", EndpointOAuth2ApplicationsBot(appID), nil, EndpointOAuth2ApplicationsBot(""))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
@@ -33,7 +33,7 @@ func NewRatelimiter() *RateLimiter {
|
||||
buckets: make(map[string]*Bucket),
|
||||
global: new(int64),
|
||||
customRateLimits: []*customRateLimit{
|
||||
&customRateLimit{
|
||||
{
|
||||
suffix: "//reactions//",
|
||||
requests: 1,
|
||||
reset: 200 * time.Millisecond,
|
File diff suppressed because it is too large
Load Diff
@@ -38,13 +38,15 @@ type State struct {
|
||||
Ready
|
||||
|
||||
// MaxMessageCount represents how many messages per channel the state will store.
|
||||
MaxMessageCount int
|
||||
TrackChannels bool
|
||||
TrackEmojis bool
|
||||
TrackMembers bool
|
||||
TrackRoles bool
|
||||
TrackVoice bool
|
||||
TrackPresences bool
|
||||
MaxMessageCount int
|
||||
TrackChannels bool
|
||||
TrackThreads bool
|
||||
TrackEmojis bool
|
||||
TrackMembers bool
|
||||
TrackThreadMembers bool
|
||||
TrackRoles bool
|
||||
TrackVoice bool
|
||||
TrackPresences bool
|
||||
|
||||
guildMap map[string]*Guild
|
||||
channelMap map[string]*Channel
|
||||
@@ -58,15 +60,17 @@ func NewState() *State {
|
||||
PrivateChannels: []*Channel{},
|
||||
Guilds: []*Guild{},
|
||||
},
|
||||
TrackChannels: true,
|
||||
TrackEmojis: true,
|
||||
TrackMembers: true,
|
||||
TrackRoles: true,
|
||||
TrackVoice: true,
|
||||
TrackPresences: true,
|
||||
guildMap: make(map[string]*Guild),
|
||||
channelMap: make(map[string]*Channel),
|
||||
memberMap: make(map[string]map[string]*Member),
|
||||
TrackChannels: true,
|
||||
TrackThreads: true,
|
||||
TrackEmojis: true,
|
||||
TrackMembers: true,
|
||||
TrackThreadMembers: true,
|
||||
TrackRoles: true,
|
||||
TrackVoice: true,
|
||||
TrackPresences: true,
|
||||
guildMap: make(map[string]*Guild),
|
||||
channelMap: make(map[string]*Channel),
|
||||
memberMap: make(map[string]map[string]*Member),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -93,6 +97,11 @@ func (s *State) GuildAdd(guild *Guild) error {
|
||||
s.channelMap[c.ID] = c
|
||||
}
|
||||
|
||||
// Add all the threads to the state in case of thread sync list.
|
||||
for _, t := range guild.Threads {
|
||||
s.channelMap[t.ID] = t
|
||||
}
|
||||
|
||||
// If this guild contains a new member slice, we must regenerate the member map so the pointers stay valid
|
||||
if guild.Members != nil {
|
||||
s.createMemberMap(guild)
|
||||
@@ -122,6 +131,9 @@ func (s *State) GuildAdd(guild *Guild) error {
|
||||
if guild.Channels == nil {
|
||||
guild.Channels = g.Channels
|
||||
}
|
||||
if guild.Threads == nil {
|
||||
guild.Threads = g.Threads
|
||||
}
|
||||
if guild.VoiceStates == nil {
|
||||
guild.VoiceStates = g.VoiceStates
|
||||
}
|
||||
@@ -180,21 +192,12 @@ func (s *State) Guild(guildID string) (*Guild, error) {
|
||||
return nil, ErrStateNotFound
|
||||
}
|
||||
|
||||
// PresenceAdd adds a presence to the current world state, or
|
||||
// updates it if it already exists.
|
||||
func (s *State) PresenceAdd(guildID string, presence *Presence) error {
|
||||
if s == nil {
|
||||
return ErrNilState
|
||||
func (s *State) presenceAdd(guildID string, presence *Presence) error {
|
||||
guild, ok := s.guildMap[guildID]
|
||||
if !ok {
|
||||
return ErrStateNotFound
|
||||
}
|
||||
|
||||
guild, err := s.Guild(guildID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
for i, p := range guild.Presences {
|
||||
if p.User.ID == presence.User.ID {
|
||||
//guild.Presences[i] = presence
|
||||
@@ -233,6 +236,19 @@ func (s *State) PresenceAdd(guildID string, presence *Presence) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// PresenceAdd adds a presence to the current world state, or
|
||||
// updates it if it already exists.
|
||||
func (s *State) PresenceAdd(guildID string, presence *Presence) error {
|
||||
if s == nil {
|
||||
return ErrNilState
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
return s.presenceAdd(guildID, presence)
|
||||
}
|
||||
|
||||
// PresenceRemove removes a presence from the current world state.
|
||||
func (s *State) PresenceRemove(guildID string, presence *Presence) error {
|
||||
if s == nil {
|
||||
@@ -279,21 +295,12 @@ func (s *State) Presence(guildID, userID string) (*Presence, error) {
|
||||
|
||||
// TODO: Consider moving Guild state update methods onto *Guild.
|
||||
|
||||
// MemberAdd adds a member to the current world state, or
|
||||
// updates it if it already exists.
|
||||
func (s *State) MemberAdd(member *Member) error {
|
||||
if s == nil {
|
||||
return ErrNilState
|
||||
func (s *State) memberAdd(member *Member) error {
|
||||
guild, ok := s.guildMap[member.GuildID]
|
||||
if !ok {
|
||||
return ErrStateNotFound
|
||||
}
|
||||
|
||||
guild, err := s.Guild(member.GuildID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
members, ok := s.memberMap[member.GuildID]
|
||||
if !ok {
|
||||
return ErrStateNotFound
|
||||
@@ -306,15 +313,27 @@ func (s *State) MemberAdd(member *Member) error {
|
||||
} else {
|
||||
// We are about to replace `m` in the state with `member`, but first we need to
|
||||
// make sure we preserve any fields that the `member` doesn't contain from `m`.
|
||||
if member.JoinedAt == "" {
|
||||
if member.JoinedAt.IsZero() {
|
||||
member.JoinedAt = m.JoinedAt
|
||||
}
|
||||
*m = *member
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// MemberAdd adds a member to the current world state, or
|
||||
// updates it if it already exists.
|
||||
func (s *State) MemberAdd(member *Member) error {
|
||||
if s == nil {
|
||||
return ErrNilState
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
return s.memberAdd(member)
|
||||
}
|
||||
|
||||
// MemberRemove removes a member from current world state.
|
||||
func (s *State) MemberRemove(member *Member) error {
|
||||
if s == nil {
|
||||
@@ -465,6 +484,9 @@ func (s *State) ChannelAdd(channel *Channel) error {
|
||||
if channel.PermissionOverwrites == nil {
|
||||
channel.PermissionOverwrites = c.PermissionOverwrites
|
||||
}
|
||||
if channel.ThreadMetadata == nil {
|
||||
channel.ThreadMetadata = c.ThreadMetadata
|
||||
}
|
||||
|
||||
*c = *channel
|
||||
return nil
|
||||
@@ -472,12 +494,18 @@ func (s *State) ChannelAdd(channel *Channel) error {
|
||||
|
||||
if channel.Type == ChannelTypeDM || channel.Type == ChannelTypeGroupDM {
|
||||
s.PrivateChannels = append(s.PrivateChannels, channel)
|
||||
} else {
|
||||
guild, ok := s.guildMap[channel.GuildID]
|
||||
if !ok {
|
||||
return ErrStateNotFound
|
||||
}
|
||||
s.channelMap[channel.ID] = channel
|
||||
return nil
|
||||
}
|
||||
|
||||
guild, ok := s.guildMap[channel.GuildID]
|
||||
if !ok {
|
||||
return ErrStateNotFound
|
||||
}
|
||||
|
||||
if channel.IsThread() {
|
||||
guild.Threads = append(guild.Threads, channel)
|
||||
} else {
|
||||
guild.Channels = append(guild.Channels, channel)
|
||||
}
|
||||
|
||||
@@ -507,15 +535,26 @@ func (s *State) ChannelRemove(channel *Channel) error {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else {
|
||||
guild, err := s.Guild(channel.GuildID)
|
||||
if err != nil {
|
||||
return err
|
||||
delete(s.channelMap, channel.ID)
|
||||
return nil
|
||||
}
|
||||
|
||||
guild, err := s.Guild(channel.GuildID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
if channel.IsThread() {
|
||||
for i, t := range guild.Threads {
|
||||
if t.ID == channel.ID {
|
||||
guild.Threads = append(guild.Threads[:i], guild.Threads[i+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
} else {
|
||||
for i, c := range guild.Channels {
|
||||
if c.ID == channel.ID {
|
||||
guild.Channels = append(guild.Channels[:i], guild.Channels[i+1:]...)
|
||||
@@ -529,6 +568,99 @@ func (s *State) ChannelRemove(channel *Channel) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ThreadListSync syncs guild threads with provided ones.
|
||||
func (s *State) ThreadListSync(tls *ThreadListSync) error {
|
||||
guild, err := s.Guild(tls.GuildID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
// This algorithm filters out archived or
|
||||
// threads which are children of channels in channelIDs
|
||||
// and then it adds all synced threads to guild threads and cache
|
||||
index := 0
|
||||
outer:
|
||||
for _, t := range guild.Threads {
|
||||
if !t.ThreadMetadata.Archived && tls.ChannelIDs != nil {
|
||||
for _, v := range tls.ChannelIDs {
|
||||
if t.ParentID == v {
|
||||
delete(s.channelMap, t.ID)
|
||||
continue outer
|
||||
}
|
||||
}
|
||||
guild.Threads[index] = t
|
||||
index++
|
||||
} else {
|
||||
delete(s.channelMap, t.ID)
|
||||
}
|
||||
}
|
||||
guild.Threads = guild.Threads[:index]
|
||||
for _, t := range tls.Threads {
|
||||
s.channelMap[t.ID] = t
|
||||
guild.Threads = append(guild.Threads, t)
|
||||
}
|
||||
|
||||
for _, m := range tls.Members {
|
||||
if c, ok := s.channelMap[m.ID]; ok {
|
||||
c.Member = m
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ThreadMembersUpdate updates thread members list
|
||||
func (s *State) ThreadMembersUpdate(tmu *ThreadMembersUpdate) error {
|
||||
thread, err := s.Channel(tmu.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
s.Lock()
|
||||
defer s.Unlock()
|
||||
|
||||
for idx, member := range thread.Members {
|
||||
for _, removedMember := range tmu.RemovedMembers {
|
||||
if member.ID == removedMember {
|
||||
thread.Members = append(thread.Members[:idx], thread.Members[idx+1:]...)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, addedMember := range tmu.AddedMembers {
|
||||
thread.Members = append(thread.Members, addedMember.ThreadMember)
|
||||
if addedMember.Member != nil {
|
||||
err = s.memberAdd(addedMember.Member)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if addedMember.Presence != nil {
|
||||
err = s.presenceAdd(tmu.GuildID, addedMember.Presence)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
thread.MemberCount = tmu.MemberCount
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ThreadMemberUpdate sets or updates member data for the current user.
|
||||
func (s *State) ThreadMemberUpdate(mu *ThreadMemberUpdate) error {
|
||||
thread, err := s.Channel(mu.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
thread.Member = mu.ThreadMember
|
||||
return nil
|
||||
}
|
||||
|
||||
// GuildChannel gets a channel by ID from a guild.
|
||||
// This method is Deprecated, use Channel(channelID)
|
||||
func (s *State) GuildChannel(guildID, channelID string) (*Channel, error) {
|
||||
@@ -637,7 +769,7 @@ func (s *State) MessageAdd(message *Message) error {
|
||||
if message.Content != "" {
|
||||
m.Content = message.Content
|
||||
}
|
||||
if message.EditedTimestamp != "" {
|
||||
if message.EditedTimestamp != nil {
|
||||
m.EditedTimestamp = message.EditedTimestamp
|
||||
}
|
||||
if message.Mentions != nil {
|
||||
@@ -649,12 +781,15 @@ func (s *State) MessageAdd(message *Message) error {
|
||||
if message.Attachments != nil {
|
||||
m.Attachments = message.Attachments
|
||||
}
|
||||
if message.Timestamp != "" {
|
||||
if !message.Timestamp.IsZero() {
|
||||
m.Timestamp = message.Timestamp
|
||||
}
|
||||
if message.Author != nil {
|
||||
m.Author = message.Author
|
||||
}
|
||||
if message.Components != nil {
|
||||
m.Components = message.Components
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -665,6 +800,7 @@ func (s *State) MessageAdd(message *Message) error {
|
||||
if len(c.Messages) > s.MaxMessageCount {
|
||||
c.Messages = c.Messages[len(c.Messages)-s.MaxMessageCount:]
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -690,6 +826,7 @@ func (s *State) messageRemoveByID(channelID, messageID string) error {
|
||||
for i, m := range c.Messages {
|
||||
if m.ID == messageID {
|
||||
c.Messages = append(c.Messages[:i], c.Messages[i+1:]...)
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -833,6 +970,13 @@ func (s *State) OnInterface(se *Session, i interface{}) (err error) {
|
||||
case *GuildUpdate:
|
||||
err = s.GuildAdd(t.Guild)
|
||||
case *GuildDelete:
|
||||
var old *Guild
|
||||
old, err = s.Guild(t.ID)
|
||||
if err == nil {
|
||||
oldCopy := *old
|
||||
t.BeforeDelete = &oldCopy
|
||||
}
|
||||
|
||||
err = s.GuildRemove(t.Guild)
|
||||
case *GuildMemberAdd:
|
||||
// Updates the MemberCount of the guild.
|
||||
@@ -903,6 +1047,35 @@ func (s *State) OnInterface(se *Session, i interface{}) (err error) {
|
||||
if s.TrackChannels {
|
||||
err = s.ChannelRemove(t.Channel)
|
||||
}
|
||||
case *ThreadCreate:
|
||||
if s.TrackThreads {
|
||||
err = s.ChannelAdd(t.Channel)
|
||||
}
|
||||
case *ThreadUpdate:
|
||||
if s.TrackThreads {
|
||||
old, err := s.Channel(t.ID)
|
||||
if err == nil {
|
||||
oldCopy := *old
|
||||
t.BeforeUpdate = &oldCopy
|
||||
}
|
||||
err = s.ChannelAdd(t.Channel)
|
||||
}
|
||||
case *ThreadDelete:
|
||||
if s.TrackThreads {
|
||||
err = s.ChannelRemove(t.Channel)
|
||||
}
|
||||
case *ThreadMemberUpdate:
|
||||
if s.TrackThreads {
|
||||
err = s.ThreadMemberUpdate(t)
|
||||
}
|
||||
case *ThreadMembersUpdate:
|
||||
if s.TrackThreadMembers {
|
||||
err = s.ThreadMembersUpdate(t)
|
||||
}
|
||||
case *ThreadListSync:
|
||||
if s.TrackThreads {
|
||||
err = s.ThreadListSync(t)
|
||||
}
|
||||
case *MessageCreate:
|
||||
if s.MaxMessageCount != 0 {
|
||||
err = s.MessageAdd(t.Message)
|
2038
vendor/github.com/bwmarrin/discordgo/structs.go
generated
vendored
Normal file
2038
vendor/github.com/bwmarrin/discordgo/structs.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -12,18 +12,8 @@ package discordgo
|
||||
import (
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// Timestamp stores a timestamp, as sent by the Discord API.
|
||||
type Timestamp string
|
||||
|
||||
// Parse parses a timestamp string into a time.Time object.
|
||||
// The only time this can fail is if Discord changes their timestamp format.
|
||||
func (t Timestamp) Parse() (time.Time, error) {
|
||||
return time.Parse(time.RFC3339, string(t))
|
||||
}
|
||||
|
||||
// RESTError stores error information about a request with a bad response code.
|
||||
// Message is not always present, there are cases where api calls can fail
|
||||
// without returning a json message.
|
@@ -1,26 +1,25 @@
|
||||
package discordgo
|
||||
|
||||
import "strings"
|
||||
|
||||
// UserFlags is the flags of "user" (see UserFlags* consts)
|
||||
// https://discord.com/developers/docs/resources/user#user-object-user-flags
|
||||
type UserFlags int
|
||||
|
||||
// Valid UserFlags values
|
||||
const (
|
||||
UserFlagDiscordEmployee UserFlags = 1 << 0
|
||||
UserFlagDiscordPartner = 1 << 1
|
||||
UserFlagHypeSquadEvents = 1 << 2
|
||||
UserFlagBugHunterLevel1 = 1 << 3
|
||||
UserFlagHouseBravery = 1 << 6
|
||||
UserFlagHouseBrilliance = 1 << 7
|
||||
UserFlagHouseBalance = 1 << 8
|
||||
UserFlagEarlySupporter = 1 << 9
|
||||
UserFlagTeamUser = 1 << 10
|
||||
UserFlagSystem = 1 << 12
|
||||
UserFlagBugHunterLevel2 = 1 << 14
|
||||
UserFlagVerifiedBot = 1 << 16
|
||||
UserFlagVerifiedBotDeveloper = 1 << 17
|
||||
UserFlagDiscordEmployee UserFlags = 1 << 0
|
||||
UserFlagDiscordPartner UserFlags = 1 << 1
|
||||
UserFlagHypeSquadEvents UserFlags = 1 << 2
|
||||
UserFlagBugHunterLevel1 UserFlags = 1 << 3
|
||||
UserFlagHouseBravery UserFlags = 1 << 6
|
||||
UserFlagHouseBrilliance UserFlags = 1 << 7
|
||||
UserFlagHouseBalance UserFlags = 1 << 8
|
||||
UserFlagEarlySupporter UserFlags = 1 << 9
|
||||
UserFlagTeamUser UserFlags = 1 << 10
|
||||
UserFlagSystem UserFlags = 1 << 12
|
||||
UserFlagBugHunterLevel2 UserFlags = 1 << 14
|
||||
UserFlagVerifiedBot UserFlags = 1 << 16
|
||||
UserFlagVerifiedBotDeveloper UserFlags = 1 << 17
|
||||
UserFlagDiscordCertifiedModerator UserFlags = 1 << 18
|
||||
)
|
||||
|
||||
// A User stores all data for an individual Discord user.
|
||||
@@ -55,6 +54,12 @@ type User struct {
|
||||
// Whether the user has multi-factor authentication enabled.
|
||||
MFAEnabled bool `json:"mfa_enabled"`
|
||||
|
||||
// The hash of the user's banner image.
|
||||
Banner string `json:"banner"`
|
||||
|
||||
// User's banner color, encoded as an integer representation of hexadecimal color code
|
||||
AccentColor int `json:"accent_color"`
|
||||
|
||||
// Whether the user is a bot.
|
||||
Bot bool `json:"bot"`
|
||||
|
||||
@@ -90,17 +95,13 @@ func (u *User) Mention() string {
|
||||
// if size is an empty string, no size parameter will
|
||||
// be added to the URL.
|
||||
func (u *User) AvatarURL(size string) string {
|
||||
var URL string
|
||||
if u.Avatar == "" {
|
||||
URL = EndpointDefaultUserAvatar(u.Discriminator)
|
||||
} else if strings.HasPrefix(u.Avatar, "a_") {
|
||||
URL = EndpointUserAvatarAnimated(u.ID, u.Avatar)
|
||||
} else {
|
||||
URL = EndpointUserAvatar(u.ID, u.Avatar)
|
||||
}
|
||||
|
||||
if size != "" {
|
||||
return URL + "?size=" + size
|
||||
}
|
||||
return URL
|
||||
return avatarURL(u.Avatar, EndpointDefaultUserAvatar(u.Discriminator),
|
||||
EndpointUserAvatar(u.ID, u.Avatar), EndpointUserAvatarAnimated(u.ID, u.Avatar), size)
|
||||
}
|
||||
|
||||
// BannerURL returns the URL of the users's banner image.
|
||||
// size: The size of the desired banner image as a power of two
|
||||
// Image size can be any power of two between 16 and 4096.
|
||||
func (u *User) BannerURL(size string) string {
|
||||
return bannerURL(u.Banner, EndpointUserBanner(u.ID, u.Banner), EndpointUserBannerAnimated(u.ID, u.Banner), size)
|
||||
}
|
110
vendor/github.com/bwmarrin/discordgo/util.go
generated
vendored
Normal file
110
vendor/github.com/bwmarrin/discordgo/util.go
generated
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
package discordgo
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/textproto"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// SnowflakeTimestamp returns the creation time of a Snowflake ID relative to the creation of Discord.
|
||||
func SnowflakeTimestamp(ID string) (t time.Time, err error) {
|
||||
i, err := strconv.ParseInt(ID, 10, 64)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
timestamp := (i >> 22) + 1420070400000
|
||||
t = time.Unix(0, timestamp*1000000)
|
||||
return
|
||||
}
|
||||
|
||||
// MultipartBodyWithJSON returns the contentType and body for a discord request
|
||||
// data : The object to encode for payload_json in the multipart request
|
||||
// files : Files to include in the request
|
||||
func MultipartBodyWithJSON(data interface{}, files []*File) (requestContentType string, requestBody []byte, err error) {
|
||||
body := &bytes.Buffer{}
|
||||
bodywriter := multipart.NewWriter(body)
|
||||
|
||||
payload, err := json.Marshal(data)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var p io.Writer
|
||||
|
||||
h := make(textproto.MIMEHeader)
|
||||
h.Set("Content-Disposition", `form-data; name="payload_json"`)
|
||||
h.Set("Content-Type", "application/json")
|
||||
|
||||
p, err = bodywriter.CreatePart(h)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = p.Write(payload); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for i, file := range files {
|
||||
h := make(textproto.MIMEHeader)
|
||||
h.Set("Content-Disposition", fmt.Sprintf(`form-data; name="file%d"; filename="%s"`, i, quoteEscaper.Replace(file.Name)))
|
||||
contentType := file.ContentType
|
||||
if contentType == "" {
|
||||
contentType = "application/octet-stream"
|
||||
}
|
||||
h.Set("Content-Type", contentType)
|
||||
|
||||
p, err = bodywriter.CreatePart(h)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if _, err = io.Copy(p, file.Reader); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
err = bodywriter.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return bodywriter.FormDataContentType(), body.Bytes(), nil
|
||||
}
|
||||
|
||||
func avatarURL(avatarHash, defaultAvatarURL, staticAvatarURL, animatedAvatarURL, size string) string {
|
||||
var URL string
|
||||
if avatarHash == "" {
|
||||
URL = defaultAvatarURL
|
||||
} else if strings.HasPrefix(avatarHash, "a_") {
|
||||
URL = animatedAvatarURL
|
||||
} else {
|
||||
URL = staticAvatarURL
|
||||
}
|
||||
|
||||
if size != "" {
|
||||
return URL + "?size=" + size
|
||||
}
|
||||
return URL
|
||||
}
|
||||
|
||||
func bannerURL(bannerHash, staticBannerURL, animatedBannerURL, size string) string {
|
||||
var URL string
|
||||
if bannerHash == "" {
|
||||
return ""
|
||||
} else if strings.HasPrefix(bannerHash, "a_") {
|
||||
URL = animatedBannerURL
|
||||
} else {
|
||||
URL = staticBannerURL
|
||||
}
|
||||
|
||||
if size != "" {
|
||||
return URL + "?size=" + size
|
||||
}
|
||||
return URL
|
||||
}
|
@@ -831,9 +831,15 @@ func (v *VoiceConnection) opusReceiver(udpConn *net.UDPConn, close <-chan struct
|
||||
copy(nonce[:], recvbuf[0:12])
|
||||
p.Opus, _ = secretbox.Open(nil, recvbuf[12:rlen], &nonce, &v.op4.SecretKey)
|
||||
|
||||
if len(p.Opus) > 8 && recvbuf[0] == 0x90 {
|
||||
// Extension bit is set, first 8 bytes is the extended header
|
||||
p.Opus = p.Opus[8:]
|
||||
// extension bit set, and not a RTCP packet
|
||||
if ((recvbuf[0] & 0x10) == 0x10) && ((recvbuf[1] & 0x80) == 0) {
|
||||
// get extended header length
|
||||
extlen := binary.BigEndian.Uint16(p.Opus[2:4])
|
||||
// 4 bytes (ext header header) + 4*extlen (ext header data)
|
||||
shift := int(4 + 4*extlen)
|
||||
if len(p.Opus) > shift {
|
||||
p.Opus = p.Opus[shift:]
|
||||
}
|
||||
}
|
||||
|
||||
if c != nil {
|
49
vendor/github.com/bwmarrin/discordgo/webhook.go
generated
vendored
Normal file
49
vendor/github.com/bwmarrin/discordgo/webhook.go
generated
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
package discordgo
|
||||
|
||||
// Webhook stores the data for a webhook.
|
||||
type Webhook struct {
|
||||
ID string `json:"id"`
|
||||
Type WebhookType `json:"type"`
|
||||
GuildID string `json:"guild_id"`
|
||||
ChannelID string `json:"channel_id"`
|
||||
User *User `json:"user"`
|
||||
Name string `json:"name"`
|
||||
Avatar string `json:"avatar"`
|
||||
Token string `json:"token"`
|
||||
|
||||
// ApplicationID is the bot/OAuth2 application that created this webhook
|
||||
ApplicationID string `json:"application_id,omitempty"`
|
||||
}
|
||||
|
||||
// WebhookType is the type of Webhook (see WebhookType* consts) in the Webhook struct
|
||||
// https://discord.com/developers/docs/resources/webhook#webhook-object-webhook-types
|
||||
type WebhookType int
|
||||
|
||||
// Valid WebhookType values
|
||||
const (
|
||||
WebhookTypeIncoming WebhookType = 1
|
||||
WebhookTypeChannelFollower WebhookType = 2
|
||||
)
|
||||
|
||||
// WebhookParams is a struct for webhook params, used in the WebhookExecute command.
|
||||
type WebhookParams struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
Username string `json:"username,omitempty"`
|
||||
AvatarURL string `json:"avatar_url,omitempty"`
|
||||
TTS bool `json:"tts,omitempty"`
|
||||
Files []*File `json:"-"`
|
||||
Components []MessageComponent `json:"components"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
// NOTE: Works only for followup messages.
|
||||
Flags uint64 `json:"flags,omitempty"`
|
||||
}
|
||||
|
||||
// WebhookEdit stores data for editing of a webhook message.
|
||||
type WebhookEdit struct {
|
||||
Content string `json:"content,omitempty"`
|
||||
Components []MessageComponent `json:"components"`
|
||||
Embeds []*MessageEmbed `json:"embeds,omitempty"`
|
||||
Files []*File `json:"-"`
|
||||
AllowedMentions *MessageAllowedMentions `json:"allowed_mentions,omitempty"`
|
||||
}
|
@@ -33,7 +33,7 @@ var ErrWSAlreadyOpen = errors.New("web socket already opened")
|
||||
var ErrWSNotFound = errors.New("no websocket connection exists")
|
||||
|
||||
// ErrWSShardBounds is thrown when you try to use a shard ID that is
|
||||
// less than the total shard count
|
||||
// more than the total shard count
|
||||
var ErrWSShardBounds = errors.New("ShardID must be less than ShardCount")
|
||||
|
||||
type resumePacket struct {
|
||||
@@ -383,6 +383,17 @@ func (s *Session) UpdateListeningStatus(name string) (err error) {
|
||||
|
||||
// UpdateStatusComplex allows for sending the raw status update data untouched by discordgo.
|
||||
func (s *Session) UpdateStatusComplex(usd UpdateStatusData) (err error) {
|
||||
// The comment does say "untouched by discordgo", but we might need to lie a bit here.
|
||||
// The Discord documentation lists `activities` as being nullable, but in practice this
|
||||
// doesn't seem to be the case. I had filed an issue about this at
|
||||
// https://github.com/discord/discord-api-docs/issues/2559, but as of writing this
|
||||
// haven't had any movement on it, so at this point I'm assuming this is an error,
|
||||
// and am fixing this bug accordingly. Because sending `null` for `activities` instantly
|
||||
// disconnects us, I think that disallowing it from being sent in `UpdateStatusComplex`
|
||||
// isn't that big of an issue.
|
||||
if usd.Activities == nil {
|
||||
usd.Activities = make([]*Activity, 0)
|
||||
}
|
||||
|
||||
s.RLock()
|
||||
defer s.RUnlock()
|
||||
@@ -755,13 +766,13 @@ func (s *Session) identify() error {
|
||||
s.log(LogDebug, "called")
|
||||
|
||||
// TODO: This is a temporary block of code to help
|
||||
// maintain backwards compatability
|
||||
// maintain backwards compatibility
|
||||
if s.Compress == false {
|
||||
s.Identify.Compress = false
|
||||
}
|
||||
|
||||
// TODO: This is a temporary block of code to help
|
||||
// maintain backwards compatability
|
||||
// maintain backwards compatibility
|
||||
if s.Token != "" && s.Identify.Token == "" {
|
||||
s.Identify.Token = s.Token
|
||||
}
|
3
vendor/github.com/d5/tengo/v2/README.md
generated
vendored
3
vendor/github.com/d5/tengo/v2/README.md
generated
vendored
@@ -147,7 +147,4 @@ fmt.Println(res) // "success"
|
||||
- Syntax Highlighters: [VSCode](https://github.com/lissein/vscode-tengo), [Atom](https://github.com/d5/tengo-atom)
|
||||
- **Why the name Tengo?** It's from [1Q84](https://en.wikipedia.org/wiki/1Q84).
|
||||
|
||||
##
|
||||
|
||||
:hearts: Like writing Go code? Come work at Skool. [We're hiring!](https://jobs.lever.co/skool)
|
||||
|
||||
|
7
vendor/github.com/d5/tengo/v2/objects.go
generated
vendored
7
vendor/github.com/d5/tengo/v2/objects.go
generated
vendored
@@ -1577,9 +1577,8 @@ func (o *Undefined) Value() Object {
|
||||
// UserFunction represents a user function.
|
||||
type UserFunction struct {
|
||||
ObjectImpl
|
||||
Name string
|
||||
Value CallableFunc
|
||||
EncodingID string
|
||||
Name string
|
||||
Value CallableFunc
|
||||
}
|
||||
|
||||
// TypeName returns the name of the type.
|
||||
@@ -1593,7 +1592,7 @@ func (o *UserFunction) String() string {
|
||||
|
||||
// Copy returns a copy of the type.
|
||||
func (o *UserFunction) Copy() Object {
|
||||
return &UserFunction{Value: o.Value}
|
||||
return &UserFunction{Value: o.Value, Name: o.Name}
|
||||
}
|
||||
|
||||
// Equals returns true if the value of the type is equal to the value of
|
||||
|
2
vendor/github.com/d5/tengo/v2/stdlib/source_modules.go
generated
vendored
2
vendor/github.com/d5/tengo/v2/stdlib/source_modules.go
generated
vendored
@@ -4,5 +4,5 @@ package stdlib
|
||||
|
||||
// SourceModules are source type standard library modules.
|
||||
var SourceModules = map[string]string{
|
||||
"enum": "is_enumerable := func(x) {\n return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)\n}\n\nis_array_like := func(x) {\n return is_array(x) || is_immutable_array(x)\n}\n\nexport {\n // all returns true if the given function `fn` evaluates to a truthy value on\n // all of the items in `x`. It returns undefined if `x` is not enumerable.\n all: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if !fn(k, v) { return false }\n }\n\n return true\n },\n // any returns true if the given function `fn` evaluates to a truthy value on\n // any of the items in `x`. It returns undefined if `x` is not enumerable.\n any: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return true }\n }\n\n return false\n },\n // chunk returns an array of elements split into groups the length of size.\n // If `x` can't be split evenly, the final chunk will be the remaining elements.\n // It returns undefined if `x` is not array.\n chunk: func(x, size) {\n if !is_array_like(x) || !size { return undefined }\n\n numElements := len(x)\n if !numElements { return [] }\n\n res := []\n idx := 0\n for idx < numElements {\n res = append(res, x[idx:idx+size])\n idx += size\n }\n\n return res\n },\n // at returns an element at the given index (if `x` is array) or\n // key (if `x` is map). It returns undefined if `x` is not enumerable.\n at: func(x, key) {\n if !is_enumerable(x) { return undefined }\n\n if is_array_like(x) {\n if !is_int(key) { return undefined }\n } else {\n if !is_string(key) { return undefined }\n }\n\n return x[key]\n },\n // each iterates over elements of `x` and invokes `fn` for each element. `fn` is\n // invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It does not iterate\n // and returns undefined if `x` is not enumerable.\n each: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n fn(k, v)\n }\n },\n // filter iterates over elements of `x`, returning an array of all elements `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n filter: func(x, fn) {\n if !is_array_like(x) { return undefined }\n\n dst := []\n for k, v in x {\n if fn(k, v) { dst = append(dst, v) }\n }\n\n return dst\n },\n // find iterates over elements of `x`, returning value of the first element `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n find: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return v }\n }\n },\n // find_key iterates over elements of `x`, returning key or index of the first\n // element `fn` returns truthy for. `fn` is invoked with two arguments: `key`\n // and `value`. `key` is an int index if `x` is array. `key` is a string key if\n // `x` is map. It returns undefined if `x` is not enumerable.\n find_key: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return k }\n }\n },\n // map creates an array of values by running each element in `x` through `fn`.\n // `fn` is invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It returns undefined\n // if `x` is not enumerable.\n map: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n dst := []\n for k, v in x {\n dst = append(dst, fn(k, v))\n }\n\n return dst\n },\n // key returns the first argument.\n key: func(k, _) { return k },\n // value returns the second argument.\n value: func(_, v) { return v }\n}\n",
|
||||
"enum": "is_enumerable := func(x) {\n return is_array(x) || is_map(x) || is_immutable_array(x) || is_immutable_map(x)\n}\n\nis_array_like := func(x) {\n return is_array(x) || is_immutable_array(x)\n}\n\nexport {\n // all returns true if the given function `fn` evaluates to a truthy value on\n // all of the items in `x`. It returns undefined if `x` is not enumerable.\n all: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if !fn(k, v) { return false }\n }\n\n return true\n },\n // any returns true if the given function `fn` evaluates to a truthy value on\n // any of the items in `x`. It returns undefined if `x` is not enumerable.\n any: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return true }\n }\n\n return false\n },\n // chunk returns an array of elements split into groups the length of size.\n // If `x` can't be split evenly, the final chunk will be the remaining elements.\n // It returns undefined if `x` is not array.\n chunk: func(x, size) {\n if !is_array_like(x) || !size { return undefined }\n\n numElements := len(x)\n if !numElements { return [] }\n\n res := []\n idx := 0\n for idx < numElements {\n res = append(res, x[idx:idx+size])\n idx += size\n }\n\n return res\n },\n // at returns an element at the given index (if `x` is array) or\n // key (if `x` is map). It returns undefined if `x` is not enumerable.\n at: func(x, key) {\n if !is_enumerable(x) { return undefined }\n\n if is_array_like(x) {\n if !is_int(key) { return undefined }\n } else {\n if !is_string(key) { return undefined }\n }\n\n return x[key]\n },\n // each iterates over elements of `x` and invokes `fn` for each element. `fn` is\n // invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It does not iterate\n // and returns undefined if `x` is not enumerable.\n each: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n fn(k, v)\n }\n },\n // filter iterates over elements of `x`, returning an array of all elements `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. It returns undefined if `x` is not array.\n filter: func(x, fn) {\n if !is_array_like(x) { return undefined }\n\n dst := []\n for k, v in x {\n if fn(k, v) { dst = append(dst, v) }\n }\n\n return dst\n },\n // find iterates over elements of `x`, returning value of the first element `fn`\n // returns truthy for. `fn` is invoked with two arguments: `key` and `value`.\n // `key` is an int index if `x` is array. `key` is a string key if `x` is map.\n // It returns undefined if `x` is not enumerable.\n find: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return v }\n }\n },\n // find_key iterates over elements of `x`, returning key or index of the first\n // element `fn` returns truthy for. `fn` is invoked with two arguments: `key`\n // and `value`. `key` is an int index if `x` is array. `key` is a string key if\n // `x` is map. It returns undefined if `x` is not enumerable.\n find_key: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n for k, v in x {\n if fn(k, v) { return k }\n }\n },\n // map creates an array of values by running each element in `x` through `fn`.\n // `fn` is invoked with two arguments: `key` and `value`. `key` is an int index\n // if `x` is array. `key` is a string key if `x` is map. It returns undefined\n // if `x` is not enumerable.\n map: func(x, fn) {\n if !is_enumerable(x) { return undefined }\n\n dst := []\n for k, v in x {\n dst = append(dst, fn(k, v))\n }\n\n return dst\n },\n // key returns the first argument.\n key: func(k, _) { return k },\n // value returns the second argument.\n value: func(_, v) { return v }\n}\n",
|
||||
}
|
||||
|
3
vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo
generated
vendored
3
vendor/github.com/d5/tengo/v2/stdlib/srcmod_enum.tengo
generated
vendored
@@ -73,8 +73,7 @@ export {
|
||||
},
|
||||
// filter iterates over elements of `x`, returning an array of all elements `fn`
|
||||
// returns truthy for. `fn` is invoked with two arguments: `key` and `value`.
|
||||
// `key` is an int index if `x` is array. `key` is a string key if `x` is map.
|
||||
// It returns undefined if `x` is not enumerable.
|
||||
// `key` is an int index if `x` is array. It returns undefined if `x` is not array.
|
||||
filter: func(x, fn) {
|
||||
if !is_array_like(x) { return undefined }
|
||||
|
||||
|
20
vendor/github.com/gomarkdown/markdown/README.md
generated
vendored
20
vendor/github.com/gomarkdown/markdown/README.md
generated
vendored
@@ -1,6 +1,6 @@
|
||||
# Markdown Parser and HTML Renderer for Go
|
||||
|
||||
[](https://godoc.org/github.com/gomarkdown/markdown) [](https://codecov.io/gh/gomarkdown/markdown)
|
||||
[](https://pkg.go.dev/badge/github.com/gomarkdown/markdown)
|
||||
|
||||
Package `github.com/gomarkdown/markdown` is a very fast Go library for parsing [Markdown](https://daringfireball.net/projects/markdown/) documents and rendering them to HTML.
|
||||
|
||||
@@ -8,10 +8,10 @@ It's fast and supports common extensions.
|
||||
|
||||
## API Docs:
|
||||
|
||||
- https://godoc.org/github.com/gomarkdown/markdown : top level package
|
||||
- https://godoc.org/github.com/gomarkdown/markdown/ast : defines abstract syntax tree of parsed markdown document
|
||||
- https://godoc.org/github.com/gomarkdown/markdown/parser : parser
|
||||
- https://godoc.org/github.com/gomarkdown/markdown/html : html renderer
|
||||
- https://pkg.go.dev/github.com/gomarkdown/markdown : top level package
|
||||
- https://pkg.go.dev/github.com/gomarkdown/markdown/ast : defines abstract syntax tree of parsed markdown document
|
||||
- https://pkg.go.dev/github.com/gomarkdown/markdown/parser : parser
|
||||
- https://pkg.go.dev/github.com/gomarkdown/markdown/html : html renderer
|
||||
|
||||
## Users
|
||||
|
||||
@@ -40,7 +40,7 @@ output := markdown.ToHTML(md, nil, nil)
|
||||
|
||||
Markdown format is loosely specified and there are multiple extensions invented after original specification was created.
|
||||
|
||||
The parser supports several [extensions](https://godoc.org/github.com/gomarkdown/markdown/parser#Extensions).
|
||||
The parser supports several [extensions](https://pkg.go.dev/github.com/gomarkdown/markdown/parser#Extensions).
|
||||
|
||||
Default parser uses most common `parser.CommonExtensions` but you can easily use parser with custom extension:
|
||||
|
||||
@@ -59,7 +59,7 @@ html := markdown.ToHTML(md, parser, nil)
|
||||
|
||||
## Customizing HTML renderer
|
||||
|
||||
Similarly, HTML renderer can be configured with different [options](https://godoc.org/github.com/gomarkdown/markdown/html#RendererOptions)
|
||||
Similarly, HTML renderer can be configured with different [options](https://pkg.go.dev/github.com/gomarkdown/markdown/html#RendererOptions)
|
||||
|
||||
Here's how to use a custom renderer:
|
||||
|
||||
@@ -77,9 +77,9 @@ md := []byte("markdown text")
|
||||
html := markdown.ToHTML(md, nil, renderer)
|
||||
```
|
||||
|
||||
HTML renderer also supports reusing most of the logic and overriding rendering of only specifc nodes.
|
||||
HTML renderer also supports reusing most of the logic and overriding rendering of only specific nodes.
|
||||
|
||||
You can provide [RenderNodeFunc](https://godoc.org/github.com/gomarkdown/markdown/html#RenderNodeFunc) in [RendererOptions](https://godoc.org/github.com/gomarkdown/markdown/html#RendererOptions).
|
||||
You can provide [RenderNodeFunc](https://pkg.go.dev/github.com/gomarkdown/markdown/html#RenderNodeFunc) in [RendererOptions](https://pkg.go.dev/github.com/gomarkdown/markdown/html#RendererOptions).
|
||||
|
||||
The function is called for each node in AST, you can implement custom rendering logic and tell HTML renderer to skip rendering this node.
|
||||
|
||||
@@ -134,7 +134,7 @@ html := bluemonday.UGCPolicy().SanitizeBytes(maybeUnsafeHTML)
|
||||
## Windows / Mac newlines
|
||||
|
||||
The library only supports Unix newlines. If you have markdown text with possibly
|
||||
Windows / Mac newlines, normalize newlines before caling this librar using
|
||||
Windows / Mac newlines, normalize newlines before calling this library using
|
||||
`d = markdown.NormalizeNewlines(d)`
|
||||
|
||||
## mdtohtml command-line tool
|
||||
|
9
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
9
vendor/github.com/gomarkdown/markdown/parser/block.go
generated
vendored
@@ -1412,6 +1412,13 @@ gatherlines:
|
||||
// is this a nested list item?
|
||||
case (p.uliPrefix(chunk) > 0 && !p.isHRule(chunk)) || p.oliPrefix(chunk) > 0 || p.dliPrefix(chunk) > 0:
|
||||
|
||||
// if indent is 4 or more spaces on unordered or ordered lists
|
||||
// we need to add leadingWhiteSpaces + 1 spaces in the beginning of the chunk
|
||||
if indentIndex >= 4 && p.dliPrefix(chunk) <= 0 {
|
||||
leadingWhiteSpaces := skipChar(chunk, 0, ' ')
|
||||
chunk = data[ line+indentIndex - (leadingWhiteSpaces + 1) : i]
|
||||
}
|
||||
|
||||
// to be a nested list, it must be indented more
|
||||
// if not, it is either a different kind of list
|
||||
// or the next item in the same list
|
||||
@@ -1484,7 +1491,7 @@ gatherlines:
|
||||
}
|
||||
|
||||
// add the line into the working buffer without prefix
|
||||
raw.Write(data[line+indentIndex : i])
|
||||
raw.Write(chunk)
|
||||
|
||||
line = i
|
||||
}
|
||||
|
15
vendor/github.com/gomarkdown/markdown/parser/block_table.go
generated
vendored
15
vendor/github.com/gomarkdown/markdown/parser/block_table.go
generated
vendored
@@ -25,6 +25,11 @@ func (p *Parser) tableRow(data []byte, columns []ast.CellAlignFlags, header bool
|
||||
|
||||
cellStart := i
|
||||
|
||||
// If we are in a codespan we should discount any | we see, check for that here and skip ahead.
|
||||
if isCode, _ := codeSpan(p, data[i:], 0); isCode > 0 {
|
||||
i += isCode - 1
|
||||
}
|
||||
|
||||
for i < n && (data[i] != '|' || isBackslashEscaped(data, i)) && data[i] != '\n' {
|
||||
i++
|
||||
}
|
||||
@@ -84,6 +89,11 @@ func (p *Parser) tableFooter(data []byte) bool {
|
||||
n := len(data)
|
||||
i := skipCharN(data, 0, ' ', 3)
|
||||
for ; i < n && data[i] != '\n'; i++ {
|
||||
// If we are in a codespan we should discount any | we see, check for that here and skip ahead.
|
||||
if isCode, _ := codeSpan(p, data[i:], 0); isCode > 0 {
|
||||
i += isCode - 1
|
||||
}
|
||||
|
||||
if data[i] == '|' && !isBackslashEscaped(data, i) {
|
||||
colCount++
|
||||
continue
|
||||
@@ -111,6 +121,11 @@ func (p *Parser) tableHeader(data []byte, doRender bool) (size int, columns []as
|
||||
headerIsUnderline := true
|
||||
headerIsWithEmptyFields := true
|
||||
for i = 0; i < len(data) && data[i] != '\n'; i++ {
|
||||
// If we are in a codespan we should discount any | we see, check for that here and skip ahead.
|
||||
if isCode, _ := codeSpan(p, data[i:], 0); isCode > 0 {
|
||||
i += isCode - 1
|
||||
}
|
||||
|
||||
if data[i] == '|' && !isBackslashEscaped(data, i) {
|
||||
colCount++
|
||||
}
|
||||
|
39
vendor/github.com/gorilla/websocket/README.md
generated
vendored
39
vendor/github.com/gorilla/websocket/README.md
generated
vendored
@@ -6,6 +6,13 @@
|
||||
Gorilla WebSocket is a [Go](http://golang.org/) implementation of the
|
||||
[WebSocket](http://www.rfc-editor.org/rfc/rfc6455.txt) protocol.
|
||||
|
||||
|
||||
---
|
||||
|
||||
⚠️ **[The Gorilla WebSocket Package is looking for a new maintainer](https://github.com/gorilla/websocket/issues/370)**
|
||||
|
||||
---
|
||||
|
||||
### Documentation
|
||||
|
||||
* [API Reference](https://pkg.go.dev/github.com/gorilla/websocket?tab=doc)
|
||||
@@ -30,35 +37,3 @@ The Gorilla WebSocket package passes the server tests in the [Autobahn Test
|
||||
Suite](https://github.com/crossbario/autobahn-testsuite) using the application in the [examples/autobahn
|
||||
subdirectory](https://github.com/gorilla/websocket/tree/master/examples/autobahn).
|
||||
|
||||
### Gorilla WebSocket compared with other packages
|
||||
|
||||
<table>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th><a href="http://godoc.org/github.com/gorilla/websocket">github.com/gorilla</a></th>
|
||||
<th><a href="http://godoc.org/golang.org/x/net/websocket">golang.org/x/net</a></th>
|
||||
</tr>
|
||||
<tr>
|
||||
<tr><td colspan="3"><a href="http://tools.ietf.org/html/rfc6455">RFC 6455</a> Features</td></tr>
|
||||
<tr><td>Passes <a href="https://github.com/crossbario/autobahn-testsuite">Autobahn Test Suite</a></td><td><a href="https://github.com/gorilla/websocket/tree/master/examples/autobahn">Yes</a></td><td>No</td></tr>
|
||||
<tr><td>Receive <a href="https://tools.ietf.org/html/rfc6455#section-5.4">fragmented</a> message<td>Yes</td><td><a href="https://code.google.com/p/go/issues/detail?id=7632">No</a>, see note 1</td></tr>
|
||||
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.1">close</a> message</td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td><a href="https://code.google.com/p/go/issues/detail?id=4588">No</a></td></tr>
|
||||
<tr><td>Send <a href="https://tools.ietf.org/html/rfc6455#section-5.5.2">pings</a> and receive <a href="https://tools.ietf.org/html/rfc6455#section-5.5.3">pongs</a></td><td><a href="http://godoc.org/github.com/gorilla/websocket#hdr-Control_Messages">Yes</a></td><td>No</td></tr>
|
||||
<tr><td>Get the <a href="https://tools.ietf.org/html/rfc6455#section-5.6">type</a> of a received data message</td><td>Yes</td><td>Yes, see note 2</td></tr>
|
||||
<tr><td colspan="3">Other Features</tr></td>
|
||||
<tr><td><a href="https://tools.ietf.org/html/rfc7692">Compression Extensions</a></td><td>Experimental</td><td>No</td></tr>
|
||||
<tr><td>Read message using io.Reader</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextReader">Yes</a></td><td>No, see note 3</td></tr>
|
||||
<tr><td>Write message using io.WriteCloser</td><td><a href="http://godoc.org/github.com/gorilla/websocket#Conn.NextWriter">Yes</a></td><td>No, see note 3</td></tr>
|
||||
</table>
|
||||
|
||||
Notes:
|
||||
|
||||
1. Large messages are fragmented in [Chrome's new WebSocket implementation](http://www.ietf.org/mail-archive/web/hybi/current/msg10503.html).
|
||||
2. The application can get the type of a received data message by implementing
|
||||
a [Codec marshal](http://godoc.org/golang.org/x/net/websocket#Codec.Marshal)
|
||||
function.
|
||||
3. The go.net io.Reader and io.Writer operate across WebSocket frame boundaries.
|
||||
Read returns when the input buffer is full or a frame boundary is
|
||||
encountered. Each call to Write sends a single frame message. The Gorilla
|
||||
io.Reader and io.WriteCloser operate on a single WebSocket message.
|
||||
|
||||
|
77
vendor/github.com/gorilla/websocket/client.go
generated
vendored
77
vendor/github.com/gorilla/websocket/client.go
generated
vendored
@@ -48,15 +48,23 @@ func NewClient(netConn net.Conn, u *url.URL, requestHeader http.Header, readBufS
|
||||
}
|
||||
|
||||
// A Dialer contains options for connecting to WebSocket server.
|
||||
//
|
||||
// It is safe to call Dialer's methods concurrently.
|
||||
type Dialer struct {
|
||||
// NetDial specifies the dial function for creating TCP connections. If
|
||||
// NetDial is nil, net.Dial is used.
|
||||
NetDial func(network, addr string) (net.Conn, error)
|
||||
|
||||
// NetDialContext specifies the dial function for creating TCP connections. If
|
||||
// NetDialContext is nil, net.DialContext is used.
|
||||
// NetDialContext is nil, NetDial is used.
|
||||
NetDialContext func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
|
||||
// NetDialTLSContext specifies the dial function for creating TLS/TCP connections. If
|
||||
// NetDialTLSContext is nil, NetDialContext is used.
|
||||
// If NetDialTLSContext is set, Dial assumes the TLS handshake is done there and
|
||||
// TLSClientConfig is ignored.
|
||||
NetDialTLSContext func(ctx context.Context, network, addr string) (net.Conn, error)
|
||||
|
||||
// Proxy specifies a function to return a proxy for a given
|
||||
// Request. If the function returns a non-nil error, the
|
||||
// request is aborted with the provided error.
|
||||
@@ -65,6 +73,8 @@ type Dialer struct {
|
||||
|
||||
// TLSClientConfig specifies the TLS configuration to use with tls.Client.
|
||||
// If nil, the default configuration is used.
|
||||
// If either NetDialTLS or NetDialTLSContext are set, Dial assumes the TLS handshake
|
||||
// is done there and TLSClientConfig is ignored.
|
||||
TLSClientConfig *tls.Config
|
||||
|
||||
// HandshakeTimeout specifies the duration for the handshake to complete.
|
||||
@@ -176,7 +186,7 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||
}
|
||||
|
||||
req := &http.Request{
|
||||
Method: "GET",
|
||||
Method: http.MethodGet,
|
||||
URL: u,
|
||||
Proto: "HTTP/1.1",
|
||||
ProtoMajor: 1,
|
||||
@@ -237,13 +247,32 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||
// Get network dial function.
|
||||
var netDial func(network, add string) (net.Conn, error)
|
||||
|
||||
if d.NetDialContext != nil {
|
||||
netDial = func(network, addr string) (net.Conn, error) {
|
||||
return d.NetDialContext(ctx, network, addr)
|
||||
switch u.Scheme {
|
||||
case "http":
|
||||
if d.NetDialContext != nil {
|
||||
netDial = func(network, addr string) (net.Conn, error) {
|
||||
return d.NetDialContext(ctx, network, addr)
|
||||
}
|
||||
} else if d.NetDial != nil {
|
||||
netDial = d.NetDial
|
||||
}
|
||||
} else if d.NetDial != nil {
|
||||
netDial = d.NetDial
|
||||
} else {
|
||||
case "https":
|
||||
if d.NetDialTLSContext != nil {
|
||||
netDial = func(network, addr string) (net.Conn, error) {
|
||||
return d.NetDialTLSContext(ctx, network, addr)
|
||||
}
|
||||
} else if d.NetDialContext != nil {
|
||||
netDial = func(network, addr string) (net.Conn, error) {
|
||||
return d.NetDialContext(ctx, network, addr)
|
||||
}
|
||||
} else if d.NetDial != nil {
|
||||
netDial = d.NetDial
|
||||
}
|
||||
default:
|
||||
return nil, nil, errMalformedURL
|
||||
}
|
||||
|
||||
if netDial == nil {
|
||||
netDialer := &net.Dialer{}
|
||||
netDial = func(network, addr string) (net.Conn, error) {
|
||||
return netDialer.DialContext(ctx, network, addr)
|
||||
@@ -304,7 +333,9 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||
}
|
||||
}()
|
||||
|
||||
if u.Scheme == "https" {
|
||||
if u.Scheme == "https" && d.NetDialTLSContext == nil {
|
||||
// If NetDialTLSContext is set, assume that the TLS handshake has already been done
|
||||
|
||||
cfg := cloneTLSConfig(d.TLSClientConfig)
|
||||
if cfg.ServerName == "" {
|
||||
cfg.ServerName = hostNoPort
|
||||
@@ -312,11 +343,12 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||
tlsConn := tls.Client(netConn, cfg)
|
||||
netConn = tlsConn
|
||||
|
||||
var err error
|
||||
if trace != nil {
|
||||
err = doHandshakeWithTrace(trace, tlsConn, cfg)
|
||||
} else {
|
||||
err = doHandshake(tlsConn, cfg)
|
||||
if trace != nil && trace.TLSHandshakeStart != nil {
|
||||
trace.TLSHandshakeStart()
|
||||
}
|
||||
err := doHandshake(ctx, tlsConn, cfg)
|
||||
if trace != nil && trace.TLSHandshakeDone != nil {
|
||||
trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -348,8 +380,8 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||
}
|
||||
|
||||
if resp.StatusCode != 101 ||
|
||||
!strings.EqualFold(resp.Header.Get("Upgrade"), "websocket") ||
|
||||
!strings.EqualFold(resp.Header.Get("Connection"), "upgrade") ||
|
||||
!tokenListContainsValue(resp.Header, "Upgrade", "websocket") ||
|
||||
!tokenListContainsValue(resp.Header, "Connection", "upgrade") ||
|
||||
resp.Header.Get("Sec-Websocket-Accept") != computeAcceptKey(challengeKey) {
|
||||
// Before closing the network connection on return from this
|
||||
// function, slurp up some of the response to aid application
|
||||
@@ -382,14 +414,9 @@ func (d *Dialer) DialContext(ctx context.Context, urlStr string, requestHeader h
|
||||
return conn, resp, nil
|
||||
}
|
||||
|
||||
func doHandshake(tlsConn *tls.Conn, cfg *tls.Config) error {
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
return err
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{}
|
||||
}
|
||||
if !cfg.InsecureSkipVerify {
|
||||
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return cfg.Clone()
|
||||
}
|
||||
|
16
vendor/github.com/gorilla/websocket/client_clone.go
generated
vendored
16
vendor/github.com/gorilla/websocket/client_clone.go
generated
vendored
@@ -1,16 +0,0 @@
|
||||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{}
|
||||
}
|
||||
return cfg.Clone()
|
||||
}
|
38
vendor/github.com/gorilla/websocket/client_clone_legacy.go
generated
vendored
38
vendor/github.com/gorilla/websocket/client_clone_legacy.go
generated
vendored
@@ -1,38 +0,0 @@
|
||||
// Copyright 2013 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
import "crypto/tls"
|
||||
|
||||
// cloneTLSConfig clones all public fields except the fields
|
||||
// SessionTicketsDisabled and SessionTicketKey. This avoids copying the
|
||||
// sync.Mutex in the sync.Once and makes it safe to call cloneTLSConfig on a
|
||||
// config in active use.
|
||||
func cloneTLSConfig(cfg *tls.Config) *tls.Config {
|
||||
if cfg == nil {
|
||||
return &tls.Config{}
|
||||
}
|
||||
return &tls.Config{
|
||||
Rand: cfg.Rand,
|
||||
Time: cfg.Time,
|
||||
Certificates: cfg.Certificates,
|
||||
NameToCertificate: cfg.NameToCertificate,
|
||||
GetCertificate: cfg.GetCertificate,
|
||||
RootCAs: cfg.RootCAs,
|
||||
NextProtos: cfg.NextProtos,
|
||||
ServerName: cfg.ServerName,
|
||||
ClientAuth: cfg.ClientAuth,
|
||||
ClientCAs: cfg.ClientCAs,
|
||||
InsecureSkipVerify: cfg.InsecureSkipVerify,
|
||||
CipherSuites: cfg.CipherSuites,
|
||||
PreferServerCipherSuites: cfg.PreferServerCipherSuites,
|
||||
ClientSessionCache: cfg.ClientSessionCache,
|
||||
MinVersion: cfg.MinVersion,
|
||||
MaxVersion: cfg.MaxVersion,
|
||||
CurvePreferences: cfg.CurvePreferences,
|
||||
}
|
||||
}
|
63
vendor/github.com/gorilla/websocket/conn.go
generated
vendored
63
vendor/github.com/gorilla/websocket/conn.go
generated
vendored
@@ -13,6 +13,7 @@ import (
|
||||
"math/rand"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
"unicode/utf8"
|
||||
@@ -401,6 +402,12 @@ func (c *Conn) write(frameType int, deadline time.Time, buf0, buf1 []byte) error
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Conn) writeBufs(bufs ...[]byte) error {
|
||||
b := net.Buffers(bufs)
|
||||
_, err := b.WriteTo(c.conn)
|
||||
return err
|
||||
}
|
||||
|
||||
// WriteControl writes a control message with the given deadline. The allowed
|
||||
// message types are CloseMessage, PingMessage and PongMessage.
|
||||
func (c *Conn) WriteControl(messageType int, data []byte, deadline time.Time) error {
|
||||
@@ -794,47 +801,69 @@ func (c *Conn) advanceFrame() (int, error) {
|
||||
}
|
||||
|
||||
// 2. Read and parse first two bytes of frame header.
|
||||
// To aid debugging, collect and report all errors in the first two bytes
|
||||
// of the header.
|
||||
|
||||
var errors []string
|
||||
|
||||
p, err := c.read(2)
|
||||
if err != nil {
|
||||
return noFrame, err
|
||||
}
|
||||
|
||||
final := p[0]&finalBit != 0
|
||||
frameType := int(p[0] & 0xf)
|
||||
final := p[0]&finalBit != 0
|
||||
rsv1 := p[0]&rsv1Bit != 0
|
||||
rsv2 := p[0]&rsv2Bit != 0
|
||||
rsv3 := p[0]&rsv3Bit != 0
|
||||
mask := p[1]&maskBit != 0
|
||||
c.setReadRemaining(int64(p[1] & 0x7f))
|
||||
|
||||
c.readDecompress = false
|
||||
if c.newDecompressionReader != nil && (p[0]&rsv1Bit) != 0 {
|
||||
c.readDecompress = true
|
||||
p[0] &^= rsv1Bit
|
||||
if rsv1 {
|
||||
if c.newDecompressionReader != nil {
|
||||
c.readDecompress = true
|
||||
} else {
|
||||
errors = append(errors, "RSV1 set")
|
||||
}
|
||||
}
|
||||
|
||||
if rsv := p[0] & (rsv1Bit | rsv2Bit | rsv3Bit); rsv != 0 {
|
||||
return noFrame, c.handleProtocolError("unexpected reserved bits 0x" + strconv.FormatInt(int64(rsv), 16))
|
||||
if rsv2 {
|
||||
errors = append(errors, "RSV2 set")
|
||||
}
|
||||
|
||||
if rsv3 {
|
||||
errors = append(errors, "RSV3 set")
|
||||
}
|
||||
|
||||
switch frameType {
|
||||
case CloseMessage, PingMessage, PongMessage:
|
||||
if c.readRemaining > maxControlFramePayloadSize {
|
||||
return noFrame, c.handleProtocolError("control frame length > 125")
|
||||
errors = append(errors, "len > 125 for control")
|
||||
}
|
||||
if !final {
|
||||
return noFrame, c.handleProtocolError("control frame not final")
|
||||
errors = append(errors, "FIN not set on control")
|
||||
}
|
||||
case TextMessage, BinaryMessage:
|
||||
if !c.readFinal {
|
||||
return noFrame, c.handleProtocolError("message start before final message frame")
|
||||
errors = append(errors, "data before FIN")
|
||||
}
|
||||
c.readFinal = final
|
||||
case continuationFrame:
|
||||
if c.readFinal {
|
||||
return noFrame, c.handleProtocolError("continuation after final message frame")
|
||||
errors = append(errors, "continuation after FIN")
|
||||
}
|
||||
c.readFinal = final
|
||||
default:
|
||||
return noFrame, c.handleProtocolError("unknown opcode " + strconv.Itoa(frameType))
|
||||
errors = append(errors, "bad opcode "+strconv.Itoa(frameType))
|
||||
}
|
||||
|
||||
if mask != c.isServer {
|
||||
errors = append(errors, "bad MASK")
|
||||
}
|
||||
|
||||
if len(errors) > 0 {
|
||||
return noFrame, c.handleProtocolError(strings.Join(errors, ", "))
|
||||
}
|
||||
|
||||
// 3. Read and parse frame length as per
|
||||
@@ -872,10 +901,6 @@ func (c *Conn) advanceFrame() (int, error) {
|
||||
|
||||
// 4. Handle frame masking.
|
||||
|
||||
if mask != c.isServer {
|
||||
return noFrame, c.handleProtocolError("incorrect mask flag")
|
||||
}
|
||||
|
||||
if mask {
|
||||
c.readMaskPos = 0
|
||||
p, err := c.read(len(c.readMaskKey))
|
||||
@@ -935,7 +960,7 @@ func (c *Conn) advanceFrame() (int, error) {
|
||||
if len(payload) >= 2 {
|
||||
closeCode = int(binary.BigEndian.Uint16(payload))
|
||||
if !isValidReceivedCloseCode(closeCode) {
|
||||
return noFrame, c.handleProtocolError("invalid close code")
|
||||
return noFrame, c.handleProtocolError("bad close code " + strconv.Itoa(closeCode))
|
||||
}
|
||||
closeText = string(payload[2:])
|
||||
if !utf8.ValidString(closeText) {
|
||||
@@ -952,7 +977,11 @@ func (c *Conn) advanceFrame() (int, error) {
|
||||
}
|
||||
|
||||
func (c *Conn) handleProtocolError(message string) error {
|
||||
c.WriteControl(CloseMessage, FormatCloseMessage(CloseProtocolError, message), time.Now().Add(writeWait))
|
||||
data := FormatCloseMessage(CloseProtocolError, message)
|
||||
if len(data) > maxControlFramePayloadSize {
|
||||
data = data[:maxControlFramePayloadSize]
|
||||
}
|
||||
c.WriteControl(CloseMessage, data, time.Now().Add(writeWait))
|
||||
return errors.New("websocket: " + message)
|
||||
}
|
||||
|
||||
|
15
vendor/github.com/gorilla/websocket/conn_write.go
generated
vendored
15
vendor/github.com/gorilla/websocket/conn_write.go
generated
vendored
@@ -1,15 +0,0 @@
|
||||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
import "net"
|
||||
|
||||
func (c *Conn) writeBufs(bufs ...[]byte) error {
|
||||
b := net.Buffers(bufs)
|
||||
_, err := b.WriteTo(c.conn)
|
||||
return err
|
||||
}
|
18
vendor/github.com/gorilla/websocket/conn_write_legacy.go
generated
vendored
18
vendor/github.com/gorilla/websocket/conn_write_legacy.go
generated
vendored
@@ -1,18 +0,0 @@
|
||||
// Copyright 2016 The Gorilla WebSocket Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// +build !go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
func (c *Conn) writeBufs(bufs ...[]byte) error {
|
||||
for _, buf := range bufs {
|
||||
if len(buf) > 0 {
|
||||
if _, err := c.conn.Write(buf); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
1
vendor/github.com/gorilla/websocket/mask.go
generated
vendored
1
vendor/github.com/gorilla/websocket/mask.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// this source code is governed by a BSD-style license that can be found in the
|
||||
// LICENSE file.
|
||||
|
||||
//go:build !appengine
|
||||
// +build !appengine
|
||||
|
||||
package websocket
|
||||
|
1
vendor/github.com/gorilla/websocket/mask_safe.go
generated
vendored
1
vendor/github.com/gorilla/websocket/mask_safe.go
generated
vendored
@@ -2,6 +2,7 @@
|
||||
// this source code is governed by a BSD-style license that can be found in the
|
||||
// LICENSE file.
|
||||
|
||||
//go:build appengine
|
||||
// +build appengine
|
||||
|
||||
package websocket
|
||||
|
2
vendor/github.com/gorilla/websocket/proxy.go
generated
vendored
2
vendor/github.com/gorilla/websocket/proxy.go
generated
vendored
@@ -48,7 +48,7 @@ func (hpd *httpProxyDialer) Dial(network string, addr string) (net.Conn, error)
|
||||
}
|
||||
|
||||
connectReq := &http.Request{
|
||||
Method: "CONNECT",
|
||||
Method: http.MethodConnect,
|
||||
URL: &url.URL{Opaque: addr},
|
||||
Host: addr,
|
||||
Header: connectHeader,
|
||||
|
8
vendor/github.com/gorilla/websocket/server.go
generated
vendored
8
vendor/github.com/gorilla/websocket/server.go
generated
vendored
@@ -23,6 +23,8 @@ func (e HandshakeError) Error() string { return e.message }
|
||||
|
||||
// Upgrader specifies parameters for upgrading an HTTP connection to a
|
||||
// WebSocket connection.
|
||||
//
|
||||
// It is safe to call Upgrader's methods concurrently.
|
||||
type Upgrader struct {
|
||||
// HandshakeTimeout specifies the duration for the handshake to complete.
|
||||
HandshakeTimeout time.Duration
|
||||
@@ -115,8 +117,8 @@ func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header
|
||||
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
|
||||
//
|
||||
// The responseHeader is included in the response to the client's upgrade
|
||||
// request. Use the responseHeader to specify cookies (Set-Cookie) and the
|
||||
// application negotiated subprotocol (Sec-WebSocket-Protocol).
|
||||
// request. Use the responseHeader to specify cookies (Set-Cookie). To specify
|
||||
// subprotocols supported by the server, set Upgrader.Subprotocols directly.
|
||||
//
|
||||
// If the upgrade fails, then Upgrade replies to the client with an HTTP error
|
||||
// response.
|
||||
@@ -131,7 +133,7 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
|
||||
return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header")
|
||||
}
|
||||
|
||||
if r.Method != "GET" {
|
||||
if r.Method != http.MethodGet {
|
||||
return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET")
|
||||
}
|
||||
|
||||
|
21
vendor/github.com/gorilla/websocket/tls_handshake.go
generated
vendored
Normal file
21
vendor/github.com/gorilla/websocket/tls_handshake.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
//go:build go1.17
|
||||
// +build go1.17
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error {
|
||||
if err := tlsConn.HandshakeContext(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
if !cfg.InsecureSkipVerify {
|
||||
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
21
vendor/github.com/gorilla/websocket/tls_handshake_116.go
generated
vendored
Normal file
21
vendor/github.com/gorilla/websocket/tls_handshake_116.go
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
//go:build !go1.17
|
||||
// +build !go1.17
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
)
|
||||
|
||||
func doHandshake(ctx context.Context, tlsConn *tls.Conn, cfg *tls.Config) error {
|
||||
if err := tlsConn.Handshake(); err != nil {
|
||||
return err
|
||||
}
|
||||
if !cfg.InsecureSkipVerify {
|
||||
if err := tlsConn.VerifyHostname(cfg.ServerName); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
19
vendor/github.com/gorilla/websocket/trace.go
generated
vendored
19
vendor/github.com/gorilla/websocket/trace.go
generated
vendored
@@ -1,19 +0,0 @@
|
||||
// +build go1.8
|
||||
|
||||
package websocket
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"net/http/httptrace"
|
||||
)
|
||||
|
||||
func doHandshakeWithTrace(trace *httptrace.ClientTrace, tlsConn *tls.Conn, cfg *tls.Config) error {
|
||||
if trace.TLSHandshakeStart != nil {
|
||||
trace.TLSHandshakeStart()
|
||||
}
|
||||
err := doHandshake(tlsConn, cfg)
|
||||
if trace.TLSHandshakeDone != nil {
|
||||
trace.TLSHandshakeDone(tlsConn.ConnectionState(), err)
|
||||
}
|
||||
return err
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user