Compare commits
	
		
			16 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					24bc0f127b | ||
| 
						 | 
					f0f801402d | ||
| 
						 | 
					663850a2b8 | ||
| 
						 | 
					c51753cab1 | ||
| 
						 | 
					b3be2e208c | ||
| 
						 | 
					c30e90ff3f | ||
| 
						 | 
					e4c0ca0f48 | ||
| 
						 | 
					9c203327c0 | ||
| 
						 | 
					ccb5b1d075 | ||
| 
						 | 
					0dbbd0414c | ||
| 
						 | 
					e7b3ebf98a | ||
| 
						 | 
					5bc18fb780 | ||
| 
						 | 
					df30366072 | ||
| 
						 | 
					65c7ac80b5 | ||
| 
						 | 
					dd3fb32ec7 | ||
| 
						 | 
					2a3f475ff5 | 
							
								
								
									
										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]
 | 
			
		||||
@@ -164,7 +164,7 @@ See <https://github.com/42wim/matterbridge/wiki>
 | 
			
		||||
 | 
			
		||||
### Binaries
 | 
			
		||||
 | 
			
		||||
- Latest stable release [v1.23.2](https://github.com/42wim/matterbridge/releases/latest)
 | 
			
		||||
- Latest stable release [v1.24.1](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.
 | 
			
		||||
@@ -185,13 +185,13 @@ Go 1.17+ is required. Make sure you have [Go](https://golang.org/doc/install) pr
 | 
			
		||||
To install the latest stable run:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
go install github.com/42wim/matterbridge
 | 
			
		||||
go install github.com/42wim/matterbridge@v1.24.1
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
To install the latest dev run:
 | 
			
		||||
 | 
			
		||||
```bash
 | 
			
		||||
go install github.com/42wim/matterbridge@master
 | 
			
		||||
go install github.com/42wim/matterbridge@latest
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
You should now have matterbridge binary in the ~/go/bin directory:
 | 
			
		||||
 
 | 
			
		||||
@@ -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 (
 | 
			
		||||
 
 | 
			
		||||
@@ -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 {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
@@ -182,6 +187,9 @@ func (b *Btelegram) handleRecv(updates <-chan tgbotapi.Update) {
 | 
			
		||||
		rmsg.ID = strconv.Itoa(message.MessageID)
 | 
			
		||||
		rmsg.Channel = strconv.FormatInt(message.Chat.ID, 10)
 | 
			
		||||
 | 
			
		||||
		// handle entities (adding URLs)
 | 
			
		||||
		b.handleEntities(&rmsg, message)
 | 
			
		||||
 | 
			
		||||
		// handle username
 | 
			
		||||
		b.handleUsername(&rmsg, message)
 | 
			
		||||
 | 
			
		||||
@@ -197,11 +205,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)
 | 
			
		||||
@@ -483,31 +489,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
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -293,7 +293,11 @@ func (b *Bwhatsapp) Send(msg config.Message) (string, error) {
 | 
			
		||||
	if msg.ID != "" {
 | 
			
		||||
		b.Log.Debugf("updating message with id %s", msg.ID)
 | 
			
		||||
 | 
			
		||||
		msg.Text += " (edited)"
 | 
			
		||||
		if b.GetString("editsuffix") != "" {
 | 
			
		||||
			msg.Text += b.GetString("EditSuffix")
 | 
			
		||||
		} else {
 | 
			
		||||
			msg.Text += " (edited)"
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Handle Upload a file
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										62
									
								
								changelog.md
									
									
									
									
									
								
							
							
						
						
									
										62
									
								
								changelog.md
									
									
									
									
									
								
							@@ -1,3 +1,59 @@
 | 
			
		||||
# 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
 | 
			
		||||
 | 
			
		||||
- harmony: new protocol added: Add support for Harmony (#1656)
 | 
			
		||||
- irc: Allow binding to IP on IRC (#1640)
 | 
			
		||||
- irc: Add support for client certificate (irc) (#1710)
 | 
			
		||||
- mattermost: Add UseUsername option (mattermost). Fixes #1665 (#1714)
 | 
			
		||||
- mattermost: Add support for using ID in channel config (mattermost) (#1715)
 | 
			
		||||
- matrix: Reply support for Matrix (#1664)
 | 
			
		||||
- telegram: Add Telegram Bot Command /chatId (telegram) (#1703)
 | 
			
		||||
 | 
			
		||||
## Enhancements
 | 
			
		||||
 | 
			
		||||
- general: Update dependencies/vendor (#1659)
 | 
			
		||||
- discord: Add more debug options for discord (#1712)
 | 
			
		||||
- docker: Use Alpine stable again in Dockerfile (#1643)
 | 
			
		||||
- mattermost: Log eventtype in debug (mattermost) (#1676)
 | 
			
		||||
- mattermost: Add more ignore debug messages (mattermost) (#1678)
 | 
			
		||||
- slack: Add support for deleting files from slack to discord. Fixes #1705 (#1709)
 | 
			
		||||
- telegram: Add support for code blocks in telegram (#1650)
 | 
			
		||||
- telegram: Update telegram-bot-api to v5 (#1660)
 | 
			
		||||
- telegram: Add comments to messages (telegram) (#1652)
 | 
			
		||||
- telegram: Add support for sender_chat (telegram) (#1677)
 | 
			
		||||
- vk: Remove GroupID (vk) (#1668)
 | 
			
		||||
 | 
			
		||||
## Bugfix
 | 
			
		||||
 | 
			
		||||
- mattermost: Use current parentID if rootId is not set (mattermost) (#1675)
 | 
			
		||||
- 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.
 | 
			
		||||
@@ -6,6 +62,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.
 | 
			
		||||
@@ -20,6 +79,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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										33
									
								
								go.mod
									
									
									
									
									
								
							@@ -6,33 +6,32 @@ require (
 | 
			
		||||
	github.com/Benau/tgsconverter v0.0.0-20210809170556-99f4a4f6337f
 | 
			
		||||
	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.0
 | 
			
		||||
	github.com/d5/tengo/v2 v2.10.0
 | 
			
		||||
	github.com/SevereCloud/vksdk/v2 v2.13.1
 | 
			
		||||
	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/kyokomi/emoji/v2 v2.2.9
 | 
			
		||||
	github.com/labstack/echo/v4 v4.7.0
 | 
			
		||||
	github.com/lrstanley/girc v0.0.0-20211023233735-147f0ff77566
 | 
			
		||||
	github.com/matrix-org/gomatrix v0.0.0-20210324163249-be2af5ef2e16
 | 
			
		||||
	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/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.4.2
 | 
			
		||||
	github.com/mattn/godown v0.0.1
 | 
			
		||||
	github.com/missdeer/golib v1.0.4
 | 
			
		||||
	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,15 +39,16 @@ 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
 | 
			
		||||
	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
 | 
			
		||||
	gopkg.in/olahol/melody.v1 v1.0.0-20170518105555-d52139073376
 | 
			
		||||
	layeh.com/gumble v0.0.0-20200818122324-146f9205029b
 | 
			
		||||
@@ -73,7 +73,7 @@ require (
 | 
			
		||||
	github.com/hashicorp/hcl v1.0.0 // indirect
 | 
			
		||||
	github.com/json-iterator/go v1.1.12 // indirect
 | 
			
		||||
	github.com/kettek/apng v0.0.0-20191108220231-414630eed80f // indirect
 | 
			
		||||
	github.com/klauspost/compress v1.14.1 // indirect
 | 
			
		||||
	github.com/klauspost/compress v1.14.2 // indirect
 | 
			
		||||
	github.com/klauspost/cpuid/v2 v2.0.9 // indirect
 | 
			
		||||
	github.com/labstack/gommon v0.3.1 // indirect
 | 
			
		||||
	github.com/magiconair/properties v1.8.5 // indirect
 | 
			
		||||
@@ -123,10 +123,9 @@ require (
 | 
			
		||||
	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/net v0.0.0-20220127200216-cd36cc0744dd // 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/term v0.0.0-20210927222741-03fcf44c2211 // indirect
 | 
			
		||||
	golang.org/x/time v0.0.0-20201208040808-7e3f01d25324 // indirect
 | 
			
		||||
	google.golang.org/appengine v1.6.7 // indirect
 | 
			
		||||
	google.golang.org/protobuf v1.27.1 // indirect
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										89
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										89
									
								
								go.sum
									
									
									
									
									
								
							@@ -54,7 +54,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=
 | 
			
		||||
@@ -72,7 +71,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 +78,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 +85,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=
 | 
			
		||||
@@ -153,8 +149,8 @@ github.com/Rhymen/go-whatsapp v0.1.2-0.20211102134409-31a2e740845c/go.mod h1:DNS
 | 
			
		||||
github.com/RoaringBitmap/roaring v0.4.23/go.mod h1:D0gp8kJQgE1A4LQ5wFLggQEyvDi06Mq5mKs52e1TwOo=
 | 
			
		||||
github.com/RoaringBitmap/roaring v0.8.0/go.mod h1:jdT9ykXwHFNdJbEtxePexlFYH9LXucApeS0/+/g+p1I=
 | 
			
		||||
github.com/RoaringBitmap/roaring v0.9.4/go.mod h1:icnadbWcNyfEHlYdr+tDlOTih1Bf/h+rzPpv4sbomAA=
 | 
			
		||||
github.com/SevereCloud/vksdk/v2 v2.13.0 h1:sXAGkWRHCsPUDitiiPBU7PqzoTSdF7vdXZjLnHzYZQc=
 | 
			
		||||
github.com/SevereCloud/vksdk/v2 v2.13.0/go.mod h1:skoTmXOqmQIESWnNKSpkWhpNdFK2Jjp1GxGZDElOKUw=
 | 
			
		||||
github.com/SevereCloud/vksdk/v2 v2.13.1 h1:D11NaP275mW01v2hRF0ycDHdJaIyZEvasZV4MSkg5Sk=
 | 
			
		||||
github.com/SevereCloud/vksdk/v2 v2.13.1/go.mod h1:UyOgSj/CYt2dByu3Fyf/y1yT1NoahVi4zECvvrbtPU4=
 | 
			
		||||
github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0=
 | 
			
		||||
github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ=
 | 
			
		||||
github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo=
 | 
			
		||||
@@ -165,7 +161,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 +170,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,7 +206,6 @@ 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-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=
 | 
			
		||||
@@ -290,6 +283,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=
 | 
			
		||||
@@ -450,8 +445,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 +465,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 +517,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=
 | 
			
		||||
@@ -588,6 +580,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.20220126093237-74bffc135498/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=
 | 
			
		||||
@@ -650,8 +643,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 +702,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=
 | 
			
		||||
@@ -794,8 +785,9 @@ 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/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,9 +803,8 @@ 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.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
 | 
			
		||||
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
 | 
			
		||||
@@ -1005,8 +996,8 @@ github.com/klauspost/compress v1.13.1/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8
 | 
			
		||||
github.com/klauspost/compress v1.13.4/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg=
 | 
			
		||||
github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 | 
			
		||||
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 | 
			
		||||
github.com/klauspost/compress v1.14.1 h1:hLQYb23E8/fO+1u53d02A97a8UnsddcvYzq4ERRU4ds=
 | 
			
		||||
github.com/klauspost/compress v1.14.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 | 
			
		||||
github.com/klauspost/compress v1.14.2 h1:S0OHlFk/Gbon/yauFJ4FfJJF5V0fc5HbBTJazi28pRw=
 | 
			
		||||
github.com/klauspost/compress v1.14.2/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
 | 
			
		||||
github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 | 
			
		||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 | 
			
		||||
github.com/klauspost/cpuid v1.2.3/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek=
 | 
			
		||||
@@ -1038,11 +1029,11 @@ 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.7.0 h1:8wHgZhoE9OT1NSLw6sfrX7ZGpWMtO5Zlfr68+BIo180=
 | 
			
		||||
github.com/labstack/echo/v4 v4.7.0/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=
 | 
			
		||||
@@ -1079,8 +1070,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 +1097,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.4.2 h1:UyrYoBYrV7dB7JWSEOPXKZaTyYZE2PRDysqx/54ayng=
 | 
			
		||||
github.com/mattermost/mattermost-server/v6 v6.4.2/go.mod h1:5dOl/bx4N9iTytZ4p44xfGiOiZelbdap42FbEjmN+FU=
 | 
			
		||||
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=
 | 
			
		||||
@@ -1174,8 +1163,6 @@ github.com/minio/minio-go/v7 v7.0.16/go.mod h1:pUV0Pc+hPd1nccgmzQF/EXh48l/Z/yps6
 | 
			
		||||
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/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 | 
			
		||||
github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
 | 
			
		||||
@@ -1208,7 +1195,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=
 | 
			
		||||
@@ -1449,7 +1435,6 @@ github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxT
 | 
			
		||||
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=
 | 
			
		||||
@@ -1506,8 +1491,8 @@ github.com/sizeofint/webpanimation v0.0.0-20210809145948-1d2b32119882 h1:A7o8tOE
 | 
			
		||||
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/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=
 | 
			
		||||
@@ -1628,14 +1613,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=
 | 
			
		||||
@@ -1791,7 +1772,7 @@ 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=
 | 
			
		||||
@@ -1825,8 +1806,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=
 | 
			
		||||
@@ -1924,18 +1906,18 @@ 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-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-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-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 +1940,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 +2059,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=
 | 
			
		||||
@@ -2105,8 +2089,9 @@ golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBc
 | 
			
		||||
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/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=
 | 
			
		||||
@@ -2347,7 +2332,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=
 | 
			
		||||
@@ -2554,4 +2538,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=
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/SevereCloud/vksdk/v2/.golangci.yml
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -54,6 +54,9 @@ linters:
 | 
			
		||||
    - nilnil
 | 
			
		||||
    - tenv
 | 
			
		||||
    - nestif
 | 
			
		||||
    - grouper
 | 
			
		||||
    - decorder
 | 
			
		||||
    - containedctx
 | 
			
		||||
 | 
			
		||||
# - wrapcheck # TODO: v3 Fix
 | 
			
		||||
# - testpackage # TODO: Fix testpackage
 | 
			
		||||
@@ -82,6 +85,8 @@ linters:
 | 
			
		||||
# - tagliatelle
 | 
			
		||||
# - errname
 | 
			
		||||
# - varnamelen
 | 
			
		||||
# - errchkjson
 | 
			
		||||
# - maintidx
 | 
			
		||||
 | 
			
		||||
# depricated
 | 
			
		||||
# - maligned
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/api.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/SevereCloud/vksdk/v2/api/api.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -269,9 +269,15 @@ func (vk *VK) DefaultHandler(method string, sliceParams ...Params) (Response, er
 | 
			
		||||
 | 
			
		||||
		switch resp.Header.Get("Content-Encoding") {
 | 
			
		||||
		case "zstd":
 | 
			
		||||
			reader, _ = zstd.NewReader(resp.Body)
 | 
			
		||||
			zstdReader, _ := zstd.NewReader(resp.Body)
 | 
			
		||||
			defer zstdReader.Close()
 | 
			
		||||
 | 
			
		||||
			reader = zstdReader
 | 
			
		||||
		case "gzip":
 | 
			
		||||
			reader, _ = gzip.NewReader(resp.Body)
 | 
			
		||||
			gzipReader, _ := gzip.NewReader(resp.Body)
 | 
			
		||||
			defer gzipReader.Close()
 | 
			
		||||
 | 
			
		||||
			reader = gzipReader
 | 
			
		||||
		default:
 | 
			
		||||
			reader = resp.Body
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								vendor/github.com/SevereCloud/vksdk/v2/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								vendor/github.com/SevereCloud/vksdk/v2/doc.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -7,6 +7,6 @@ package vksdk
 | 
			
		||||
 | 
			
		||||
// Module constants.
 | 
			
		||||
const (
 | 
			
		||||
	Version = "2.13.0"
 | 
			
		||||
	Version = "2.13.1"
 | 
			
		||||
	API     = "5.131"
 | 
			
		||||
)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										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
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										12
									
								
								vendor/github.com/gorilla/websocket/trace_17.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										12
									
								
								vendor/github.com/gorilla/websocket/trace_17.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,12 +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 {
 | 
			
		||||
	return doHandshake(tlsConn, cfg)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/harmony-development/shibshib/gen/chat/v1/chat_hrpc_client.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/harmony-development/shibshib/gen/chat/v1/chat_hrpc_client.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -156,6 +156,9 @@ type ChatServiceClient interface {
 | 
			
		||||
	// Endpoint to unpin a message in a guild channel.
 | 
			
		||||
	UnpinMessage(context.Context, *UnpinMessageRequest) (*UnpinMessageResponse, error)
 | 
			
		||||
	// Endpoint to stream events from the homeserver.
 | 
			
		||||
	// By default, this endpoint will subscribe to all events.
 | 
			
		||||
	// Any guilds joined in the future will be added to the subscription as well.
 | 
			
		||||
	// Use the UnsubscribeFromAll event for unsubscribing from all current subscriptions and disable the automatic guild subscriptions
 | 
			
		||||
	StreamEvents(context.Context, chan *StreamEventsRequest) (chan *StreamEventsResponse, error)
 | 
			
		||||
	// Endpoint to add a reaction to a message.
 | 
			
		||||
	AddReaction(context.Context, *AddReactionRequest) (*AddReactionResponse, error)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1154
									
								
								vendor/github.com/harmony-development/shibshib/gen/chat/v1/guilds.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1154
									
								
								vendor/github.com/harmony-development/shibshib/gen/chat/v1/guilds.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1338
									
								
								vendor/github.com/harmony-development/shibshib/gen/chat/v1/stream.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1338
									
								
								vendor/github.com/harmony-development/shibshib/gen/chat/v1/stream.pb.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										400
									
								
								vendor/github.com/harmony-development/shibshib/gen/profile/v1/appdata.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										400
									
								
								vendor/github.com/harmony-development/shibshib/gen/profile/v1/appdata.pb.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,400 @@
 | 
			
		||||
// Code generated by protoc-gen-go. DO NOT EDIT.
 | 
			
		||||
// versions:
 | 
			
		||||
// 	protoc-gen-go v1.23.0
 | 
			
		||||
// 	protoc        v3.17.3
 | 
			
		||||
// source: profile/v1/appdata.proto
 | 
			
		||||
 | 
			
		||||
package profilev1
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	proto "github.com/golang/protobuf/proto"
 | 
			
		||||
	v1 "github.com/harmony-development/shibshib/gen/harmonytypes/v1"
 | 
			
		||||
	protoreflect "google.golang.org/protobuf/reflect/protoreflect"
 | 
			
		||||
	protoimpl "google.golang.org/protobuf/runtime/protoimpl"
 | 
			
		||||
	reflect "reflect"
 | 
			
		||||
	sync "sync"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Verify that this generated code is sufficiently up-to-date.
 | 
			
		||||
	_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
 | 
			
		||||
	// Verify that runtime/protoimpl is sufficiently up-to-date.
 | 
			
		||||
	_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// This is a compile-time assertion that a sufficiently up-to-date version
 | 
			
		||||
// of the legacy proto package is being used.
 | 
			
		||||
const _ = proto.ProtoPackageIsVersion4
 | 
			
		||||
 | 
			
		||||
// A tag for an override. This is used as a
 | 
			
		||||
// standard shorthand for sending a message with
 | 
			
		||||
// an override. If a message starts with before and
 | 
			
		||||
// ends with after, clients should send a message
 | 
			
		||||
// with the override the tag belongs to, stripping
 | 
			
		||||
// the tag indicators.
 | 
			
		||||
type OverrideTag struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	// The portion of the tag before the messge.
 | 
			
		||||
	Before string `protobuf:"bytes,1,opt,name=before,proto3" json:"before,omitempty"`
 | 
			
		||||
	// The portion of the tag after the messge.
 | 
			
		||||
	After string `protobuf:"bytes,2,opt,name=after,proto3" json:"after,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *OverrideTag) Reset() {
 | 
			
		||||
	*x = OverrideTag{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_profile_v1_appdata_proto_msgTypes[0]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		ms.StoreMessageInfo(mi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *OverrideTag) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*OverrideTag) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *OverrideTag) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_profile_v1_appdata_proto_msgTypes[0]
 | 
			
		||||
	if protoimpl.UnsafeEnabled && x != nil {
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		if ms.LoadMessageInfo() == nil {
 | 
			
		||||
			ms.StoreMessageInfo(mi)
 | 
			
		||||
		}
 | 
			
		||||
		return ms
 | 
			
		||||
	}
 | 
			
		||||
	return mi.MessageOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deprecated: Use OverrideTag.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*OverrideTag) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_profile_v1_appdata_proto_rawDescGZIP(), []int{0}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *OverrideTag) GetBefore() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Before
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *OverrideTag) GetAfter() string {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.After
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// An individual override
 | 
			
		||||
type ProfileOverride struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	// The username for this override
 | 
			
		||||
	Username *string `protobuf:"bytes,1,opt,name=username,proto3,oneof" json:"username,omitempty"`
 | 
			
		||||
	// The avatar for this override
 | 
			
		||||
	Avatar *string `protobuf:"bytes,2,opt,name=avatar,proto3,oneof" json:"avatar,omitempty"`
 | 
			
		||||
	// The tags for this override.
 | 
			
		||||
	Tags []*OverrideTag `protobuf:"bytes,3,rep,name=tags,proto3" json:"tags,omitempty"`
 | 
			
		||||
	// The reason this override is used
 | 
			
		||||
	//
 | 
			
		||||
	// Types that are assignable to Reason:
 | 
			
		||||
	//	*ProfileOverride_UserDefined
 | 
			
		||||
	//	*ProfileOverride_SystemPlurality
 | 
			
		||||
	Reason isProfileOverride_Reason `protobuf_oneof:"reason"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) Reset() {
 | 
			
		||||
	*x = ProfileOverride{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_profile_v1_appdata_proto_msgTypes[1]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		ms.StoreMessageInfo(mi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*ProfileOverride) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_profile_v1_appdata_proto_msgTypes[1]
 | 
			
		||||
	if protoimpl.UnsafeEnabled && x != nil {
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		if ms.LoadMessageInfo() == nil {
 | 
			
		||||
			ms.StoreMessageInfo(mi)
 | 
			
		||||
		}
 | 
			
		||||
		return ms
 | 
			
		||||
	}
 | 
			
		||||
	return mi.MessageOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deprecated: Use ProfileOverride.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*ProfileOverride) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_profile_v1_appdata_proto_rawDescGZIP(), []int{1}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) GetUsername() string {
 | 
			
		||||
	if x != nil && x.Username != nil {
 | 
			
		||||
		return *x.Username
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) GetAvatar() string {
 | 
			
		||||
	if x != nil && x.Avatar != nil {
 | 
			
		||||
		return *x.Avatar
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) GetTags() []*OverrideTag {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Tags
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (m *ProfileOverride) GetReason() isProfileOverride_Reason {
 | 
			
		||||
	if m != nil {
 | 
			
		||||
		return m.Reason
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) GetUserDefined() string {
 | 
			
		||||
	if x, ok := x.GetReason().(*ProfileOverride_UserDefined); ok {
 | 
			
		||||
		return x.UserDefined
 | 
			
		||||
	}
 | 
			
		||||
	return ""
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *ProfileOverride) GetSystemPlurality() *v1.Empty {
 | 
			
		||||
	if x, ok := x.GetReason().(*ProfileOverride_SystemPlurality); ok {
 | 
			
		||||
		return x.SystemPlurality
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type isProfileOverride_Reason interface {
 | 
			
		||||
	isProfileOverride_Reason()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ProfileOverride_UserDefined struct {
 | 
			
		||||
	// a custom reason in case the builtin ones don't fit
 | 
			
		||||
	UserDefined string `protobuf:"bytes,4,opt,name=user_defined,json=userDefined,proto3,oneof"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
type ProfileOverride_SystemPlurality struct {
 | 
			
		||||
	// plurality, not system as in computer
 | 
			
		||||
	SystemPlurality *v1.Empty `protobuf:"bytes,5,opt,name=system_plurality,json=systemPlurality,proto3,oneof"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*ProfileOverride_UserDefined) isProfileOverride_Reason() {}
 | 
			
		||||
 | 
			
		||||
func (*ProfileOverride_SystemPlurality) isProfileOverride_Reason() {}
 | 
			
		||||
 | 
			
		||||
// The message used for the 'h.overrides' key
 | 
			
		||||
// of appdata.
 | 
			
		||||
type AppDataOverrides struct {
 | 
			
		||||
	state         protoimpl.MessageState
 | 
			
		||||
	sizeCache     protoimpl.SizeCache
 | 
			
		||||
	unknownFields protoimpl.UnknownFields
 | 
			
		||||
 | 
			
		||||
	// The list of overrides.
 | 
			
		||||
	Overrides []*ProfileOverride `protobuf:"bytes,1,rep,name=overrides,proto3" json:"overrides,omitempty"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *AppDataOverrides) Reset() {
 | 
			
		||||
	*x = AppDataOverrides{}
 | 
			
		||||
	if protoimpl.UnsafeEnabled {
 | 
			
		||||
		mi := &file_profile_v1_appdata_proto_msgTypes[2]
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		ms.StoreMessageInfo(mi)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *AppDataOverrides) String() string {
 | 
			
		||||
	return protoimpl.X.MessageStringOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (*AppDataOverrides) ProtoMessage() {}
 | 
			
		||||
 | 
			
		||||
func (x *AppDataOverrides) ProtoReflect() protoreflect.Message {
 | 
			
		||||
	mi := &file_profile_v1_appdata_proto_msgTypes[2]
 | 
			
		||||
	if protoimpl.UnsafeEnabled && x != nil {
 | 
			
		||||
		ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
 | 
			
		||||
		if ms.LoadMessageInfo() == nil {
 | 
			
		||||
			ms.StoreMessageInfo(mi)
 | 
			
		||||
		}
 | 
			
		||||
		return ms
 | 
			
		||||
	}
 | 
			
		||||
	return mi.MessageOf(x)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Deprecated: Use AppDataOverrides.ProtoReflect.Descriptor instead.
 | 
			
		||||
func (*AppDataOverrides) Descriptor() ([]byte, []int) {
 | 
			
		||||
	return file_profile_v1_appdata_proto_rawDescGZIP(), []int{2}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (x *AppDataOverrides) GetOverrides() []*ProfileOverride {
 | 
			
		||||
	if x != nil {
 | 
			
		||||
		return x.Overrides
 | 
			
		||||
	}
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var File_profile_v1_appdata_proto protoreflect.FileDescriptor
 | 
			
		||||
 | 
			
		||||
var file_profile_v1_appdata_proto_rawDesc = []byte{
 | 
			
		||||
	0x0a, 0x18, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f, 0x76, 0x31, 0x2f, 0x61, 0x70, 0x70,
 | 
			
		||||
	0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x13, 0x70, 0x72, 0x6f, 0x74,
 | 
			
		||||
	0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x1a,
 | 
			
		||||
	0x1b, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x76, 0x31,
 | 
			
		||||
	0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x3b, 0x0a, 0x0b,
 | 
			
		||||
	0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x54, 0x61, 0x67, 0x12, 0x16, 0x0a, 0x06, 0x62,
 | 
			
		||||
	0x65, 0x66, 0x6f, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x65, 0x66,
 | 
			
		||||
	0x6f, 0x72, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01,
 | 
			
		||||
	0x28, 0x09, 0x52, 0x05, 0x61, 0x66, 0x74, 0x65, 0x72, 0x22, 0x9a, 0x02, 0x0a, 0x0f, 0x50, 0x72,
 | 
			
		||||
	0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x1f, 0x0a,
 | 
			
		||||
	0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x48,
 | 
			
		||||
	0x01, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x88, 0x01, 0x01, 0x12, 0x1b,
 | 
			
		||||
	0x0a, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x02,
 | 
			
		||||
	0x52, 0x06, 0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x88, 0x01, 0x01, 0x12, 0x34, 0x0a, 0x04, 0x74,
 | 
			
		||||
	0x61, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x20, 0x2e, 0x70, 0x72, 0x6f, 0x74,
 | 
			
		||||
	0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x2e,
 | 
			
		||||
	0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x54, 0x61, 0x67, 0x52, 0x04, 0x74, 0x61, 0x67,
 | 
			
		||||
	0x73, 0x12, 0x23, 0x0a, 0x0c, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x64, 0x65, 0x66, 0x69, 0x6e, 0x65,
 | 
			
		||||
	0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x75, 0x73, 0x65, 0x72, 0x44,
 | 
			
		||||
	0x65, 0x66, 0x69, 0x6e, 0x65, 0x64, 0x12, 0x4c, 0x0a, 0x10, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d,
 | 
			
		||||
	0x5f, 0x70, 0x6c, 0x75, 0x72, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b,
 | 
			
		||||
	0x32, 0x1f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x68, 0x61, 0x72, 0x6d,
 | 
			
		||||
	0x6f, 0x6e, 0x79, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x6d, 0x70, 0x74,
 | 
			
		||||
	0x79, 0x48, 0x00, 0x52, 0x0f, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x50, 0x6c, 0x75, 0x72, 0x61,
 | 
			
		||||
	0x6c, 0x69, 0x74, 0x79, 0x42, 0x08, 0x0a, 0x06, 0x72, 0x65, 0x61, 0x73, 0x6f, 0x6e, 0x42, 0x0b,
 | 
			
		||||
	0x0a, 0x09, 0x5f, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x42, 0x09, 0x0a, 0x07, 0x5f,
 | 
			
		||||
	0x61, 0x76, 0x61, 0x74, 0x61, 0x72, 0x22, 0x56, 0x0a, 0x10, 0x41, 0x70, 0x70, 0x44, 0x61, 0x74,
 | 
			
		||||
	0x61, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x12, 0x42, 0x0a, 0x09, 0x6f, 0x76,
 | 
			
		||||
	0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x24, 0x2e,
 | 
			
		||||
	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65,
 | 
			
		||||
	0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72,
 | 
			
		||||
	0x69, 0x64, 0x65, 0x52, 0x09, 0x6f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x73, 0x42, 0xd7,
 | 
			
		||||
	0x01, 0x0a, 0x17, 0x63, 0x6f, 0x6d, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e,
 | 
			
		||||
	0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x76, 0x31, 0x42, 0x0c, 0x41, 0x70, 0x70, 0x64,
 | 
			
		||||
	0x61, 0x74, 0x61, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x40, 0x67, 0x69, 0x74, 0x68,
 | 
			
		||||
	0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x72, 0x6d, 0x6f, 0x6e, 0x79, 0x2d, 0x64,
 | 
			
		||||
	0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x6d, 0x65, 0x6e, 0x74, 0x2f, 0x73, 0x68, 0x69, 0x62, 0x73,
 | 
			
		||||
	0x68, 0x69, 0x62, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2f,
 | 
			
		||||
	0x76, 0x31, 0x3b, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x76, 0x31, 0xa2, 0x02, 0x03, 0x50,
 | 
			
		||||
	0x50, 0x58, 0xaa, 0x02, 0x13, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x2e, 0x50, 0x72,
 | 
			
		||||
	0x6f, 0x66, 0x69, 0x6c, 0x65, 0x2e, 0x56, 0x31, 0xca, 0x02, 0x13, 0x50, 0x72, 0x6f, 0x74, 0x6f,
 | 
			
		||||
	0x63, 0x6f, 0x6c, 0x5c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x5c, 0x56, 0x31, 0xe2, 0x02,
 | 
			
		||||
	0x1f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x5c, 0x50, 0x72, 0x6f, 0x66, 0x69, 0x6c,
 | 
			
		||||
	0x65, 0x5c, 0x56, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61,
 | 
			
		||||
	0xea, 0x02, 0x15, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x3a, 0x3a, 0x50, 0x72, 0x6f,
 | 
			
		||||
	0x66, 0x69, 0x6c, 0x65, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	file_profile_v1_appdata_proto_rawDescOnce sync.Once
 | 
			
		||||
	file_profile_v1_appdata_proto_rawDescData = file_profile_v1_appdata_proto_rawDesc
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func file_profile_v1_appdata_proto_rawDescGZIP() []byte {
 | 
			
		||||
	file_profile_v1_appdata_proto_rawDescOnce.Do(func() {
 | 
			
		||||
		file_profile_v1_appdata_proto_rawDescData = protoimpl.X.CompressGZIP(file_profile_v1_appdata_proto_rawDescData)
 | 
			
		||||
	})
 | 
			
		||||
	return file_profile_v1_appdata_proto_rawDescData
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var file_profile_v1_appdata_proto_msgTypes = make([]protoimpl.MessageInfo, 3)
 | 
			
		||||
var file_profile_v1_appdata_proto_goTypes = []interface{}{
 | 
			
		||||
	(*OverrideTag)(nil),      // 0: protocol.profile.v1.OverrideTag
 | 
			
		||||
	(*ProfileOverride)(nil),  // 1: protocol.profile.v1.ProfileOverride
 | 
			
		||||
	(*AppDataOverrides)(nil), // 2: protocol.profile.v1.AppDataOverrides
 | 
			
		||||
	(*v1.Empty)(nil),         // 3: protocol.harmonytypes.v1.Empty
 | 
			
		||||
}
 | 
			
		||||
var file_profile_v1_appdata_proto_depIdxs = []int32{
 | 
			
		||||
	0, // 0: protocol.profile.v1.ProfileOverride.tags:type_name -> protocol.profile.v1.OverrideTag
 | 
			
		||||
	3, // 1: protocol.profile.v1.ProfileOverride.system_plurality:type_name -> protocol.harmonytypes.v1.Empty
 | 
			
		||||
	1, // 2: protocol.profile.v1.AppDataOverrides.overrides:type_name -> protocol.profile.v1.ProfileOverride
 | 
			
		||||
	3, // [3:3] is the sub-list for method output_type
 | 
			
		||||
	3, // [3:3] is the sub-list for method input_type
 | 
			
		||||
	3, // [3:3] is the sub-list for extension type_name
 | 
			
		||||
	3, // [3:3] is the sub-list for extension extendee
 | 
			
		||||
	0, // [0:3] is the sub-list for field type_name
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func init() { file_profile_v1_appdata_proto_init() }
 | 
			
		||||
func file_profile_v1_appdata_proto_init() {
 | 
			
		||||
	if File_profile_v1_appdata_proto != nil {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if !protoimpl.UnsafeEnabled {
 | 
			
		||||
		file_profile_v1_appdata_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*OverrideTag); i {
 | 
			
		||||
			case 0:
 | 
			
		||||
				return &v.state
 | 
			
		||||
			case 1:
 | 
			
		||||
				return &v.sizeCache
 | 
			
		||||
			case 2:
 | 
			
		||||
				return &v.unknownFields
 | 
			
		||||
			default:
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		file_profile_v1_appdata_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*ProfileOverride); i {
 | 
			
		||||
			case 0:
 | 
			
		||||
				return &v.state
 | 
			
		||||
			case 1:
 | 
			
		||||
				return &v.sizeCache
 | 
			
		||||
			case 2:
 | 
			
		||||
				return &v.unknownFields
 | 
			
		||||
			default:
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		file_profile_v1_appdata_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
 | 
			
		||||
			switch v := v.(*AppDataOverrides); i {
 | 
			
		||||
			case 0:
 | 
			
		||||
				return &v.state
 | 
			
		||||
			case 1:
 | 
			
		||||
				return &v.sizeCache
 | 
			
		||||
			case 2:
 | 
			
		||||
				return &v.unknownFields
 | 
			
		||||
			default:
 | 
			
		||||
				return nil
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	file_profile_v1_appdata_proto_msgTypes[1].OneofWrappers = []interface{}{
 | 
			
		||||
		(*ProfileOverride_UserDefined)(nil),
 | 
			
		||||
		(*ProfileOverride_SystemPlurality)(nil),
 | 
			
		||||
	}
 | 
			
		||||
	type x struct{}
 | 
			
		||||
	out := protoimpl.TypeBuilder{
 | 
			
		||||
		File: protoimpl.DescBuilder{
 | 
			
		||||
			GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
 | 
			
		||||
			RawDescriptor: file_profile_v1_appdata_proto_rawDesc,
 | 
			
		||||
			NumEnums:      0,
 | 
			
		||||
			NumMessages:   3,
 | 
			
		||||
			NumExtensions: 0,
 | 
			
		||||
			NumServices:   0,
 | 
			
		||||
		},
 | 
			
		||||
		GoTypes:           file_profile_v1_appdata_proto_goTypes,
 | 
			
		||||
		DependencyIndexes: file_profile_v1_appdata_proto_depIdxs,
 | 
			
		||||
		MessageInfos:      file_profile_v1_appdata_proto_msgTypes,
 | 
			
		||||
	}.Build()
 | 
			
		||||
	File_profile_v1_appdata_proto = out.File
 | 
			
		||||
	file_profile_v1_appdata_proto_rawDesc = nil
 | 
			
		||||
	file_profile_v1_appdata_proto_goTypes = nil
 | 
			
		||||
	file_profile_v1_appdata_proto_depIdxs = nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										6
									
								
								vendor/github.com/klauspost/compress/s2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								vendor/github.com/klauspost/compress/s2/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -704,7 +704,7 @@ To automatically add an index to a stream, add `WriterAddIndex()` option to your
 | 
			
		||||
Then the index will be added to the stream when `Close()` is called.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    // Add Index to stream...
 | 
			
		||||
	// Add Index to stream...
 | 
			
		||||
	enc := s2.NewWriter(w, s2.WriterAddIndex())
 | 
			
		||||
	io.Copy(enc, r)
 | 
			
		||||
	enc.Close()
 | 
			
		||||
@@ -714,7 +714,7 @@ If you want to store the index separately, you can use `CloseIndex()` instead of
 | 
			
		||||
This will return the index. Note that `CloseIndex()` should only be called once, and you shouldn't call `Close()`.
 | 
			
		||||
 | 
			
		||||
```
 | 
			
		||||
    // Get index for separate storage... 
 | 
			
		||||
	// Get index for separate storage... 
 | 
			
		||||
	enc := s2.NewWriter(w)
 | 
			
		||||
	io.Copy(enc, r)
 | 
			
		||||
	index, err := enc.CloseIndex()
 | 
			
		||||
@@ -894,7 +894,7 @@ for each entry {
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    // Compressed uses previous and our estimate.
 | 
			
		||||
    entry[entryNum].CompressedOffset = entry[entryNum-1].CompressedOffset + CompressGuess
 | 
			
		||||
    entry[entryNum].CompressedOffset = entry[entryNum-1].CompressedOffset + CompressGuess + cOff
 | 
			
		||||
        
 | 
			
		||||
     // Adjust compressed offset for next loop, integer truncating division must be used. 
 | 
			
		||||
     CompressGuess += cOff/2               
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										24
									
								
								vendor/github.com/klauspost/compress/zstd/blockdec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								vendor/github.com/klauspost/compress/zstd/blockdec.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -76,12 +76,11 @@ type blockDec struct {
 | 
			
		||||
	// Window size of the block.
 | 
			
		||||
	WindowSize uint64
 | 
			
		||||
 | 
			
		||||
	history     chan *history
 | 
			
		||||
	input       chan struct{}
 | 
			
		||||
	result      chan decodeOutput
 | 
			
		||||
	sequenceBuf []seq
 | 
			
		||||
	err         error
 | 
			
		||||
	decWG       sync.WaitGroup
 | 
			
		||||
	history chan *history
 | 
			
		||||
	input   chan struct{}
 | 
			
		||||
	result  chan decodeOutput
 | 
			
		||||
	err     error
 | 
			
		||||
	decWG   sync.WaitGroup
 | 
			
		||||
 | 
			
		||||
	// Frame to use for singlethreaded decoding.
 | 
			
		||||
	// Should not be used by the decoder itself since parent may be another frame.
 | 
			
		||||
@@ -512,18 +511,7 @@ func (b *blockDec) decodeCompressed(hist *history) error {
 | 
			
		||||
		nSeqs = 0x7f00 + int(in[1]) + (int(in[2]) << 8)
 | 
			
		||||
		in = in[3:]
 | 
			
		||||
	}
 | 
			
		||||
	// Allocate sequences
 | 
			
		||||
	if cap(b.sequenceBuf) < nSeqs {
 | 
			
		||||
		if b.lowMem {
 | 
			
		||||
			b.sequenceBuf = make([]seq, nSeqs)
 | 
			
		||||
		} else {
 | 
			
		||||
			// Allocate max
 | 
			
		||||
			b.sequenceBuf = make([]seq, nSeqs, maxSequences)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// Reuse buffer
 | 
			
		||||
		b.sequenceBuf = b.sequenceBuf[:nSeqs]
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	var seqs = &sequenceDecs{}
 | 
			
		||||
	if nSeqs > 0 {
 | 
			
		||||
		if len(in) < 1 {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										98
									
								
								vendor/github.com/klauspost/compress/zstd/decodeheader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										98
									
								
								vendor/github.com/klauspost/compress/zstd/decodeheader.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5,6 +5,7 @@ package zstd
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"bytes"
 | 
			
		||||
	"encoding/binary"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io"
 | 
			
		||||
)
 | 
			
		||||
@@ -15,18 +16,50 @@ const HeaderMaxSize = 14 + 3
 | 
			
		||||
 | 
			
		||||
// Header contains information about the first frame and block within that.
 | 
			
		||||
type Header struct {
 | 
			
		||||
	// Window Size the window of data to keep while decoding.
 | 
			
		||||
	// Will only be set if HasFCS is false.
 | 
			
		||||
	WindowSize uint64
 | 
			
		||||
	// SingleSegment specifies whether the data is to be decompressed into a
 | 
			
		||||
	// single contiguous memory segment.
 | 
			
		||||
	// It implies that WindowSize is invalid and that FrameContentSize is valid.
 | 
			
		||||
	SingleSegment bool
 | 
			
		||||
 | 
			
		||||
	// Frame content size.
 | 
			
		||||
	// Expected size of the entire frame.
 | 
			
		||||
	FrameContentSize uint64
 | 
			
		||||
	// WindowSize is the window of data to keep while decoding.
 | 
			
		||||
	// Will only be set if SingleSegment is false.
 | 
			
		||||
	WindowSize uint64
 | 
			
		||||
 | 
			
		||||
	// Dictionary ID.
 | 
			
		||||
	// If 0, no dictionary.
 | 
			
		||||
	DictionaryID uint32
 | 
			
		||||
 | 
			
		||||
	// HasFCS specifies whether FrameContentSize has a valid value.
 | 
			
		||||
	HasFCS bool
 | 
			
		||||
 | 
			
		||||
	// FrameContentSize is the expected uncompressed size of the entire frame.
 | 
			
		||||
	FrameContentSize uint64
 | 
			
		||||
 | 
			
		||||
	// Skippable will be true if the frame is meant to be skipped.
 | 
			
		||||
	// This implies that FirstBlock.OK is false.
 | 
			
		||||
	Skippable bool
 | 
			
		||||
 | 
			
		||||
	// SkippableID is the user-specific ID for the skippable frame.
 | 
			
		||||
	// Valid values are between 0 to 15, inclusive.
 | 
			
		||||
	SkippableID int
 | 
			
		||||
 | 
			
		||||
	// SkippableSize is the length of the user data to skip following
 | 
			
		||||
	// the header.
 | 
			
		||||
	SkippableSize uint32
 | 
			
		||||
 | 
			
		||||
	// HeaderSize is the raw size of the frame header.
 | 
			
		||||
	//
 | 
			
		||||
	// For normal frames, it includes the size of the magic number and
 | 
			
		||||
	// the size of the header (per section 3.1.1.1).
 | 
			
		||||
	// It does not include the size for any data blocks (section 3.1.1.2) nor
 | 
			
		||||
	// the size for the trailing content checksum.
 | 
			
		||||
	//
 | 
			
		||||
	// For skippable frames, this counts the size of the magic number
 | 
			
		||||
	// along with the size of the size field of the payload.
 | 
			
		||||
	// It does not include the size of the skippable payload itself.
 | 
			
		||||
	// The total frame size is the HeaderSize plus the SkippableSize.
 | 
			
		||||
	HeaderSize int
 | 
			
		||||
 | 
			
		||||
	// First block information.
 | 
			
		||||
	FirstBlock struct {
 | 
			
		||||
		// OK will be set if first block could be decoded.
 | 
			
		||||
@@ -51,17 +84,9 @@ type Header struct {
 | 
			
		||||
		CompressedSize int
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Skippable will be true if the frame is meant to be skipped.
 | 
			
		||||
	// No other information will be populated.
 | 
			
		||||
	Skippable bool
 | 
			
		||||
 | 
			
		||||
	// If set there is a checksum present for the block content.
 | 
			
		||||
	// The checksum field at the end is always 4 bytes long.
 | 
			
		||||
	HasCheckSum bool
 | 
			
		||||
 | 
			
		||||
	// If this is true FrameContentSize will have a valid value
 | 
			
		||||
	HasFCS bool
 | 
			
		||||
 | 
			
		||||
	SingleSegment bool
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Decode the header from the beginning of the stream.
 | 
			
		||||
@@ -71,39 +96,46 @@ type Header struct {
 | 
			
		||||
// If there isn't enough input, io.ErrUnexpectedEOF is returned.
 | 
			
		||||
// The FirstBlock.OK will indicate if enough information was available to decode the first block header.
 | 
			
		||||
func (h *Header) Decode(in []byte) error {
 | 
			
		||||
	*h = Header{}
 | 
			
		||||
	if len(in) < 4 {
 | 
			
		||||
		return io.ErrUnexpectedEOF
 | 
			
		||||
	}
 | 
			
		||||
	h.HeaderSize += 4
 | 
			
		||||
	b, in := in[:4], in[4:]
 | 
			
		||||
	if !bytes.Equal(b, frameMagic) {
 | 
			
		||||
		if !bytes.Equal(b[1:4], skippableFrameMagic) || b[0]&0xf0 != 0x50 {
 | 
			
		||||
			return ErrMagicMismatch
 | 
			
		||||
		}
 | 
			
		||||
		*h = Header{Skippable: true}
 | 
			
		||||
		if len(in) < 4 {
 | 
			
		||||
			return io.ErrUnexpectedEOF
 | 
			
		||||
		}
 | 
			
		||||
		h.HeaderSize += 4
 | 
			
		||||
		h.Skippable = true
 | 
			
		||||
		h.SkippableID = int(b[0] & 0xf)
 | 
			
		||||
		h.SkippableSize = binary.LittleEndian.Uint32(in)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	if len(in) < 1 {
 | 
			
		||||
		return io.ErrUnexpectedEOF
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Clear output
 | 
			
		||||
	*h = Header{}
 | 
			
		||||
	fhd, in := in[0], in[1:]
 | 
			
		||||
	h.SingleSegment = fhd&(1<<5) != 0
 | 
			
		||||
	h.HasCheckSum = fhd&(1<<2) != 0
 | 
			
		||||
 | 
			
		||||
	if fhd&(1<<3) != 0 {
 | 
			
		||||
		return errors.New("reserved bit set on frame header")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Read Window_Descriptor
 | 
			
		||||
	// https://github.com/facebook/zstd/blob/dev/doc/zstd_compression_format.md#window_descriptor
 | 
			
		||||
	if len(in) < 1 {
 | 
			
		||||
		return io.ErrUnexpectedEOF
 | 
			
		||||
	}
 | 
			
		||||
	fhd, in := in[0], in[1:]
 | 
			
		||||
	h.HeaderSize++
 | 
			
		||||
	h.SingleSegment = fhd&(1<<5) != 0
 | 
			
		||||
	h.HasCheckSum = fhd&(1<<2) != 0
 | 
			
		||||
	if fhd&(1<<3) != 0 {
 | 
			
		||||
		return errors.New("reserved bit set on frame header")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if !h.SingleSegment {
 | 
			
		||||
		if len(in) < 1 {
 | 
			
		||||
			return io.ErrUnexpectedEOF
 | 
			
		||||
		}
 | 
			
		||||
		var wd byte
 | 
			
		||||
		wd, in = in[0], in[1:]
 | 
			
		||||
		h.HeaderSize++
 | 
			
		||||
		windowLog := 10 + (wd >> 3)
 | 
			
		||||
		windowBase := uint64(1) << windowLog
 | 
			
		||||
		windowAdd := (windowBase / 8) * uint64(wd&0x7)
 | 
			
		||||
@@ -120,9 +152,7 @@ func (h *Header) Decode(in []byte) error {
 | 
			
		||||
			return io.ErrUnexpectedEOF
 | 
			
		||||
		}
 | 
			
		||||
		b, in = in[:size], in[size:]
 | 
			
		||||
		if b == nil {
 | 
			
		||||
			return io.ErrUnexpectedEOF
 | 
			
		||||
		}
 | 
			
		||||
		h.HeaderSize += int(size)
 | 
			
		||||
		switch size {
 | 
			
		||||
		case 1:
 | 
			
		||||
			h.DictionaryID = uint32(b[0])
 | 
			
		||||
@@ -152,9 +182,7 @@ func (h *Header) Decode(in []byte) error {
 | 
			
		||||
			return io.ErrUnexpectedEOF
 | 
			
		||||
		}
 | 
			
		||||
		b, in = in[:fcsSize], in[fcsSize:]
 | 
			
		||||
		if b == nil {
 | 
			
		||||
			return io.ErrUnexpectedEOF
 | 
			
		||||
		}
 | 
			
		||||
		h.HeaderSize += int(fcsSize)
 | 
			
		||||
		switch fcsSize {
 | 
			
		||||
		case 1:
 | 
			
		||||
			h.FrameContentSize = uint64(b[0])
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								vendor/github.com/klauspost/compress/zstd/encoder_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/klauspost/compress/zstd/encoder_options.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -24,6 +24,7 @@ type encoderOptions struct {
 | 
			
		||||
	allLitEntropy   bool
 | 
			
		||||
	customWindow    bool
 | 
			
		||||
	customALEntropy bool
 | 
			
		||||
	customBlockSize bool
 | 
			
		||||
	lowMem          bool
 | 
			
		||||
	dict            *dict
 | 
			
		||||
}
 | 
			
		||||
@@ -33,7 +34,7 @@ func (o *encoderOptions) setDefault() {
 | 
			
		||||
		concurrent:    runtime.GOMAXPROCS(0),
 | 
			
		||||
		crc:           true,
 | 
			
		||||
		single:        nil,
 | 
			
		||||
		blockSize:     1 << 16,
 | 
			
		||||
		blockSize:     maxCompressedBlockSize,
 | 
			
		||||
		windowSize:    8 << 20,
 | 
			
		||||
		level:         SpeedDefault,
 | 
			
		||||
		allLitEntropy: true,
 | 
			
		||||
@@ -106,6 +107,7 @@ func WithWindowSize(n int) EOption {
 | 
			
		||||
		o.customWindow = true
 | 
			
		||||
		if o.blockSize > o.windowSize {
 | 
			
		||||
			o.blockSize = o.windowSize
 | 
			
		||||
			o.customBlockSize = true
 | 
			
		||||
		}
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
@@ -188,10 +190,9 @@ func EncoderLevelFromZstd(level int) EncoderLevel {
 | 
			
		||||
		return SpeedDefault
 | 
			
		||||
	case level >= 6 && level < 10:
 | 
			
		||||
		return SpeedBetterCompression
 | 
			
		||||
	case level >= 10:
 | 
			
		||||
	default:
 | 
			
		||||
		return SpeedBestCompression
 | 
			
		||||
	}
 | 
			
		||||
	return SpeedDefault
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// String provides a string representation of the compression level.
 | 
			
		||||
@@ -222,6 +223,9 @@ func WithEncoderLevel(l EncoderLevel) EOption {
 | 
			
		||||
			switch o.level {
 | 
			
		||||
			case SpeedFastest:
 | 
			
		||||
				o.windowSize = 4 << 20
 | 
			
		||||
				if !o.customBlockSize {
 | 
			
		||||
					o.blockSize = 1 << 16
 | 
			
		||||
				}
 | 
			
		||||
			case SpeedDefault:
 | 
			
		||||
				o.windowSize = 8 << 20
 | 
			
		||||
			case SpeedBetterCompression:
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_amd64.s
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,6 +1,7 @@
 | 
			
		||||
// +build !appengine
 | 
			
		||||
// +build gc
 | 
			
		||||
// +build !purego
 | 
			
		||||
// +build !noasm
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										81
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										81
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_arm64.s
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,13 +1,13 @@
 | 
			
		||||
// +build gc,!purego
 | 
			
		||||
// +build gc,!purego,!noasm
 | 
			
		||||
 | 
			
		||||
#include "textflag.h"
 | 
			
		||||
 | 
			
		||||
// Register allocation.
 | 
			
		||||
#define digest	R1
 | 
			
		||||
#define h	R2	// Return value.
 | 
			
		||||
#define p	R3	// Input pointer.
 | 
			
		||||
#define h	R2 // Return value.
 | 
			
		||||
#define p	R3 // Input pointer.
 | 
			
		||||
#define len	R4
 | 
			
		||||
#define nblocks	R5	// len / 32.
 | 
			
		||||
#define nblocks	R5 // len / 32.
 | 
			
		||||
#define prime1	R7
 | 
			
		||||
#define prime2	R8
 | 
			
		||||
#define prime3	R9
 | 
			
		||||
@@ -22,50 +22,48 @@
 | 
			
		||||
#define x3	R22
 | 
			
		||||
#define x4	R23
 | 
			
		||||
 | 
			
		||||
#define round(acc, x) 			\
 | 
			
		||||
	MADD prime2, acc, x, acc	\
 | 
			
		||||
	ROR  $64-31, acc		\
 | 
			
		||||
	MUL  prime1, acc		\
 | 
			
		||||
#define round(acc, x) \
 | 
			
		||||
	MADD prime2, acc, x, acc \
 | 
			
		||||
	ROR  $64-31, acc         \
 | 
			
		||||
	MUL  prime1, acc         \
 | 
			
		||||
 | 
			
		||||
// x = round(0, x).
 | 
			
		||||
#define round0(x)	\
 | 
			
		||||
	MUL prime2, x	\
 | 
			
		||||
	ROR $64-31, x	\
 | 
			
		||||
	MUL prime1, x	\
 | 
			
		||||
#define round0(x) \
 | 
			
		||||
	MUL prime2, x \
 | 
			
		||||
	ROR $64-31, x \
 | 
			
		||||
	MUL prime1, x \
 | 
			
		||||
 | 
			
		||||
#define mergeRound(x)			\
 | 
			
		||||
	round0(x)			\
 | 
			
		||||
	EOR  x, h			\
 | 
			
		||||
	MADD h, prime4, prime1, h	\
 | 
			
		||||
#define mergeRound(x) \
 | 
			
		||||
	round0(x)                 \
 | 
			
		||||
	EOR  x, h                 \
 | 
			
		||||
	MADD h, prime4, prime1, h \
 | 
			
		||||
 | 
			
		||||
// Update v[1-4] with 32-byte blocks. Assumes len >= 32.
 | 
			
		||||
#define blocksLoop()		\
 | 
			
		||||
	LSR  $5, len, nblocks	\
 | 
			
		||||
	PCALIGN $16		\
 | 
			
		||||
loop:				\
 | 
			
		||||
	LDP.P 32(p), (x1, x2)	\
 | 
			
		||||
	round(v1, x1)		\
 | 
			
		||||
	LDP  -16(p), (x3, x4)	\
 | 
			
		||||
	round(v2, x2)		\
 | 
			
		||||
	SUB  $1, nblocks	\
 | 
			
		||||
	round(v3, x3)		\
 | 
			
		||||
	round(v4, x4)		\
 | 
			
		||||
	CBNZ nblocks, loop	\
 | 
			
		||||
 | 
			
		||||
#define blocksLoop() \
 | 
			
		||||
	LSR     $5, len, nblocks \
 | 
			
		||||
	PCALIGN $16              \
 | 
			
		||||
	loop:                    \
 | 
			
		||||
	LDP.P   32(p), (x1, x2)  \
 | 
			
		||||
	round(v1, x1)            \
 | 
			
		||||
	LDP     -16(p), (x3, x4) \
 | 
			
		||||
	round(v2, x2)            \
 | 
			
		||||
	SUB     $1, nblocks      \
 | 
			
		||||
	round(v3, x3)            \
 | 
			
		||||
	round(v4, x4)            \
 | 
			
		||||
	CBNZ    nblocks, loop    \
 | 
			
		||||
 | 
			
		||||
// The primes are repeated here to ensure that they're stored
 | 
			
		||||
// in a contiguous array, so we can load them with LDP.
 | 
			
		||||
DATA  primes<> +0(SB)/8, $11400714785074694791
 | 
			
		||||
DATA  primes<> +8(SB)/8, $14029467366897019727
 | 
			
		||||
DATA  primes<>+16(SB)/8, $1609587929392839161
 | 
			
		||||
DATA  primes<>+24(SB)/8, $9650029242287828579
 | 
			
		||||
DATA  primes<>+32(SB)/8, $2870177450012600261
 | 
			
		||||
DATA primes<> +0(SB)/8, $11400714785074694791
 | 
			
		||||
DATA primes<> +8(SB)/8, $14029467366897019727
 | 
			
		||||
DATA primes<>+16(SB)/8, $1609587929392839161
 | 
			
		||||
DATA primes<>+24(SB)/8, $9650029242287828579
 | 
			
		||||
DATA primes<>+32(SB)/8, $2870177450012600261
 | 
			
		||||
GLOBL primes<>(SB), NOPTR+RODATA, $40
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// func Sum64(b []byte) uint64
 | 
			
		||||
TEXT ·Sum64(SB), NOFRAME+NOSPLIT, $0-32
 | 
			
		||||
	LDP  b_base+0(FP), (p, len)
 | 
			
		||||
	LDP b_base+0(FP), (p, len)
 | 
			
		||||
 | 
			
		||||
	LDP  primes<> +0(SB), (prime1, prime2)
 | 
			
		||||
	LDP  primes<>+16(SB), (prime3, prime4)
 | 
			
		||||
@@ -156,24 +154,23 @@ try1:
 | 
			
		||||
 | 
			
		||||
end:
 | 
			
		||||
	EOR h >> 33, h
 | 
			
		||||
	MUL prime2,  h
 | 
			
		||||
	MUL prime2, h
 | 
			
		||||
	EOR h >> 29, h
 | 
			
		||||
	MUL prime3,  h
 | 
			
		||||
	MUL prime3, h
 | 
			
		||||
	EOR h >> 32, h
 | 
			
		||||
 | 
			
		||||
	MOVD h, ret+24(FP)
 | 
			
		||||
	RET
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// func writeBlocks(d *Digest, b []byte) int
 | 
			
		||||
//
 | 
			
		||||
// Assumes len(b) >= 32.
 | 
			
		||||
TEXT ·writeBlocks(SB), NOFRAME+NOSPLIT, $0-40
 | 
			
		||||
	LDP  primes<>(SB), (prime1, prime2)
 | 
			
		||||
	LDP primes<>(SB), (prime1, prime2)
 | 
			
		||||
 | 
			
		||||
	// Load state. Assume v[1-4] are stored contiguously.
 | 
			
		||||
	MOVD d+0(FP), digest
 | 
			
		||||
	LDP   0(digest), (v1, v2)
 | 
			
		||||
	LDP  0(digest), (v1, v2)
 | 
			
		||||
	LDP  16(digest), (v3, v4)
 | 
			
		||||
 | 
			
		||||
	LDP b_base+8(FP), (p, len)
 | 
			
		||||
@@ -181,7 +178,7 @@ TEXT ·writeBlocks(SB), NOFRAME+NOSPLIT, $0-40
 | 
			
		||||
	blocksLoop()
 | 
			
		||||
 | 
			
		||||
	// Store updated state.
 | 
			
		||||
	STP (v1, v2),  0(digest)
 | 
			
		||||
	STP (v1, v2), 0(digest)
 | 
			
		||||
	STP (v3, v4), 16(digest)
 | 
			
		||||
 | 
			
		||||
	BIC  $31, len
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										3
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_asm.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,8 +1,9 @@
 | 
			
		||||
//go:build (amd64 || arm64) && !appengine && gc && !purego
 | 
			
		||||
//go:build (amd64 || arm64) && !appengine && gc && !purego && !noasm
 | 
			
		||||
// +build amd64 arm64
 | 
			
		||||
// +build !appengine
 | 
			
		||||
// +build gc
 | 
			
		||||
// +build !purego
 | 
			
		||||
// +build !noasm
 | 
			
		||||
 | 
			
		||||
package xxhash
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								vendor/github.com/klauspost/compress/zstd/internal/xxhash/xxhash_other.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,5 +1,5 @@
 | 
			
		||||
//go:build (!amd64 && !arm64) || appengine || !gc || purego
 | 
			
		||||
// +build !amd64,!arm64 appengine !gc purego
 | 
			
		||||
//go:build (!amd64 && !arm64) || appengine || !gc || purego || noasm
 | 
			
		||||
// +build !amd64,!arm64 appengine !gc purego noasm
 | 
			
		||||
 | 
			
		||||
package xxhash
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1397
									
								
								vendor/github.com/kyokomi/emoji/v2/emoji_codemap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										1397
									
								
								vendor/github.com/kyokomi/emoji/v2/emoji_codemap.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								vendor/github.com/labstack/echo/v4/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										21
									
								
								vendor/github.com/labstack/echo/v4/CHANGELOG.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -1,5 +1,26 @@
 | 
			
		||||
# Changelog
 | 
			
		||||
 | 
			
		||||
## v4.7.0 - 2022-03-01
 | 
			
		||||
 | 
			
		||||
**Enhancements**
 | 
			
		||||
 | 
			
		||||
* Add JWT, KeyAuth, CSRF multivalue extractors [#2060](https://github.com/labstack/echo/pull/2060)
 | 
			
		||||
* Add LogErrorFunc to recover middleware [#2072](https://github.com/labstack/echo/pull/2072)
 | 
			
		||||
* Add support for HEAD method query params binding [#2027](https://github.com/labstack/echo/pull/2027)
 | 
			
		||||
* Improve filesystem support with echo.FileFS, echo.StaticFS, group.FileFS, group.StaticFS [#2064](https://github.com/labstack/echo/pull/2064)
 | 
			
		||||
 | 
			
		||||
**Fixes**
 | 
			
		||||
 | 
			
		||||
* Fix X-Real-IP bug, improve tests [#2007](https://github.com/labstack/echo/pull/2007)
 | 
			
		||||
* Minor syntax fixes [#1994](https://github.com/labstack/echo/pull/1994), [#2102](https://github.com/labstack/echo/pull/2102), [#2102](https://github.com/labstack/echo/pull/2102)
 | 
			
		||||
 | 
			
		||||
**General**
 | 
			
		||||
 | 
			
		||||
* Add cache-control and connection headers [#2103](https://github.com/labstack/echo/pull/2103)
 | 
			
		||||
* Add Retry-After header constant [#2078](https://github.com/labstack/echo/pull/2078)
 | 
			
		||||
* Upgrade `go` directive in `go.mod` to 1.17 [#2049](https://github.com/labstack/echo/pull/2049)
 | 
			
		||||
* Add Pagoda [#2077](https://github.com/labstack/echo/pull/2077) and Souin [#2069](https://github.com/labstack/echo/pull/2069) to 3rd-party middlewares in README
 | 
			
		||||
 | 
			
		||||
## v4.6.3 - 2022-01-10
 | 
			
		||||
 | 
			
		||||
**Fixes**
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								vendor/github.com/labstack/echo/v4/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								vendor/github.com/labstack/echo/v4/README.md
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -5,7 +5,6 @@
 | 
			
		||||
[](https://goreportcard.com/report/github.com/labstack/echo)
 | 
			
		||||
[](https://travis-ci.org/labstack/echo)
 | 
			
		||||
[](https://codecov.io/gh/labstack/echo)
 | 
			
		||||
[](https://gitter.im/labstack/echo)
 | 
			
		||||
[](https://github.com/labstack/echo/discussions)
 | 
			
		||||
[](https://twitter.com/labstack)
 | 
			
		||||
[](https://raw.githubusercontent.com/labstack/echo/master/LICENSE)
 | 
			
		||||
@@ -92,10 +91,23 @@ func hello(c echo.Context) error {
 | 
			
		||||
}
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
# Third-party middlewares
 | 
			
		||||
 | 
			
		||||
| Repository | Description                                                                                                                                                                                                                                                                                                                                                                                                    |
 | 
			
		||||
|------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
 | 
			
		||||
| [github.com/labstack/echo-contrib](https://github.com/labstack/echo-contrib) | (by Echo team) [casbin](https://github.com/casbin/casbin), [gorilla/sessions](https://github.com/gorilla/sessions), [jaegertracing](github.com/uber/jaeger-client-go), [prometheus](https://github.com/prometheus/client_golang/), [pprof](https://pkg.go.dev/net/http/pprof), [zipkin](https://github.com/openzipkin/zipkin-go) middlewares | 
 | 
			
		||||
| [deepmap/oapi-codegen](https://github.com/deepmap/oapi-codegen) | Automatically generate RESTful API documentation with [OpenAPI](https://swagger.io/specification/) Client and Server Code Generator                                                                                                                                                                                                                       |
 | 
			
		||||
| [github.com/swaggo/echo-swagger](https://github.com/swaggo/echo-swagger) | Automatically generate RESTful API documentation with [Swagger](https://swagger.io/) 2.0.                                                                                                                                                                                                                                                        |
 | 
			
		||||
| [github.com/ziflex/lecho](https://github.com/ziflex/lecho) | [Zerolog](https://github.com/rs/zerolog) logging library wrapper for Echo logger interface.                                                                                                                                                                                                                                                                    |
 | 
			
		||||
| [github.com/brpaz/echozap](https://github.com/brpaz/echozap) | Uber´s [Zap](https://github.com/uber-go/zap) logging library wrapper for Echo logger interface.                                                                                                                                                                                                                                                              |
 | 
			
		||||
| [github.com/darkweak/souin/plugins/echo](https://github.com/darkweak/souin/tree/master/plugins/echo) | HTTP cache system based on [Souin](https://github.com/darkweak/souin) to automatically get your endpoints cached. It supports some distributed and non-distributed storage systems depending your needs.                                                                                                             |
 | 
			
		||||
| [github.com/mikestefanello/pagoda](https://github.com/mikestefanello/pagoda) | Rapid, easy full-stack web development starter kit built with Echo.
 | 
			
		||||
 | 
			
		||||
Please send a PR to add your own library here.
 | 
			
		||||
 | 
			
		||||
## Help
 | 
			
		||||
 | 
			
		||||
- [Forum](https://github.com/labstack/echo/discussions)
 | 
			
		||||
- [Chat](https://gitter.im/labstack/echo)
 | 
			
		||||
 | 
			
		||||
## Contribute
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								vendor/github.com/labstack/echo/v4/bind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								vendor/github.com/labstack/echo/v4/bind.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -111,11 +111,11 @@ func (b *DefaultBinder) Bind(i interface{}, c Context) (err error) {
 | 
			
		||||
	if err := b.BindPathParams(c, i); err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
	// Issue #1670 - Query params are binded only for GET/DELETE and NOT for usual request with body (POST/PUT/PATCH)
 | 
			
		||||
	// Reasoning here is that parameters in query and bind destination struct could have UNEXPECTED matches and results due that.
 | 
			
		||||
	// i.e. is `&id=1&lang=en` from URL same as `{"id":100,"lang":"de"}` request body and which one should have priority when binding.
 | 
			
		||||
	// This HTTP method check restores pre v4.1.11 behavior and avoids different problems when query is mixed with body
 | 
			
		||||
	if c.Request().Method == http.MethodGet || c.Request().Method == http.MethodDelete {
 | 
			
		||||
	// Only bind query parameters for GET/DELETE/HEAD to avoid unexpected behavior with destination struct binding from body.
 | 
			
		||||
	// For example a request URL `&id=1&lang=en` with body `{"id":100,"lang":"de"}` would lead to precedence issues.
 | 
			
		||||
	// The HTTP method check restores pre-v4.1.11 behavior to avoid these problems (see issue #1670)
 | 
			
		||||
  method := c.Request().Method
 | 
			
		||||
	if method == http.MethodGet || method == http.MethodDelete || method == http.MethodHead {
 | 
			
		||||
		if err = b.BindQueryParams(c, i); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										32
									
								
								vendor/github.com/labstack/echo/v4/context.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										32
									
								
								vendor/github.com/labstack/echo/v4/context.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -9,8 +9,6 @@ import (
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"sync"
 | 
			
		||||
)
 | 
			
		||||
@@ -210,6 +208,13 @@ type (
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// ContextKeyHeaderAllow is set by Router for getting value for `Allow` header in later stages of handler call chain.
 | 
			
		||||
	// Allow header is mandatory for status 405 (method not found) and useful for OPTIONS method requests.
 | 
			
		||||
	// It is added to context only when Router does not find matching method handler for request.
 | 
			
		||||
	ContextKeyHeaderAllow = "echo_header_allow"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	defaultMemory = 32 << 20 // 32 MB
 | 
			
		||||
	indexPage     = "index.html"
 | 
			
		||||
@@ -562,29 +567,6 @@ func (c *context) Stream(code int, contentType string, r io.Reader) (err error)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *context) File(file string) (err error) {
 | 
			
		||||
	f, err := os.Open(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return NotFoundHandler(c)
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
 | 
			
		||||
	fi, _ := f.Stat()
 | 
			
		||||
	if fi.IsDir() {
 | 
			
		||||
		file = filepath.Join(file, indexPage)
 | 
			
		||||
		f, err = os.Open(file)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return NotFoundHandler(c)
 | 
			
		||||
		}
 | 
			
		||||
		defer f.Close()
 | 
			
		||||
		if fi, err = f.Stat(); err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), f)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (c *context) Attachment(file, name string) error {
 | 
			
		||||
	return c.contentDisposition(file, name, "attachment")
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										33
									
								
								vendor/github.com/labstack/echo/v4/context_fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/labstack/echo/v4/context_fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
//go:build !go1.16
 | 
			
		||||
// +build !go1.16
 | 
			
		||||
 | 
			
		||||
package echo
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (c *context) File(file string) (err error) {
 | 
			
		||||
	f, err := os.Open(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return NotFoundHandler(c)
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
 | 
			
		||||
	fi, _ := f.Stat()
 | 
			
		||||
	if fi.IsDir() {
 | 
			
		||||
		file = filepath.Join(file, indexPage)
 | 
			
		||||
		f, err = os.Open(file)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return NotFoundHandler(c)
 | 
			
		||||
		}
 | 
			
		||||
		defer f.Close()
 | 
			
		||||
		if fi, err = f.Stat(); err != nil {
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), f)
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										52
									
								
								vendor/github.com/labstack/echo/v4/context_fs_go1.16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								vendor/github.com/labstack/echo/v4/context_fs_go1.16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,52 @@
 | 
			
		||||
//go:build go1.16
 | 
			
		||||
// +build go1.16
 | 
			
		||||
 | 
			
		||||
package echo
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"io"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
func (c *context) File(file string) error {
 | 
			
		||||
	return fsFile(c, file, c.echo.Filesystem)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FileFS serves file from given file system.
 | 
			
		||||
//
 | 
			
		||||
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
 | 
			
		||||
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
 | 
			
		||||
// including `assets/images` as their prefix.
 | 
			
		||||
func (c *context) FileFS(file string, filesystem fs.FS) error {
 | 
			
		||||
	return fsFile(c, file, filesystem)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func fsFile(c Context, file string, filesystem fs.FS) error {
 | 
			
		||||
	f, err := filesystem.Open(file)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return ErrNotFound
 | 
			
		||||
	}
 | 
			
		||||
	defer f.Close()
 | 
			
		||||
 | 
			
		||||
	fi, _ := f.Stat()
 | 
			
		||||
	if fi.IsDir() {
 | 
			
		||||
		file = filepath.ToSlash(filepath.Join(file, indexPage)) // ToSlash is necessary for Windows. fs.Open and os.Open are different in that aspect.
 | 
			
		||||
		f, err = filesystem.Open(file)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return ErrNotFound
 | 
			
		||||
		}
 | 
			
		||||
		defer f.Close()
 | 
			
		||||
		if fi, err = f.Stat(); err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	ff, ok := f.(io.ReadSeeker)
 | 
			
		||||
	if !ok {
 | 
			
		||||
		return errors.New("file does not implement io.ReadSeeker")
 | 
			
		||||
	}
 | 
			
		||||
	http.ServeContent(c.Response(), c.Request(), fi.Name(), fi.ModTime(), ff)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										85
									
								
								vendor/github.com/labstack/echo/v4/echo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										85
									
								
								vendor/github.com/labstack/echo/v4/echo.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -47,9 +47,6 @@ import (
 | 
			
		||||
	stdLog "log"
 | 
			
		||||
	"net"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"runtime"
 | 
			
		||||
	"sync"
 | 
			
		||||
@@ -66,6 +63,7 @@ import (
 | 
			
		||||
type (
 | 
			
		||||
	// Echo is the top-level framework instance.
 | 
			
		||||
	Echo struct {
 | 
			
		||||
		filesystem
 | 
			
		||||
		common
 | 
			
		||||
		// startupMutex is mutex to lock Echo instance access during server configuration and startup. Useful for to get
 | 
			
		||||
		// listener address info (on which interface/port was listener binded) without having data races.
 | 
			
		||||
@@ -77,7 +75,6 @@ type (
 | 
			
		||||
		maxParam         *int
 | 
			
		||||
		router           *Router
 | 
			
		||||
		routers          map[string]*Router
 | 
			
		||||
		notFoundHandler  HandlerFunc
 | 
			
		||||
		pool             sync.Pool
 | 
			
		||||
		Server           *http.Server
 | 
			
		||||
		TLSServer        *http.Server
 | 
			
		||||
@@ -113,10 +110,10 @@ type (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// MiddlewareFunc defines a function to process middleware.
 | 
			
		||||
	MiddlewareFunc func(HandlerFunc) HandlerFunc
 | 
			
		||||
	MiddlewareFunc func(next HandlerFunc) HandlerFunc
 | 
			
		||||
 | 
			
		||||
	// HandlerFunc defines a function to serve HTTP requests.
 | 
			
		||||
	HandlerFunc func(Context) error
 | 
			
		||||
	HandlerFunc func(c Context) error
 | 
			
		||||
 | 
			
		||||
	// HTTPErrorHandler is a centralized HTTP error handler.
 | 
			
		||||
	HTTPErrorHandler func(error, Context)
 | 
			
		||||
@@ -190,8 +187,12 @@ const (
 | 
			
		||||
 | 
			
		||||
// Headers
 | 
			
		||||
const (
 | 
			
		||||
	HeaderAccept              = "Accept"
 | 
			
		||||
	HeaderAcceptEncoding      = "Accept-Encoding"
 | 
			
		||||
	HeaderAccept         = "Accept"
 | 
			
		||||
	HeaderAcceptEncoding = "Accept-Encoding"
 | 
			
		||||
	// HeaderAllow is the name of the "Allow" header field used to list the set of methods
 | 
			
		||||
	// advertised as supported by the target resource. Returning an Allow header is mandatory
 | 
			
		||||
	// for status 405 (method not found) and useful for the OPTIONS method in responses.
 | 
			
		||||
	// See RFC 7231: https://datatracker.ietf.org/doc/html/rfc7231#section-7.4.1
 | 
			
		||||
	HeaderAllow               = "Allow"
 | 
			
		||||
	HeaderAuthorization       = "Authorization"
 | 
			
		||||
	HeaderContentDisposition  = "Content-Disposition"
 | 
			
		||||
@@ -203,6 +204,7 @@ const (
 | 
			
		||||
	HeaderIfModifiedSince     = "If-Modified-Since"
 | 
			
		||||
	HeaderLastModified        = "Last-Modified"
 | 
			
		||||
	HeaderLocation            = "Location"
 | 
			
		||||
	HeaderRetryAfter          = "Retry-After"
 | 
			
		||||
	HeaderUpgrade             = "Upgrade"
 | 
			
		||||
	HeaderVary                = "Vary"
 | 
			
		||||
	HeaderWWWAuthenticate     = "WWW-Authenticate"
 | 
			
		||||
@@ -212,12 +214,14 @@ const (
 | 
			
		||||
	HeaderXForwardedSsl       = "X-Forwarded-Ssl"
 | 
			
		||||
	HeaderXUrlScheme          = "X-Url-Scheme"
 | 
			
		||||
	HeaderXHTTPMethodOverride = "X-HTTP-Method-Override"
 | 
			
		||||
	HeaderXRealIP             = "X-Real-IP"
 | 
			
		||||
	HeaderXRequestID          = "X-Request-ID"
 | 
			
		||||
	HeaderXCorrelationID      = "X-Correlation-ID"
 | 
			
		||||
	HeaderXRealIP             = "X-Real-Ip"
 | 
			
		||||
	HeaderXRequestID          = "X-Request-Id"
 | 
			
		||||
	HeaderXCorrelationID      = "X-Correlation-Id"
 | 
			
		||||
	HeaderXRequestedWith      = "X-Requested-With"
 | 
			
		||||
	HeaderServer              = "Server"
 | 
			
		||||
	HeaderOrigin              = "Origin"
 | 
			
		||||
	HeaderCacheControl        = "Cache-Control"
 | 
			
		||||
	HeaderConnection          = "Connection"
 | 
			
		||||
 | 
			
		||||
	// Access control
 | 
			
		||||
	HeaderAccessControlRequestMethod    = "Access-Control-Request-Method"
 | 
			
		||||
@@ -242,7 +246,7 @@ const (
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// Version of Echo
 | 
			
		||||
	Version = "4.6.3"
 | 
			
		||||
	Version = "4.7.0"
 | 
			
		||||
	website = "https://echo.labstack.com"
 | 
			
		||||
	// http://patorjk.com/software/taag/#p=display&f=Small%20Slant&t=Echo
 | 
			
		||||
	banner = `
 | 
			
		||||
@@ -302,6 +306,12 @@ var (
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	MethodNotAllowedHandler = func(c Context) error {
 | 
			
		||||
		// See RFC 7231 section 7.4.1: An origin server MUST generate an Allow field in a 405 (Method Not Allowed)
 | 
			
		||||
		// response and MAY do so in any other response. For disabled resources an empty Allow header may be returned
 | 
			
		||||
		routerAllowMethods, ok := c.Get(ContextKeyHeaderAllow).(string)
 | 
			
		||||
		if ok && routerAllowMethods != "" {
 | 
			
		||||
			c.Response().Header().Set(HeaderAllow, routerAllowMethods)
 | 
			
		||||
		}
 | 
			
		||||
		return ErrMethodNotAllowed
 | 
			
		||||
	}
 | 
			
		||||
)
 | 
			
		||||
@@ -309,8 +319,9 @@ var (
 | 
			
		||||
// New creates an instance of Echo.
 | 
			
		||||
func New() (e *Echo) {
 | 
			
		||||
	e = &Echo{
 | 
			
		||||
		Server:    new(http.Server),
 | 
			
		||||
		TLSServer: new(http.Server),
 | 
			
		||||
		filesystem: createFilesystem(),
 | 
			
		||||
		Server:     new(http.Server),
 | 
			
		||||
		TLSServer:  new(http.Server),
 | 
			
		||||
		AutoTLSManager: autocert.Manager{
 | 
			
		||||
			Prompt: autocert.AcceptTOS,
 | 
			
		||||
		},
 | 
			
		||||
@@ -489,50 +500,6 @@ func (e *Echo) Match(methods []string, path string, handler HandlerFunc, middlew
 | 
			
		||||
	return routes
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Static registers a new route with path prefix to serve static files from the
 | 
			
		||||
// provided root directory.
 | 
			
		||||
func (e *Echo) Static(prefix, root string) *Route {
 | 
			
		||||
	if root == "" {
 | 
			
		||||
		root = "." // For security we want to restrict to CWD.
 | 
			
		||||
	}
 | 
			
		||||
	return e.static(prefix, root, e.GET)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (common) static(prefix, root string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route) *Route {
 | 
			
		||||
	h := func(c Context) error {
 | 
			
		||||
		p, err := url.PathUnescape(c.Param("*"))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		name := filepath.Join(root, filepath.Clean("/"+p)) // "/"+ for security
 | 
			
		||||
		fi, err := os.Stat(name)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// The access path does not exist
 | 
			
		||||
			return NotFoundHandler(c)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the request is for a directory and does not end with "/"
 | 
			
		||||
		p = c.Request().URL.Path // path must not be empty.
 | 
			
		||||
		if fi.IsDir() && p[len(p)-1] != '/' {
 | 
			
		||||
			// Redirect to ends with "/"
 | 
			
		||||
			return c.Redirect(http.StatusMovedPermanently, p+"/")
 | 
			
		||||
		}
 | 
			
		||||
		return c.File(name)
 | 
			
		||||
	}
 | 
			
		||||
	// Handle added routes based on trailing slash:
 | 
			
		||||
	// 	/prefix  => exact route "/prefix" + any route "/prefix/*"
 | 
			
		||||
	// 	/prefix/ => only any route "/prefix/*"
 | 
			
		||||
	if prefix != "" {
 | 
			
		||||
		if prefix[len(prefix)-1] == '/' {
 | 
			
		||||
			// Only add any route for intentional trailing slash
 | 
			
		||||
			return get(prefix+"*", h)
 | 
			
		||||
		}
 | 
			
		||||
		get(prefix, h)
 | 
			
		||||
	}
 | 
			
		||||
	return get(prefix+"/*", h)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (common) file(path, file string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route,
 | 
			
		||||
	m ...MiddlewareFunc) *Route {
 | 
			
		||||
	return get(path, func(c Context) error {
 | 
			
		||||
@@ -643,7 +610,7 @@ func (e *Echo) ServeHTTP(w http.ResponseWriter, r *http.Request) {
 | 
			
		||||
	// Acquire context
 | 
			
		||||
	c := e.pool.Get().(*context)
 | 
			
		||||
	c.Reset(r, w)
 | 
			
		||||
	h := NotFoundHandler
 | 
			
		||||
	var h func(Context) error
 | 
			
		||||
 | 
			
		||||
	if e.premiddleware == nil {
 | 
			
		||||
		e.findRouter(r.Host).Find(r.Method, GetPath(r), c)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										62
									
								
								vendor/github.com/labstack/echo/v4/echo_fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								vendor/github.com/labstack/echo/v4/echo_fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,62 @@
 | 
			
		||||
//go:build !go1.16
 | 
			
		||||
// +build !go1.16
 | 
			
		||||
 | 
			
		||||
package echo
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type filesystem struct {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createFilesystem() filesystem {
 | 
			
		||||
	return filesystem{}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Static registers a new route with path prefix to serve static files from the
 | 
			
		||||
// provided root directory.
 | 
			
		||||
func (e *Echo) Static(prefix, root string) *Route {
 | 
			
		||||
	if root == "" {
 | 
			
		||||
		root = "." // For security we want to restrict to CWD.
 | 
			
		||||
	}
 | 
			
		||||
	return e.static(prefix, root, e.GET)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (common) static(prefix, root string, get func(string, HandlerFunc, ...MiddlewareFunc) *Route) *Route {
 | 
			
		||||
	h := func(c Context) error {
 | 
			
		||||
		p, err := url.PathUnescape(c.Param("*"))
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return err
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		name := filepath.Join(root, filepath.Clean("/"+p)) // "/"+ for security
 | 
			
		||||
		fi, err := os.Stat(name)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			// The access path does not exist
 | 
			
		||||
			return NotFoundHandler(c)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the request is for a directory and does not end with "/"
 | 
			
		||||
		p = c.Request().URL.Path // path must not be empty.
 | 
			
		||||
		if fi.IsDir() && p[len(p)-1] != '/' {
 | 
			
		||||
			// Redirect to ends with "/"
 | 
			
		||||
			return c.Redirect(http.StatusMovedPermanently, p+"/")
 | 
			
		||||
		}
 | 
			
		||||
		return c.File(name)
 | 
			
		||||
	}
 | 
			
		||||
	// Handle added routes based on trailing slash:
 | 
			
		||||
	// 	/prefix  => exact route "/prefix" + any route "/prefix/*"
 | 
			
		||||
	// 	/prefix/ => only any route "/prefix/*"
 | 
			
		||||
	if prefix != "" {
 | 
			
		||||
		if prefix[len(prefix)-1] == '/' {
 | 
			
		||||
			// Only add any route for intentional trailing slash
 | 
			
		||||
			return get(prefix+"*", h)
 | 
			
		||||
		}
 | 
			
		||||
		get(prefix, h)
 | 
			
		||||
	}
 | 
			
		||||
	return get(prefix+"/*", h)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										145
									
								
								vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								vendor/github.com/labstack/echo/v4/echo_fs_go1.16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,145 @@
 | 
			
		||||
//go:build go1.16
 | 
			
		||||
// +build go1.16
 | 
			
		||||
 | 
			
		||||
package echo
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"net/http"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"os"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type filesystem struct {
 | 
			
		||||
	// Filesystem is file system used by Static and File handlers to access files.
 | 
			
		||||
	// Defaults to os.DirFS(".")
 | 
			
		||||
	//
 | 
			
		||||
	// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
 | 
			
		||||
	// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
 | 
			
		||||
	// including `assets/images` as their prefix.
 | 
			
		||||
	Filesystem fs.FS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func createFilesystem() filesystem {
 | 
			
		||||
	return filesystem{
 | 
			
		||||
		Filesystem: newDefaultFS(),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Static registers a new route with path prefix to serve static files from the provided root directory.
 | 
			
		||||
func (e *Echo) Static(pathPrefix, fsRoot string) *Route {
 | 
			
		||||
	subFs := MustSubFS(e.Filesystem, fsRoot)
 | 
			
		||||
	return e.Add(
 | 
			
		||||
		http.MethodGet,
 | 
			
		||||
		pathPrefix+"*",
 | 
			
		||||
		StaticDirectoryHandler(subFs, false),
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StaticFS registers a new route with path prefix to serve static files from the provided file system.
 | 
			
		||||
//
 | 
			
		||||
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
 | 
			
		||||
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
 | 
			
		||||
// including `assets/images` as their prefix.
 | 
			
		||||
func (e *Echo) StaticFS(pathPrefix string, filesystem fs.FS) *Route {
 | 
			
		||||
	return e.Add(
 | 
			
		||||
		http.MethodGet,
 | 
			
		||||
		pathPrefix+"*",
 | 
			
		||||
		StaticDirectoryHandler(filesystem, false),
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StaticDirectoryHandler creates handler function to serve files from provided file system
 | 
			
		||||
// When disablePathUnescaping is set then file name from path is not unescaped and is served as is.
 | 
			
		||||
func StaticDirectoryHandler(fileSystem fs.FS, disablePathUnescaping bool) HandlerFunc {
 | 
			
		||||
	return func(c Context) error {
 | 
			
		||||
		p := c.Param("*")
 | 
			
		||||
		if !disablePathUnescaping { // when router is already unescaping we do not want to do is twice
 | 
			
		||||
			tmpPath, err := url.PathUnescape(p)
 | 
			
		||||
			if err != nil {
 | 
			
		||||
				return fmt.Errorf("failed to unescape path variable: %w", err)
 | 
			
		||||
			}
 | 
			
		||||
			p = tmpPath
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// fs.FS.Open() already assumes that file names are relative to FS root path and considers name with prefix `/` as invalid
 | 
			
		||||
		name := filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
 | 
			
		||||
		fi, err := fs.Stat(fileSystem, name)
 | 
			
		||||
		if err != nil {
 | 
			
		||||
			return ErrNotFound
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		// If the request is for a directory and does not end with "/"
 | 
			
		||||
		p = c.Request().URL.Path // path must not be empty.
 | 
			
		||||
		if fi.IsDir() && len(p) > 0 && p[len(p)-1] != '/' {
 | 
			
		||||
			// Redirect to ends with "/"
 | 
			
		||||
			return c.Redirect(http.StatusMovedPermanently, p+"/")
 | 
			
		||||
		}
 | 
			
		||||
		return fsFile(c, name, fileSystem)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FileFS registers a new route with path to serve file from the provided file system.
 | 
			
		||||
func (e *Echo) FileFS(path, file string, filesystem fs.FS, m ...MiddlewareFunc) *Route {
 | 
			
		||||
	return e.GET(path, StaticFileHandler(file, filesystem), m...)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StaticFileHandler creates handler function to serve file from provided file system
 | 
			
		||||
func StaticFileHandler(file string, filesystem fs.FS) HandlerFunc {
 | 
			
		||||
	return func(c Context) error {
 | 
			
		||||
		return fsFile(c, file, filesystem)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// defaultFS emulates os.Open behaviour with filesystem opened by `os.DirFs`. Difference between `os.Open` and `fs.Open`
 | 
			
		||||
// is that FS does not allow to open path that start with `..` or `/` etc. For example previously you could have `../images`
 | 
			
		||||
// in your application but `fs := os.DirFS("./")` would not allow you to use `fs.Open("../images")` and this would break
 | 
			
		||||
// all old applications that rely on being able to traverse up from current executable run path.
 | 
			
		||||
// NB: private because you really should use fs.FS implementation instances
 | 
			
		||||
type defaultFS struct {
 | 
			
		||||
	prefix string
 | 
			
		||||
	fs     fs.FS
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func newDefaultFS() *defaultFS {
 | 
			
		||||
	dir, _ := os.Getwd()
 | 
			
		||||
	return &defaultFS{
 | 
			
		||||
		prefix: dir,
 | 
			
		||||
		fs:     os.DirFS(dir),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (fs defaultFS) Open(name string) (fs.File, error) {
 | 
			
		||||
	return fs.fs.Open(name)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func subFS(currentFs fs.FS, root string) (fs.FS, error) {
 | 
			
		||||
	root = filepath.ToSlash(filepath.Clean(root)) // note: fs.FS operates only with slashes. `ToSlash` is necessary for Windows
 | 
			
		||||
	if dFS, ok := currentFs.(*defaultFS); ok {
 | 
			
		||||
		// we need to make exception for `defaultFS` instances as it interprets root prefix differently from fs.FS to
 | 
			
		||||
		// allow cases when root is given as `../somepath` which is not valid for fs.FS
 | 
			
		||||
		root = filepath.Join(dFS.prefix, root)
 | 
			
		||||
		return &defaultFS{
 | 
			
		||||
			prefix: root,
 | 
			
		||||
			fs:     os.DirFS(root),
 | 
			
		||||
		}, nil
 | 
			
		||||
	}
 | 
			
		||||
	return fs.Sub(currentFs, root)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// MustSubFS creates sub FS from current filesystem or panic on failure.
 | 
			
		||||
// Panic happens when `fsRoot` contains invalid path according to `fs.ValidPath` rules.
 | 
			
		||||
//
 | 
			
		||||
// MustSubFS is helpful when dealing with `embed.FS` because for example `//go:embed assets/images` embeds files with
 | 
			
		||||
// paths including `assets/images` as their prefix. In that case use `fs := echo.MustSubFS(fs, "rootDirectory") to
 | 
			
		||||
// create sub fs which uses necessary prefix for directory path.
 | 
			
		||||
func MustSubFS(currentFs fs.FS, fsRoot string) fs.FS {
 | 
			
		||||
	subFs, err := subFS(currentFs, fsRoot)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		panic(fmt.Errorf("can not create sub FS, invalid root given, err: %w", err))
 | 
			
		||||
	}
 | 
			
		||||
	return subFs
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										5
									
								
								vendor/github.com/labstack/echo/v4/group.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								vendor/github.com/labstack/echo/v4/group.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -102,11 +102,6 @@ func (g *Group) Group(prefix string, middleware ...MiddlewareFunc) (sg *Group) {
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Static implements `Echo#Static()` for sub-routes within the Group.
 | 
			
		||||
func (g *Group) Static(prefix, root string) {
 | 
			
		||||
	g.static(prefix, root, g.GET)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// File implements `Echo#File()` for sub-routes within the Group.
 | 
			
		||||
func (g *Group) File(path, file string) {
 | 
			
		||||
	g.file(path, file, g.GET)
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								vendor/github.com/labstack/echo/v4/group_fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								vendor/github.com/labstack/echo/v4/group_fs.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
//go:build !go1.16
 | 
			
		||||
// +build !go1.16
 | 
			
		||||
 | 
			
		||||
package echo
 | 
			
		||||
 | 
			
		||||
// Static implements `Echo#Static()` for sub-routes within the Group.
 | 
			
		||||
func (g *Group) Static(prefix, root string) {
 | 
			
		||||
	g.static(prefix, root, g.GET)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										33
									
								
								vendor/github.com/labstack/echo/v4/group_fs_go1.16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								vendor/github.com/labstack/echo/v4/group_fs_go1.16.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
			
		||||
//go:build go1.16
 | 
			
		||||
// +build go1.16
 | 
			
		||||
 | 
			
		||||
package echo
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"io/fs"
 | 
			
		||||
	"net/http"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// Static implements `Echo#Static()` for sub-routes within the Group.
 | 
			
		||||
func (g *Group) Static(pathPrefix, fsRoot string) {
 | 
			
		||||
	subFs := MustSubFS(g.echo.Filesystem, fsRoot)
 | 
			
		||||
	g.StaticFS(pathPrefix, subFs)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// StaticFS implements `Echo#StaticFS()` for sub-routes within the Group.
 | 
			
		||||
//
 | 
			
		||||
// When dealing with `embed.FS` use `fs := echo.MustSubFS(fs, "rootDirectory") to create sub fs which uses necessary
 | 
			
		||||
// prefix for directory path. This is necessary as `//go:embed assets/images` embeds files with paths
 | 
			
		||||
// including `assets/images` as their prefix.
 | 
			
		||||
func (g *Group) StaticFS(pathPrefix string, filesystem fs.FS) {
 | 
			
		||||
	g.Add(
 | 
			
		||||
		http.MethodGet,
 | 
			
		||||
		pathPrefix+"*",
 | 
			
		||||
		StaticDirectoryHandler(filesystem, false),
 | 
			
		||||
	)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// FileFS implements `Echo#FileFS()` for sub-routes within the Group.
 | 
			
		||||
func (g *Group) FileFS(path, file string, filesystem fs.FS, m ...MiddlewareFunc) *Route {
 | 
			
		||||
	return g.GET(path, StaticFileHandler(file, filesystem), m...)
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										142
									
								
								vendor/github.com/labstack/echo/v4/ip.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										142
									
								
								vendor/github.com/labstack/echo/v4/ip.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -6,6 +6,130 @@ import (
 | 
			
		||||
	"strings"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
By: https://github.com/tmshn (See: https://github.com/labstack/echo/pull/1478 , https://github.com/labstack/echox/pull/134 )
 | 
			
		||||
Source: https://echo.labstack.com/guide/ip-address/
 | 
			
		||||
 | 
			
		||||
IP address plays fundamental role in HTTP; it's used for access control, auditing, geo-based access analysis and more.
 | 
			
		||||
Echo provides handy method [`Context#RealIP()`](https://godoc.org/github.com/labstack/echo#Context) for that.
 | 
			
		||||
 | 
			
		||||
However, it is not trivial to retrieve the _real_ IP address from requests especially when you put L7 proxies before the application.
 | 
			
		||||
In such situation, _real_ IP needs to be relayed on HTTP layer from proxies to your app, but you must not trust HTTP headers unconditionally.
 | 
			
		||||
Otherwise, you might give someone a chance of deceiving you. **A security risk!**
 | 
			
		||||
 | 
			
		||||
To retrieve IP address reliably/securely, you must let your application be aware of the entire architecture of your infrastructure.
 | 
			
		||||
In Echo, this can be done by configuring `Echo#IPExtractor` appropriately.
 | 
			
		||||
This guides show you why and how.
 | 
			
		||||
 | 
			
		||||
> Note: if you dont' set `Echo#IPExtractor` explicitly, Echo fallback to legacy behavior, which is not a good choice.
 | 
			
		||||
 | 
			
		||||
Let's start from two questions to know the right direction:
 | 
			
		||||
 | 
			
		||||
1. Do you put any HTTP (L7) proxy in front of the application?
 | 
			
		||||
    - It includes both cloud solutions (such as AWS ALB or GCP HTTP LB) and OSS ones (such as Nginx, Envoy or Istio ingress gateway).
 | 
			
		||||
2. If yes, what HTTP header do your proxies use to pass client IP to the application?
 | 
			
		||||
 | 
			
		||||
## Case 1. With no proxy
 | 
			
		||||
 | 
			
		||||
If you put no proxy (e.g.: directory facing to the internet), all you need to (and have to) see is IP address from network layer.
 | 
			
		||||
Any HTTP header is untrustable because the clients have full control what headers to be set.
 | 
			
		||||
 | 
			
		||||
In this case, use `echo.ExtractIPDirect()`.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
e.IPExtractor = echo.ExtractIPDirect()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
## Case 2. With proxies using `X-Forwarded-For` header
 | 
			
		||||
 | 
			
		||||
[`X-Forwared-For` (XFF)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-For) is the popular header
 | 
			
		||||
to relay clients' IP addresses.
 | 
			
		||||
At each hop on the proxies, they append the request IP address at the end of the header.
 | 
			
		||||
 | 
			
		||||
Following example diagram illustrates this behavior.
 | 
			
		||||
 | 
			
		||||
```text
 | 
			
		||||
┌──────────┐            ┌──────────┐            ┌──────────┐            ┌──────────┐
 | 
			
		||||
│ "Origin" │───────────>│ Proxy 1  │───────────>│ Proxy 2  │───────────>│ Your app │
 | 
			
		||||
│ (IP: a)  │            │ (IP: b)  │            │ (IP: c)  │            │          │
 | 
			
		||||
└──────────┘            └──────────┘            └──────────┘            └──────────┘
 | 
			
		||||
 | 
			
		||||
Case 1.
 | 
			
		||||
XFF:  ""                    "a"                     "a, b"
 | 
			
		||||
                                                    ~~~~~~
 | 
			
		||||
Case 2.
 | 
			
		||||
XFF:  "x"                   "x, a"                  "x, a, b"
 | 
			
		||||
                                                    ~~~~~~~~~
 | 
			
		||||
                                                    ↑ What your app will see
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
In this case, use **first _untrustable_ IP reading from right**. Never use first one reading from left, as it is
 | 
			
		||||
configurable by client. Here "trustable" means "you are sure the IP address belongs to your infrastructre".
 | 
			
		||||
In above example, if `b` and `c` are trustable, the IP address of the client is `a` for both cases, never be `x`.
 | 
			
		||||
 | 
			
		||||
In Echo, use `ExtractIPFromXFFHeader(...TrustOption)`.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
e.IPExtractor = echo.ExtractIPFromXFFHeader()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
By default, it trusts internal IP addresses (loopback, link-local unicast, private-use and unique local address
 | 
			
		||||
from [RFC6890](https://tools.ietf.org/html/rfc6890), [RFC4291](https://tools.ietf.org/html/rfc4291) and
 | 
			
		||||
[RFC4193](https://tools.ietf.org/html/rfc4193)).
 | 
			
		||||
To control this behavior, use [`TrustOption`](https://godoc.org/github.com/labstack/echo#TrustOption)s.
 | 
			
		||||
 | 
			
		||||
E.g.:
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
e.IPExtractor = echo.ExtractIPFromXFFHeader(
 | 
			
		||||
	TrustLinkLocal(false),
 | 
			
		||||
	TrustIPRanges(lbIPRange),
 | 
			
		||||
)
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- Ref: https://godoc.org/github.com/labstack/echo#TrustOption
 | 
			
		||||
 | 
			
		||||
## Case 3. With proxies using `X-Real-IP` header
 | 
			
		||||
 | 
			
		||||
`X-Real-IP` is another HTTP header to relay clients' IP addresses, but it carries only one address unlike XFF.
 | 
			
		||||
 | 
			
		||||
If your proxies set this header, use `ExtractIPFromRealIPHeader(...TrustOption)`.
 | 
			
		||||
 | 
			
		||||
```go
 | 
			
		||||
e.IPExtractor = echo.ExtractIPFromRealIPHeader()
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Again, it trusts internal IP addresses by default (loopback, link-local unicast, private-use and unique local address
 | 
			
		||||
from [RFC6890](https://tools.ietf.org/html/rfc6890), [RFC4291](https://tools.ietf.org/html/rfc4291) and
 | 
			
		||||
[RFC4193](https://tools.ietf.org/html/rfc4193)).
 | 
			
		||||
To control this behavior, use [`TrustOption`](https://godoc.org/github.com/labstack/echo#TrustOption)s.
 | 
			
		||||
 | 
			
		||||
- Ref: https://godoc.org/github.com/labstack/echo#TrustOption
 | 
			
		||||
 | 
			
		||||
> **Never forget** to configure the outermost proxy (i.e.; at the edge of your infrastructure) **not to pass through incoming headers**.
 | 
			
		||||
> Otherwise there is a chance of fraud, as it is what clients can control.
 | 
			
		||||
 | 
			
		||||
## About default behavior
 | 
			
		||||
 | 
			
		||||
In default behavior, Echo sees all of first XFF header, X-Real-IP header and IP from network layer.
 | 
			
		||||
 | 
			
		||||
As you might already notice, after reading this article, this is not good.
 | 
			
		||||
Sole reason this is default is just backward compatibility.
 | 
			
		||||
 | 
			
		||||
## Private IP ranges
 | 
			
		||||
 | 
			
		||||
See: https://en.wikipedia.org/wiki/Private_network
 | 
			
		||||
 | 
			
		||||
Private IPv4 address ranges (RFC 1918):
 | 
			
		||||
* 10.0.0.0 – 10.255.255.255 (24-bit block)
 | 
			
		||||
* 172.16.0.0 – 172.31.255.255 (20-bit block)
 | 
			
		||||
* 192.168.0.0 – 192.168.255.255 (16-bit block)
 | 
			
		||||
 | 
			
		||||
Private IPv6 address ranges:
 | 
			
		||||
* fc00::/7 address block = RFC 4193 Unique Local Addresses (ULA)
 | 
			
		||||
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
type ipChecker struct {
 | 
			
		||||
	trustLoopback    bool
 | 
			
		||||
	trustLinkLocal   bool
 | 
			
		||||
@@ -52,6 +176,7 @@ func newIPChecker(configs []TrustOption) *ipChecker {
 | 
			
		||||
	return checker
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Go1.16+ added `ip.IsPrivate()` but until that use this implementation
 | 
			
		||||
func isPrivateIPRange(ip net.IP) bool {
 | 
			
		||||
	if ip4 := ip.To4(); ip4 != nil {
 | 
			
		||||
		return ip4[0] == 10 ||
 | 
			
		||||
@@ -87,10 +212,12 @@ type IPExtractor func(*http.Request) string
 | 
			
		||||
// ExtractIPDirect extracts IP address using actual IP address.
 | 
			
		||||
// Use this if your server faces to internet directory (i.e.: uses no proxy).
 | 
			
		||||
func ExtractIPDirect() IPExtractor {
 | 
			
		||||
	return func(req *http.Request) string {
 | 
			
		||||
		ra, _, _ := net.SplitHostPort(req.RemoteAddr)
 | 
			
		||||
		return ra
 | 
			
		||||
	}
 | 
			
		||||
	return extractIP
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func extractIP(req *http.Request) string {
 | 
			
		||||
	ra, _, _ := net.SplitHostPort(req.RemoteAddr)
 | 
			
		||||
	return ra
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// ExtractIPFromRealIPHeader extracts IP address using x-real-ip header.
 | 
			
		||||
@@ -98,14 +225,13 @@ func ExtractIPDirect() IPExtractor {
 | 
			
		||||
func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
 | 
			
		||||
	checker := newIPChecker(options)
 | 
			
		||||
	return func(req *http.Request) string {
 | 
			
		||||
		directIP := ExtractIPDirect()(req)
 | 
			
		||||
		realIP := req.Header.Get(HeaderXRealIP)
 | 
			
		||||
		if realIP != "" {
 | 
			
		||||
			if ip := net.ParseIP(directIP); ip != nil && checker.trust(ip) {
 | 
			
		||||
			if ip := net.ParseIP(realIP); ip != nil && checker.trust(ip) {
 | 
			
		||||
				return realIP
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		return directIP
 | 
			
		||||
		return extractIP(req)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -115,7 +241,7 @@ func ExtractIPFromRealIPHeader(options ...TrustOption) IPExtractor {
 | 
			
		||||
func ExtractIPFromXFFHeader(options ...TrustOption) IPExtractor {
 | 
			
		||||
	checker := newIPChecker(options)
 | 
			
		||||
	return func(req *http.Request) string {
 | 
			
		||||
		directIP := ExtractIPDirect()(req)
 | 
			
		||||
		directIP := extractIP(req)
 | 
			
		||||
		xffs := req.Header[HeaderXForwardedFor]
 | 
			
		||||
		if len(xffs) == 0 {
 | 
			
		||||
			return directIP
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										69
									
								
								vendor/github.com/labstack/echo/v4/middleware/cors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							
							
						
						
									
										69
									
								
								vendor/github.com/labstack/echo/v4/middleware/cors.go
									
									
									
										generated
									
									
										vendored
									
									
								
							@@ -29,6 +29,8 @@ type (
 | 
			
		||||
		// AllowMethods defines a list methods allowed when accessing the resource.
 | 
			
		||||
		// This is used in response to a preflight request.
 | 
			
		||||
		// Optional. Default value DefaultCORSConfig.AllowMethods.
 | 
			
		||||
		// If `allowMethods` is left empty will fill for preflight request `Access-Control-Allow-Methods` header value
 | 
			
		||||
		// from `Allow` header that echo.Router set into context.
 | 
			
		||||
		AllowMethods []string `yaml:"allow_methods"`
 | 
			
		||||
 | 
			
		||||
		// AllowHeaders defines a list of request headers that can be used when
 | 
			
		||||
@@ -41,6 +43,8 @@ type (
 | 
			
		||||
		// a response to a preflight request, this indicates whether or not the
 | 
			
		||||
		// actual request can be made using credentials.
 | 
			
		||||
		// Optional. Default value false.
 | 
			
		||||
		// Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`.
 | 
			
		||||
		// See http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html
 | 
			
		||||
		AllowCredentials bool `yaml:"allow_credentials"`
 | 
			
		||||
 | 
			
		||||
		// ExposeHeaders defines a whitelist headers that clients are allowed to
 | 
			
		||||
@@ -80,7 +84,9 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
 | 
			
		||||
	if len(config.AllowOrigins) == 0 {
 | 
			
		||||
		config.AllowOrigins = DefaultCORSConfig.AllowOrigins
 | 
			
		||||
	}
 | 
			
		||||
	hasCustomAllowMethods := true
 | 
			
		||||
	if len(config.AllowMethods) == 0 {
 | 
			
		||||
		hasCustomAllowMethods = false
 | 
			
		||||
		config.AllowMethods = DefaultCORSConfig.AllowMethods
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@@ -109,10 +115,28 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
 | 
			
		||||
			origin := req.Header.Get(echo.HeaderOrigin)
 | 
			
		||||
			allowOrigin := ""
 | 
			
		||||
 | 
			
		||||
			preflight := req.Method == http.MethodOptions
 | 
			
		||||
			res.Header().Add(echo.HeaderVary, echo.HeaderOrigin)
 | 
			
		||||
 | 
			
		||||
			// No Origin provided
 | 
			
		||||
			// Preflight request is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method,
 | 
			
		||||
			// Access-Control-Request-Headers, and the Origin header. See: https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request
 | 
			
		||||
			// For simplicity we just consider method type and later `Origin` header.
 | 
			
		||||
			preflight := req.Method == http.MethodOptions
 | 
			
		||||
 | 
			
		||||
			// Although router adds special handler in case of OPTIONS method we avoid calling next for OPTIONS in this middleware
 | 
			
		||||
			// as CORS requests do not have cookies / authentication headers by default, so we could get stuck in auth
 | 
			
		||||
			// middlewares by calling next(c).
 | 
			
		||||
			// But we still want to send `Allow` header as response in case of Non-CORS OPTIONS request as router default
 | 
			
		||||
			// handler does.
 | 
			
		||||
			routerAllowMethods := ""
 | 
			
		||||
			if preflight {
 | 
			
		||||
				tmpAllowMethods, ok := c.Get(echo.ContextKeyHeaderAllow).(string)
 | 
			
		||||
				if ok && tmpAllowMethods != "" {
 | 
			
		||||
					routerAllowMethods = tmpAllowMethods
 | 
			
		||||
					c.Response().Header().Set(echo.HeaderAllow, routerAllowMethods)
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// No Origin provided. This is (probably) not request from actual browser - proceed executing middleware chain
 | 
			
		||||
			if origin == "" {
 | 
			
		||||
				if !preflight {
 | 
			
		||||
					return next(c)
 | 
			
		||||
@@ -145,19 +169,15 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				// Check allowed origin patterns
 | 
			
		||||
				for _, re := range allowOriginPatterns {
 | 
			
		||||
					if allowOrigin == "" {
 | 
			
		||||
						didx := strings.Index(origin, "://")
 | 
			
		||||
						if didx == -1 {
 | 
			
		||||
							continue
 | 
			
		||||
						}
 | 
			
		||||
						domAuth := origin[didx+3:]
 | 
			
		||||
						// to avoid regex cost by invalid long domain
 | 
			
		||||
						if len(domAuth) > 253 {
 | 
			
		||||
							break
 | 
			
		||||
						}
 | 
			
		||||
 | 
			
		||||
				checkPatterns := false
 | 
			
		||||
				if allowOrigin == "" {
 | 
			
		||||
					// to avoid regex cost by invalid (long) domains (253 is domain name max limit)
 | 
			
		||||
					if len(origin) <= (253+3+5) && strings.Contains(origin, "://") {
 | 
			
		||||
						checkPatterns = true
 | 
			
		||||
					}
 | 
			
		||||
				}
 | 
			
		||||
				if checkPatterns {
 | 
			
		||||
					for _, re := range allowOriginPatterns {
 | 
			
		||||
						if match, _ := regexp.MatchString(re, origin); match {
 | 
			
		||||
							allowOrigin = origin
 | 
			
		||||
							break
 | 
			
		||||
@@ -174,12 +194,13 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
 | 
			
		||||
				return c.NoContent(http.StatusNoContent)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowOrigin)
 | 
			
		||||
			if config.AllowCredentials {
 | 
			
		||||
				res.Header().Set(echo.HeaderAccessControlAllowCredentials, "true")
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Simple request
 | 
			
		||||
			if !preflight {
 | 
			
		||||
				res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowOrigin)
 | 
			
		||||
				if config.AllowCredentials {
 | 
			
		||||
					res.Header().Set(echo.HeaderAccessControlAllowCredentials, "true")
 | 
			
		||||
				}
 | 
			
		||||
				if exposeHeaders != "" {
 | 
			
		||||
					res.Header().Set(echo.HeaderAccessControlExposeHeaders, exposeHeaders)
 | 
			
		||||
				}
 | 
			
		||||
@@ -189,11 +210,13 @@ func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc {
 | 
			
		||||
			// Preflight request
 | 
			
		||||
			res.Header().Add(echo.HeaderVary, echo.HeaderAccessControlRequestMethod)
 | 
			
		||||
			res.Header().Add(echo.HeaderVary, echo.HeaderAccessControlRequestHeaders)
 | 
			
		||||
			res.Header().Set(echo.HeaderAccessControlAllowOrigin, allowOrigin)
 | 
			
		||||
			res.Header().Set(echo.HeaderAccessControlAllowMethods, allowMethods)
 | 
			
		||||
			if config.AllowCredentials {
 | 
			
		||||
				res.Header().Set(echo.HeaderAccessControlAllowCredentials, "true")
 | 
			
		||||
 | 
			
		||||
			if !hasCustomAllowMethods && routerAllowMethods != "" {
 | 
			
		||||
				res.Header().Set(echo.HeaderAccessControlAllowMethods, routerAllowMethods)
 | 
			
		||||
			} else {
 | 
			
		||||
				res.Header().Set(echo.HeaderAccessControlAllowMethods, allowMethods)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if allowHeaders != "" {
 | 
			
		||||
				res.Header().Set(echo.HeaderAccessControlAllowHeaders, allowHeaders)
 | 
			
		||||
			} else {
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user