summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/mattermost/mattermost-server/v5/model
diff options
context:
space:
mode:
authorWim <wim@42.be>2021-10-17 00:47:22 +0200
committerGitHub <noreply@github.com>2021-10-17 00:47:22 +0200
commit4dd8bae5c91fa4aef09d865d8fef1acd84f90925 (patch)
treeffad9b242daccaf8c86d1c1fbd59032302bd3be9 /vendor/github.com/mattermost/mattermost-server/v5/model
parent7ae45c42e712bd0e66c101f3f714c05aa1dc2104 (diff)
downloadmatterbridge-msglm-4dd8bae5c91fa4aef09d865d8fef1acd84f90925.tar.gz
matterbridge-msglm-4dd8bae5c91fa4aef09d865d8fef1acd84f90925.tar.bz2
matterbridge-msglm-4dd8bae5c91fa4aef09d865d8fef1acd84f90925.zip
Update dependencies (#1610)
* Update dependencies * Update module to go 1.17
Diffstat (limited to 'vendor/github.com/mattermost/mattermost-server/v5/model')
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/access.go7
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/analytics_row.go24
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/at_mentions.go4
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/auditconv.go48
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/audits.go9
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/authorize.go8
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/bot.go22
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/bot_default_image.go288
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/bundle_info.go4
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/channel.go79
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/channel_count.go3
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/channel_list.go12
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/channel_member.go60
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go25
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/channel_sidebar.go13
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/channel_view.go5
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/client4.go692
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/cloud.go84
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/cluster_discovery.go12
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/cluster_info.go13
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/cluster_message.go1
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/cluster_stats.go10
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/command.go2
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go24
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/command_autocomplete.go2
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/command_response.go2
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/command_webhook.go4
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/compliance.go26
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/compliance_post.go54
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/config.go1195
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/custom_status.go141
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/data_retention_policy.go121
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/emoji.go27
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/emoji_data.go3
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/feature_flags.go76
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/file.go5
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/file_info.go38
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/file_info_list.go128
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/file_info_search_results.go37
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/group.go2
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/group_syncable.go33
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/guest_invite.go2
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/incoming_webhook.go6
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/initial_load.go10
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go4
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/job.go35
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/license.go62
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/manifest.go108
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/marketplace_plugin.go12
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/message_export.go5
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/mfa_secret.go10
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/migration.go12
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/oauth.go8
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/outgoing_webhook.go10
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/permission.go1209
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/plugin_cluster_event.go28
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/plugin_key_value.go4
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/post.go116
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/post_list.go8
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/post_search_results.go3
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/preference.go22
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/preferences.go5
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/product_notices.go33
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/push_notification.go20
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/push_response.go7
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/reaction.go40
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/remote_cluster.go355
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/role.go243
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/scheduled_task.go55
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/scheme.go11
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/search_params.go35
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/security_bulletin.go12
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/serialized_gen.go1779
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/session.go129
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/session_serial_gen.go540
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/shared_channel.go273
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/slack_attachment.go3
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/status.go2
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/switch_request.go6
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/system.go39
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/team.go7
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/team_member.go42
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/team_member_serial_gen.go193
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/team_search.go17
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/thread.go55
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/token.go4
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/upload_session.go11
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/user.go199
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/user_autocomplete.go5
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/user_serial_gen.go826
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/utils.go103
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/version.go14
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/websocket_message.go4
-rw-r--r--vendor/github.com/mattermost/mattermost-server/v5/model/websocket_request.go8
94 files changed, 6795 insertions, 3297 deletions
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/access.go b/vendor/github.com/mattermost/mattermost-server/v5/model/access.go
index bbac3601..6b60ea9e 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/access.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/access.go
@@ -31,17 +31,18 @@ type AccessResponse struct {
ExpiresIn int32 `json:"expires_in"`
Scope string `json:"scope"`
RefreshToken string `json:"refresh_token"`
+ IdToken string `json:"id_token"`
}
// IsValid validates the AccessData and returns an error if it isn't configured
// correctly.
func (ad *AccessData) IsValid() *AppError {
- if len(ad.ClientId) == 0 || len(ad.ClientId) > 26 {
+ if ad.ClientId == "" || len(ad.ClientId) > 26 {
return NewAppError("AccessData.IsValid", "model.access.is_valid.client_id.app_error", nil, "", http.StatusBadRequest)
}
- if len(ad.UserId) == 0 || len(ad.UserId) > 26 {
+ if ad.UserId == "" || len(ad.UserId) > 26 {
return NewAppError("AccessData.IsValid", "model.access.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
}
@@ -53,7 +54,7 @@ func (ad *AccessData) IsValid() *AppError {
return NewAppError("AccessData.IsValid", "model.access.is_valid.refresh_token.app_error", nil, "", http.StatusBadRequest)
}
- if len(ad.RedirectUri) == 0 || len(ad.RedirectUri) > 256 || !IsValidHttpUrl(ad.RedirectUri) {
+ if ad.RedirectUri == "" || len(ad.RedirectUri) > 256 || !IsValidHttpUrl(ad.RedirectUri) {
return NewAppError("AccessData.IsValid", "model.access.is_valid.redirect_uri.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/analytics_row.go b/vendor/github.com/mattermost/mattermost-server/v5/model/analytics_row.go
index 1180ad22..d1216664 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/analytics_row.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/analytics_row.go
@@ -15,27 +15,27 @@ type AnalyticsRow struct {
type AnalyticsRows []*AnalyticsRow
-func (me *AnalyticsRow) ToJson() string {
- b, _ := json.Marshal(me)
+func (ar *AnalyticsRow) ToJson() string {
+ b, _ := json.Marshal(ar)
return string(b)
}
func AnalyticsRowFromJson(data io.Reader) *AnalyticsRow {
- var me *AnalyticsRow
- json.NewDecoder(data).Decode(&me)
- return me
+ var ar *AnalyticsRow
+ json.NewDecoder(data).Decode(&ar)
+ return ar
}
-func (me AnalyticsRows) ToJson() string {
- if b, err := json.Marshal(me); err != nil {
+func (ar AnalyticsRows) ToJson() string {
+ b, err := json.Marshal(ar)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func AnalyticsRowsFromJson(data io.Reader) AnalyticsRows {
- var me AnalyticsRows
- json.NewDecoder(data).Decode(&me)
- return me
+ var ar AnalyticsRows
+ json.NewDecoder(data).Decode(&ar)
+ return ar
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/at_mentions.go b/vendor/github.com/mattermost/mattermost-server/v5/model/at_mentions.go
index f41d182a..b5bfc0c7 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/at_mentions.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/at_mentions.go
@@ -8,7 +8,7 @@ import (
"strings"
)
-var atMentionRegexp = regexp.MustCompile(`\B@[[:alnum:]][[:alnum:]\.\-_]*`)
+var atMentionRegexp = regexp.MustCompile(`\B@[[:alnum:]][[:alnum:]\.\-_:]*`)
const usernameSpecialChars = ".-_"
@@ -24,7 +24,7 @@ func PossibleAtMentions(message string) []string {
alreadyMentioned := make(map[string]bool)
for _, match := range atMentionRegexp.FindAllString(message, -1) {
name := NormalizeUsername(match[1:])
- if !alreadyMentioned[name] && IsValidUsername(name) {
+ if !alreadyMentioned[name] && IsValidUsernameAllowRemote(name) {
names = append(names, name)
alreadyMentioned[name] = true
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/auditconv.go b/vendor/github.com/mattermost/mattermost-server/v5/model/auditconv.go
index 50af2880..b3cf6062 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/auditconv.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/auditconv.go
@@ -3,7 +3,9 @@
package model
-import "github.com/francoispqt/gojay"
+import (
+ "github.com/francoispqt/gojay"
+)
// AuditModelTypeConv converts key model types to something better suited for audit output.
func AuditModelTypeConv(val interface{}) (newVal interface{}, converted bool) {
@@ -49,6 +51,8 @@ func AuditModelTypeConv(val interface{}) (newVal interface{}, converted bool) {
return newAuditIncomingWebhook(v), true
case *OutgoingWebhook:
return newAuditOutgoingWebhook(v), true
+ case *RemoteCluster:
+ return newRemoteCluster(v), true
}
return val, false
}
@@ -665,3 +669,45 @@ func (h auditOutgoingWebhook) MarshalJSONObject(enc *gojay.Encoder) {
func (h auditOutgoingWebhook) IsNil() bool {
return false
}
+
+type auditRemoteCluster struct {
+ RemoteId string
+ RemoteTeamId string
+ Name string
+ DisplayName string
+ SiteURL string
+ CreateAt int64
+ LastPingAt int64
+ CreatorId string
+}
+
+// newRemoteCluster creates a simplified representation of RemoteCluster for output to audit log.
+func newRemoteCluster(r *RemoteCluster) auditRemoteCluster {
+ var rc auditRemoteCluster
+ if r != nil {
+ rc.RemoteId = r.RemoteId
+ rc.RemoteTeamId = r.RemoteTeamId
+ rc.Name = r.Name
+ rc.DisplayName = r.DisplayName
+ rc.SiteURL = r.SiteURL
+ rc.CreateAt = r.CreateAt
+ rc.LastPingAt = r.LastPingAt
+ rc.CreatorId = r.CreatorId
+ }
+ return rc
+}
+
+func (r auditRemoteCluster) MarshalJSONObject(enc *gojay.Encoder) {
+ enc.StringKey("remote_id", r.RemoteId)
+ enc.StringKey("remote_team_id", r.RemoteTeamId)
+ enc.StringKey("name", r.Name)
+ enc.StringKey("display_name", r.DisplayName)
+ enc.StringKey("site_url", r.SiteURL)
+ enc.Int64Key("create_at", r.CreateAt)
+ enc.Int64Key("last_ping_at", r.LastPingAt)
+ enc.StringKey("creator_id", r.CreatorId)
+}
+
+func (r auditRemoteCluster) IsNil() bool {
+ return false
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/audits.go b/vendor/github.com/mattermost/mattermost-server/v5/model/audits.go
index a8f01e1b..54e361f9 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/audits.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/audits.go
@@ -14,17 +14,16 @@ func (o Audits) Etag() string {
if len(o) > 0 {
// the first in the list is always the most current
return Etag(o[0].CreateAt)
- } else {
- return ""
}
+ return ""
}
func (o Audits) ToJson() string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func AuditsFromJson(data io.Reader) Audits {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/authorize.go b/vendor/github.com/mattermost/mattermost-server/v5/model/authorize.go
index 0191a670..f2a8e8dc 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/authorize.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/authorize.go
@@ -47,7 +47,7 @@ func (ad *AuthData) IsValid() *AppError {
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
}
- if len(ad.Code) == 0 || len(ad.Code) > 128 {
+ if ad.Code == "" || len(ad.Code) > 128 {
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.auth_code.app_error", nil, "client_id="+ad.ClientId, http.StatusBadRequest)
}
@@ -82,11 +82,11 @@ func (ar *AuthorizeRequest) IsValid() *AppError {
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.client_id.app_error", nil, "", http.StatusBadRequest)
}
- if len(ar.ResponseType) == 0 {
+ if ar.ResponseType == "" {
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.response_type.app_error", nil, "", http.StatusBadRequest)
}
- if len(ar.RedirectUri) == 0 || len(ar.RedirectUri) > 256 || !IsValidHttpUrl(ar.RedirectUri) {
+ if ar.RedirectUri == "" || len(ar.RedirectUri) > 256 || !IsValidHttpUrl(ar.RedirectUri) {
return NewAppError("AuthData.IsValid", "model.authorize.is_valid.redirect_uri.app_error", nil, "client_id="+ar.ClientId, http.StatusBadRequest)
}
@@ -110,7 +110,7 @@ func (ad *AuthData) PreSave() {
ad.CreateAt = GetMillis()
}
- if len(ad.Scope) == 0 {
+ if ad.Scope == "" {
ad.Scope = DEFAULT_SCOPE
}
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/bot.go b/vendor/github.com/mattermost/mattermost-server/v5/model/bot.go
index fb46be49..e58fc0be 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/bot.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/bot.go
@@ -17,6 +17,7 @@ const (
BOT_DESCRIPTION_MAX_RUNES = 1024
BOT_CREATOR_ID_MAX_RUNES = KEY_VALUE_PLUGIN_ID_MAX_RUNES // UserId or PluginId
BOT_WARN_METRIC_BOT_USERNAME = "mattermost-advisor"
+ BOT_SYSTEM_BOT_USERNAME = "system-bot"
)
// Bot is a special type of User meant for programmatic interactions.
@@ -82,7 +83,7 @@ func (b *Bot) IsValid() *AppError {
return NewAppError("Bot.IsValid", "model.bot.is_valid.description.app_error", b.Trace(), "", http.StatusBadRequest)
}
- if len(b.OwnerId) == 0 || utf8.RuneCountInString(b.OwnerId) > BOT_CREATOR_ID_MAX_RUNES {
+ if b.OwnerId == "" || utf8.RuneCountInString(b.OwnerId) > BOT_CREATOR_ID_MAX_RUNES {
return NewAppError("Bot.IsValid", "model.bot.is_valid.creator_id.app_error", b.Trace(), "", http.StatusBadRequest)
}
@@ -128,6 +129,8 @@ func BotFromJson(data io.Reader) *Bot {
}
// Patch modifies an existing bot with optional fields from the given patch.
+// TODO 6.0: consider returning a boolean to indicate whether or not the patch
+// applied any changes.
func (b *Bot) Patch(patch *BotPatch) {
if patch.Username != nil {
b.Username = *patch.Username
@@ -142,6 +145,23 @@ func (b *Bot) Patch(patch *BotPatch) {
}
}
+// WouldPatch returns whether or not the given patch would be applied or not.
+func (b *Bot) WouldPatch(patch *BotPatch) bool {
+ if patch == nil {
+ return false
+ }
+ if patch.Username != nil && *patch.Username != b.Username {
+ return true
+ }
+ if patch.DisplayName != nil && *patch.DisplayName != b.DisplayName {
+ return true
+ }
+ if patch.Description != nil && *patch.Description != b.Description {
+ return true
+ }
+ return false
+}
+
// ToJson serializes the bot patch to json.
func (b *BotPatch) ToJson() []byte {
data, err := json.Marshal(b)
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/bot_default_image.go b/vendor/github.com/mattermost/mattermost-server/v5/model/bot_default_image.go
deleted file mode 100644
index d9cdd2e2..00000000
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/bot_default_image.go
+++ /dev/null
@@ -1,288 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See LICENSE.txt for license information.
-
-package model
-
-var BotDefaultImage = []byte{
- 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d,
- 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x7e,
- 0x08, 0x06, 0x00, 0x00, 0x00, 0xec, 0xa6, 0x19, 0xa2, 0x00, 0x00, 0x00,
- 0x04, 0x67, 0x41, 0x4d, 0x41, 0x00, 0x00, 0xb1, 0x8f, 0x0b, 0xfc, 0x61,
- 0x05, 0x00, 0x00, 0x0c, 0xe3, 0x49, 0x44, 0x41, 0x54, 0x78, 0x01, 0xed,
- 0x5d, 0x5b, 0x88, 0x15, 0xc9, 0x19, 0xae, 0xf1, 0xba, 0x5e, 0xc6, 0x4b,
- 0xbc, 0xa0, 0x46, 0xd7, 0x2b, 0xce, 0x2a, 0xba, 0xca, 0x8a, 0xa3, 0x82,
- 0x38, 0xa3, 0x46, 0x47, 0x5d, 0x59, 0xa3, 0x2f, 0x9b, 0x28, 0x6e, 0xc2,
- 0xea, 0x83, 0x22, 0x04, 0x82, 0x78, 0x41, 0xf2, 0xb2, 0x04, 0xd4, 0x07,
- 0x49, 0x22, 0xc4, 0x07, 0xcd, 0x53, 0x30, 0x26, 0x1a, 0xa2, 0x08, 0xee,
- 0xaa, 0xa8, 0x71, 0xb2, 0x41, 0x11, 0xbc, 0xdf, 0xd0, 0x8d, 0x6e, 0x24,
- 0x82, 0xe3, 0x65, 0x32, 0x9b, 0x19, 0x1d, 0x47, 0xd7, 0xeb, 0xc9, 0xf7,
- 0xb5, 0xa7, 0x0f, 0xe7, 0x9c, 0xe9, 0x3e, 0xdd, 0xe7, 0x4c, 0x57, 0x77,
- 0x75, 0x75, 0xfd, 0xf0, 0x9f, 0xee, 0xae, 0xaa, 0xae, 0xfa, 0xff, 0xef,
- 0xfb, 0x4f, 0x9d, 0xee, 0xaa, 0xea, 0x3e, 0x65, 0x42, 0x4f, 0xe9, 0x0b,
- 0xb7, 0x46, 0x43, 0x2b, 0xd2, 0xdb, 0x91, 0xd8, 0xf6, 0x84, 0x96, 0x67,
- 0x69, 0xf7, 0xf4, 0x3e, 0x36, 0xa2, 0x19, 0xfa, 0x34, 0xbd, 0xe5, 0x3e,
- 0xf5, 0x31, 0xf4, 0xdf, 0xd0, 0x5b, 0xd0, 0x7f, 0xa5, 0xb7, 0x0d, 0xd8,
- 0x6a, 0x25, 0x65, 0x1a, 0x78, 0xd3, 0x1b, 0x3e, 0x54, 0x41, 0x67, 0x42,
- 0x2b, 0xa1, 0x24, 0x9d, 0x69, 0x32, 0xa4, 0x11, 0x95, 0x32, 0x18, 0xce,
- 0x42, 0x6b, 0xa1, 0x5f, 0x43, 0x99, 0x16, 0x5b, 0x89, 0x63, 0x00, 0x74,
- 0x03, 0xda, 0xb3, 0xa0, 0x24, 0xbc, 0x1a, 0x3a, 0x01, 0xda, 0x0e, 0x1a,
- 0x85, 0xbc, 0x45, 0xa3, 0x57, 0xa0, 0xff, 0x80, 0x32, 0x20, 0x4e, 0x42,
- 0x5b, 0xa0, 0x46, 0x02, 0x46, 0xa0, 0x3d, 0xea, 0xab, 0x81, 0xee, 0x86,
- 0xb2, 0xab, 0x4e, 0x29, 0xaa, 0xb4, 0x8d, 0x36, 0xd2, 0x56, 0xda, 0x6c,
- 0xa4, 0x8d, 0x08, 0x7c, 0x84, 0xf3, 0x7f, 0x03, 0x7d, 0x00, 0x55, 0x95,
- 0x74, 0x37, 0xbb, 0x68, 0x33, 0x6d, 0xa7, 0x0f, 0x46, 0x8a, 0x44, 0xe0,
- 0x63, 0x94, 0x3f, 0x0d, 0x75, 0x03, 0x37, 0x6e, 0xe9, 0xf4, 0x85, 0x3e,
- 0x19, 0x29, 0x80, 0x00, 0xbb, 0xcc, 0x9f, 0x40, 0xf9, 0x9b, 0x1a, 0x37,
- 0x82, 0xfd, 0xda, 0x4b, 0xdf, 0xe8, 0xa3, 0xf9, 0x79, 0x00, 0x08, 0xb6,
- 0xf0, 0x02, 0xee, 0x73, 0xe8, 0xb7, 0x50, 0xbf, 0x40, 0xc6, 0xbd, 0x1c,
- 0x7d, 0xa5, 0xcf, 0x51, 0x5d, 0xbc, 0xa2, 0x69, 0x35, 0x84, 0xb7, 0x6d,
- 0xe7, 0xa0, 0x71, 0x27, 0xb4, 0x54, 0xfb, 0xe9, 0x3b, 0x31, 0x48, 0x9c,
- 0x70, 0xa0, 0x66, 0x17, 0x94, 0xb7, 0x51, 0xa5, 0x82, 0xa7, 0xcb, 0x79,
- 0xc4, 0x80, 0x58, 0x10, 0x13, 0xed, 0x85, 0xe3, 0x0e, 0xab, 0xa0, 0xdf,
- 0x41, 0x75, 0x21, 0x30, 0x28, 0x3f, 0x88, 0x09, 0xb1, 0x89, 0xe3, 0xd8,
- 0x0c, 0xcc, 0xf6, 0x16, 0x46, 0xf8, 0x57, 0xd0, 0xa0, 0x00, 0xd3, 0xb5,
- 0x1e, 0x62, 0xa4, 0x5d, 0x6f, 0x50, 0x0d, 0xa7, 0xea, 0x0c, 0xf9, 0xbe,
- 0x83, 0x9f, 0x58, 0x11, 0xb3, 0xd8, 0x0b, 0x6f, 0x77, 0xbe, 0x80, 0xbe,
- 0x81, 0xea, 0xfa, 0x8d, 0x95, 0xe5, 0x17, 0x31, 0x23, 0x76, 0xb1, 0xbd,
- 0x65, 0xe4, 0x84, 0x4c, 0xad, 0x21, 0xbe, 0xcd, 0x81, 0x4f, 0x0c, 0x89,
- 0x65, 0xac, 0xe4, 0x7d, 0x58, 0x7b, 0x03, 0x2a, 0xeb, 0xdb, 0x91, 0xb4,
- 0x7a, 0x89, 0x25, 0x31, 0x8d, 0x85, 0x8c, 0x87, 0x95, 0xf7, 0xa0, 0x49,
- 0x23, 0x49, 0xb6, 0xbf, 0xc4, 0x94, 0xd8, 0x2a, 0x2d, 0xd5, 0xb0, 0xae,
- 0x09, 0x2a, 0x1b, 0x8c, 0xa4, 0xd6, 0x4f, 0x6c, 0x89, 0xb1, 0x92, 0xf2,
- 0x09, 0xac, 0xfa, 0x1e, 0x9a, 0x54, 0x72, 0xc2, 0xf2, 0x9b, 0x18, 0x13,
- 0x6b, 0xa5, 0xa4, 0x1a, 0xd6, 0x18, 0xf2, 0xc3, 0x0b, 0x7e, 0x62, 0x4d,
- 0xcc, 0x95, 0x90, 0x49, 0xb0, 0xe2, 0x09, 0x34, 0xac, 0x6f, 0x80, 0x69,
- 0xe7, 0x1d, 0xd6, 0xc4, 0x9c, 0xd8, 0x47, 0x2a, 0x5c, 0x78, 0x59, 0x0f,
- 0x35, 0xa4, 0x44, 0x83, 0x01, 0xb1, 0x27, 0x07, 0x91, 0xc8, 0x60, 0xb4,
- 0x7a, 0x17, 0x6a, 0xc8, 0x8f, 0x16, 0x03, 0x72, 0x40, 0x2e, 0x42, 0x95,
- 0x4e, 0x68, 0x2d, 0xc9, 0xd3, 0xb8, 0xaa, 0x05, 0x3d, 0xb9, 0x20, 0x27,
- 0x45, 0x4b, 0xa9, 0xc3, 0x8c, 0xdb, 0xd1, 0xd2, 0x8f, 0x8b, 0x6e, 0xcd,
- 0x9c, 0x20, 0x0b, 0x81, 0x41, 0xa8, 0xf8, 0x07, 0xd0, 0xc3, 0xb2, 0x1a,
- 0xc8, 0xae, 0xf7, 0x53, 0x1c, 0xa8, 0xf6, 0x0d, 0x30, 0xf6, 0xbc, 0xe3,
- 0x84, 0xdc, 0x48, 0x15, 0x5e, 0x70, 0x98, 0x2b, 0x7e, 0x75, 0xbf, 0x00,
- 0xe4, 0xa6, 0xa8, 0x8b, 0xc2, 0x62, 0xd6, 0xa4, 0xbd, 0x87, 0xca, 0xff,
- 0x06, 0x2d, 0x87, 0x1a, 0x51, 0x13, 0x01, 0x72, 0x43, 0x8e, 0xc8, 0x95,
- 0x2f, 0x29, 0x26, 0x00, 0x7e, 0x85, 0x1a, 0x95, 0x1f, 0x8b, 0xf6, 0xe3,
- 0xf5, 0x80, 0x01, 0x03, 0xc4, 0xee, 0xdd, 0xbb, 0x45, 0x5d, 0x5d, 0x9d,
- 0xa5, 0xdc, 0x67, 0x9a, 0x26, 0x42, 0x8e, 0xc8, 0x55, 0xa0, 0xf2, 0x01,
- 0x6a, 0x7b, 0x01, 0x8d, 0xfd, 0x6f, 0x6d, 0xbf, 0x7e, 0xfd, 0x52, 0x0f,
- 0x1f, 0x3e, 0x4c, 0xe5, 0x0b, 0xd3, 0x98, 0xa7, 0x83, 0x8f, 0x69, 0xae,
- 0xc8, 0x59, 0x60, 0x52, 0x8b, 0x9a, 0xb4, 0x00, 0x67, 0xd7, 0xae, 0x5d,
- 0xf9, 0xdc, 0x67, 0x8e, 0x99, 0xa7, 0x8b, 0x9f, 0xf0, 0x83, 0x9c, 0x05,
- 0x22, 0x9f, 0xa1, 0x16, 0x6d, 0x80, 0xb9, 0x7d, 0xfb, 0x76, 0x86, 0xf0,
- 0xfc, 0x1d, 0xe6, 0xe9, 0xe4, 0x2b, 0x7c, 0x21, 0x77, 0x05, 0xa5, 0xac,
- 0x60, 0xee, 0xbb, 0x95, 0x28, 0x7c, 0x1c, 0xba, 0x9f, 0x47, 0xb9, 0xd8,
- 0x64, 0xbf, 0x78, 0xf1, 0x42, 0x74, 0xea, 0xe4, 0x3c, 0x66, 0xf2, 0xf2,
- 0xe5, 0x4b, 0xd1, 0xb9, 0x73, 0xe7, 0xd8, 0xf8, 0xe2, 0xc3, 0xd0, 0xff,
- 0xa2, 0x4c, 0x05, 0xd4, 0xf5, 0x11, 0x76, 0xaf, 0x8b, 0xc0, 0x8d, 0x38,
- 0x59, 0x1b, 0xf2, 0x7d, 0x00, 0xa6, 0x5b, 0x11, 0x72, 0x47, 0x0e, 0x5d,
- 0xa5, 0x50, 0x0f, 0xc0, 0x91, 0x25, 0x8e, 0x33, 0xf3, 0x4d, 0x1a, 0xda,
- 0x48, 0xc2, 0x7a, 0x00, 0xf2, 0xf6, 0x14, 0x3a, 0x14, 0xfa, 0x3f, 0x1e,
- 0xe4, 0x4b, 0xa1, 0x1e, 0xe0, 0x97, 0x28, 0xac, 0x15, 0xf9, 0xf9, 0xce,
- 0x27, 0xe4, 0x98, 0x1c, 0x92, 0x4b, 0x47, 0x71, 0xeb, 0x01, 0x7a, 0xa1,
- 0xf4, 0x7f, 0xa0, 0x3d, 0x1d, 0xcf, 0x8a, 0x71, 0x62, 0x02, 0x7b, 0x00,
- 0xb2, 0xf5, 0x18, 0x3a, 0x0c, 0xca, 0x25, 0x65, 0x39, 0xe2, 0xd6, 0x03,
- 0xfc, 0x02, 0xa5, 0xb4, 0x23, 0x3f, 0xc7, 0xf3, 0x64, 0x1d, 0x90, 0x4b,
- 0x72, 0xda, 0x4a, 0x9c, 0x7a, 0x80, 0x2e, 0x28, 0xc5, 0x15, 0xa8, 0xbc,
- 0x06, 0xd0, 0x4e, 0x12, 0xda, 0x03, 0x90, 0x47, 0x5e, 0x03, 0x70, 0xdd,
- 0xc0, 0x73, 0x1e, 0xd8, 0xe2, 0xd4, 0x03, 0x70, 0x9a, 0x57, 0x4b, 0xf2,
- 0x6d, 0xa7, 0x13, 0xba, 0x25, 0xa7, 0xad, 0xa6, 0xf0, 0x3b, 0x38, 0x80,
- 0xf1, 0x73, 0x87, 0xb4, 0xc8, 0x93, 0x78, 0x7f, 0x3e, 0x67, 0xce, 0x1c,
- 0x31, 0x7d, 0xfa, 0x74, 0x31, 0x68, 0xd0, 0x20, 0xd1, 0xbb, 0x77, 0xef,
- 0x92, 0x6c, 0xea, 0xd8, 0xb1, 0xa3, 0xeb, 0x79, 0xcc, 0x3b, 0x74, 0xe8,
- 0x90, 0x6b, 0x7e, 0xa1, 0x8c, 0xc6, 0xc6, 0x46, 0x6b, 0x5e, 0xe1, 0xf4,
- 0xe9, 0xd3, 0xe2, 0xf8, 0xf1, 0xe3, 0x82, 0x3d, 0x8d, 0x82, 0xf2, 0x33,
- 0xd8, 0xf4, 0x97, 0x42, 0x76, 0xfd, 0x10, 0x99, 0x4a, 0x3d, 0xc7, 0xd7,
- 0xa5, 0x4b, 0x97, 0xd4, 0xa6, 0x4d, 0x9b, 0x52, 0x4d, 0x4d, 0x4d, 0xf9,
- 0x03, 0x77, 0xca, 0x1e, 0xd3, 0x56, 0xda, 0x4c, 0xdb, 0x81, 0xa7, 0x4a,
- 0x4a, 0x6e, 0xc9, 0xb1, 0xab, 0x6c, 0x40, 0x8e, 0x32, 0x06, 0x8f, 0x18,
- 0x31, 0x22, 0x75, 0xe3, 0xc6, 0x0d, 0x65, 0x89, 0xf6, 0x32, 0x8c, 0xb6,
- 0xd3, 0x07, 0x95, 0x30, 0x85, 0x2d, 0xe4, 0xd8, 0x55, 0x94, 0x79, 0x9e,
- 0x6f, 0xd4, 0xa8, 0x51, 0xa9, 0xfa, 0xfa, 0x7a, 0x2f, 0x8c, 0x95, 0xcf,
- 0xa7, 0x0f, 0xf4, 0x05, 0x88, 0xab, 0xa2, 0xe4, 0xd8, 0x51, 0x3e, 0x44,
- 0xaa, 0x12, 0x46, 0x76, 0xed, 0xda, 0x35, 0x75, 0xed, 0xda, 0x35, 0xe5,
- 0xc9, 0xf5, 0x6b, 0x20, 0x7d, 0xa1, 0x4f, 0xaa, 0xe0, 0x0b, 0x3b, 0xc8,
- 0xb5, 0x25, 0xd9, 0x77, 0x01, 0x3f, 0xb2, 0x13, 0xa3, 0xde, 0xae, 0x5d,
- 0xbb, 0x56, 0x8c, 0x1b, 0x37, 0x2e, 0x6a, 0x33, 0x02, 0x6b, 0x9f, 0xbe,
- 0xd0, 0x27, 0x85, 0xc4, 0x91, 0x6b, 0xbe, 0x9a, 0x24, 0xf2, 0x28, 0x2d,
- 0x2f, 0x2f, 0x8f, 0xd5, 0x05, 0x9f, 0xdf, 0x5e, 0x80, 0x17, 0x86, 0xf4,
- 0x4d, 0x05, 0x8c, 0x61, 0xc3, 0x97, 0x76, 0x30, 0xda, 0x3d, 0x00, 0x6f,
- 0x07, 0x67, 0xd8, 0x89, 0x51, 0x6e, 0x6b, 0x6a, 0x6a, 0x44, 0xcf, 0x9e,
- 0xfa, 0x0d, 0x42, 0xd2, 0x27, 0xfa, 0xa6, 0x88, 0x54, 0xc1, 0x0e, 0x6b,
- 0x08, 0xc0, 0x0e, 0x80, 0x4a, 0x24, 0x28, 0x31, 0xf1, 0x33, 0x77, 0xee,
- 0x5c, 0x45, 0x30, 0x0a, 0xde, 0x0c, 0x85, 0x7c, 0x23, 0xd7, 0xe4, 0x3c,
- 0xf3, 0xa6, 0xca, 0xd9, 0xc1, 0xbb, 0x5b, 0x5a, 0x8d, 0x43, 0x87, 0x0e,
- 0x2d, 0xed, 0xc4, 0x18, 0x9c, 0xa5, 0x98, 0x6f, 0x16, 0xe7, 0x76, 0x0f,
- 0x30, 0x5d, 0x15, 0xfc, 0xfa, 0xf7, 0xef, 0xaf, 0x8a, 0x29, 0x81, 0xdb,
- 0xa1, 0x98, 0x6f, 0x16, 0xe7, 0x76, 0x00, 0x8c, 0x09, 0xdc, 0xdb, 0x12,
- 0x2b, 0xec, 0xd0, 0xc1, 0xfa, 0x69, 0x2a, 0xf1, 0x6c, 0xb5, 0x4f, 0x53,
- 0xcc, 0x37, 0x8b, 0x73, 0x06, 0x40, 0x37, 0x28, 0x67, 0x89, 0x8c, 0x24,
- 0x0b, 0x01, 0x72, 0xde, 0x8d, 0x01, 0xc0, 0x45, 0x83, 0x4e, 0xd3, 0xc2,
- 0xc9, 0x82, 0x23, 0x79, 0xde, 0x92, 0xf3, 0x0a, 0x3b, 0x00, 0x92, 0xe7,
- 0xbe, 0xf1, 0x98, 0x08, 0x58, 0x01, 0x10, 0xe8, 0x13, 0x24, 0x51, 0xe0,
- 0x7a, 0xe2, 0xc4, 0x09, 0xb1, 0x62, 0xc5, 0x0a, 0x31, 0x71, 0xe2, 0x44,
- 0x31, 0x73, 0xe6, 0x4c, 0xb1, 0x7e, 0xfd, 0x7a, 0x71, 0xff, 0xfe, 0xfd,
- 0xc0, 0x4c, 0x39, 0x7b, 0xf6, 0xac, 0x58, 0xb9, 0x72, 0xa5, 0x98, 0x30,
- 0x61, 0x82, 0x98, 0x3f, 0x7f, 0xbe, 0xd8, 0xb6, 0x6d, 0x9b, 0x78, 0xf5,
- 0xea, 0x55, 0x60, 0xf5, 0x47, 0x58, 0x91, 0xc5, 0xfd, 0x9f, 0x61, 0x40,
- 0x28, 0x23, 0x54, 0x3d, 0x7a, 0xf4, 0xb0, 0x66, 0xc7, 0x38, 0x43, 0x46,
- 0x1d, 0x3c, 0x78, 0x70, 0xab, 0x76, 0x8b, 0x99, 0x03, 0x78, 0xfb, 0xf6,
- 0x6d, 0x6a, 0xf5, 0xea, 0xd5, 0xad, 0xea, 0xa0, 0x3f, 0x58, 0x2f, 0x90,
- 0x3a, 0x78, 0xf0, 0xa0, 0xdf, 0x81, 0x3a, 0xd7, 0x72, 0x3b, 0x76, 0xec,
- 0x48, 0x61, 0x9d, 0x40, 0xab, 0x36, 0x2a, 0x2b, 0x2b, 0x8b, 0x9e, 0xac,
- 0xa2, 0x6f, 0xf9, 0x58, 0x13, 0x03, 0x1b, 0x0f, 0x6e, 0x89, 0x51, 0x7e,
- 0x19, 0x89, 0xc7, 0xe4, 0x5e, 0x1c, 0x91, 0xd8, 0x80, 0xe5, 0xcc, 0xe4,
- 0xc9, 0x93, 0x53, 0x17, 0x2e, 0x5c, 0x48, 0x91, 0xb0, 0x6c, 0x71, 0x02,
- 0xa4, 0x98, 0x00, 0xd8, 0xbe, 0x7d, 0x7b, 0x41, 0xb0, 0xba, 0x77, 0xef,
- 0x9e, 0xba, 0x73, 0xe7, 0x4e, 0x76, 0x93, 0x45, 0xed, 0x5f, 0xb9, 0x72,
- 0x25, 0x85, 0x2b, 0x77, 0xd7, 0x36, 0x96, 0x2d, 0x5b, 0x56, 0x54, 0x7d,
- 0x7e, 0xfc, 0x25, 0x46, 0xc4, 0x8a, 0x98, 0xc9, 0xe6, 0x25, 0xcd, 0xbd,
- 0x38, 0x25, 0xb3, 0xa1, 0xb1, 0x63, 0xc7, 0xa6, 0xb0, 0x3a, 0xc6, 0x11,
- 0x28, 0x3f, 0x80, 0x38, 0x9e, 0x88, 0xc4, 0xe7, 0xcf, 0x9f, 0xfb, 0x9a,
- 0x61, 0x5b, 0xba, 0x74, 0xa9, 0x5b, 0x15, 0x9e, 0xe9, 0x4b, 0x96, 0x2c,
- 0xf1, 0x24, 0xe1, 0xe6, 0xcd, 0x9b, 0x9e, 0xf5, 0xd8, 0x05, 0x8a, 0xf1,
- 0x97, 0x98, 0x11, 0x3b, 0x99, 0xdc, 0xa0, 0xee, 0x53, 0xbc, 0x08, 0xec,
- 0x01, 0x95, 0x26, 0x5b, 0xb6, 0x6c, 0x71, 0x7d, 0x14, 0xab, 0x2d, 0x8d,
- 0xe2, 0xdb, 0x29, 0x9e, 0x3d, 0x7b, 0xe6, 0x59, 0xc5, 0x99, 0x33, 0x67,
- 0x3c, 0xcb, 0xb8, 0x15, 0x38, 0x77, 0x8e, 0xaf, 0xde, 0x29, 0x2c, 0xe7,
- 0xcf, 0x9f, 0x2f, 0x5c, 0xa0, 0xc4, 0x5c, 0x3e, 0xbe, 0x46, 0xec, 0x24,
- 0x4b, 0x0f, 0x06, 0x80, 0xd4, 0x17, 0x3e, 0x4c, 0x9d, 0x3a, 0x55, 0x8a,
- 0x0f, 0x77, 0xef, 0xde, 0xf5, 0x55, 0xef, 0xbd, 0x7b, 0xf7, 0x04, 0xba,
- 0x55, 0x5f, 0x65, 0xb3, 0x0b, 0xf1, 0x9c, 0x07, 0x0f, 0x1e, 0x64, 0x27,
- 0x39, 0xee, 0xb3, 0x7e, 0x59, 0x22, 0x0b, 0xbb, 0x2c, 0x7b, 0xcb, 0xa5,
- 0x07, 0x80, 0xac, 0xe1, 0xcf, 0xf1, 0xe3, 0xfd, 0xbd, 0xab, 0x02, 0xdd,
- 0xa8, 0x68, 0xd7, 0x8e, 0x6e, 0x16, 0x27, 0x3c, 0x67, 0xf4, 0xe8, 0xd1,
- 0x9e, 0x27, 0x8d, 0x19, 0x23, 0x6f, 0x10, 0x55, 0x16, 0x76, 0x59, 0x4e,
- 0xc9, 0x0f, 0x80, 0xac, 0xc6, 0x02, 0xdd, 0xad, 0xa8, 0xa8, 0x10, 0xc3,
- 0x87, 0x0f, 0xf7, 0xac, 0x73, 0xde, 0xbc, 0x79, 0x9e, 0x65, 0xdc, 0x0a,
- 0xcc, 0x9a, 0x35, 0xcb, 0x2d, 0xcb, 0x4a, 0xc7, 0xa2, 0x4f, 0x11, 0xc2,
- 0xb7, 0xb4, 0xa0, 0x0d, 0x6d, 0xcc, 0xb4, 0x7a, 0x7f, 0xa9, 0x6f, 0xfe,
- 0xb0, 0x2f, 0x80, 0x9c, 0xb6, 0xc5, 0x5c, 0x14, 0x39, 0x9d, 0x7f, 0xf2,
- 0xe4, 0xc9, 0x54, 0x59, 0x59, 0x99, 0xeb, 0x85, 0x12, 0xd7, 0xe2, 0xb5,
- 0xb4, 0xb4, 0x38, 0x9d, 0xea, 0x2b, 0xad, 0xa1, 0xa1, 0x21, 0xd5, 0xb7,
- 0x6f, 0x5f, 0xd7, 0xfa, 0x37, 0x6f, 0xde, 0xec, 0xab, 0x1e, 0xbb, 0x50,
- 0x29, 0xfe, 0x82, 0x60, 0xd7, 0xf6, 0x03, 0xc8, 0x7b, 0xc1, 0xbe, 0xb1,
- 0xb9, 0x8d, 0x51, 0x14, 0xd9, 0xe9, 0x1c, 0xf4, 0xd9, 0xbf, 0x7f, 0xbf,
- 0xc0, 0xab, 0x5d, 0x5a, 0xd9, 0x30, 0x63, 0xc6, 0x0c, 0x71, 0xec, 0xd8,
- 0x31, 0x81, 0xb5, 0x78, 0xad, 0xf2, 0xfc, 0x26, 0xf4, 0xe9, 0xd3, 0x47,
- 0x1c, 0x3d, 0x7a, 0x54, 0x8c, 0x1c, 0x39, 0x32, 0xe7, 0x14, 0x04, 0x9d,
- 0xd8, 0xb0, 0x61, 0x83, 0x58, 0xb7, 0x6e, 0x5d, 0x4e, 0x7a, 0x0c, 0x0f,
- 0x9a, 0x39, 0xf5, 0xc6, 0x00, 0xe8, 0x13, 0x43, 0xe3, 0x2d, 0x93, 0x17,
- 0x2f, 0x5e, 0x2c, 0xaa, 0xaa, 0xaa, 0xac, 0x87, 0x31, 0x2e, 0x5e, 0xbc,
- 0x28, 0x7a, 0xf5, 0xea, 0x25, 0x70, 0x0f, 0x2d, 0x66, 0xcf, 0x9e, 0x2d,
- 0x48, 0x54, 0x5b, 0x65, 0xd2, 0xa4, 0x49, 0xe2, 0xd2, 0xa5, 0x4b, 0xe2,
- 0xc8, 0x91, 0x23, 0x82, 0x57, 0xfc, 0x03, 0x07, 0x0e, 0x14, 0xfc, 0x69,
- 0xe0, 0xa8, 0xa0, 0x06, 0x62, 0x7d, 0xf9, 0xaf, 0xc2, 0x11, 0x69, 0xdd,
- 0x8c, 0xdd, 0xfd, 0x39, 0x6d, 0x4b, 0xe9, 0x12, 0x9d, 0xea, 0x89, 0x4b,
- 0x5a, 0x29, 0xfe, 0xca, 0xe4, 0x06, 0x75, 0x5f, 0xe5, 0x4f, 0xc0, 0x13,
- 0xa8, 0x91, 0x64, 0x22, 0xf0, 0x24, 0xd6, 0xd7, 0x00, 0xc9, 0xe4, 0x2c,
- 0x50, 0xaf, 0x9b, 0x19, 0x00, 0x8d, 0x81, 0x56, 0x69, 0x2a, 0x8b, 0x13,
- 0x02, 0x8d, 0x0c, 0x80, 0xdb, 0x71, 0xb2, 0xd8, 0xd8, 0x1a, 0x28, 0x02,
- 0xb7, 0x19, 0x00, 0xdf, 0x04, 0x5a, 0xa5, 0xa9, 0x2c, 0x4e, 0x08, 0x7c,
- 0xc3, 0x00, 0xe0, 0x7b, 0x00, 0x8d, 0x24, 0x13, 0x81, 0x4c, 0x00, 0xf0,
- 0x36, 0xd0, 0x48, 0xb2, 0x10, 0x20, 0xe7, 0xb7, 0xd8, 0x03, 0xb4, 0x40,
- 0xe5, 0x4d, 0x69, 0x25, 0x0b, 0xd4, 0x38, 0x79, 0x4b, 0xce, 0x5b, 0x18,
- 0x00, 0x94, 0x9b, 0xef, 0x36, 0xe6, 0x33, 0x41, 0x08, 0x58, 0x9c, 0x73,
- 0x28, 0x98, 0x72, 0x0a, 0x3a, 0xd7, 0xda, 0x8b, 0xd9, 0xc7, 0x9b, 0x37,
- 0x6f, 0x04, 0x46, 0x02, 0x5d, 0xad, 0xce, 0x7f, 0x18, 0x83, 0xf3, 0xfc,
- 0x85, 0xd6, 0x07, 0xb4, 0x6f, 0xdf, 0x3e, 0x67, 0x08, 0xf9, 0xf5, 0xeb,
- 0xd7, 0xae, 0x75, 0x73, 0xa8, 0x99, 0xe5, 0x63, 0x2a, 0xe4, 0x3c, 0xf3,
- 0x6c, 0xe0, 0xdf, 0x65, 0x39, 0xd1, 0xdc, 0x2c, 0x77, 0xae, 0x69, 0xf9,
- 0xf2, 0xe5, 0x82, 0x2f, 0x77, 0x72, 0xd3, 0xeb, 0xd7, 0xaf, 0xe7, 0xb8,
- 0xb6, 0x75, 0xeb, 0x56, 0xd7, 0xb2, 0xac, 0x63, 0xdf, 0xbe, 0x7d, 0x99,
- 0xf2, 0x3c, 0xd7, 0xad, 0x5e, 0xa6, 0xb3, 0x6d, 0x99, 0x22, 0x19, 0x3b,
- 0x8b, 0x73, 0xfb, 0x27, 0xe0, 0x2c, 0x1c, 0x91, 0xc2, 0xd4, 0xe5, 0xcb,
- 0x97, 0x65, 0x62, 0xa4, 0x75, 0xdd, 0x12, 0xb1, 0x23, 0xd7, 0xe4, 0x3c,
- 0xd3, 0x03, 0xb0, 0x9f, 0xfb, 0x27, 0x13, 0x82, 0x16, 0xcc, 0x99, 0x07,
- 0x5d, 0xa5, 0xd4, 0xfa, 0x0a, 0xfd, 0x9c, 0x48, 0x6d, 0xd8, 0xa1, 0x72,
- 0x89, 0xd8, 0x91, 0x6b, 0xeb, 0xb7, 0xcd, 0xee, 0x01, 0xd8, 0xbc, 0x94,
- 0x9f, 0x01, 0xce, 0xa7, 0xaf, 0x5a, 0xb5, 0xca, 0xd7, 0x02, 0x4e, 0x07,
- 0x0c, 0x42, 0x4f, 0x0a, 0x62, 0x0a, 0xb9, 0xad, 0x46, 0x73, 0xb1, 0x2b,
- 0x31, 0x23, 0x76, 0x92, 0x24, 0xc3, 0xb5, 0x7d, 0x11, 0xc8, 0x76, 0x32,
- 0x89, 0x41, 0x37, 0xba, 0x73, 0xe7, 0x4e, 0xb1, 0x77, 0xef, 0x5e, 0x6b,
- 0x9e, 0x3e, 0x7b, 0x9d, 0xdb, 0xe3, 0xc7, 0x7c, 0x87, 0x71, 0xdb, 0x64,
- 0xcd, 0x9a, 0x35, 0x62, 0xe1, 0xc2, 0x85, 0xae, 0x95, 0x0c, 0x19, 0x32,
- 0x24, 0x27, 0x6f, 0xd1, 0xa2, 0x45, 0x62, 0xd8, 0xb0, 0x61, 0x39, 0x69,
- 0xd9, 0x07, 0xd3, 0xa6, 0x4d, 0xcb, 0x1c, 0xf2, 0xdc, 0x3d, 0x7b, 0xf6,
- 0x64, 0x8e, 0xf3, 0x77, 0x82, 0x78, 0xde, 0x7f, 0xe3, 0xc6, 0x8d, 0x39,
- 0x6f, 0x44, 0xc1, 0x5b, 0xc5, 0x04, 0x57, 0x23, 0x07, 0x81, 0x4d, 0xbe,
- 0xbd, 0x59, 0xc7, 0xae, 0x5c, 0xdf, 0x40, 0x21, 0x69, 0x6b, 0x03, 0xfc,
- 0xd4, 0xcd, 0x39, 0x73, 0x5d, 0xc5, 0x69, 0x3d, 0x80, 0x1f, 0x4c, 0x02,
- 0x2e, 0x43, 0x8e, 0x33, 0x92, 0xfd, 0x13, 0xc0, 0xc4, 0x3f, 0x66, 0x72,
- 0xcc, 0x8e, 0xae, 0x08, 0xe4, 0x70, 0x9c, 0x1f, 0x00, 0x7f, 0x82, 0xd7,
- 0xc5, 0x2f, 0xa2, 0xd7, 0x15, 0x2a, 0xfd, 0xfc, 0x22, 0xb7, 0xe4, 0x38,
- 0x23, 0xf9, 0x01, 0x50, 0x87, 0x9c, 0xe3, 0x99, 0xdc, 0x08, 0x76, 0x0a,
- 0x0d, 0xbc, 0x44, 0x60, 0x4e, 0xa0, 0x4d, 0x2a, 0xf0, 0x44, 0x31, 0xb9,
- 0x25, 0xc7, 0x19, 0xc9, 0x0f, 0x00, 0x66, 0xe4, 0x74, 0x11, 0x99, 0x92,
- 0x21, 0xed, 0xe0, 0x0f, 0x1c, 0x43, 0x6a, 0x29, 0xfc, 0x66, 0x1e, 0x3d,
- 0x7a, 0x14, 0x7e, 0xa3, 0xb9, 0x2d, 0xb6, 0xe2, 0xd6, 0x29, 0x00, 0x0e,
- 0xe2, 0x1c, 0xfe, 0xb9, 0x40, 0x24, 0x22, 0x71, 0xf0, 0x23, 0x12, 0x7f,
- 0xb2, 0x1b, 0x8d, 0xd8, 0x37, 0x72, 0x4a, 0x6e, 0x73, 0xc4, 0x29, 0x00,
- 0x9e, 0xa3, 0xc4, 0xef, 0x72, 0x4a, 0x85, 0x78, 0x70, 0xe0, 0xc0, 0x81,
- 0x10, 0x5b, 0x0b, 0xb7, 0xa9, 0x88, 0x7d, 0x23, 0xa7, 0xe4, 0xd6, 0x97,
- 0xf4, 0x42, 0xa9, 0x26, 0x68, 0x24, 0xb7, 0x84, 0x18, 0x00, 0xd1, 0xee,
- 0x4e, 0x90, 0x3e, 0x45, 0x85, 0x67, 0x9a, 0x4b, 0x72, 0x5a, 0x94, 0xfc,
- 0x1a, 0xa5, 0x23, 0x31, 0x1a, 0x03, 0x35, 0x29, 0x3e, 0x96, 0xa5, 0x8b,
- 0xd0, 0x17, 0xfa, 0x14, 0x15, 0x9e, 0x68, 0x97, 0x5c, 0x16, 0x2d, 0xfc,
- 0x8f, 0x19, 0x4e, 0x1a, 0x44, 0x62, 0xf8, 0x94, 0x29, 0x53, 0x8a, 0x7e,
- 0x05, 0x8b, 0x8a, 0x01, 0xc3, 0xff, 0x0b, 0xa0, 0x2f, 0x51, 0xe1, 0x98,
- 0xe6, 0x90, 0x5c, 0x96, 0x24, 0x5b, 0x71, 0x56, 0x64, 0xc6, 0x63, 0x28,
- 0x36, 0x85, 0x21, 0xe4, 0x56, 0xaf, 0x96, 0x51, 0x91, 0xe8, 0x7c, 0x9b,
- 0xb0, 0xe6, 0xc0, 0xb2, 0x9d, 0x3e, 0x44, 0x89, 0x21, 0xda, 0x26, 0x87,
- 0xae, 0x52, 0xe6, 0x9a, 0xf3, 0x2e, 0x83, 0xff, 0xcc, 0xc4, 0x45, 0xa3,
- 0xad, 0x9f, 0xbe, 0xf4, 0x38, 0x31, 0xc8, 0x6c, 0xbc, 0x48, 0x49, 0x2c,
- 0x58, 0xb0, 0x40, 0xe0, 0x25, 0x4a, 0x25, 0xff, 0x59, 0x54, 0x90, 0xf6,
- 0x14, 0xaa, 0x8b, 0x7f, 0x1e, 0x85, 0xf7, 0x12, 0x89, 0xc3, 0x87, 0x0f,
- 0x0b, 0x99, 0x2f, 0x8f, 0x28, 0x64, 0x43, 0x56, 0x9e, 0xe7, 0x9f, 0x47,
- 0x67, 0x95, 0x75, 0xdd, 0xfd, 0x0c, 0x39, 0x51, 0x47, 0xb1, 0x69, 0xbf,
- 0x34, 0x0e, 0x96, 0xbb, 0xb2, 0x5a, 0x64, 0x46, 0xad, 0x09, 0x82, 0xd8,
- 0x7d, 0x09, 0xc8, 0x99, 0xa7, 0x78, 0xfd, 0x04, 0xd8, 0x15, 0x7c, 0x80,
- 0x9d, 0x2b, 0xd0, 0x4e, 0x76, 0x82, 0xd9, 0x2a, 0x8d, 0xc0, 0x4b, 0x58,
- 0xc7, 0xe7, 0xd7, 0x3d, 0x1f, 0xfa, 0xf1, 0xbb, 0xa2, 0xb1, 0x01, 0x95,
- 0xbd, 0x07, 0x9d, 0x01, 0x35, 0xa2, 0x3e, 0x02, 0xbc, 0xf0, 0xfb, 0x6b,
- 0xd0, 0x66, 0x32, 0x00, 0xa4, 0xbe, 0x4b, 0x00, 0xf5, 0x9b, 0xdf, 0xfa,
- 0xb6, 0x63, 0x40, 0x8e, 0xc8, 0x95, 0x14, 0xe1, 0x6b, 0xb3, 0x9e, 0x40,
- 0x0d, 0x51, 0x6a, 0x62, 0x40, 0x6e, 0xc8, 0x91, 0x54, 0xf9, 0x14, 0xb5,
- 0x9b, 0x00, 0x50, 0x13, 0x03, 0x72, 0x13, 0x8a, 0xfc, 0x1e, 0xad, 0x98,
- 0x20, 0x50, 0x0b, 0x03, 0x72, 0x12, 0x9a, 0xf0, 0x6e, 0x80, 0xef, 0x51,
- 0x35, 0x41, 0xa0, 0x06, 0x06, 0xe4, 0x22, 0xf4, 0x3b, 0x34, 0xfe, 0xe5,
- 0xc8, 0x5d, 0x13, 0x04, 0x91, 0x7f, 0x09, 0xc8, 0x01, 0xb9, 0x88, 0x44,
- 0x78, 0xc1, 0x51, 0x0f, 0x35, 0x3d, 0x41, 0x34, 0x18, 0x10, 0x7b, 0xe9,
- 0x17, 0x7d, 0x5e, 0x91, 0x35, 0x09, 0x05, 0xcc, 0x9d, 0x41, 0xf8, 0x01,
- 0x40, 0xcc, 0x89, 0xbd, 0x12, 0x52, 0x0d, 0x2b, 0xbe, 0x87, 0x9a, 0x9e,
- 0x20, 0x1c, 0x0c, 0x88, 0x35, 0x31, 0x57, 0x4a, 0x3e, 0x81, 0x35, 0x26,
- 0x08, 0xe4, 0x07, 0x00, 0x31, 0x26, 0xd6, 0x4a, 0x4a, 0x35, 0xac, 0x8a,
- 0x6c, 0x29, 0x19, 0xda, 0xd6, 0xbd, 0x07, 0x22, 0xb6, 0xc4, 0x58, 0x69,
- 0xe1, 0x8b, 0xfc, 0xef, 0x41, 0x75, 0x27, 0x23, 0x6c, 0xff, 0x88, 0xa9,
- 0xbf, 0x3f, 0x49, 0x50, 0x20, 0x3c, 0xde, 0x87, 0x0d, 0x91, 0x3f, 0x67,
- 0xa8, 0x51, 0x10, 0x12, 0x4b, 0x62, 0x1a, 0x2b, 0xe1, 0x6a, 0xa2, 0x5a,
- 0x68, 0xd8, 0xdf, 0x14, 0xdd, 0xda, 0x23, 0x86, 0xc4, 0x32, 0x96, 0xc2,
- 0xe9, 0xe6, 0x2f, 0xa0, 0x6f, 0xa0, 0xba, 0x11, 0x23, 0xdb, 0x1f, 0x62,
- 0x46, 0xec, 0xfc, 0x4e, 0xd9, 0xa3, 0xa8, 0xba, 0x52, 0x0d, 0xd3, 0xf8,
- 0x4c, 0x9a, 0x6c, 0xd0, 0x74, 0xa9, 0x9f, 0x58, 0x11, 0x33, 0xad, 0xa4,
- 0x2f, 0xbc, 0xf9, 0x0a, 0xaa, 0x0b, 0x49, 0xb2, 0xfc, 0x20, 0x46, 0xc4,
- 0x4a, 0x4b, 0x29, 0x83, 0x57, 0xab, 0xa0, 0xdf, 0x41, 0x65, 0x01, 0x18,
- 0xd7, 0x7a, 0x89, 0x09, 0xb1, 0x21, 0x46, 0xda, 0x0b, 0x23, 0xfc, 0x0f,
- 0xd0, 0xb7, 0xd0, 0xb8, 0x12, 0x16, 0x94, 0xdd, 0xc4, 0x80, 0x58, 0x68,
- 0xfb, 0xad, 0x87, 0x6f, 0xae, 0x52, 0x89, 0x9c, 0x24, 0x4f, 0x2b, 0xd3,
- 0x77, 0x62, 0x90, 0x68, 0xe1, 0x13, 0xca, 0x9f, 0x43, 0xbf, 0x85, 0x06,
- 0xf5, 0xad, 0x52, 0xbd, 0x1e, 0xfa, 0x4a, 0x9f, 0xe9, 0xbb, 0x91, 0x34,
- 0x02, 0xbc, 0xdd, 0xf9, 0x29, 0x94, 0xcb, 0xcf, 0x55, 0x27, 0xb0, 0x54,
- 0xfb, 0xe8, 0x1b, 0x7d, 0xd4, 0xe2, 0xd6, 0x0e, 0x7e, 0x48, 0x93, 0x8f,
- 0x51, 0xf3, 0x69, 0x68, 0xa9, 0x40, 0xab, 0x76, 0x1e, 0x7d, 0xa1, 0x4f,
- 0x46, 0x8a, 0x44, 0xe0, 0x23, 0x94, 0xff, 0x2d, 0x94, 0xff, 0xe2, 0xac,
- 0x1a, 0xa9, 0x5e, 0xf6, 0xd0, 0x66, 0xda, 0x4e, 0x1f, 0x8c, 0xb4, 0x11,
- 0x01, 0x76, 0x99, 0x35, 0xd0, 0xdd, 0xd0, 0xa7, 0x50, 0x2f, 0xf0, 0xa3,
- 0xca, 0xa7, 0x6d, 0xb4, 0x91, 0xb6, 0xc6, 0xa2, 0x9b, 0x8f, 0xe3, 0x3d,
- 0x67, 0x37, 0x80, 0x3b, 0x0b, 0x3a, 0x33, 0xad, 0x1f, 0x62, 0x1b, 0xd5,
- 0xc5, 0x14, 0x6f, 0xe1, 0xae, 0x42, 0x6b, 0xd3, 0x7a, 0x12, 0x5b, 0xfe,
- 0x01, 0x47, 0x6c, 0x24, 0x8e, 0x01, 0x90, 0x0f, 0x2e, 0x27, 0x4a, 0xaa,
- 0xa0, 0x0c, 0x08, 0xde, 0x52, 0x55, 0x40, 0x65, 0x4d, 0x9e, 0xf0, 0x2f,
- 0xf6, 0xf8, 0xb8, 0x3c, 0xdf, 0xb4, 0x4d, 0xd2, 0xbf, 0x86, 0x32, 0x2d,
- 0xb6, 0xa2, 0x43, 0x00, 0x38, 0x81, 0xcf, 0x41, 0x15, 0x06, 0x02, 0x17,
- 0x4c, 0x72, 0x3b, 0x02, 0xca, 0x77, 0xe4, 0x74, 0x87, 0x96, 0xa7, 0xd5,
- 0xde, 0xc7, 0xa1, 0xf5, 0x26, 0x14, 0x76, 0xdf, 0x7c, 0x23, 0x0a, 0x95,
- 0xfb, 0x5c, 0x7c, 0x71, 0x07, 0x4a, 0xc2, 0x6f, 0xa5, 0xb7, 0x7c, 0x46,
- 0x52, 0x2b, 0xf9, 0x3f, 0x92, 0xc9, 0x00, 0xb6, 0x61, 0xee, 0xab, 0xc9,
- 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x44, 0xae, 0x42, 0x60, 0x82,
-}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/bundle_info.go b/vendor/github.com/mattermost/mattermost-server/v5/model/bundle_info.go
index 429e1c3d..e4cfe125 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/bundle_info.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/bundle_info.go
@@ -3,7 +3,9 @@
package model
-import "github.com/mattermost/mattermost-server/v5/mlog"
+import (
+ "github.com/mattermost/mattermost-server/v5/shared/mlog"
+)
type BundleInfo struct {
Path string
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/channel.go b/vendor/github.com/mattermost/mattermost-server/v5/model/channel.go
index 282271ad..8dc3fa8d 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/channel.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/channel.go
@@ -34,23 +34,26 @@ const (
)
type Channel struct {
- Id string `json:"id"`
- CreateAt int64 `json:"create_at"`
- UpdateAt int64 `json:"update_at"`
- DeleteAt int64 `json:"delete_at"`
- TeamId string `json:"team_id"`
- Type string `json:"type"`
- DisplayName string `json:"display_name"`
- Name string `json:"name"`
- Header string `json:"header"`
- Purpose string `json:"purpose"`
- LastPostAt int64 `json:"last_post_at"`
- TotalMsgCount int64 `json:"total_msg_count"`
- ExtraUpdateAt int64 `json:"extra_update_at"`
- CreatorId string `json:"creator_id"`
- SchemeId *string `json:"scheme_id"`
- Props map[string]interface{} `json:"props" db:"-"`
- GroupConstrained *bool `json:"group_constrained"`
+ Id string `json:"id"`
+ CreateAt int64 `json:"create_at"`
+ UpdateAt int64 `json:"update_at"`
+ DeleteAt int64 `json:"delete_at"`
+ TeamId string `json:"team_id"`
+ Type string `json:"type"`
+ DisplayName string `json:"display_name"`
+ Name string `json:"name"`
+ Header string `json:"header"`
+ Purpose string `json:"purpose"`
+ LastPostAt int64 `json:"last_post_at"`
+ TotalMsgCount int64 `json:"total_msg_count"`
+ ExtraUpdateAt int64 `json:"extra_update_at"`
+ CreatorId string `json:"creator_id"`
+ SchemeId *string `json:"scheme_id"`
+ Props map[string]interface{} `json:"props" db:"-"`
+ GroupConstrained *bool `json:"group_constrained"`
+ Shared *bool `json:"shared"`
+ TotalMsgCountRoot int64 `json:"total_msg_count_root"`
+ PolicyID *string `json:"policy_id" db:"-"`
}
type ChannelWithTeamData struct {
@@ -120,18 +123,21 @@ type ChannelModeratedRolesPatch struct {
// PerPage number of results per page, if paginated.
//
type ChannelSearchOpts struct {
- NotAssociatedToGroup string
- ExcludeDefaultChannels bool
- IncludeDeleted bool
- Deleted bool
- ExcludeChannelNames []string
- TeamIds []string
- GroupConstrained bool
- ExcludeGroupConstrained bool
- Public bool
- Private bool
- Page *int
- PerPage *int
+ NotAssociatedToGroup string
+ ExcludeDefaultChannels bool
+ IncludeDeleted bool
+ Deleted bool
+ ExcludeChannelNames []string
+ TeamIds []string
+ GroupConstrained bool
+ ExcludeGroupConstrained bool
+ PolicyID string
+ ExcludePolicyConstrained bool
+ IncludePolicyID bool
+ Public bool
+ Private bool
+ Page *int
+ PerPage *int
}
type ChannelMemberCountByGroup struct {
@@ -140,6 +146,14 @@ type ChannelMemberCountByGroup struct {
ChannelMemberTimezonesCount int64 `db:"-" json:"channel_member_timezones_count"`
}
+type ChannelOption func(channel *Channel)
+
+func WithID(ID string) ChannelOption {
+ return func(channel *Channel) {
+ channel.Id = ID
+ }
+}
+
func (o *Channel) DeepCopy() *Channel {
copy := *o
if copy.SchemeId != nil {
@@ -313,6 +327,10 @@ func (o *Channel) IsGroupConstrained() bool {
return o.GroupConstrained != nil && *o.GroupConstrained
}
+func (o *Channel) IsShared() bool {
+ return o.Shared != nil && *o.Shared
+}
+
func (o *Channel) GetOtherUserIdForDM(userId string) string {
if o.Type != CHANNEL_DIRECT {
return ""
@@ -336,9 +354,8 @@ func (o *Channel) GetOtherUserIdForDM(userId string) string {
func GetDMNameFromIds(userId1, userId2 string) string {
if userId1 > userId2 {
return userId2 + "__" + userId1
- } else {
- return userId1 + "__" + userId2
}
+ return userId1 + "__" + userId2
}
func GetGroupDisplayNameFromUsers(users []*User, truncate bool) string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_count.go b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_count.go
index 11ddeec4..6230ab3d 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_count.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_count.go
@@ -14,11 +14,12 @@ import (
type ChannelCounts struct {
Counts map[string]int64 `json:"counts"`
+ CountsRoot map[string]int64 `json:"counts_root"`
UpdateTimes map[string]int64 `json:"update_times"`
}
func (o *ChannelCounts) Etag() string {
-
+ // we don't include CountsRoot in ETag calculation, since it's a deriviative
ids := []string{}
for id := range o.Counts {
ids = append(ids, id)
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_list.go b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_list.go
index b47077ae..4ba9e5c3 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_list.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_list.go
@@ -11,11 +11,11 @@ import (
type ChannelList []*Channel
func (o *ChannelList) ToJson() string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func (o *ChannelList) Etag() string {
@@ -55,11 +55,11 @@ func ChannelSliceFromJson(data io.Reader) []*Channel {
type ChannelListWithTeamData []*ChannelWithTeamData
func (o *ChannelListWithTeamData) ToJson() string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func (o *ChannelListWithTeamData) Etag() string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_member.go b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_member.go
index d7a76e2d..bc02881e 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_member.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_member.go
@@ -24,36 +24,42 @@ const (
)
type ChannelUnread struct {
- TeamId string `json:"team_id"`
- ChannelId string `json:"channel_id"`
- MsgCount int64 `json:"msg_count"`
- MentionCount int64 `json:"mention_count"`
- NotifyProps StringMap `json:"-"`
+ TeamId string `json:"team_id"`
+ ChannelId string `json:"channel_id"`
+ MsgCount int64 `json:"msg_count"`
+ MentionCount int64 `json:"mention_count"`
+ MentionCountRoot int64 `json:"mention_count_root"`
+ MsgCountRoot int64 `json:"msg_count_root"`
+ NotifyProps StringMap `json:"-"`
}
type ChannelUnreadAt struct {
- TeamId string `json:"team_id"`
- UserId string `json:"user_id"`
- ChannelId string `json:"channel_id"`
- MsgCount int64 `json:"msg_count"`
- MentionCount int64 `json:"mention_count"`
- LastViewedAt int64 `json:"last_viewed_at"`
- NotifyProps StringMap `json:"-"`
+ TeamId string `json:"team_id"`
+ UserId string `json:"user_id"`
+ ChannelId string `json:"channel_id"`
+ MsgCount int64 `json:"msg_count"`
+ MentionCount int64 `json:"mention_count"`
+ MentionCountRoot int64 `json:"mention_count_root"`
+ MsgCountRoot int64 `json:"msg_count_root"`
+ LastViewedAt int64 `json:"last_viewed_at"`
+ NotifyProps StringMap `json:"-"`
}
type ChannelMember struct {
- ChannelId string `json:"channel_id"`
- UserId string `json:"user_id"`
- Roles string `json:"roles"`
- LastViewedAt int64 `json:"last_viewed_at"`
- MsgCount int64 `json:"msg_count"`
- MentionCount int64 `json:"mention_count"`
- NotifyProps StringMap `json:"notify_props"`
- LastUpdateAt int64 `json:"last_update_at"`
- SchemeGuest bool `json:"scheme_guest"`
- SchemeUser bool `json:"scheme_user"`
- SchemeAdmin bool `json:"scheme_admin"`
- ExplicitRoles string `json:"explicit_roles"`
+ ChannelId string `json:"channel_id"`
+ UserId string `json:"user_id"`
+ Roles string `json:"roles"`
+ LastViewedAt int64 `json:"last_viewed_at"`
+ MsgCount int64 `json:"msg_count"`
+ MentionCount int64 `json:"mention_count"`
+ MentionCountRoot int64 `json:"mention_count_root"`
+ MsgCountRoot int64 `json:"msg_count_root"`
+ NotifyProps StringMap `json:"notify_props"`
+ LastUpdateAt int64 `json:"last_update_at"`
+ SchemeGuest bool `json:"scheme_guest"`
+ SchemeUser bool `json:"scheme_user"`
+ SchemeAdmin bool `json:"scheme_admin"`
+ ExplicitRoles string `json:"explicit_roles"`
}
type ChannelMembers []ChannelMember
@@ -65,11 +71,11 @@ type ChannelMemberForExport struct {
}
func (o *ChannelMembers) ToJson() string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func (o *ChannelUnread) ToJson() string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go
index 87fd3aef..51e11736 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_search.go
@@ -11,18 +11,19 @@ import (
const CHANNEL_SEARCH_DEFAULT_LIMIT = 50
type ChannelSearch struct {
- Term string `json:"term"`
- ExcludeDefaultChannels bool `json:"exclude_default_channels"`
- NotAssociatedToGroup string `json:"not_associated_to_group"`
- TeamIds []string `json:"team_ids"`
- GroupConstrained bool `json:"group_constrained"`
- ExcludeGroupConstrained bool `json:"exclude_group_constrained"`
- Public bool `json:"public"`
- Private bool `json:"private"`
- IncludeDeleted bool `json:"include_deleted"`
- Deleted bool `json:"deleted"`
- Page *int `json:"page,omitempty"`
- PerPage *int `json:"per_page,omitempty"`
+ Term string `json:"term"`
+ ExcludeDefaultChannels bool `json:"exclude_default_channels"`
+ NotAssociatedToGroup string `json:"not_associated_to_group"`
+ TeamIds []string `json:"team_ids"`
+ GroupConstrained bool `json:"group_constrained"`
+ ExcludeGroupConstrained bool `json:"exclude_group_constrained"`
+ ExcludePolicyConstrained bool `json:"exclude_policy_constrained"`
+ Public bool `json:"public"`
+ Private bool `json:"private"`
+ IncludeDeleted bool `json:"include_deleted"`
+ Deleted bool `json:"deleted"`
+ Page *int `json:"page,omitempty"`
+ PerPage *int `json:"per_page,omitempty"`
}
// ToJson convert a Channel to a json string
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_sidebar.go b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_sidebar.go
index 033432c9..35301d1e 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_sidebar.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_sidebar.go
@@ -47,6 +47,7 @@ type SidebarCategory struct {
Type SidebarCategoryType `json:"type"`
DisplayName string `json:"display_name"`
Muted bool `json:"muted"`
+ Collapsed bool `json:"collapsed"`
}
// SidebarCategoryWithChannels combines data from SidebarCategory table with the Channel IDs that belong to that category
@@ -97,19 +98,19 @@ func (o SidebarCategoryWithChannels) ToJson() []byte {
}
func SidebarCategoriesWithChannelsToJson(o []*SidebarCategoryWithChannels) []byte {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return []byte("[]")
- } else {
- return b
}
+ return b
}
func (o OrderedSidebarCategories) ToJson() []byte {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return []byte("[]")
- } else {
- return b
}
+ return b
}
var categoryIdPattern = regexp.MustCompile("(favorites|channels|direct_messages)_[a-z0-9]{26}_[a-z0-9]{26}")
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_view.go b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_view.go
index 42fcac3a..2ba74434 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/channel_view.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/channel_view.go
@@ -9,8 +9,9 @@ import (
)
type ChannelView struct {
- ChannelId string `json:"channel_id"`
- PrevChannelId string `json:"prev_channel_id"`
+ ChannelId string `json:"channel_id"`
+ PrevChannelId string `json:"prev_channel_id"`
+ CollapsedThreadsSupported bool `json:"collapsed_threads_supported"`
}
func (o *ChannelView) ToJson() string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/client4.go b/vendor/github.com/mattermost/mattermost-server/v5/model/client4.go
index 8ebf0da1..0b9e713a 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/client4.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/client4.go
@@ -19,25 +19,29 @@ import (
)
const (
- HEADER_REQUEST_ID = "X-Request-ID"
- HEADER_VERSION_ID = "X-Version-ID"
- HEADER_CLUSTER_ID = "X-Cluster-ID"
- HEADER_ETAG_SERVER = "ETag"
- HEADER_ETAG_CLIENT = "If-None-Match"
- HEADER_FORWARDED = "X-Forwarded-For"
- HEADER_REAL_IP = "X-Real-IP"
- HEADER_FORWARDED_PROTO = "X-Forwarded-Proto"
- HEADER_TOKEN = "token"
- HEADER_CSRF_TOKEN = "X-CSRF-Token"
- HEADER_BEARER = "BEARER"
- HEADER_AUTH = "Authorization"
- HEADER_REQUESTED_WITH = "X-Requested-With"
- HEADER_REQUESTED_WITH_XML = "XMLHttpRequest"
- STATUS = "status"
- STATUS_OK = "OK"
- STATUS_FAIL = "FAIL"
- STATUS_UNHEALTHY = "UNHEALTHY"
- STATUS_REMOVE = "REMOVE"
+ HEADER_REQUEST_ID = "X-Request-ID"
+ HEADER_VERSION_ID = "X-Version-ID"
+ HEADER_CLUSTER_ID = "X-Cluster-ID"
+ HEADER_ETAG_SERVER = "ETag"
+ HEADER_ETAG_CLIENT = "If-None-Match"
+ HEADER_FORWARDED = "X-Forwarded-For"
+ HEADER_REAL_IP = "X-Real-IP"
+ HEADER_FORWARDED_PROTO = "X-Forwarded-Proto"
+ HEADER_TOKEN = "token"
+ HEADER_CSRF_TOKEN = "X-CSRF-Token"
+ HEADER_BEARER = "BEARER"
+ HEADER_AUTH = "Authorization"
+ HEADER_CLOUD_TOKEN = "X-Cloud-Token"
+ HEADER_REMOTECLUSTER_TOKEN = "X-RemoteCluster-Token"
+ HEADER_REMOTECLUSTER_ID = "X-RemoteCluster-Id"
+ HEADER_REQUESTED_WITH = "X-Requested-With"
+ HEADER_REQUESTED_WITH_XML = "XMLHttpRequest"
+ HEADER_RANGE = "Range"
+ STATUS = "status"
+ STATUS_OK = "OK"
+ STATUS_FAIL = "FAIL"
+ STATUS_UNHEALTHY = "UNHEALTHY"
+ STATUS_REMOVE = "REMOVE"
CLIENT_DIR = "client"
@@ -93,9 +97,8 @@ func (c *Client4) boolString(value bool) string {
if value {
return "true"
- } else {
- return "false"
}
+ return "false"
}
func closeBody(r *http.Response) {
@@ -189,12 +192,12 @@ func (c *Client4) GetUserRoute(userId string) string {
return fmt.Sprintf(c.GetUsersRoute()+"/%v", userId)
}
-func (c *Client4) GetUserThreadsRoute(userId string) string {
- return fmt.Sprintf(c.GetUsersRoute()+"/%v/threads", userId)
+func (c *Client4) GetUserThreadsRoute(userID, teamID string) string {
+ return c.GetUserRoute(userID) + c.GetTeamRoute(teamID) + "/threads"
}
-func (c *Client4) GetUserThreadRoute(userId, threadId string) string {
- return fmt.Sprintf(c.GetUserThreadsRoute(userId)+"/%v", threadId)
+func (c *Client4) GetUserThreadRoute(userId, teamId, threadId string) string {
+ return c.GetUserThreadsRoute(userId, teamId) + "/" + threadId
}
func (c *Client4) GetUserCategoryRoute(userID, teamID string) string {
@@ -383,7 +386,11 @@ func (c *Client4) GetComplianceReportsRoute() string {
}
func (c *Client4) GetComplianceReportRoute(reportId string) string {
- return fmt.Sprintf("/compliance/reports/%v", reportId)
+ return fmt.Sprintf("%s/%s", c.GetComplianceReportsRoute(), reportId)
+}
+
+func (c *Client4) GetComplianceReportDownloadRoute(reportId string) string {
+ return fmt.Sprintf("%s/%s/download", c.GetComplianceReportsRoute(), reportId)
}
func (c *Client4) GetOutgoingWebhooksRoute() string {
@@ -422,6 +429,10 @@ func (c *Client4) GetDataRetentionRoute() string {
return "/data_retention"
}
+func (c *Client4) GetDataRetentionPolicyRoute(policyID string) string {
+ return fmt.Sprintf(c.GetDataRetentionRoute()+"/policies/%v", policyID)
+}
+
func (c *Client4) GetElasticsearchRoute() string {
return "/elasticsearch"
}
@@ -542,6 +553,30 @@ func (c *Client4) GetGroupSyncablesRoute(groupID string, syncableType GroupSynca
return fmt.Sprintf("%s/%ss", c.GetGroupRoute(groupID), strings.ToLower(syncableType.String()))
}
+func (c *Client4) GetImportsRoute() string {
+ return "/imports"
+}
+
+func (c *Client4) GetExportsRoute() string {
+ return "/exports"
+}
+
+func (c *Client4) GetExportRoute(name string) string {
+ return fmt.Sprintf(c.GetExportsRoute()+"/%v", name)
+}
+
+func (c *Client4) GetRemoteClusterRoute() string {
+ return "/remotecluster"
+}
+
+func (c *Client4) GetSharedChannelsRoute() string {
+ return "/sharedchannels"
+}
+
+func (c *Client4) GetPermissionsRoute() string {
+ return "/permissions"
+}
+
func (c *Client4) DoApiGet(url string, etag string) (*http.Response, *AppError) {
return c.DoApiRequest(http.MethodGet, c.ApiUrl+url, "", etag)
}
@@ -550,6 +585,14 @@ func (c *Client4) DoApiPost(url string, data string) (*http.Response, *AppError)
return c.DoApiRequest(http.MethodPost, c.ApiUrl+url, data, "")
}
+func (c *Client4) doApiDeleteBytes(url string, data []byte) (*http.Response, *AppError) {
+ return c.doApiRequestBytes(http.MethodDelete, c.ApiUrl+url, data, "")
+}
+
+func (c *Client4) doApiPatchBytes(url string, data []byte) (*http.Response, *AppError) {
+ return c.doApiRequestBytes(http.MethodPatch, c.ApiUrl+url, data, "")
+}
+
func (c *Client4) doApiPostBytes(url string, data []byte) (*http.Response, *AppError) {
return c.doApiRequestBytes(http.MethodPost, c.ApiUrl+url, data, "")
}
@@ -567,24 +610,28 @@ func (c *Client4) DoApiDelete(url string) (*http.Response, *AppError) {
}
func (c *Client4) DoApiRequest(method, url, data, etag string) (*http.Response, *AppError) {
- return c.doApiRequestReader(method, url, strings.NewReader(data), etag)
+ return c.doApiRequestReader(method, url, strings.NewReader(data), map[string]string{HEADER_ETAG_CLIENT: etag})
+}
+
+func (c *Client4) DoApiRequestWithHeaders(method, url, data string, headers map[string]string) (*http.Response, *AppError) {
+ return c.doApiRequestReader(method, url, strings.NewReader(data), headers)
}
func (c *Client4) doApiRequestBytes(method, url string, data []byte, etag string) (*http.Response, *AppError) {
- return c.doApiRequestReader(method, url, bytes.NewReader(data), etag)
+ return c.doApiRequestReader(method, url, bytes.NewReader(data), map[string]string{HEADER_ETAG_CLIENT: etag})
}
-func (c *Client4) doApiRequestReader(method, url string, data io.Reader, etag string) (*http.Response, *AppError) {
+func (c *Client4) doApiRequestReader(method, url string, data io.Reader, headers map[string]string) (*http.Response, *AppError) {
rq, err := http.NewRequest(method, url, data)
if err != nil {
return nil, NewAppError(url, "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)
}
- if len(etag) > 0 {
- rq.Header.Set(HEADER_ETAG_CLIENT, etag)
+ for k, v := range headers {
+ rq.Header.Set(k, v)
}
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -625,7 +672,7 @@ func (c *Client4) doUploadFile(url string, body io.Reader, contentType string, c
}
rq.Header.Set("Content-Type", contentType)
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -649,7 +696,7 @@ func (c *Client4) DoEmojiUploadFile(url string, data []byte, contentType string)
}
rq.Header.Set("Content-Type", contentType)
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -673,7 +720,7 @@ func (c *Client4) DoUploadImportTeam(url string, data []byte, contentType string
}
rq.Header.Set("Content-Type", contentType)
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -1393,14 +1440,20 @@ func (c *Client4) AttachDeviceId(deviceId string) (bool, *Response) {
// GetTeamsUnreadForUser will return an array with TeamUnread objects that contain the amount
// of unread messages and mentions the current user has for the teams it belongs to.
-// An optional team ID can be set to exclude that team from the results. Must be authenticated.
-func (c *Client4) GetTeamsUnreadForUser(userId, teamIdToExclude string) ([]*TeamUnread, *Response) {
- var optional string
+// An optional team ID can be set to exclude that team from the results.
+// An optional boolean can be set to include collapsed thread unreads. Must be authenticated.
+func (c *Client4) GetTeamsUnreadForUser(userId, teamIdToExclude string, includeCollapsedThreads bool) ([]*TeamUnread, *Response) {
+ query := url.Values{}
+
if teamIdToExclude != "" {
- optional += fmt.Sprintf("?exclude_team=%s", url.QueryEscape(teamIdToExclude))
+ query.Set("exclude_team", teamIdToExclude)
+ }
+
+ if includeCollapsedThreads {
+ query.Set("include_collapsed_threads", "true")
}
- r, err := c.DoApiGet(c.GetUserRoute(userId)+"/teams/unread"+optional, "")
+ r, err := c.DoApiGet(c.GetUserRoute(userId)+"/teams/unread?"+query.Encode(), "")
if err != nil {
return nil, BuildErrorResponse(r, err)
}
@@ -1486,7 +1539,7 @@ func (c *Client4) SetProfileImage(userId string, data []byte) (bool, *Response)
}
rq.Header.Set("Content-Type", writer.FormDataContentType())
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -1735,7 +1788,7 @@ func (c *Client4) SetBotIconImage(botUserId string, data []byte) (bool, *Respons
}
rq.Header.Set("Content-Type", writer.FormDataContentType())
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -1822,6 +1875,18 @@ func (c *Client4) GetAllTeamsWithTotalCount(etag string, page int, perPage int)
return teamsListWithCount.Teams, teamsListWithCount.TotalCount, BuildResponse(r)
}
+// GetAllTeamsExcludePolicyConstrained returns all teams which are not part of a data retention policy.
+// Must be a system administrator.
+func (c *Client4) GetAllTeamsExcludePolicyConstrained(etag string, page int, perPage int) ([]*Team, *Response) {
+ query := fmt.Sprintf("?page=%v&per_page=%v&exclude_policy_constrained=%v", page, perPage, true)
+ r, err := c.DoApiGet(c.GetTeamsRoute()+query, etag)
+ if err != nil {
+ return nil, BuildErrorResponse(r, err)
+ }
+ defer closeBody(r)
+ return TeamListFromJson(r.Body), BuildResponse(r)
+}
+
// GetTeamByName returns a team based on the provided team name string.
func (c *Client4) GetTeamByName(name, etag string) (*Team, *Response) {
r, err := c.DoApiGet(c.GetTeamByNameRoute(name), etag)
@@ -2269,7 +2334,7 @@ func (c *Client4) SetTeamIcon(teamId string, data []byte) (bool, *Response) {
}
rq.Header.Set("Content-Type", writer.FormDataContentType())
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -2316,16 +2381,23 @@ func (c *Client4) RemoveTeamIcon(teamId string) (bool, *Response) {
// GetAllChannels get all the channels. Must be a system administrator.
func (c *Client4) GetAllChannels(page int, perPage int, etag string) (*ChannelListWithTeamData, *Response) {
- return c.getAllChannels(page, perPage, etag, false)
+ return c.getAllChannels(page, perPage, etag, ChannelSearchOpts{})
}
// GetAllChannelsIncludeDeleted get all the channels. Must be a system administrator.
func (c *Client4) GetAllChannelsIncludeDeleted(page int, perPage int, etag string) (*ChannelListWithTeamData, *Response) {
- return c.getAllChannels(page, perPage, etag, true)
+ return c.getAllChannels(page, perPage, etag, ChannelSearchOpts{IncludeDeleted: true})
+}
+
+// GetAllChannelsExcludePolicyConstrained gets all channels which are not part of a data retention policy.
+// Must be a system administrator.
+func (c *Client4) GetAllChannelsExcludePolicyConstrained(page, perPage int, etag string) (*ChannelListWithTeamData, *Response) {
+ return c.getAllChannels(page, perPage, etag, ChannelSearchOpts{ExcludePolicyConstrained: true})
}
-func (c *Client4) getAllChannels(page int, perPage int, etag string, includeDeleted bool) (*ChannelListWithTeamData, *Response) {
- query := fmt.Sprintf("?page=%v&per_page=%v&include_deleted=%v", page, perPage, includeDeleted)
+func (c *Client4) getAllChannels(page int, perPage int, etag string, opts ChannelSearchOpts) (*ChannelListWithTeamData, *Response) {
+ query := fmt.Sprintf("?page=%v&per_page=%v&include_deleted=%v&exclude_policy_constrained=%v",
+ page, perPage, opts.IncludeDeleted, opts.ExcludePolicyConstrained)
r, err := c.DoApiGet(c.GetChannelsRoute()+query, etag)
if err != nil {
return nil, BuildErrorResponse(r, err)
@@ -2849,8 +2921,9 @@ func (c *Client4) PatchPost(postId string, patch *PostPatch) (*Post, *Response)
}
// SetPostUnread marks channel where post belongs as unread on the time of the provided post.
-func (c *Client4) SetPostUnread(userId string, postId string) *Response {
- r, err := c.DoApiPost(c.GetUserRoute(userId)+c.GetPostRoute(postId)+"/set_unread", "")
+func (c *Client4) SetPostUnread(userId string, postId string, collapsedThreadsSupported bool) *Response {
+ b, _ := json.Marshal(map[string]bool{"collapsed_threads_supported": collapsedThreadsSupported})
+ r, err := c.DoApiPost(c.GetUserRoute(userId)+c.GetPostRoute(postId)+"/set_unread", string(b))
if err != nil {
return BuildErrorResponse(r, err)
}
@@ -2899,8 +2972,12 @@ func (c *Client4) DeletePost(postId string) (bool, *Response) {
}
// GetPostThread gets a post with all the other posts in the same thread.
-func (c *Client4) GetPostThread(postId string, etag string) (*PostList, *Response) {
- r, err := c.DoApiGet(c.GetPostRoute(postId)+"/thread", etag)
+func (c *Client4) GetPostThread(postId string, etag string, collapsedThreads bool) (*PostList, *Response) {
+ url := c.GetPostRoute(postId) + "/thread"
+ if collapsedThreads {
+ url += "?collapsedThreads=true"
+ }
+ r, err := c.DoApiGet(url, etag)
if err != nil {
return nil, BuildErrorResponse(r, err)
}
@@ -2909,8 +2986,11 @@ func (c *Client4) GetPostThread(postId string, etag string) (*PostList, *Respons
}
// GetPostsForChannel gets a page of posts with an array for ordering for a channel.
-func (c *Client4) GetPostsForChannel(channelId string, page, perPage int, etag string) (*PostList, *Response) {
+func (c *Client4) GetPostsForChannel(channelId string, page, perPage int, etag string, collapsedThreads bool) (*PostList, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v", page, perPage)
+ if collapsedThreads {
+ query += "&collapsedThreads=true"
+ }
r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, etag)
if err != nil {
return nil, BuildErrorResponse(r, err)
@@ -2961,8 +3041,11 @@ func (c *Client4) GetFlaggedPostsForUserInChannel(userId string, channelId strin
}
// GetPostsSince gets posts created after a specified time as Unix time in milliseconds.
-func (c *Client4) GetPostsSince(channelId string, time int64) (*PostList, *Response) {
+func (c *Client4) GetPostsSince(channelId string, time int64, collapsedThreads bool) (*PostList, *Response) {
query := fmt.Sprintf("?since=%v", time)
+ if collapsedThreads {
+ query += "&collapsedThreads=true"
+ }
r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, "")
if err != nil {
return nil, BuildErrorResponse(r, err)
@@ -2972,8 +3055,11 @@ func (c *Client4) GetPostsSince(channelId string, time int64) (*PostList, *Respo
}
// GetPostsAfter gets a page of posts that were posted after the post provided.
-func (c *Client4) GetPostsAfter(channelId, postId string, page, perPage int, etag string) (*PostList, *Response) {
+func (c *Client4) GetPostsAfter(channelId, postId string, page, perPage int, etag string, collapsedThreads bool) (*PostList, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v&after=%v", page, perPage, postId)
+ if collapsedThreads {
+ query += "&collapsedThreads=true"
+ }
r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, etag)
if err != nil {
return nil, BuildErrorResponse(r, err)
@@ -2983,8 +3069,11 @@ func (c *Client4) GetPostsAfter(channelId, postId string, page, perPage int, eta
}
// GetPostsBefore gets a page of posts that were posted before the post provided.
-func (c *Client4) GetPostsBefore(channelId, postId string, page, perPage int, etag string) (*PostList, *Response) {
+func (c *Client4) GetPostsBefore(channelId, postId string, page, perPage int, etag string, collapsedThreads bool) (*PostList, *Response) {
query := fmt.Sprintf("?page=%v&per_page=%v&before=%v", page, perPage, postId)
+ if collapsedThreads {
+ query += "&collapsedThreads=true"
+ }
r, err := c.DoApiGet(c.GetChannelRoute(channelId)+"/posts"+query, etag)
if err != nil {
return nil, BuildErrorResponse(r, err)
@@ -2994,14 +3083,36 @@ func (c *Client4) GetPostsBefore(channelId, postId string, page, perPage int, et
}
// GetPostsAroundLastUnread gets a list of posts around last unread post by a user in a channel.
-func (c *Client4) GetPostsAroundLastUnread(userId, channelId string, limitBefore, limitAfter int) (*PostList, *Response) {
+func (c *Client4) GetPostsAroundLastUnread(userId, channelId string, limitBefore, limitAfter int, collapsedThreads bool) (*PostList, *Response) {
query := fmt.Sprintf("?limit_before=%v&limit_after=%v", limitBefore, limitAfter)
- if r, err := c.DoApiGet(c.GetUserRoute(userId)+c.GetChannelRoute(channelId)+"/posts/unread"+query, ""); err != nil {
+ if collapsedThreads {
+ query += "&collapsedThreads=true"
+ }
+ r, err := c.DoApiGet(c.GetUserRoute(userId)+c.GetChannelRoute(channelId)+"/posts/unread"+query, "")
+ if err != nil {
return nil, BuildErrorResponse(r, err)
- } else {
- defer closeBody(r)
- return PostListFromJson(r.Body), BuildResponse(r)
}
+ defer closeBody(r)
+ return PostListFromJson(r.Body), BuildResponse(r)
+}
+
+// SearchFiles returns any posts with matching terms string.
+func (c *Client4) SearchFiles(teamId string, terms string, isOrSearch bool) (*FileInfoList, *Response) {
+ params := SearchParameter{
+ Terms: &terms,
+ IsOrSearch: &isOrSearch,
+ }
+ return c.SearchFilesWithParams(teamId, &params)
+}
+
+// SearchFilesWithParams returns any posts with matching terms string.
+func (c *Client4) SearchFilesWithParams(teamId string, params *SearchParameter) (*FileInfoList, *Response) {
+ r, err := c.DoApiPost(c.GetTeamRoute(teamId)+"/files/search", params.SearchParameterToJson())
+ if err != nil {
+ return nil, BuildErrorResponse(r, err)
+ }
+ defer closeBody(r)
+ return FileInfoListFromJson(r.Body), BuildResponse(r)
}
// SearchPosts returns any posts with matching terms string.
@@ -3251,6 +3362,21 @@ func (c *Client4) GetFileInfosForPost(postId string, etag string) ([]*FileInfo,
// General/System Section
+// GenerateSupportPacket downloads the generated support packet
+func (c *Client4) GenerateSupportPacket() ([]byte, *Response) {
+ r, appErr := c.DoApiGet(c.GetSystemRoute()+"/support_packet", "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+
+ data, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ return nil, BuildErrorResponse(r, NewAppError("GetFile", "model.client.read_job_result_file.app_error", nil, err.Error(), r.StatusCode))
+ }
+ return data, BuildResponse(r)
+}
+
// GetPing will return ok if the running goRoutines are below the threshold and unhealthy for above.
func (c *Client4) GetPing() (string, *Response) {
r, err := c.DoApiGet(c.GetSystemRoute()+"/ping", "")
@@ -3448,7 +3574,7 @@ func (c *Client4) UploadLicenseFile(data []byte) (bool, *Response) {
}
rq.Header.Set("Content-Type", writer.FormDataContentType())
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -3815,6 +3941,28 @@ func (c *Client4) GetSamlMetadataFromIdp(samlMetadataURL string) (*SamlMetadataR
return SamlMetadataResponseFromJson(r.Body), BuildResponse(r)
}
+// ResetSamlAuthDataToEmail resets the AuthData field of SAML users to their Email.
+func (c *Client4) ResetSamlAuthDataToEmail(includeDeleted bool, dryRun bool, userIDs []string) (int64, *Response) {
+ params := map[string]interface{}{
+ "include_deleted": includeDeleted,
+ "dry_run": dryRun,
+ "user_ids": userIDs,
+ }
+ b, _ := json.Marshal(params)
+ r, err := c.doApiPostBytes(c.GetSamlRoute()+"/reset_auth_data", b)
+ if err != nil {
+ return 0, BuildErrorResponse(r, err)
+ }
+ defer closeBody(r)
+ respBody := map[string]int64{}
+ jsonErr := json.NewDecoder(r.Body).Decode(&respBody)
+ if jsonErr != nil {
+ appErr := NewAppError("Api4.ResetSamlAuthDataToEmail", "api.marshal_error", nil, err.Error(), http.StatusInternalServerError)
+ return 0, BuildErrorResponse(r, appErr)
+ }
+ return respBody["num_affected"], BuildResponse(r)
+}
+
// Compliance Section
// CreateComplianceReport creates an incoming webhook for a channel.
@@ -3850,12 +3998,12 @@ func (c *Client4) GetComplianceReport(reportId string) (*Compliance, *Response)
// DownloadComplianceReport returns a full compliance report as a file.
func (c *Client4) DownloadComplianceReport(reportId string) ([]byte, *Response) {
- rq, err := http.NewRequest("GET", c.ApiUrl+c.GetComplianceReportRoute(reportId), nil)
+ rq, err := http.NewRequest("GET", c.ApiUrl+c.GetComplianceReportDownloadRoute(reportId), nil)
if err != nil {
return nil, &Response{Error: NewAppError("DownloadComplianceReport", "model.client.connecting.app_error", nil, err.Error(), http.StatusBadRequest)}
}
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, "BEARER "+c.AuthToken)
}
@@ -3892,8 +4040,13 @@ func (c *Client4) GetClusterStatus() ([]*ClusterInfo, *Response) {
// LDAP Section
// SyncLdap will force a sync with the configured LDAP server.
-func (c *Client4) SyncLdap() (bool, *Response) {
- r, err := c.DoApiPost(c.GetLdapRoute()+"/sync", "")
+// If includeRemovedMembers is true, then group members who left or were removed from a
+// synced team/channel will be re-joined; otherwise, they will be excluded.
+func (c *Client4) SyncLdap(includeRemovedMembers bool) (bool, *Response) {
+ reqBody, _ := json.Marshal(map[string]interface{}{
+ "include_removed_members": includeRemovedMembers,
+ })
+ r, err := c.doApiPostBytes(c.GetLdapRoute()+"/sync", reqBody)
if err != nil {
return false, BuildErrorResponse(r, err)
}
@@ -4225,7 +4378,7 @@ func (c *Client4) UploadBrandImage(data []byte) (bool, *Response) {
}
rq.Header.Set("Content-Type", writer.FormDataContentType())
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -4380,7 +4533,7 @@ func (c *Client4) GetOAuthAccessToken(data url.Values) (*AccessResponse, *Respon
}
rq.Header.Set("Content-Type", "application/x-www-form-urlencoded")
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -4434,14 +4587,236 @@ func (c *Client4) PurgeBleveIndexes() (bool, *Response) {
// Data Retention Section
-// GetDataRetentionPolicy will get the current server data retention policy details.
-func (c *Client4) GetDataRetentionPolicy() (*DataRetentionPolicy, *Response) {
+// GetDataRetentionPolicy will get the current global data retention policy details.
+func (c *Client4) GetDataRetentionPolicy() (*GlobalRetentionPolicy, *Response) {
r, err := c.DoApiGet(c.GetDataRetentionRoute()+"/policy", "")
if err != nil {
return nil, BuildErrorResponse(r, err)
}
defer closeBody(r)
- return DataRetentionPolicyFromJson(r.Body), BuildResponse(r)
+ return GlobalRetentionPolicyFromJson(r.Body), BuildResponse(r)
+}
+
+// GetDataRetentionPolicyByID will get the details for the granular data retention policy with the specified ID.
+func (c *Client4) GetDataRetentionPolicyByID(policyID string) (*RetentionPolicyWithTeamAndChannelCounts, *Response) {
+ r, appErr := c.DoApiGet(c.GetDataRetentionPolicyRoute(policyID), "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ policy, err := RetentionPolicyWithTeamAndChannelCountsFromJson(r.Body)
+ if err != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.GetDataRetentionPolicyByID", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
+ }
+ return policy, BuildResponse(r)
+}
+
+// GetDataRetentionPoliciesCount will get the total number of granular data retention policies.
+func (c *Client4) GetDataRetentionPoliciesCount() (int64, *Response) {
+ type CountBody struct {
+ TotalCount int64 `json:"total_count"`
+ }
+ r, appErr := c.DoApiGet(c.GetDataRetentionRoute()+"/policies_count", "")
+ if appErr != nil {
+ return 0, BuildErrorResponse(r, appErr)
+ }
+ var countObj CountBody
+ jsonErr := json.NewDecoder(r.Body).Decode(&countObj)
+ if jsonErr != nil {
+ return 0, BuildErrorResponse(r, NewAppError("Client4.GetDataRetentionPoliciesCount", "model.utils.decode_json.app_error", nil, jsonErr.Error(), r.StatusCode))
+ }
+ return countObj.TotalCount, BuildResponse(r)
+}
+
+// GetDataRetentionPolicies will get the current granular data retention policies' details.
+func (c *Client4) GetDataRetentionPolicies(page, perPage int) (*RetentionPolicyWithTeamAndChannelCountsList, *Response) {
+ query := fmt.Sprintf("?page=%d&per_page=%d", page, perPage)
+ r, appErr := c.DoApiGet(c.GetDataRetentionRoute()+"/policies"+query, "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ policies, err := RetentionPolicyWithTeamAndChannelCountsListFromJson(r.Body)
+ if err != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.GetDataRetentionPolicies", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
+ }
+ return policies, BuildResponse(r)
+}
+
+// CreateDataRetentionPolicy will create a new granular data retention policy which will be applied to
+// the specified teams and channels. The Id field of `policy` must be empty.
+func (c *Client4) CreateDataRetentionPolicy(policy *RetentionPolicyWithTeamAndChannelIDs) (*RetentionPolicyWithTeamAndChannelCounts, *Response) {
+ r, appErr := c.doApiPostBytes(c.GetDataRetentionRoute()+"/policies", policy.ToJson())
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ newPolicy, err := RetentionPolicyWithTeamAndChannelCountsFromJson(r.Body)
+ if err != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.CreateDataRetentionPolicy", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
+ }
+ return newPolicy, BuildResponse(r)
+}
+
+// DeleteDataRetentionPolicy will delete the granular data retention policy with the specified ID.
+func (c *Client4) DeleteDataRetentionPolicy(policyID string) *Response {
+ r, appErr := c.DoApiDelete(c.GetDataRetentionPolicyRoute(policyID))
+ if appErr != nil {
+ return BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ return BuildResponse(r)
+}
+
+// PatchDataRetentionPolicy will patch the granular data retention policy with the specified ID.
+// The Id field of `patch` must be non-empty.
+func (c *Client4) PatchDataRetentionPolicy(patch *RetentionPolicyWithTeamAndChannelIDs) (*RetentionPolicyWithTeamAndChannelCounts, *Response) {
+ r, appErr := c.doApiPatchBytes(c.GetDataRetentionPolicyRoute(patch.ID), patch.ToJson())
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ policy, err := RetentionPolicyWithTeamAndChannelCountsFromJson(r.Body)
+ if err != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.PatchDataRetentionPolicy", "model.utils.decode_json.app_error", nil, err.Error(), r.StatusCode))
+ }
+ return policy, BuildResponse(r)
+}
+
+// GetTeamsForRetentionPolicy will get the teams to which the specified policy is currently applied.
+func (c *Client4) GetTeamsForRetentionPolicy(policyID string, page, perPage int) (*TeamsWithCount, *Response) {
+ query := fmt.Sprintf("?page=%d&per_page=%d", page, perPage)
+ r, appErr := c.DoApiGet(c.GetDataRetentionPolicyRoute(policyID)+"/teams"+query, "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ var teams *TeamsWithCount
+ jsonErr := json.NewDecoder(r.Body).Decode(&teams)
+ if jsonErr != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.GetTeamsForRetentionPolicy", "model.utils.decode_json.app_error", nil, jsonErr.Error(), r.StatusCode))
+ }
+ return teams, BuildResponse(r)
+}
+
+// SearchTeamsForRetentionPolicy will search the teams to which the specified policy is currently applied.
+func (c *Client4) SearchTeamsForRetentionPolicy(policyID string, term string) ([]*Team, *Response) {
+ body, _ := json.Marshal(map[string]interface{}{"term": term})
+ r, appErr := c.doApiPostBytes(c.GetDataRetentionPolicyRoute(policyID)+"/teams/search", body)
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ var teams []*Team
+ jsonErr := json.NewDecoder(r.Body).Decode(&teams)
+ if jsonErr != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.SearchTeamsForRetentionPolicy", "model.utils.decode_json.app_error", nil, jsonErr.Error(), r.StatusCode))
+ }
+ return teams, BuildResponse(r)
+}
+
+// AddTeamsToRetentionPolicy will add the specified teams to the granular data retention policy
+// with the specified ID.
+func (c *Client4) AddTeamsToRetentionPolicy(policyID string, teamIDs []string) *Response {
+ body, _ := json.Marshal(teamIDs)
+ r, appErr := c.doApiPostBytes(c.GetDataRetentionPolicyRoute(policyID)+"/teams", body)
+ if appErr != nil {
+ return BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ return BuildResponse(r)
+}
+
+// RemoveTeamsFromRetentionPolicy will remove the specified teams from the granular data retention policy
+// with the specified ID.
+func (c *Client4) RemoveTeamsFromRetentionPolicy(policyID string, teamIDs []string) *Response {
+ body, _ := json.Marshal(teamIDs)
+ r, appErr := c.doApiDeleteBytes(c.GetDataRetentionPolicyRoute(policyID)+"/teams", body)
+ if appErr != nil {
+ return BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ return BuildResponse(r)
+}
+
+// GetChannelsForRetentionPolicy will get the channels to which the specified policy is currently applied.
+func (c *Client4) GetChannelsForRetentionPolicy(policyID string, page, perPage int) (*ChannelsWithCount, *Response) {
+ query := fmt.Sprintf("?page=%d&per_page=%d", page, perPage)
+ r, appErr := c.DoApiGet(c.GetDataRetentionPolicyRoute(policyID)+"/channels"+query, "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ var channels *ChannelsWithCount
+ jsonErr := json.NewDecoder(r.Body).Decode(&channels)
+ if jsonErr != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.GetChannelsForRetentionPolicy", "model.utils.decode_json.app_error", nil, jsonErr.Error(), r.StatusCode))
+ }
+ return channels, BuildResponse(r)
+}
+
+// SearchChannelsForRetentionPolicy will search the channels to which the specified policy is currently applied.
+func (c *Client4) SearchChannelsForRetentionPolicy(policyID string, term string) (ChannelListWithTeamData, *Response) {
+ body, _ := json.Marshal(map[string]interface{}{"term": term})
+ r, appErr := c.doApiPostBytes(c.GetDataRetentionPolicyRoute(policyID)+"/channels/search", body)
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ var channels ChannelListWithTeamData
+ jsonErr := json.NewDecoder(r.Body).Decode(&channels)
+ if jsonErr != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.SearchChannelsForRetentionPolicy", "model.utils.decode_json.app_error", nil, jsonErr.Error(), r.StatusCode))
+ }
+ return channels, BuildResponse(r)
+}
+
+// AddChannelsToRetentionPolicy will add the specified channels to the granular data retention policy
+// with the specified ID.
+func (c *Client4) AddChannelsToRetentionPolicy(policyID string, channelIDs []string) *Response {
+ body, _ := json.Marshal(channelIDs)
+ r, appErr := c.doApiPostBytes(c.GetDataRetentionPolicyRoute(policyID)+"/channels", body)
+ if appErr != nil {
+ return BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ return BuildResponse(r)
+}
+
+// RemoveChannelsFromRetentionPolicy will remove the specified channels from the granular data retention policy
+// with the specified ID.
+func (c *Client4) RemoveChannelsFromRetentionPolicy(policyID string, channelIDs []string) *Response {
+ body, _ := json.Marshal(channelIDs)
+ r, appErr := c.doApiDeleteBytes(c.GetDataRetentionPolicyRoute(policyID)+"/channels", body)
+ if appErr != nil {
+ return BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ return BuildResponse(r)
+}
+
+// GetTeamPoliciesForUser will get the data retention policies for the teams to which a user belongs.
+func (c *Client4) GetTeamPoliciesForUser(userID string, offset, limit int) (*RetentionPolicyForTeamList, *Response) {
+ r, appErr := c.DoApiGet(c.GetUserRoute(userID)+"/data_retention/team_policies", "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ var teams RetentionPolicyForTeamList
+ jsonErr := json.NewDecoder(r.Body).Decode(&teams)
+ if jsonErr != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.GetTeamPoliciesForUser", "model.utils.decode_json.app_error", nil, jsonErr.Error(), r.StatusCode))
+ }
+ return &teams, BuildResponse(r)
+}
+
+// GetChannelPoliciesForUser will get the data retention policies for the channels to which a user belongs.
+func (c *Client4) GetChannelPoliciesForUser(userID string, offset, limit int) (*RetentionPolicyForChannelList, *Response) {
+ r, appErr := c.DoApiGet(c.GetUserRoute(userID)+"/data_retention/channel_policies", "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ var channels RetentionPolicyForChannelList
+ jsonErr := json.NewDecoder(r.Body).Decode(&channels)
+ if jsonErr != nil {
+ return nil, BuildErrorResponse(r, NewAppError("Client4.GetChannelPoliciesForUser", "model.utils.decode_json.app_error", nil, jsonErr.Error(), r.StatusCode))
+ }
+ return &channels, BuildResponse(r)
}
// Commands Section
@@ -5019,7 +5394,7 @@ func (c *Client4) uploadPlugin(file io.Reader, force bool) (*Manifest, *Response
}
rq.Header.Set("Content-Type", writer.FormDataContentType())
- if len(c.AuthToken) > 0 {
+ if c.AuthToken != "" {
rq.Header.Set(HEADER_AUTH, c.AuthType+" "+c.AuthToken)
}
@@ -5436,7 +5811,7 @@ func (c *Client4) GetChannelMemberCountsByGroup(channelID string, includeTimezon
// RequestTrialLicense will request a trial license and install it in the server
func (c *Client4) RequestTrialLicense(users int) (bool, *Response) {
- b, _ := json.Marshal(map[string]int{"users": users})
+ b, _ := json.Marshal(map[string]interface{}{"users": users, "terms_accepted": true})
r, err := c.DoApiPost("/trial-license", string(b))
if err != nil {
return false, BuildErrorResponse(r, err)
@@ -5626,7 +6001,7 @@ func (c *Client4) GetUploadsForUser(userId string) ([]*UploadSession, *Response)
// a FileInfo object.
func (c *Client4) UploadData(uploadId string, data io.Reader) (*FileInfo, *Response) {
url := c.GetUploadRoute(uploadId)
- r, err := c.doApiRequestReader("POST", c.ApiUrl+url, data, "")
+ r, err := c.doApiRequestReader("POST", c.ApiUrl+url, data, nil)
if err != nil {
return nil, BuildErrorResponse(r, err)
}
@@ -5710,6 +6085,18 @@ func (c *Client4) GetSubscription() (*Subscription, *Response) {
return subscription, BuildResponse(r)
}
+func (c *Client4) GetSubscriptionStats() (*SubscriptionStats, *Response) {
+ r, appErr := c.DoApiGet(c.GetCloudRoute()+"/subscription/stats", "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+
+ var stats *SubscriptionStats
+ json.NewDecoder(r.Body).Decode(&stats)
+ return stats, BuildResponse(r)
+}
+
func (c *Client4) GetInvoicesForSubscription() ([]*Invoice, *Response) {
r, appErr := c.DoApiGet(c.GetCloudRoute()+"/subscription/invoices", "")
if appErr != nil {
@@ -5753,13 +6140,62 @@ func (c *Client4) UpdateCloudCustomerAddress(address *Address) (*CloudCustomer,
return customer, BuildResponse(r)
}
-func (c *Client4) GetUserThreads(userId string, options GetUserThreadsOpts) (*Threads, *Response) {
+func (c *Client4) ListImports() ([]string, *Response) {
+ r, err := c.DoApiGet(c.GetImportsRoute(), "")
+ if err != nil {
+ return nil, BuildErrorResponse(r, err)
+ }
+ defer closeBody(r)
+ return ArrayFromJson(r.Body), BuildResponse(r)
+}
+
+func (c *Client4) ListExports() ([]string, *Response) {
+ r, err := c.DoApiGet(c.GetExportsRoute(), "")
+ if err != nil {
+ return nil, BuildErrorResponse(r, err)
+ }
+ defer closeBody(r)
+ return ArrayFromJson(r.Body), BuildResponse(r)
+}
+
+func (c *Client4) DeleteExport(name string) (bool, *Response) {
+ r, err := c.DoApiDelete(c.GetExportRoute(name))
+ if err != nil {
+ return false, BuildErrorResponse(r, err)
+ }
+ defer closeBody(r)
+ return CheckStatusOK(r), BuildResponse(r)
+}
+
+func (c *Client4) DownloadExport(name string, wr io.Writer, offset int64) (int64, *Response) {
+ var headers map[string]string
+ if offset > 0 {
+ headers = map[string]string{
+ HEADER_RANGE: fmt.Sprintf("bytes=%d-", offset),
+ }
+ }
+ r, appErr := c.DoApiRequestWithHeaders(http.MethodGet, c.ApiUrl+c.GetExportRoute(name), "", headers)
+ if appErr != nil {
+ return 0, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ n, err := io.Copy(wr, r.Body)
+ if err != nil {
+ return n, BuildErrorResponse(r, NewAppError("DownloadExport", "model.client.copy.app_error", nil, err.Error(), r.StatusCode))
+ }
+ return n, BuildResponse(r)
+}
+
+func (c *Client4) GetUserThreads(userId, teamId string, options GetUserThreadsOpts) (*Threads, *Response) {
v := url.Values{}
if options.Since != 0 {
v.Set("since", fmt.Sprintf("%d", options.Since))
}
- if options.Page != 0 {
- v.Set("page", fmt.Sprintf("%d", options.Page))
+ if options.Before != "" {
+ v.Set("before", options.Before)
+ }
+ if options.After != "" {
+ v.Set("after", options.After)
}
if options.PageSize != 0 {
v.Set("pageSize", fmt.Sprintf("%d", options.PageSize))
@@ -5770,8 +6206,10 @@ func (c *Client4) GetUserThreads(userId string, options GetUserThreadsOpts) (*Th
if options.Deleted {
v.Set("deleted", "true")
}
-
- url := c.GetUserThreadsRoute(userId)
+ if options.Unread {
+ v.Set("unread", "true")
+ }
+ url := c.GetUserThreadsRoute(userId, teamId)
if len(v) > 0 {
url += "?" + v.Encode()
}
@@ -5788,18 +6226,25 @@ func (c *Client4) GetUserThreads(userId string, options GetUserThreadsOpts) (*Th
return &threads, BuildResponse(r)
}
-func (c *Client4) UpdateThreadsReadForUser(userId string, timestamp int64) *Response {
- r, appErr := c.DoApiPut(fmt.Sprintf("%s/read/%d", c.GetUserThreadsRoute(userId), timestamp), "")
+func (c *Client4) GetUserThread(userId, teamId, threadId string, extended bool) (*ThreadResponse, *Response) {
+ url := c.GetUserThreadRoute(userId, teamId, threadId)
+ if extended {
+ url += "?extended=true"
+ }
+ r, appErr := c.DoApiGet(url, "")
if appErr != nil {
- return BuildErrorResponse(r, appErr)
+ return nil, BuildErrorResponse(r, appErr)
}
defer closeBody(r)
- return BuildResponse(r)
+ var thread ThreadResponse
+ json.NewDecoder(r.Body).Decode(&thread)
+
+ return &thread, BuildResponse(r)
}
-func (c *Client4) UpdateThreadReadForUser(userId, threadId string, timestamp int64) *Response {
- r, appErr := c.DoApiPut(fmt.Sprintf("%s/read/%d", c.GetUserThreadRoute(userId, threadId), timestamp), "")
+func (c *Client4) UpdateThreadsReadForUser(userId, teamId string) *Response {
+ r, appErr := c.DoApiPut(fmt.Sprintf("%s/read", c.GetUserThreadsRoute(userId, teamId)), "")
if appErr != nil {
return BuildErrorResponse(r, appErr)
}
@@ -5808,14 +6253,46 @@ func (c *Client4) UpdateThreadReadForUser(userId, threadId string, timestamp int
return BuildResponse(r)
}
-func (c *Client4) UpdateThreadFollowForUser(userId, threadId string, state bool) *Response {
+func (c *Client4) UpdateThreadReadForUser(userId, teamId, threadId string, timestamp int64) (*ThreadResponse, *Response) {
+ r, appErr := c.DoApiPut(fmt.Sprintf("%s/read/%d", c.GetUserThreadRoute(userId, teamId, threadId), timestamp), "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+ var thread ThreadResponse
+ json.NewDecoder(r.Body).Decode(&thread)
+
+ return &thread, BuildResponse(r)
+}
+
+func (c *Client4) UpdateThreadFollowForUser(userId, teamId, threadId string, state bool) *Response {
var appErr *AppError
var r *http.Response
if state {
- r, appErr = c.DoApiPut(c.GetUserThreadRoute(userId, threadId)+"/following", "")
+ r, appErr = c.DoApiPut(c.GetUserThreadRoute(userId, teamId, threadId)+"/following", "")
} else {
- r, appErr = c.DoApiDelete(c.GetUserThreadRoute(userId, threadId) + "/following")
+ r, appErr = c.DoApiDelete(c.GetUserThreadRoute(userId, teamId, threadId) + "/following")
+ }
+ if appErr != nil {
+ return BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+
+ return BuildResponse(r)
+}
+
+func (c *Client4) SendAdminUpgradeRequestEmail() *Response {
+ r, appErr := c.DoApiPost(c.GetCloudRoute()+"/subscription/limitreached/invite", "")
+ if appErr != nil {
+ return BuildErrorResponse(r, appErr)
}
+ defer closeBody(r)
+
+ return BuildResponse(r)
+}
+
+func (c *Client4) SendAdminUpgradeRequestEmailOnJoin() *Response {
+ r, appErr := c.DoApiPost(c.GetCloudRoute()+"/subscription/limitreached/join", "")
if appErr != nil {
return BuildErrorResponse(r, appErr)
}
@@ -5823,3 +6300,44 @@ func (c *Client4) UpdateThreadFollowForUser(userId, threadId string, state bool)
return BuildResponse(r)
}
+
+func (c *Client4) GetAllSharedChannels(teamID string, page, perPage int) ([]*SharedChannel, *Response) {
+ url := fmt.Sprintf("%s/%s?page=%d&per_page=%d", c.GetSharedChannelsRoute(), teamID, page, perPage)
+ r, appErr := c.DoApiGet(url, "")
+ if appErr != nil {
+ return nil, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+
+ var channels []*SharedChannel
+ json.NewDecoder(r.Body).Decode(&channels)
+
+ return channels, BuildResponse(r)
+}
+
+func (c *Client4) GetRemoteClusterInfo(remoteID string) (RemoteClusterInfo, *Response) {
+ url := fmt.Sprintf("%s/remote_info/%s", c.GetSharedChannelsRoute(), remoteID)
+ r, appErr := c.DoApiGet(url, "")
+ if appErr != nil {
+ return RemoteClusterInfo{}, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+
+ var rci RemoteClusterInfo
+ json.NewDecoder(r.Body).Decode(&rci)
+
+ return rci, BuildResponse(r)
+}
+
+func (c *Client4) GetAncillaryPermissions(subsectionPermissions []string) ([]string, *Response) {
+ var returnedPermissions []string
+ url := fmt.Sprintf("%s/ancillary?subsection_permissions=%s", c.GetPermissionsRoute(), strings.Join(subsectionPermissions, ","))
+ r, appErr := c.DoApiGet(url, "")
+ if appErr != nil {
+ return returnedPermissions, BuildErrorResponse(r, appErr)
+ }
+ defer closeBody(r)
+
+ json.NewDecoder(r.Body).Decode(&returnedPermissions)
+ return returnedPermissions, BuildResponse(r)
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/cloud.go b/vendor/github.com/mattermost/mattermost-server/v5/model/cloud.go
index e4fddbcd..ffd85a2a 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/cloud.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/cloud.go
@@ -3,13 +3,53 @@
package model
+import "strings"
+
+const (
+ EventTypeFailedPayment = "failed-payment"
+ EventTypeFailedPaymentNoCard = "failed-payment-no-card"
+ EventTypeSendAdminWelcomeEmail = "send-admin-welcome-email"
+ EventTypeTrialWillEnd = "trial-will-end"
+ EventTypeTrialEnded = "trial-ended"
+ JoinLimitation = "join"
+ InviteLimitation = "invite"
+)
+
+var MockCWS string
+
+type BillingScheme string
+
+const (
+ BillingSchemePerSeat = BillingScheme("per_seat")
+ BillingSchemeFlatFee = BillingScheme("flat_fee")
+)
+
+type RecurringInterval string
+
+const (
+ RecurringIntervalYearly = RecurringInterval("year")
+ RecurringIntervalMonthly = RecurringInterval("month")
+)
+
+type SubscriptionFamily string
+
+const (
+ SubscriptionFamilyCloud = SubscriptionFamily("cloud")
+ SubscriptionFamilyOnPrem = SubscriptionFamily("on-prem")
+)
+
// Product model represents a product on the cloud system.
type Product struct {
- ID string `json:"id"`
- Name string `json:"name"`
- Description string `json:"description"`
- PricePerSeat float64 `json:"price_per_seat"`
- AddOns []*AddOn `json:"add_ons"`
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Description string `json:"description"`
+ PricePerSeat float64 `json:"price_per_seat"`
+ AddOns []*AddOn `json:"add_ons"`
+ SKU string `json:"sku"`
+ PriceID string `json:"price_id"`
+ Family SubscriptionFamily `json:"product_family"`
+ RecurringInterval RecurringInterval `json:"recurring_interval"`
+ BillingScheme BillingScheme `json:"billing_scheme"`
}
// AddOn represents an addon to a product.
@@ -85,6 +125,13 @@ type Subscription struct {
DNS string `json:"dns"`
IsPaidTier string `json:"is_paid_tier"`
LastInvoice *Invoice `json:"last_invoice"`
+ IsFreeTrial string `json:"is_free_trial"`
+ TrialEndAt int64 `json:"trial_end_at"`
+}
+
+// GetWorkSpaceNameFromDNS returns the work space name. For example from test.mattermost.cloud.com, it returns test
+func (s *Subscription) GetWorkSpaceNameFromDNS() string {
+ return strings.Split(s.DNS, ".")[0]
}
// Invoice model represents a cloud invoice
@@ -112,3 +159,30 @@ type InvoiceLineItem struct {
Type string `json:"type"`
Metadata map[string]interface{} `json:"metadata"`
}
+
+type CWSWebhookPayload struct {
+ Event string `json:"event"`
+ FailedPayment *FailedPayment `json:"failed_payment"`
+ CloudWorkspaceOwner *CloudWorkspaceOwner `json:"cloud_workspace_owner"`
+ SubscriptionTrialEndUnixTimeStamp int64 `json:"trial_end_time_stamp"`
+}
+
+type FailedPayment struct {
+ CardBrand string `json:"card_brand"`
+ LastFour int `json:"last_four"`
+ FailureMessage string `json:"failure_message"`
+}
+
+// CloudWorkspaceOwner is part of the CWS Webhook payload that contains information about the user that created the workspace from the CWS
+type CloudWorkspaceOwner struct {
+ UserName string `json:"username"`
+}
+type SubscriptionStats struct {
+ RemainingSeats int `json:"remaining_seats"`
+ IsPaidTier string `json:"is_paid_tier"`
+ IsFreeTrial string `json:"is_free_trial"`
+}
+
+type SubscriptionChange struct {
+ ProductID string `json:"product_id"`
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_discovery.go b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_discovery.go
index f6c9275a..758e4980 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_discovery.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_discovery.go
@@ -39,7 +39,7 @@ func (o *ClusterDiscovery) PreSave() {
func (o *ClusterDiscovery) AutoFillHostname() {
// attempt to set the hostname from the OS
- if len(o.Hostname) == 0 {
+ if o.Hostname == "" {
if hn, err := os.Hostname(); err == nil {
o.Hostname = hn
}
@@ -48,8 +48,8 @@ func (o *ClusterDiscovery) AutoFillHostname() {
func (o *ClusterDiscovery) AutoFillIpAddress(iface string, ipAddress string) {
// attempt to set the hostname to the first non-local IP address
- if len(o.Hostname) == 0 {
- if len(ipAddress) > 0 {
+ if o.Hostname == "" {
+ if ipAddress != "" {
o.Hostname = ipAddress
} else {
o.Hostname = GetServerIpAddress(iface)
@@ -93,15 +93,15 @@ func (o *ClusterDiscovery) IsValid() *AppError {
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.id.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.ClusterName) == 0 {
+ if o.ClusterName == "" {
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.name.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.Type) == 0 {
+ if o.Type == "" {
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.type.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.Hostname) == 0 {
+ if o.Hostname == "" {
return NewAppError("ClusterDiscovery.IsValid", "model.cluster.is_valid.hostname.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_info.go b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_info.go
index 82437469..fc15d38c 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_info.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_info.go
@@ -16,15 +16,15 @@ type ClusterInfo struct {
Hostname string `json:"hostname"`
}
-func (me *ClusterInfo) ToJson() string {
- b, _ := json.Marshal(me)
+func (ci *ClusterInfo) ToJson() string {
+ b, _ := json.Marshal(ci)
return string(b)
}
func ClusterInfoFromJson(data io.Reader) *ClusterInfo {
- var me *ClusterInfo
- json.NewDecoder(data).Decode(&me)
- return me
+ var ci *ClusterInfo
+ json.NewDecoder(data).Decode(&ci)
+ return ci
}
func ClusterInfosToJson(objmap []*ClusterInfo) string {
@@ -38,7 +38,6 @@ func ClusterInfosFromJson(data io.Reader) []*ClusterInfo {
var objmap []*ClusterInfo
if err := decoder.Decode(&objmap); err != nil {
return make([]*ClusterInfo, 0)
- } else {
- return objmap
}
+ return objmap
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_message.go b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_message.go
index 529f4a93..bd73ba8d 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_message.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_message.go
@@ -40,6 +40,7 @@ const (
CLUSTER_EVENT_CLEAR_SESSION_CACHE_FOR_ALL_USERS = "inv_all_user_sessions"
CLUSTER_EVENT_INSTALL_PLUGIN = "install_plugin"
CLUSTER_EVENT_REMOVE_PLUGIN = "remove_plugin"
+ CLUSTER_EVENT_PLUGIN_EVENT = "plugin_event"
CLUSTER_EVENT_INVALIDATE_CACHE_FOR_TERMS_OF_SERVICE = "inv_terms_of_service"
CLUSTER_EVENT_BUSY_STATE_CHANGED = "busy_state_change"
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_stats.go b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_stats.go
index afc2ab44..9e8c630c 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_stats.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/cluster_stats.go
@@ -15,13 +15,13 @@ type ClusterStats struct {
TotalMasterDbConnections int `json:"total_master_db_connections"`
}
-func (me *ClusterStats) ToJson() string {
- b, _ := json.Marshal(me)
+func (cs *ClusterStats) ToJson() string {
+ b, _ := json.Marshal(cs)
return string(b)
}
func ClusterStatsFromJson(data io.Reader) *ClusterStats {
- var me *ClusterStats
- json.NewDecoder(data).Decode(&me)
- return me
+ var cs *ClusterStats
+ json.NewDecoder(data).Decode(&cs)
+ return cs
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/command.go b/vendor/github.com/mattermost/mattermost-server/v5/model/command.go
index 0013046b..59a4eee4 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/command.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/command.go
@@ -105,7 +105,7 @@ func (o *Command) IsValid() *AppError {
return NewAppError("Command.IsValid", "model.command.is_valid.trigger.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.URL) == 0 || len(o.URL) > 1024 {
+ if o.URL == "" || len(o.URL) > 1024 {
return NewAppError("Command.IsValid", "model.command.is_valid.url.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go b/vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go
index 15a6372a..45239d2c 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/command_args.go
@@ -7,21 +7,21 @@ import (
"encoding/json"
"io"
- goi18n "github.com/mattermost/go-i18n/i18n"
+ "github.com/mattermost/mattermost-server/v5/shared/i18n"
)
type CommandArgs struct {
- UserId string `json:"user_id"`
- ChannelId string `json:"channel_id"`
- TeamId string `json:"team_id"`
- RootId string `json:"root_id"`
- ParentId string `json:"parent_id"`
- TriggerId string `json:"trigger_id,omitempty"`
- Command string `json:"command"`
- SiteURL string `json:"-"`
- T goi18n.TranslateFunc `json:"-"`
- UserMentions UserMentionMap `json:"-"`
- ChannelMentions ChannelMentionMap `json:"-"`
+ UserId string `json:"user_id"`
+ ChannelId string `json:"channel_id"`
+ TeamId string `json:"team_id"`
+ RootId string `json:"root_id"`
+ ParentId string `json:"parent_id"`
+ TriggerId string `json:"trigger_id,omitempty"`
+ Command string `json:"command"`
+ SiteURL string `json:"-"`
+ T i18n.TranslateFunc `json:"-"`
+ UserMentions UserMentionMap `json:"-"`
+ ChannelMentions ChannelMentionMap `json:"-"`
// DO NOT USE Session field is deprecated. MM-26398
Session Session `json:"-"`
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/command_autocomplete.go b/vendor/github.com/mattermost/mattermost-server/v5/model/command_autocomplete.go
index 68d91b23..f115ed24 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/command_autocomplete.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/command_autocomplete.go
@@ -52,7 +52,7 @@ type AutocompleteArg struct {
HelpText string
// Type of the argument
Type AutocompleteArgType
- // Required determins if argument is optional or not.
+ // Required determines if argument is optional or not.
Required bool
// Actual data of the argument (depends on the Type)
Data interface{}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/command_response.go b/vendor/github.com/mattermost/mattermost-server/v5/model/command_response.go
index 26b6cceb..80cca5ab 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/command_response.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/command_response.go
@@ -62,7 +62,7 @@ func CommandResponseFromJson(data io.Reader) (*CommandResponse, error) {
var o CommandResponse
err = json.Unmarshal(b, &o)
if err != nil {
- return nil, jsonutils.HumanizeJsonError(err, b)
+ return nil, jsonutils.HumanizeJSONError(err, b)
}
o.Attachments = StringifySlackFieldValue(o.Attachments)
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/command_webhook.go b/vendor/github.com/mattermost/mattermost-server/v5/model/command_webhook.go
index 42a16cc7..3757ecc7 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/command_webhook.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/command_webhook.go
@@ -53,11 +53,11 @@ func (o *CommandWebhook) IsValid() *AppError {
return NewAppError("CommandWebhook.IsValid", "model.command_hook.channel_id.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.RootId) != 0 && !IsValidId(o.RootId) {
+ if o.RootId != "" && !IsValidId(o.RootId) {
return NewAppError("CommandWebhook.IsValid", "model.command_hook.root_id.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.ParentId) != 0 && !IsValidId(o.ParentId) {
+ if o.ParentId != "" && !IsValidId(o.ParentId) {
return NewAppError("CommandWebhook.IsValid", "model.command_hook.parent_id.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/compliance.go b/vendor/github.com/mattermost/mattermost-server/v5/model/compliance.go
index a86087c1..0211805e 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/compliance.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/compliance.go
@@ -37,6 +37,19 @@ type Compliance struct {
type Compliances []Compliance
+// ComplianceExportCursor is used for paginated iteration of posts
+// for compliance export.
+// We need to keep track of the last post ID in addition to the last post
+// CreateAt to break ties when two posts have the same CreateAt.
+type ComplianceExportCursor struct {
+ LastChannelsQueryPostCreateAt int64
+ LastChannelsQueryPostID string
+ ChannelsQueryCompleted bool
+ LastDirectMessagesQueryPostCreateAt int64
+ LastDirectMessagesQueryPostID string
+ DirectMessagesQueryCompleted bool
+}
+
func (c *Compliance) ToJson() string {
b, _ := json.Marshal(c)
return string(b)
@@ -58,6 +71,11 @@ func (c *Compliance) PreSave() {
c.CreateAt = GetMillis()
}
+func (c *Compliance) DeepCopy() *Compliance {
+ copy := *c
+ return &copy
+}
+
func (c *Compliance) JobName() string {
jobName := c.Type
if c.Type == COMPLIANCE_TYPE_DAILY {
@@ -79,7 +97,7 @@ func (c *Compliance) IsValid() *AppError {
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
}
- if len(c.Desc) > 512 || len(c.Desc) == 0 {
+ if len(c.Desc) > 512 || c.Desc == "" {
return NewAppError("Compliance.IsValid", "model.compliance.is_valid.desc.app_error", nil, "", http.StatusBadRequest)
}
@@ -105,11 +123,11 @@ func ComplianceFromJson(data io.Reader) *Compliance {
}
func (c Compliances) ToJson() string {
- if b, err := json.Marshal(c); err != nil {
+ b, err := json.Marshal(c)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func CompliancesFromJson(data io.Reader) Compliances {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/compliance_post.go b/vendor/github.com/mattermost/mattermost-server/v5/model/compliance_post.go
index fcf65075..5e18812b 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/compliance_post.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/compliance_post.go
@@ -53,6 +53,7 @@ func CompliancePostHeader() []string {
"UserUsername",
"UserEmail",
"UserNickname",
+ "UserType",
"PostId",
"PostCreateAt",
@@ -66,61 +67,58 @@ func CompliancePostHeader() []string {
"PostProps",
"PostHashtags",
"PostFileIds",
- "UserType",
}
}
func cleanComplianceStrings(in string) string {
if matched, _ := regexp.MatchString("^\\s*(=|\\+|\\-)", in); matched {
return "'" + in
-
- } else {
- return in
}
+ return in
}
-func (me *CompliancePost) Row() []string {
+func (cp *CompliancePost) Row() []string {
postDeleteAt := ""
- if me.PostDeleteAt > 0 {
- postDeleteAt = time.Unix(0, me.PostDeleteAt*int64(1000*1000)).Format(time.RFC3339)
+ if cp.PostDeleteAt > 0 {
+ postDeleteAt = time.Unix(0, cp.PostDeleteAt*int64(1000*1000)).Format(time.RFC3339)
}
postUpdateAt := ""
- if me.PostUpdateAt != me.PostCreateAt {
- postUpdateAt = time.Unix(0, me.PostUpdateAt*int64(1000*1000)).Format(time.RFC3339)
+ if cp.PostUpdateAt != cp.PostCreateAt {
+ postUpdateAt = time.Unix(0, cp.PostUpdateAt*int64(1000*1000)).Format(time.RFC3339)
}
userType := "user"
- if me.IsBot {
+ if cp.IsBot {
userType = "bot"
}
return []string{
- cleanComplianceStrings(me.TeamName),
- cleanComplianceStrings(me.TeamDisplayName),
+ cleanComplianceStrings(cp.TeamName),
+ cleanComplianceStrings(cp.TeamDisplayName),
- cleanComplianceStrings(me.ChannelName),
- cleanComplianceStrings(me.ChannelDisplayName),
- cleanComplianceStrings(me.ChannelType),
+ cleanComplianceStrings(cp.ChannelName),
+ cleanComplianceStrings(cp.ChannelDisplayName),
+ cleanComplianceStrings(cp.ChannelType),
- cleanComplianceStrings(me.UserUsername),
- cleanComplianceStrings(me.UserEmail),
- cleanComplianceStrings(me.UserNickname),
+ cleanComplianceStrings(cp.UserUsername),
+ cleanComplianceStrings(cp.UserEmail),
+ cleanComplianceStrings(cp.UserNickname),
userType,
- me.PostId,
- time.Unix(0, me.PostCreateAt*int64(1000*1000)).Format(time.RFC3339),
+ cp.PostId,
+ time.Unix(0, cp.PostCreateAt*int64(1000*1000)).Format(time.RFC3339),
postUpdateAt,
postDeleteAt,
- me.PostRootId,
- me.PostParentId,
- me.PostOriginalId,
- cleanComplianceStrings(me.PostMessage),
- me.PostType,
- me.PostProps,
- me.PostHashtags,
- me.PostFileIds,
+ cp.PostRootId,
+ cp.PostParentId,
+ cp.PostOriginalId,
+ cleanComplianceStrings(cp.PostMessage),
+ cp.PostType,
+ cp.PostProps,
+ cp.PostHashtags,
+ cp.PostFileIds,
}
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/config.go b/vendor/github.com/mattermost/mattermost-server/v5/model/config.go
index cbdf0f55..548a266e 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/config.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/config.go
@@ -19,7 +19,9 @@ import (
"time"
"github.com/mattermost/ldap"
- "github.com/mattermost/mattermost-server/v5/mlog"
+
+ "github.com/mattermost/mattermost-server/v5/shared/filestore"
+ "github.com/mattermost/mattermost-server/v5/shared/mlog"
)
const (
@@ -31,10 +33,11 @@ const (
IMAGE_DRIVER_LOCAL = "local"
IMAGE_DRIVER_S3 = "amazons3"
- DATABASE_DRIVER_SQLITE = "sqlite3"
DATABASE_DRIVER_MYSQL = "mysql"
DATABASE_DRIVER_POSTGRES = "postgres"
+ SEARCHENGINE_ELASTICSEARCH = "elasticsearch"
+
MINIO_ACCESS_KEY = "minioaccesskey"
MINIO_SECRET_KEY = "miniosecretkey"
MINIO_BUCKET = "mattermost-test"
@@ -45,11 +48,12 @@ const (
SERVICE_GITLAB = "gitlab"
SERVICE_GOOGLE = "google"
SERVICE_OFFICE365 = "office365"
+ SERVICE_OPENID = "openid"
GENERIC_NO_CHANNEL_NOTIFICATION = "generic_no_channel"
GENERIC_NOTIFICATION = "generic"
GENERIC_NOTIFICATION_SERVER = "https://push-test.mattermost.com"
- MM_SUPPORT_ADDRESS = "support@mattermost.com"
+ MM_SUPPORT_ADVISOR_ADDRESS = "support-advisor@mattermost.com"
FULL_NOTIFICATION = "full"
ID_LOADED_NOTIFICATION = "id_loaded"
@@ -83,6 +87,10 @@ const (
GROUP_UNREAD_CHANNELS_DEFAULT_ON = "default_on"
GROUP_UNREAD_CHANNELS_DEFAULT_OFF = "default_off"
+ COLLAPSED_THREADS_DISABLED = "disabled"
+ COLLAPSED_THREADS_DEFAULT_ON = "default_on"
+ COLLAPSED_THREADS_DEFAULT_OFF = "default_off"
+
EMAIL_BATCHING_BUFFER_SIZE = 256
EMAIL_BATCHING_INTERVAL = 30
@@ -113,14 +121,20 @@ const (
FILE_SETTINGS_DEFAULT_DIRECTORY = "./data/"
+ IMPORT_SETTINGS_DEFAULT_DIRECTORY = "./import"
+ IMPORT_SETTINGS_DEFAULT_RETENTION_DAYS = 30
+
+ EXPORT_SETTINGS_DEFAULT_DIRECTORY = "./export"
+ EXPORT_SETTINGS_DEFAULT_RETENTION_DAYS = 30
+
EMAIL_SETTINGS_DEFAULT_FEEDBACK_ORGANIZATION = ""
- SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK = "https://about.mattermost.com/default-terms/"
- SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK = "https://about.mattermost.com/default-privacy-policy/"
+ SUPPORT_SETTINGS_DEFAULT_TERMS_OF_SERVICE_LINK = "https://mattermost.com/terms-of-service/"
+ SUPPORT_SETTINGS_DEFAULT_PRIVACY_POLICY_LINK = "https://mattermost.com/privacy-policy/"
SUPPORT_SETTINGS_DEFAULT_ABOUT_LINK = "https://about.mattermost.com/default-about/"
SUPPORT_SETTINGS_DEFAULT_HELP_LINK = "https://about.mattermost.com/default-help/"
SUPPORT_SETTINGS_DEFAULT_REPORT_A_PROBLEM_LINK = "https://about.mattermost.com/default-report-a-problem/"
- SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL = "feedback@mattermost.com"
+ SUPPORT_SETTINGS_DEFAULT_SUPPORT_EMAIL = ""
SUPPORT_SETTINGS_DEFAULT_RE_ACCEPTANCE_PERIOD = 365
LDAP_SETTINGS_DEFAULT_FIRST_NAME_ATTRIBUTE = ""
@@ -192,6 +206,7 @@ const (
DATA_RETENTION_SETTINGS_DEFAULT_MESSAGE_RETENTION_DAYS = 365
DATA_RETENTION_SETTINGS_DEFAULT_FILE_RETENTION_DAYS = 365
DATA_RETENTION_SETTINGS_DEFAULT_DELETION_JOB_START_TIME = "02:00"
+ DATA_RETENTION_SETTINGS_DEFAULT_BATCH_SIZE = 3000
PLUGIN_SETTINGS_DEFAULT_DIRECTORY = "./plugins"
PLUGIN_SETTINGS_DEFAULT_CLIENT_DIRECTORY = "./client/plugins"
@@ -222,11 +237,17 @@ const (
OFFICE365_SETTINGS_DEFAULT_TOKEN_ENDPOINT = "https://login.microsoftonline.com/common/oauth2/v2.0/token"
OFFICE365_SETTINGS_DEFAULT_USER_API_ENDPOINT = "https://graph.microsoft.com/v1.0/me"
- CLOUD_SETTINGS_DEFAULT_CWS_URL = "https://customers.mattermost.com"
+ CLOUD_SETTINGS_DEFAULT_CWS_URL = "https://customers.mattermost.com"
+ CLOUD_SETTINGS_DEFAULT_CWS_API_URL = "https://portal.internal.prod.cloud.mattermost.com"
+ OPENID_SETTINGS_DEFAULT_SCOPE = "profile openid email"
LOCAL_MODE_SOCKET_PATH = "/var/tmp/mattermost_local.socket"
)
+func GetDefaultAppCustomURLSchemes() []string {
+ return []string{"mmauth://", "mmauthbeta://"}
+}
+
var ServerTLSSupportedCiphers = map[string]uint16{
"TLS_RSA_WITH_RC4_128_SHA": tls.TLS_RSA_WITH_RC4_128_SHA,
"TLS_RSA_WITH_3DES_EDE_CBC_SHA": tls.TLS_RSA_WITH_3DES_EDE_CBC_SHA,
@@ -253,105 +274,108 @@ var ServerTLSSupportedCiphers = map[string]uint16{
}
type ServiceSettings struct {
- SiteURL *string `access:"environment,authentication,write_restrictable"`
+ SiteURL *string `access:"environment_web_server,authentication_saml,write_restrictable"`
WebsocketURL *string `access:"write_restrictable,cloud_restrictable"`
- LicenseFileLocation *string `access:"write_restrictable,cloud_restrictable"`
- ListenAddress *string `access:"environment,write_restrictable,cloud_restrictable"`
- ConnectionSecurity *string `access:"environment,write_restrictable,cloud_restrictable"`
- TLSCertFile *string `access:"environment,write_restrictable,cloud_restrictable"`
- TLSKeyFile *string `access:"environment,write_restrictable,cloud_restrictable"`
- TLSMinVer *string `access:"write_restrictable,cloud_restrictable"`
+ LicenseFileLocation *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
+ ListenAddress *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` // telemetry: none
+ ConnectionSecurity *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ TLSCertFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ TLSKeyFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ TLSMinVer *string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
TLSStrictTransport *bool `access:"write_restrictable,cloud_restrictable"`
- TLSStrictTransportMaxAge *int64 `access:"write_restrictable,cloud_restrictable"`
- TLSOverwriteCiphers []string `access:"write_restrictable,cloud_restrictable"`
- UseLetsEncrypt *bool `access:"environment,write_restrictable,cloud_restrictable"`
- LetsEncryptCertificateCacheFile *string `access:"environment,write_restrictable,cloud_restrictable"`
- Forward80To443 *bool `access:"environment,write_restrictable,cloud_restrictable"`
- TrustedProxyIPHeader []string `access:"write_restrictable,cloud_restrictable"`
- ReadTimeout *int `access:"environment,write_restrictable,cloud_restrictable"`
- WriteTimeout *int `access:"environment,write_restrictable,cloud_restrictable"`
+ TLSStrictTransportMaxAge *int64 `access:"write_restrictable,cloud_restrictable"` // telemetry: none
+ TLSOverwriteCiphers []string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
+ UseLetsEncrypt *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ LetsEncryptCertificateCacheFile *string `access:"environment_web_server,write_restrictable,cloud_restrictable"` // telemetry: none
+ Forward80To443 *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ TrustedProxyIPHeader []string `access:"write_restrictable,cloud_restrictable"` // telemetry: none
+ ReadTimeout *int `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ WriteTimeout *int `access:"environment_web_server,write_restrictable,cloud_restrictable"`
IdleTimeout *int `access:"write_restrictable,cloud_restrictable"`
- MaximumLoginAttempts *int `access:"authentication,write_restrictable,cloud_restrictable"`
- GoroutineHealthThreshold *int `access:"write_restrictable,cloud_restrictable"`
- GoogleDeveloperKey *string `access:"site,write_restrictable,cloud_restrictable"`
- EnableOAuthServiceProvider *bool `access:"integrations"`
- EnableIncomingWebhooks *bool `access:"integrations"`
- EnableOutgoingWebhooks *bool `access:"integrations"`
- EnableCommands *bool `access:"integrations"`
- DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations *bool `json:"EnableOnlyAdminIntegrations" mapstructure:"EnableOnlyAdminIntegrations"` // This field is deprecated and must not be used.
- EnablePostUsernameOverride *bool `access:"integrations"`
- EnablePostIconOverride *bool `access:"integrations"`
- EnableLinkPreviews *bool `access:"site"`
- EnableTesting *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableDeveloper *bool `access:"environment,write_restrictable,cloud_restrictable"`
+ MaximumLoginAttempts *int `access:"authentication_password,write_restrictable,cloud_restrictable"`
+ GoroutineHealthThreshold *int `access:"write_restrictable,cloud_restrictable"` // telemetry: none
+ EnableOAuthServiceProvider *bool `access:"integrations_integration_management"`
+ EnableIncomingWebhooks *bool `access:"integrations_integration_management"`
+ EnableOutgoingWebhooks *bool `access:"integrations_integration_management"`
+ EnableCommands *bool `access:"integrations_integration_management"`
+ EnablePostUsernameOverride *bool `access:"integrations_integration_management"`
+ EnablePostIconOverride *bool `access:"integrations_integration_management"`
+ GoogleDeveloperKey *string `access:"site_posts,write_restrictable,cloud_restrictable"`
+ DEPRECATED_DO_NOT_USE_EnableOnlyAdminIntegrations *bool `json:"EnableOnlyAdminIntegrations" mapstructure:"EnableOnlyAdminIntegrations"` // Deprecated: do not use
+ EnableLinkPreviews *bool `access:"site_posts"`
+ RestrictLinkPreviews *string `access:"site_posts"`
+ EnableTesting *bool `access:"environment_developer,write_restrictable,cloud_restrictable"`
+ EnableDeveloper *bool `access:"environment_developer,write_restrictable,cloud_restrictable"`
EnableOpenTracing *bool `access:"write_restrictable,cloud_restrictable"`
- EnableSecurityFixAlert *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableInsecureOutgoingConnections *bool `access:"environment,write_restrictable,cloud_restrictable"`
- AllowedUntrustedInternalConnections *string `access:"environment,write_restrictable,cloud_restrictable"`
- EnableMultifactorAuthentication *bool `access:"authentication"`
- EnforceMultifactorAuthentication *bool `access:"authentication"`
- EnableUserAccessTokens *bool `access:"integrations"`
- AllowCorsFrom *string `access:"integrations,write_restrictable,cloud_restrictable"`
- CorsExposedHeaders *string `access:"integrations,write_restrictable,cloud_restrictable"`
- CorsAllowCredentials *bool `access:"integrations,write_restrictable,cloud_restrictable"`
- CorsDebug *bool `access:"integrations,write_restrictable,cloud_restrictable"`
+ EnableSecurityFixAlert *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"`
+ EnableInsecureOutgoingConnections *bool `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ AllowedUntrustedInternalConnections *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ EnableMultifactorAuthentication *bool `access:"authentication_mfa"`
+ EnforceMultifactorAuthentication *bool `access:"authentication_mfa"`
+ EnableUserAccessTokens *bool `access:"integrations_integration_management"`
+ AllowCorsFrom *string `access:"integrations_cors,write_restrictable,cloud_restrictable"`
+ CorsExposedHeaders *string `access:"integrations_cors,write_restrictable,cloud_restrictable"`
+ CorsAllowCredentials *bool `access:"integrations_cors,write_restrictable,cloud_restrictable"`
+ CorsDebug *bool `access:"integrations_cors,write_restrictable,cloud_restrictable"`
AllowCookiesForSubdomains *bool `access:"write_restrictable,cloud_restrictable"`
- ExtendSessionLengthWithActivity *bool `access:"environment,write_restrictable,cloud_restrictable"`
- SessionLengthWebInDays *int `access:"environment,write_restrictable,cloud_restrictable"`
- SessionLengthMobileInDays *int `access:"environment,write_restrictable,cloud_restrictable"`
- SessionLengthSSOInDays *int `access:"environment,write_restrictable,cloud_restrictable"`
- SessionCacheInMinutes *int `access:"environment,write_restrictable,cloud_restrictable"`
- SessionIdleTimeoutInMinutes *int `access:"environment,write_restrictable,cloud_restrictable"`
- WebsocketSecurePort *int `access:"write_restrictable,cloud_restrictable"`
- WebsocketPort *int `access:"write_restrictable,cloud_restrictable"`
- WebserverMode *string `access:"environment,write_restrictable,cloud_restrictable"`
- EnableCustomEmoji *bool `access:"site"`
- EnableEmojiPicker *bool `access:"site"`
- EnableGifPicker *bool `access:"integrations"`
- GfycatApiKey *string `access:"integrations"`
- GfycatApiSecret *string `access:"integrations"`
- DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation *string `json:"RestrictCustomEmojiCreation" mapstructure:"RestrictCustomEmojiCreation"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPostDelete *string `json:"RestrictPostDelete" mapstructure:"RestrictPostDelete"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_AllowEditPost *string `json:"AllowEditPost" mapstructure:"AllowEditPost"` // This field is deprecated and must not be used.
+ ExtendSessionLengthWithActivity *bool `access:"environment_session_lengths,write_restrictable,cloud_restrictable"`
+ SessionLengthWebInDays *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"`
+ SessionLengthMobileInDays *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"`
+ SessionLengthSSOInDays *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"`
+ SessionCacheInMinutes *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"`
+ SessionIdleTimeoutInMinutes *int `access:"environment_session_lengths,write_restrictable,cloud_restrictable"`
+ WebsocketSecurePort *int `access:"write_restrictable,cloud_restrictable"` // telemetry: none
+ WebsocketPort *int `access:"write_restrictable,cloud_restrictable"` // telemetry: none
+ WebserverMode *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ EnableGifPicker *bool `access:"integrations_gif"`
+ GfycatApiKey *string `access:"integrations_gif"`
+ GfycatApiSecret *string `access:"integrations_gif"`
+ EnableCustomEmoji *bool `access:"site_emoji"`
+ EnableEmojiPicker *bool `access:"site_emoji"`
+ DEPRECATED_DO_NOT_USE_RestrictCustomEmojiCreation *string `json:"RestrictCustomEmojiCreation" mapstructure:"RestrictCustomEmojiCreation"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPostDelete *string `json:"RestrictPostDelete" mapstructure:"RestrictPostDelete"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_AllowEditPost *string `json:"AllowEditPost" mapstructure:"AllowEditPost"` // Deprecated: do not use
PostEditTimeLimit *int `access:"user_management_permissions"`
- TimeBetweenUserTypingUpdatesMilliseconds *int64 `access:"experimental,write_restrictable,cloud_restrictable"`
+ TimeBetweenUserTypingUpdatesMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"`
EnablePostSearch *bool `access:"write_restrictable,cloud_restrictable"`
- MinimumHashtagLength *int `access:"environment,write_restrictable,cloud_restrictable"`
- EnableUserTypingMessages *bool `access:"experimental,write_restrictable,cloud_restrictable"`
- EnableChannelViewedMessages *bool `access:"experimental,write_restrictable,cloud_restrictable"`
+ EnableFileSearch *bool `access:"write_restrictable"`
+ MinimumHashtagLength *int `access:"environment_database,write_restrictable,cloud_restrictable"`
+ EnableUserTypingMessages *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ EnableChannelViewedMessages *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
EnableUserStatuses *bool `access:"write_restrictable,cloud_restrictable"`
- ExperimentalEnableAuthenticationTransfer *bool `access:"experimental,write_restrictable,cloud_restrictable"`
+ ExperimentalEnableAuthenticationTransfer *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
ClusterLogTimeoutMilliseconds *int `access:"write_restrictable,cloud_restrictable"`
- CloseUnusedDirectMessages *bool `access:"experimental"`
- EnablePreviewFeatures *bool `access:"experimental"`
- EnableTutorial *bool `access:"experimental"`
- ExperimentalEnableDefaultChannelLeaveJoinMessages *bool `access:"experimental"`
- ExperimentalGroupUnreadChannels *string `access:"experimental"`
- ExperimentalChannelOrganization *bool `access:"experimental"`
- ExperimentalChannelSidebarOrganization *string `access:"experimental"`
- ExperimentalDataPrefetch *bool `access:"experimental"`
- DEPRECATED_DO_NOT_USE_ImageProxyType *string `json:"ImageProxyType" mapstructure:"ImageProxyType"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_ImageProxyURL *string `json:"ImageProxyURL" mapstructure:"ImageProxyURL"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_ImageProxyOptions *string `json:"ImageProxyOptions" mapstructure:"ImageProxyOptions"` // This field is deprecated and must not be used.
+ CloseUnusedDirectMessages *bool `access:"experimental_features"`
+ EnablePreviewFeatures *bool `access:"experimental_features"`
+ EnableTutorial *bool `access:"experimental_features"`
+ ExperimentalEnableDefaultChannelLeaveJoinMessages *bool `access:"experimental_features"`
+ ExperimentalGroupUnreadChannels *string `access:"experimental_features"`
+ ExperimentalChannelOrganization *bool `access:"experimental_features"`
+ DEPRECATED_DO_NOT_USE_ImageProxyType *string `json:"ImageProxyType" mapstructure:"ImageProxyType"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_ImageProxyURL *string `json:"ImageProxyURL" mapstructure:"ImageProxyURL"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_ImageProxyOptions *string `json:"ImageProxyOptions" mapstructure:"ImageProxyOptions"` // Deprecated: do not use
EnableAPITeamDeletion *bool
EnableAPIUserDeletion *bool
- ExperimentalEnableHardenedMode *bool `access:"experimental"`
+ ExperimentalEnableHardenedMode *bool `access:"experimental_features"`
DisableLegacyMFA *bool `access:"write_restrictable,cloud_restrictable"`
- ExperimentalStrictCSRFEnforcement *bool `access:"experimental,write_restrictable,cloud_restrictable"`
- EnableEmailInvitations *bool `access:"authentication"`
- DisableBotsWhenOwnerIsDeactivated *bool `access:"integrations,write_restrictable,cloud_restrictable"`
- EnableBotAccountCreation *bool `access:"integrations"`
- EnableSVGs *bool `access:"site"`
- EnableLatex *bool `access:"site"`
+ ExperimentalStrictCSRFEnforcement *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ EnableEmailInvitations *bool `access:"authentication_signup"`
+ DisableBotsWhenOwnerIsDeactivated *bool `access:"integrations_bot_accounts,write_restrictable,cloud_restrictable"`
+ EnableBotAccountCreation *bool `access:"integrations_bot_accounts"`
+ EnableSVGs *bool `access:"site_posts"`
+ EnableLatex *bool `access:"site_posts"`
EnableAPIChannelDeletion *bool
EnableLocalMode *bool
- LocalModeSocketLocation *string
- EnableAWSMetering *bool
- SplitKey *string `access:"environment,write_restrictable"`
- FeatureFlagSyncIntervalSeconds *int `access:"environment,write_restrictable"`
- DebugSplit *bool `access:"environment,write_restrictable"`
- ThreadAutoFollow *bool `access:"experimental"`
- ManagedResourcePaths *string `access:"environment,write_restrictable,cloud_restrictable"`
+ LocalModeSocketLocation *string // telemetry: none
+ EnableAWSMetering *bool // telemetry: none
+ SplitKey *string `access:"experimental_feature_flags,write_restrictable"` // telemetry: none
+ FeatureFlagSyncIntervalSeconds *int `access:"experimental_feature_flags,write_restrictable"` // telemetry: none
+ DebugSplit *bool `access:"experimental_feature_flags,write_restrictable"` // telemetry: none
+ ThreadAutoFollow *bool `access:"experimental_features"`
+ CollapsedThreads *string `access:"experimental_features"`
+ ManagedResourcePaths *string `access:"environment_web_server,write_restrictable,cloud_restrictable"`
+ EnableLegacySidebar *bool `access:"experimental_features"`
+ EnableReliableWebSockets *bool `access:"experimental_features"` // telemetry: none
}
func (s *ServiceSettings) SetDefaults(isUpdate bool) {
@@ -388,6 +412,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
s.EnableLinkPreviews = NewBool(true)
}
+ if s.RestrictLinkPreviews == nil {
+ s.RestrictLinkPreviews = NewString("")
+ }
+
if s.EnableTesting == nil {
s.EnableTesting = NewBool(false)
}
@@ -518,6 +546,10 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
s.EnablePostSearch = NewBool(true)
}
+ if s.EnableFileSearch == nil {
+ s.EnableFileSearch = NewBool(true)
+ }
+
if s.MinimumHashtagLength == nil {
s.MinimumHashtagLength = NewInt(3)
}
@@ -690,14 +722,6 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
s.ExperimentalChannelOrganization = NewBool(experimentalUnreadEnabled)
}
- if s.ExperimentalChannelSidebarOrganization == nil {
- s.ExperimentalChannelSidebarOrganization = NewString("disabled")
- }
-
- if s.ExperimentalDataPrefetch == nil {
- s.ExperimentalDataPrefetch = NewBool(true)
- }
-
if s.DEPRECATED_DO_NOT_USE_ImageProxyType == nil {
s.DEPRECATED_DO_NOT_USE_ImageProxyType = NewString("")
}
@@ -786,27 +810,40 @@ func (s *ServiceSettings) SetDefaults(isUpdate bool) {
s.ThreadAutoFollow = NewBool(true)
}
+ if s.CollapsedThreads == nil {
+ s.CollapsedThreads = NewString(COLLAPSED_THREADS_DISABLED)
+ }
+
if s.ManagedResourcePaths == nil {
s.ManagedResourcePaths = NewString("")
}
+
+ if s.EnableLegacySidebar == nil {
+ s.EnableLegacySidebar = NewBool(false)
+ }
+
+ if s.EnableReliableWebSockets == nil {
+ s.EnableReliableWebSockets = NewBool(true)
+ }
}
type ClusterSettings struct {
- Enable *bool `access:"environment,write_restrictable"`
- ClusterName *string `access:"environment,write_restrictable,cloud_restrictable"`
- OverrideHostname *string `access:"environment,write_restrictable,cloud_restrictable"`
- NetworkInterface *string `access:"environment,write_restrictable,cloud_restrictable"`
- BindAddress *string `access:"environment,write_restrictable,cloud_restrictable"`
- AdvertiseAddress *string `access:"environment,write_restrictable,cloud_restrictable"`
- UseIpAddress *bool `access:"environment,write_restrictable,cloud_restrictable"`
- UseExperimentalGossip *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableExperimentalGossipEncryption *bool `access:"environment,write_restrictable,cloud_restrictable"`
- ReadOnlyConfig *bool `access:"environment,write_restrictable,cloud_restrictable"`
- GossipPort *int `access:"environment,write_restrictable,cloud_restrictable"`
- StreamingPort *int `access:"environment,write_restrictable,cloud_restrictable"`
- MaxIdleConns *int `access:"environment,write_restrictable,cloud_restrictable"`
- MaxIdleConnsPerHost *int `access:"environment,write_restrictable,cloud_restrictable"`
- IdleConnTimeoutMilliseconds *int `access:"environment,write_restrictable,cloud_restrictable"`
+ Enable *bool `access:"environment_high_availability,write_restrictable"`
+ ClusterName *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none
+ OverrideHostname *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none
+ NetworkInterface *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"`
+ BindAddress *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"`
+ AdvertiseAddress *string `access:"environment_high_availability,write_restrictable,cloud_restrictable"`
+ UseIpAddress *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"`
+ DEPRECATED_DO_NOT_USE_UseExperimentalGossip *bool `json:"UseExperimentalGossip" access:"environment_high_availability,write_restrictable,cloud_restrictable"` // Deprecated: do not use
+ EnableGossipCompression *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"`
+ EnableExperimentalGossipEncryption *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"`
+ ReadOnlyConfig *bool `access:"environment_high_availability,write_restrictable,cloud_restrictable"`
+ GossipPort *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none
+ StreamingPort *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none
+ MaxIdleConns *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none
+ MaxIdleConnsPerHost *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none
+ IdleConnTimeoutMilliseconds *int `access:"environment_high_availability,write_restrictable,cloud_restrictable"` // telemetry: none
}
func (s *ClusterSettings) SetDefaults() {
@@ -838,14 +875,18 @@ func (s *ClusterSettings) SetDefaults() {
s.UseIpAddress = NewBool(true)
}
- if s.UseExperimentalGossip == nil {
- s.UseExperimentalGossip = NewBool(false)
+ if s.DEPRECATED_DO_NOT_USE_UseExperimentalGossip == nil {
+ s.DEPRECATED_DO_NOT_USE_UseExperimentalGossip = NewBool(true)
}
if s.EnableExperimentalGossipEncryption == nil {
s.EnableExperimentalGossipEncryption = NewBool(false)
}
+ if s.EnableGossipCompression == nil {
+ s.EnableGossipCompression = NewBool(true)
+ }
+
if s.ReadOnlyConfig == nil {
s.ReadOnlyConfig = NewBool(true)
}
@@ -872,9 +913,9 @@ func (s *ClusterSettings) SetDefaults() {
}
type MetricsSettings struct {
- Enable *bool `access:"environment,write_restrictable,cloud_restrictable"`
- BlockProfileRate *int `access:"environment,write_restrictable,cloud_restrictable"`
- ListenAddress *string `access:"environment,write_restrictable,cloud_restrictable"`
+ Enable *bool `access:"environment_performance_monitoring,write_restrictable,cloud_restrictable"`
+ BlockProfileRate *int `access:"environment_performance_monitoring,write_restrictable,cloud_restrictable"`
+ ListenAddress *string `access:"environment_performance_monitoring,write_restrictable,cloud_restrictable"` // telemetry: none
}
func (s *MetricsSettings) SetDefaults() {
@@ -892,15 +933,16 @@ func (s *MetricsSettings) SetDefaults() {
}
type ExperimentalSettings struct {
- ClientSideCertEnable *bool `access:"experimental,cloud_restrictable"`
- ClientSideCertCheck *string `access:"experimental,cloud_restrictable"`
- EnableClickToReply *bool `access:"experimental,write_restrictable,cloud_restrictable"`
- LinkMetadataTimeoutMilliseconds *int64 `access:"experimental,write_restrictable,cloud_restrictable"`
- RestrictSystemAdmin *bool `access:"experimental,write_restrictable"`
- UseNewSAMLLibrary *bool `access:"experimental,cloud_restrictable"`
- CloudUserLimit *int64 `access:"experimental,write_restrictable"`
- CloudBilling *bool `access:"experimental,write_restrictable"`
- EnableSharedChannels *bool `access:"experimental"`
+ ClientSideCertEnable *bool `access:"experimental_features,cloud_restrictable"`
+ ClientSideCertCheck *string `access:"experimental_features,cloud_restrictable"`
+ EnableClickToReply *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ LinkMetadataTimeoutMilliseconds *int64 `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ RestrictSystemAdmin *bool `access:"experimental_features,write_restrictable"`
+ UseNewSAMLLibrary *bool `access:"experimental_features,cloud_restrictable"`
+ CloudUserLimit *int64 `access:"experimental_features,write_restrictable"`
+ CloudBilling *bool `access:"experimental_features,write_restrictable"`
+ EnableSharedChannels *bool `access:"experimental_features"`
+ EnableRemoteClusterService *bool `access:"experimental_features"`
}
func (s *ExperimentalSettings) SetDefaults() {
@@ -940,6 +982,10 @@ func (s *ExperimentalSettings) SetDefaults() {
if s.EnableSharedChannels == nil {
s.EnableSharedChannels = NewBool(false)
}
+
+ if s.EnableRemoteClusterService == nil {
+ s.EnableRemoteClusterService = NewBool(false)
+ }
}
type AnalyticsSettings struct {
@@ -953,16 +999,19 @@ func (s *AnalyticsSettings) SetDefaults() {
}
type SSOSettings struct {
- Enable *bool `access:"authentication"`
- Secret *string `access:"authentication"`
- Id *string `access:"authentication"`
- Scope *string `access:"authentication"`
- AuthEndpoint *string `access:"authentication"`
- TokenEndpoint *string `access:"authentication"`
- UserApiEndpoint *string `access:"authentication"`
-}
-
-func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEndpoint string) {
+ Enable *bool `access:"authentication_openid"`
+ Secret *string `access:"authentication_openid"` // telemetry: none
+ Id *string `access:"authentication_openid"` // telemetry: none
+ Scope *string `access:"authentication_openid"` // telemetry: none
+ AuthEndpoint *string `access:"authentication_openid"` // telemetry: none
+ TokenEndpoint *string `access:"authentication_openid"` // telemetry: none
+ UserApiEndpoint *string `access:"authentication_openid"` // telemetry: none
+ DiscoveryEndpoint *string `access:"authentication_openid"` // telemetry: none
+ ButtonText *string `access:"authentication_openid"` // telemetry: none
+ ButtonColor *string `access:"authentication_openid"` // telemetry: none
+}
+
+func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEndpoint, buttonColor string) {
if s.Enable == nil {
s.Enable = NewBool(false)
}
@@ -979,6 +1028,10 @@ func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEnd
s.Scope = NewString(scope)
}
+ if s.DiscoveryEndpoint == nil {
+ s.DiscoveryEndpoint = NewString("")
+ }
+
if s.AuthEndpoint == nil {
s.AuthEndpoint = NewString(authEndpoint)
}
@@ -990,17 +1043,26 @@ func (s *SSOSettings) setDefaults(scope, authEndpoint, tokenEndpoint, userApiEnd
if s.UserApiEndpoint == nil {
s.UserApiEndpoint = NewString(userApiEndpoint)
}
+
+ if s.ButtonText == nil {
+ s.ButtonText = NewString("")
+ }
+
+ if s.ButtonColor == nil {
+ s.ButtonColor = NewString(buttonColor)
+ }
}
type Office365Settings struct {
- Enable *bool `access:"authentication"`
- Secret *string `access:"authentication"`
- Id *string `access:"authentication"`
- Scope *string `access:"authentication"`
- AuthEndpoint *string `access:"authentication"`
- TokenEndpoint *string `access:"authentication"`
- UserApiEndpoint *string `access:"authentication"`
- DirectoryId *string `access:"authentication"`
+ Enable *bool `access:"authentication_openid"`
+ Secret *string `access:"authentication_openid"` // telemetry: none
+ Id *string `access:"authentication_openid"` // telemetry: none
+ Scope *string `access:"authentication_openid"`
+ AuthEndpoint *string `access:"authentication_openid"` // telemetry: none
+ TokenEndpoint *string `access:"authentication_openid"` // telemetry: none
+ UserApiEndpoint *string `access:"authentication_openid"` // telemetry: none
+ DiscoveryEndpoint *string `access:"authentication_openid"` // telemetry: none
+ DirectoryId *string `access:"authentication_openid"` // telemetry: none
}
func (s *Office365Settings) setDefaults() {
@@ -1020,6 +1082,10 @@ func (s *Office365Settings) setDefaults() {
s.Scope = NewString(OFFICE365_SETTINGS_DEFAULT_SCOPE)
}
+ if s.DiscoveryEndpoint == nil {
+ s.DiscoveryEndpoint = NewString("")
+ }
+
if s.AuthEndpoint == nil {
s.AuthEndpoint = NewString(OFFICE365_SETTINGS_DEFAULT_AUTH_ENDPOINT)
}
@@ -1043,24 +1109,33 @@ func (s *Office365Settings) SSOSettings() *SSOSettings {
ssoSettings.Secret = s.Secret
ssoSettings.Id = s.Id
ssoSettings.Scope = s.Scope
+ ssoSettings.DiscoveryEndpoint = s.DiscoveryEndpoint
ssoSettings.AuthEndpoint = s.AuthEndpoint
ssoSettings.TokenEndpoint = s.TokenEndpoint
ssoSettings.UserApiEndpoint = s.UserApiEndpoint
return &ssoSettings
}
+type ReplicaLagSettings struct {
+ DataSource *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none
+ QueryAbsoluteLag *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none
+ QueryTimeLag *string `access:"environment,write_restrictable,cloud_restrictable"` // telemetry: none
+}
+
type SqlSettings struct {
- DriverName *string `access:"environment,write_restrictable,cloud_restrictable"`
- DataSource *string `access:"environment,write_restrictable,cloud_restrictable"`
- DataSourceReplicas []string `access:"environment,write_restrictable,cloud_restrictable"`
- DataSourceSearchReplicas []string `access:"environment,write_restrictable,cloud_restrictable"`
- MaxIdleConns *int `access:"environment,write_restrictable,cloud_restrictable"`
- ConnMaxLifetimeMilliseconds *int `access:"environment,write_restrictable,cloud_restrictable"`
- MaxOpenConns *int `access:"environment,write_restrictable,cloud_restrictable"`
- Trace *bool `access:"environment,write_restrictable,cloud_restrictable"`
- AtRestEncryptKey *string `access:"environment,write_restrictable,cloud_restrictable"`
- QueryTimeout *int `access:"environment,write_restrictable,cloud_restrictable"`
- DisableDatabaseSearch *bool `access:"environment,write_restrictable,cloud_restrictable"`
+ DriverName *string `access:"environment_database,write_restrictable,cloud_restrictable"`
+ DataSource *string `access:"environment_database,write_restrictable,cloud_restrictable"` // telemetry: none
+ DataSourceReplicas []string `access:"environment_database,write_restrictable,cloud_restrictable"`
+ DataSourceSearchReplicas []string `access:"environment_database,write_restrictable,cloud_restrictable"`
+ MaxIdleConns *int `access:"environment_database,write_restrictable,cloud_restrictable"`
+ ConnMaxLifetimeMilliseconds *int `access:"environment_database,write_restrictable,cloud_restrictable"`
+ ConnMaxIdleTimeMilliseconds *int `access:"environment_database,write_restrictable,cloud_restrictable"`
+ MaxOpenConns *int `access:"environment_database,write_restrictable,cloud_restrictable"`
+ Trace *bool `access:"environment_database,write_restrictable,cloud_restrictable"`
+ AtRestEncryptKey *string `access:"environment_database,write_restrictable,cloud_restrictable"` // telemetry: none
+ QueryTimeout *int `access:"environment_database,write_restrictable,cloud_restrictable"`
+ DisableDatabaseSearch *bool `access:"environment_database,write_restrictable,cloud_restrictable"`
+ ReplicaLagSettings []*ReplicaLagSettings `access:"environment_database,write_restrictable,cloud_restrictable"` // telemetry: none
}
func (s *SqlSettings) SetDefaults(isUpdate bool) {
@@ -1082,7 +1157,7 @@ func (s *SqlSettings) SetDefaults(isUpdate bool) {
if isUpdate {
// When updating an existing configuration, ensure an encryption key has been specified.
- if s.AtRestEncryptKey == nil || len(*s.AtRestEncryptKey) == 0 {
+ if s.AtRestEncryptKey == nil || *s.AtRestEncryptKey == "" {
s.AtRestEncryptKey = NewString(NewRandomString(32))
}
} else {
@@ -1102,6 +1177,10 @@ func (s *SqlSettings) SetDefaults(isUpdate bool) {
s.ConnMaxLifetimeMilliseconds = NewInt(3600000)
}
+ if s.ConnMaxIdleTimeMilliseconds == nil {
+ s.ConnMaxIdleTimeMilliseconds = NewInt(300000)
+ }
+
if s.Trace == nil {
s.Trace = NewBool(false)
}
@@ -1113,20 +1192,25 @@ func (s *SqlSettings) SetDefaults(isUpdate bool) {
if s.DisableDatabaseSearch == nil {
s.DisableDatabaseSearch = NewBool(false)
}
+
+ if s.ReplicaLagSettings == nil {
+ s.ReplicaLagSettings = []*ReplicaLagSettings{}
+ }
}
type LogSettings struct {
- EnableConsole *bool `access:"environment,write_restrictable,cloud_restrictable"`
- ConsoleLevel *string `access:"environment,write_restrictable,cloud_restrictable"`
- ConsoleJson *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableFile *bool `access:"environment,write_restrictable,cloud_restrictable"`
- FileLevel *string `access:"environment,write_restrictable,cloud_restrictable"`
- FileJson *bool `access:"environment,write_restrictable,cloud_restrictable"`
- FileLocation *string `access:"environment,write_restrictable,cloud_restrictable"`
- EnableWebhookDebugging *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableDiagnostics *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableSentry *bool `access:"environment,write_restrictable,cloud_restrictable"`
- AdvancedLoggingConfig *string `access:"environment,write_restrictable,cloud_restrictable"`
+ EnableConsole *bool `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ ConsoleLevel *string `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ ConsoleJson *bool `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ EnableColor *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` // telemetry: none
+ EnableFile *bool `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ FileLevel *string `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ FileJson *bool `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ FileLocation *string `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ EnableWebhookDebugging *bool `access:"environment_logging,write_restrictable,cloud_restrictable"`
+ EnableDiagnostics *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` // telemetry: none
+ EnableSentry *bool `access:"environment_logging,write_restrictable,cloud_restrictable"` // telemetry: none
+ AdvancedLoggingConfig *string `access:"environment_logging,write_restrictable,cloud_restrictable"`
}
func (s *LogSettings) SetDefaults() {
@@ -1138,6 +1222,10 @@ func (s *LogSettings) SetDefaults() {
s.ConsoleLevel = NewString("DEBUG")
}
+ if s.EnableColor == nil {
+ s.EnableColor = NewBool(false)
+ }
+
if s.EnableFile == nil {
s.EnableFile = NewBool(true)
}
@@ -1176,14 +1264,14 @@ func (s *LogSettings) SetDefaults() {
}
type ExperimentalAuditSettings struct {
- FileEnabled *bool `access:"experimental,write_restrictable,cloud_restrictable"`
- FileName *string `access:"experimental,write_restrictable,cloud_restrictable"`
- FileMaxSizeMB *int `access:"experimental,write_restrictable,cloud_restrictable"`
- FileMaxAgeDays *int `access:"experimental,write_restrictable,cloud_restrictable"`
- FileMaxBackups *int `access:"experimental,write_restrictable,cloud_restrictable"`
- FileCompress *bool `access:"experimental,write_restrictable,cloud_restrictable"`
- FileMaxQueueSize *int `access:"experimental,write_restrictable,cloud_restrictable"`
- AdvancedLoggingConfig *string `access:"experimental,write_restrictable,cloud_restrictable"`
+ FileEnabled *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ FileName *string `access:"experimental_features,write_restrictable,cloud_restrictable"` // telemetry: none
+ FileMaxSizeMB *int `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ FileMaxAgeDays *int `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ FileMaxBackups *int `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ FileCompress *bool `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ FileMaxQueueSize *int `access:"experimental_features,write_restrictable,cloud_restrictable"`
+ AdvancedLoggingConfig *string `access:"experimental_features,write_restrictable,cloud_restrictable"`
}
func (s *ExperimentalAuditSettings) SetDefaults() {
@@ -1224,6 +1312,7 @@ type NotificationLogSettings struct {
EnableConsole *bool `access:"write_restrictable,cloud_restrictable"`
ConsoleLevel *string `access:"write_restrictable,cloud_restrictable"`
ConsoleJson *bool `access:"write_restrictable,cloud_restrictable"`
+ EnableColor *bool `access:"write_restrictable,cloud_restrictable"` // telemetry: none
EnableFile *bool `access:"write_restrictable,cloud_restrictable"`
FileLevel *string `access:"write_restrictable,cloud_restrictable"`
FileJson *bool `access:"write_restrictable,cloud_restrictable"`
@@ -1256,6 +1345,10 @@ func (s *NotificationLogSettings) SetDefaults() {
s.ConsoleJson = NewBool(true)
}
+ if s.EnableColor == nil {
+ s.EnableColor = NewBool(false)
+ }
+
if s.FileJson == nil {
s.FileJson = NewBool(true)
}
@@ -1266,11 +1359,11 @@ func (s *NotificationLogSettings) SetDefaults() {
}
type PasswordSettings struct {
- MinimumLength *int `access:"authentication"`
- Lowercase *bool `access:"authentication"`
- Number *bool `access:"authentication"`
- Uppercase *bool `access:"authentication"`
- Symbol *bool `access:"authentication"`
+ MinimumLength *int `access:"authentication_password"`
+ Lowercase *bool `access:"authentication_password"`
+ Number *bool `access:"authentication_password"`
+ Uppercase *bool `access:"authentication_password"`
+ Symbol *bool `access:"authentication_password"`
}
func (s *PasswordSettings) SetDefaults() {
@@ -1296,25 +1389,27 @@ func (s *PasswordSettings) SetDefaults() {
}
type FileSettings struct {
- EnableFileAttachments *bool `access:"site,cloud_restrictable"`
- EnableMobileUpload *bool `access:"site,cloud_restrictable"`
- EnableMobileDownload *bool `access:"site,cloud_restrictable"`
- MaxFileSize *int64 `access:"environment,cloud_restrictable"`
- DriverName *string `access:"environment,write_restrictable,cloud_restrictable"`
- Directory *string `access:"environment,write_restrictable,cloud_restrictable"`
- EnablePublicLink *bool `access:"site,cloud_restrictable"`
- PublicLinkSalt *string `access:"site,cloud_restrictable"`
- InitialFont *string `access:"environment,cloud_restrictable"`
- AmazonS3AccessKeyId *string `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3SecretAccessKey *string `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3Bucket *string `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3PathPrefix *string `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3Region *string `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3Endpoint *string `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3SSL *bool `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3SignV2 *bool `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3SSE *bool `access:"environment,write_restrictable,cloud_restrictable"`
- AmazonS3Trace *bool `access:"environment,write_restrictable,cloud_restrictable"`
+ EnableFileAttachments *bool `access:"site_file_sharing_and_downloads,cloud_restrictable"`
+ EnableMobileUpload *bool `access:"site_file_sharing_and_downloads,cloud_restrictable"`
+ EnableMobileDownload *bool `access:"site_file_sharing_and_downloads,cloud_restrictable"`
+ MaxFileSize *int64 `access:"environment_file_storage,cloud_restrictable"`
+ DriverName *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"`
+ Directory *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"`
+ EnablePublicLink *bool `access:"site_public_links,cloud_restrictable"`
+ ExtractContent *bool `access:"environment_file_storage,write_restrictable"`
+ ArchiveRecursion *bool `access:"environment_file_storage,write_restrictable"`
+ PublicLinkSalt *string `access:"site_public_links,cloud_restrictable"` // telemetry: none
+ InitialFont *string `access:"environment_file_storage,cloud_restrictable"` // telemetry: none
+ AmazonS3AccessKeyId *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
+ AmazonS3SecretAccessKey *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
+ AmazonS3Bucket *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
+ AmazonS3PathPrefix *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
+ AmazonS3Region *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
+ AmazonS3Endpoint *string `access:"environment_file_storage,write_restrictable,cloud_restrictable"` // telemetry: none
+ AmazonS3SSL *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"`
+ AmazonS3SignV2 *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"`
+ AmazonS3SSE *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"`
+ AmazonS3Trace *bool `access:"environment_file_storage,write_restrictable,cloud_restrictable"`
}
func (s *FileSettings) SetDefaults(isUpdate bool) {
@@ -1331,7 +1426,7 @@ func (s *FileSettings) SetDefaults(isUpdate bool) {
}
if s.MaxFileSize == nil {
- s.MaxFileSize = NewInt64(52428800) // 50 MB
+ s.MaxFileSize = NewInt64(MB * 100)
}
if s.DriverName == nil {
@@ -1346,9 +1441,17 @@ func (s *FileSettings) SetDefaults(isUpdate bool) {
s.EnablePublicLink = NewBool(false)
}
+ if s.ExtractContent == nil {
+ s.ExtractContent = NewBool(true)
+ }
+
+ if s.ArchiveRecursion == nil {
+ s.ArchiveRecursion = NewBool(false)
+ }
+
if isUpdate {
// When updating an existing configuration, ensure link salt has been specified.
- if s.PublicLinkSalt == nil || len(*s.PublicLinkSalt) == 0 {
+ if s.PublicLinkSalt == nil || *s.PublicLinkSalt == "" {
s.PublicLinkSalt = NewString(NewRandomString(32))
}
} else {
@@ -1381,7 +1484,7 @@ func (s *FileSettings) SetDefaults(isUpdate bool) {
s.AmazonS3Region = NewString("")
}
- if s.AmazonS3Endpoint == nil || len(*s.AmazonS3Endpoint) == 0 {
+ if s.AmazonS3Endpoint == nil || *s.AmazonS3Endpoint == "" {
// Defaults to "s3.amazonaws.com"
s.AmazonS3Endpoint = NewString("s3.amazonaws.com")
}
@@ -1404,37 +1507,59 @@ func (s *FileSettings) SetDefaults(isUpdate bool) {
}
}
+func (s *FileSettings) ToFileBackendSettings(enableComplianceFeature bool) filestore.FileBackendSettings {
+ if *s.DriverName == IMAGE_DRIVER_LOCAL {
+ return filestore.FileBackendSettings{
+ DriverName: *s.DriverName,
+ Directory: *s.Directory,
+ }
+ }
+ return filestore.FileBackendSettings{
+ DriverName: *s.DriverName,
+ AmazonS3AccessKeyId: *s.AmazonS3AccessKeyId,
+ AmazonS3SecretAccessKey: *s.AmazonS3SecretAccessKey,
+ AmazonS3Bucket: *s.AmazonS3Bucket,
+ AmazonS3PathPrefix: *s.AmazonS3PathPrefix,
+ AmazonS3Region: *s.AmazonS3Region,
+ AmazonS3Endpoint: *s.AmazonS3Endpoint,
+ AmazonS3SSL: s.AmazonS3SSL == nil || *s.AmazonS3SSL,
+ AmazonS3SignV2: s.AmazonS3SignV2 != nil && *s.AmazonS3SignV2,
+ AmazonS3SSE: s.AmazonS3SSE != nil && *s.AmazonS3SSE && enableComplianceFeature,
+ AmazonS3Trace: s.AmazonS3Trace != nil && *s.AmazonS3Trace,
+ }
+}
+
type EmailSettings struct {
- EnableSignUpWithEmail *bool `access:"authentication"`
- EnableSignInWithEmail *bool `access:"authentication"`
- EnableSignInWithUsername *bool `access:"authentication"`
- SendEmailNotifications *bool `access:"site"`
- UseChannelInEmailNotifications *bool `access:"experimental"`
- RequireEmailVerification *bool `access:"authentication"`
- FeedbackName *string `access:"site"`
- FeedbackEmail *string `access:"site,cloud_restrictable"`
- ReplyToAddress *string `access:"site,cloud_restrictable"`
- FeedbackOrganization *string `access:"site"`
- EnableSMTPAuth *bool `access:"environment,write_restrictable,cloud_restrictable"`
- SMTPUsername *string `access:"environment,write_restrictable,cloud_restrictable"`
- SMTPPassword *string `access:"environment,write_restrictable,cloud_restrictable"`
- SMTPServer *string `access:"environment,write_restrictable,cloud_restrictable"`
- SMTPPort *string `access:"environment,write_restrictable,cloud_restrictable"`
+ EnableSignUpWithEmail *bool `access:"authentication_email"`
+ EnableSignInWithEmail *bool `access:"authentication_email"`
+ EnableSignInWithUsername *bool `access:"authentication_email"`
+ SendEmailNotifications *bool `access:"site_notifications"`
+ UseChannelInEmailNotifications *bool `access:"experimental_features"`
+ RequireEmailVerification *bool `access:"authentication_email"`
+ FeedbackName *string `access:"site_notifications"`
+ FeedbackEmail *string `access:"site_notifications,cloud_restrictable"`
+ ReplyToAddress *string `access:"site_notifications,cloud_restrictable"`
+ FeedbackOrganization *string `access:"site_notifications"`
+ EnableSMTPAuth *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"`
+ SMTPUsername *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none
+ SMTPPassword *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none
+ SMTPServer *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none
+ SMTPPort *string `access:"environment_smtp,write_restrictable,cloud_restrictable"` // telemetry: none
SMTPServerTimeout *int `access:"cloud_restrictable"`
- ConnectionSecurity *string `access:"environment,write_restrictable,cloud_restrictable"`
- SendPushNotifications *bool `access:"environment"`
- PushNotificationServer *string `access:"environment"`
- PushNotificationContents *string `access:"site"`
- PushNotificationBuffer *int
- EnableEmailBatching *bool `access:"site"`
- EmailBatchingBufferSize *int `access:"experimental"`
- EmailBatchingInterval *int `access:"experimental"`
- EnablePreviewModeBanner *bool `access:"site"`
- SkipServerCertificateVerification *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EmailNotificationContentsType *string `access:"site"`
- LoginButtonColor *string `access:"experimental"`
- LoginButtonBorderColor *string `access:"experimental"`
- LoginButtonTextColor *string `access:"experimental"`
+ ConnectionSecurity *string `access:"environment_smtp,write_restrictable,cloud_restrictable"`
+ SendPushNotifications *bool `access:"environment_push_notification_server"`
+ PushNotificationServer *string `access:"environment_push_notification_server"` // telemetry: none
+ PushNotificationContents *string `access:"site_notifications"`
+ PushNotificationBuffer *int // telemetry: none
+ EnableEmailBatching *bool `access:"site_notifications"`
+ EmailBatchingBufferSize *int `access:"experimental_features"`
+ EmailBatchingInterval *int `access:"experimental_features"`
+ EnablePreviewModeBanner *bool `access:"site_notifications"`
+ SkipServerCertificateVerification *bool `access:"environment_smtp,write_restrictable,cloud_restrictable"`
+ EmailNotificationContentsType *string `access:"site_notifications"`
+ LoginButtonColor *string `access:"experimental_features"`
+ LoginButtonBorderColor *string `access:"experimental_features"`
+ LoginButtonTextColor *string `access:"experimental_features"`
}
func (s *EmailSettings) SetDefaults(isUpdate bool) {
@@ -1494,11 +1619,11 @@ func (s *EmailSettings) SetDefaults(isUpdate bool) {
s.SMTPPassword = NewString("")
}
- if s.SMTPServer == nil || len(*s.SMTPServer) == 0 {
+ if s.SMTPServer == nil || *s.SMTPServer == "" {
s.SMTPServer = NewString("localhost")
}
- if s.SMTPPort == nil || len(*s.SMTPPort) == 0 {
+ if s.SMTPPort == nil || *s.SMTPPort == "" {
s.SMTPPort = NewString("10025")
}
@@ -1580,13 +1705,13 @@ func (s *EmailSettings) SetDefaults(isUpdate bool) {
}
type RateLimitSettings struct {
- Enable *bool `access:"environment,write_restrictable,cloud_restrictable"`
- PerSec *int `access:"environment,write_restrictable,cloud_restrictable"`
- MaxBurst *int `access:"environment,write_restrictable,cloud_restrictable"`
- MemoryStoreSize *int `access:"environment,write_restrictable,cloud_restrictable"`
- VaryByRemoteAddr *bool `access:"environment,write_restrictable,cloud_restrictable"`
- VaryByUser *bool `access:"environment,write_restrictable,cloud_restrictable"`
- VaryByHeader string `access:"environment,write_restrictable,cloud_restrictable"`
+ Enable *bool `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"`
+ PerSec *int `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"`
+ MaxBurst *int `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"`
+ MemoryStoreSize *int `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"`
+ VaryByRemoteAddr *bool `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"`
+ VaryByUser *bool `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"`
+ VaryByHeader string `access:"environment_rate_limiting,write_restrictable,cloud_restrictable"`
}
func (s *RateLimitSettings) SetDefaults() {
@@ -1616,8 +1741,8 @@ func (s *RateLimitSettings) SetDefaults() {
}
type PrivacySettings struct {
- ShowEmailAddress *bool `access:"site"`
- ShowFullName *bool `access:"site"`
+ ShowEmailAddress *bool `access:"site_users_and_teams"`
+ ShowFullName *bool `access:"site_users_and_teams"`
}
func (s *PrivacySettings) setDefaults() {
@@ -1631,15 +1756,15 @@ func (s *PrivacySettings) setDefaults() {
}
type SupportSettings struct {
- TermsOfServiceLink *string `access:"site,write_restrictable,cloud_restrictable"`
- PrivacyPolicyLink *string `access:"site,write_restrictable,cloud_restrictable"`
- AboutLink *string `access:"site,write_restrictable,cloud_restrictable"`
- HelpLink *string `access:"site,write_restrictable,cloud_restrictable"`
- ReportAProblemLink *string `access:"site,write_restrictable,cloud_restrictable"`
- SupportEmail *string `access:"site"`
- CustomTermsOfServiceEnabled *bool `access:"compliance"`
- CustomTermsOfServiceReAcceptancePeriod *int `access:"compliance"`
- EnableAskCommunityLink *bool `access:"site"`
+ TermsOfServiceLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
+ PrivacyPolicyLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
+ AboutLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
+ HelpLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
+ ReportAProblemLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
+ SupportEmail *string `access:"site_customization"`
+ CustomTermsOfServiceEnabled *bool `access:"compliance_custom_terms_of_service"`
+ CustomTermsOfServiceReAcceptancePeriod *int `access:"compliance_custom_terms_of_service"`
+ EnableAskCommunityLink *bool `access:"site_customization"`
}
func (s *SupportSettings) SetDefaults() {
@@ -1701,16 +1826,16 @@ func (s *SupportSettings) SetDefaults() {
}
type AnnouncementSettings struct {
- EnableBanner *bool `access:"site"`
- BannerText *string `access:"site"`
- BannerColor *string `access:"site"`
- BannerTextColor *string `access:"site"`
- AllowBannerDismissal *bool `access:"site"`
- AdminNoticesEnabled *bool `access:"site"`
- UserNoticesEnabled *bool `access:"site"`
- NoticesURL *string `access:"site,write_restrictable"`
- NoticesFetchFrequency *int `access:"site,write_restrictable"`
- NoticesSkipCache *bool `access:"site,write_restrictable"`
+ EnableBanner *bool `access:"site_announcement_banner"`
+ BannerText *string `access:"site_announcement_banner"` // telemetry: none
+ BannerColor *string `access:"site_announcement_banner"`
+ BannerTextColor *string `access:"site_announcement_banner"`
+ AllowBannerDismissal *bool `access:"site_announcement_banner"`
+ AdminNoticesEnabled *bool `access:"site_notices"`
+ UserNoticesEnabled *bool `access:"site_notices"`
+ NoticesURL *string `access:"site_notices,write_restrictable"` // telemetry: none
+ NoticesFetchFrequency *int `access:"site_notices,write_restrictable"` // telemetry: none
+ NoticesSkipCache *bool `access:"site_notices,write_restrictable"` // telemetry: none
}
func (s *AnnouncementSettings) SetDefaults() {
@@ -1754,9 +1879,9 @@ func (s *AnnouncementSettings) SetDefaults() {
}
type ThemeSettings struct {
- EnableThemeSelection *bool `access:"experimental"`
- DefaultTheme *string `access:"experimental"`
- AllowCustomThemes *bool `access:"experimental"`
+ EnableThemeSelection *bool `access:"experimental_features"`
+ DefaultTheme *string `access:"experimental_features"`
+ AllowCustomThemes *bool `access:"experimental_features"`
AllowedThemes []string
}
@@ -1779,38 +1904,39 @@ func (s *ThemeSettings) SetDefaults() {
}
type TeamSettings struct {
- SiteName *string `access:"site"`
- MaxUsersPerTeam *int `access:"site"`
- DEPRECATED_DO_NOT_USE_EnableTeamCreation *bool `json:"EnableTeamCreation" mapstructure:"EnableTeamCreation"` // This field is deprecated and must not be used.
- EnableUserCreation *bool `access:"authentication"`
- EnableOpenServer *bool `access:"authentication"`
- EnableUserDeactivation *bool `access:"experimental"`
- RestrictCreationToDomains *string `access:"authentication"`
- EnableCustomBrand *bool `access:"site"`
- CustomBrandText *string `access:"site"`
- CustomDescriptionText *string `access:"site"`
- RestrictDirectMessage *string `access:"site"`
- DEPRECATED_DO_NOT_USE_RestrictTeamInvite *string `json:"RestrictTeamInvite" mapstructure:"RestrictTeamInvite"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement *string `json:"RestrictPublicChannelManagement" mapstructure:"RestrictPublicChannelManagement"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement *string `json:"RestrictPrivateChannelManagement" mapstructure:"RestrictPrivateChannelManagement"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation *string `json:"RestrictPublicChannelCreation" mapstructure:"RestrictPublicChannelCreation"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPrivateChannelCreation *string `json:"RestrictPrivateChannelCreation" mapstructure:"RestrictPrivateChannelCreation"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPublicChannelDeletion *string `json:"RestrictPublicChannelDeletion" mapstructure:"RestrictPublicChannelDeletion"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPrivateChannelDeletion *string `json:"RestrictPrivateChannelDeletion" mapstructure:"RestrictPrivateChannelDeletion"` // This field is deprecated and must not be used.
- DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManageMembers *string `json:"RestrictPrivateChannelManageMembers" mapstructure:"RestrictPrivateChannelManageMembers"` // This field is deprecated and must not be used.
- EnableXToLeaveChannelsFromLHS *bool `access:"experimental"`
- UserStatusAwayTimeout *int64 `access:"experimental"`
- MaxChannelsPerTeam *int64 `access:"site"`
- MaxNotificationsPerChannel *int64 `access:"environment"`
- EnableConfirmNotificationsToChannel *bool `access:"site"`
- TeammateNameDisplay *string `access:"site"`
- ExperimentalViewArchivedChannels *bool `access:"experimental,site"`
- ExperimentalEnableAutomaticReplies *bool `access:"experimental"`
- ExperimentalHideTownSquareinLHS *bool `access:"experimental"`
- ExperimentalTownSquareIsReadOnly *bool `access:"experimental"`
- LockTeammateNameDisplay *bool `access:"site"`
- ExperimentalPrimaryTeam *string `access:"experimental"`
- ExperimentalDefaultChannels []string `access:"experimental"`
+ SiteName *string `access:"site_customization"`
+ MaxUsersPerTeam *int `access:"site_users_and_teams"`
+ DEPRECATED_DO_NOT_USE_EnableTeamCreation *bool `json:"EnableTeamCreation" mapstructure:"EnableTeamCreation"` // Deprecated: do not use
+ EnableUserCreation *bool `access:"authentication_signup"`
+ EnableOpenServer *bool `access:"authentication_signup"`
+ EnableUserDeactivation *bool `access:"experimental_features"`
+ RestrictCreationToDomains *string `access:"authentication_signup"` // telemetry: none
+ EnableCustomUserStatuses *bool `access:"site_users_and_teams"`
+ EnableCustomBrand *bool `access:"site_customization"`
+ CustomBrandText *string `access:"site_customization"`
+ CustomDescriptionText *string `access:"site_customization"`
+ RestrictDirectMessage *string `access:"site_users_and_teams"`
+ DEPRECATED_DO_NOT_USE_RestrictTeamInvite *string `json:"RestrictTeamInvite" mapstructure:"RestrictTeamInvite"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPublicChannelManagement *string `json:"RestrictPublicChannelManagement" mapstructure:"RestrictPublicChannelManagement"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManagement *string `json:"RestrictPrivateChannelManagement" mapstructure:"RestrictPrivateChannelManagement"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPublicChannelCreation *string `json:"RestrictPublicChannelCreation" mapstructure:"RestrictPublicChannelCreation"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPrivateChannelCreation *string `json:"RestrictPrivateChannelCreation" mapstructure:"RestrictPrivateChannelCreation"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPublicChannelDeletion *string `json:"RestrictPublicChannelDeletion" mapstructure:"RestrictPublicChannelDeletion"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPrivateChannelDeletion *string `json:"RestrictPrivateChannelDeletion" mapstructure:"RestrictPrivateChannelDeletion"` // Deprecated: do not use
+ DEPRECATED_DO_NOT_USE_RestrictPrivateChannelManageMembers *string `json:"RestrictPrivateChannelManageMembers" mapstructure:"RestrictPrivateChannelManageMembers"` // Deprecated: do not use
+ EnableXToLeaveChannelsFromLHS *bool `access:"experimental_features"`
+ UserStatusAwayTimeout *int64 `access:"experimental_features"`
+ MaxChannelsPerTeam *int64 `access:"site_users_and_teams"`
+ MaxNotificationsPerChannel *int64 `access:"environment_push_notification_server"`
+ EnableConfirmNotificationsToChannel *bool `access:"site_notifications"`
+ TeammateNameDisplay *string `access:"site_users_and_teams"`
+ ExperimentalViewArchivedChannels *bool `access:"experimental_features,site_users_and_teams"`
+ ExperimentalEnableAutomaticReplies *bool `access:"experimental_features"`
+ ExperimentalHideTownSquareinLHS *bool `access:"experimental_features"`
+ ExperimentalTownSquareIsReadOnly *bool `access:"experimental_features"`
+ LockTeammateNameDisplay *bool `access:"site_users_and_teams"`
+ ExperimentalPrimaryTeam *string `access:"experimental_features"`
+ ExperimentalDefaultChannels []string `access:"experimental_features"`
}
func (s *TeamSettings) SetDefaults() {
@@ -1839,6 +1965,10 @@ func (s *TeamSettings) SetDefaults() {
s.RestrictCreationToDomains = NewString("")
}
+ if s.EnableCustomUserStatuses == nil {
+ s.EnableCustomUserStatuses = NewBool(true)
+ }
+
if s.EnableCustomBrand == nil {
s.EnableCustomBrand = NewBool(false)
}
@@ -1972,55 +2102,55 @@ type ClientRequirements struct {
type LdapSettings struct {
// Basic
- Enable *bool `access:"authentication"`
- EnableSync *bool `access:"authentication"`
- LdapServer *string `access:"authentication"`
- LdapPort *int `access:"authentication"`
- ConnectionSecurity *string `access:"authentication"`
- BaseDN *string `access:"authentication"`
- BindUsername *string `access:"authentication"`
- BindPassword *string `access:"authentication"`
+ Enable *bool `access:"authentication_ldap"`
+ EnableSync *bool `access:"authentication_ldap"`
+ LdapServer *string `access:"authentication_ldap"` // telemetry: none
+ LdapPort *int `access:"authentication_ldap"` // telemetry: none
+ ConnectionSecurity *string `access:"authentication_ldap"`
+ BaseDN *string `access:"authentication_ldap"` // telemetry: none
+ BindUsername *string `access:"authentication_ldap"` // telemetry: none
+ BindPassword *string `access:"authentication_ldap"` // telemetry: none
// Filtering
- UserFilter *string `access:"authentication"`
- GroupFilter *string `access:"authentication"`
- GuestFilter *string `access:"authentication"`
+ UserFilter *string `access:"authentication_ldap"` // telemetry: none
+ GroupFilter *string `access:"authentication_ldap"`
+ GuestFilter *string `access:"authentication_ldap"`
EnableAdminFilter *bool
AdminFilter *string
// Group Mapping
- GroupDisplayNameAttribute *string `access:"authentication"`
- GroupIdAttribute *string `access:"authentication"`
+ GroupDisplayNameAttribute *string `access:"authentication_ldap"`
+ GroupIdAttribute *string `access:"authentication_ldap"`
// User Mapping
- FirstNameAttribute *string `access:"authentication"`
- LastNameAttribute *string `access:"authentication"`
- EmailAttribute *string `access:"authentication"`
- UsernameAttribute *string `access:"authentication"`
- NicknameAttribute *string `access:"authentication"`
- IdAttribute *string `access:"authentication"`
- PositionAttribute *string `access:"authentication"`
- LoginIdAttribute *string `access:"authentication"`
- PictureAttribute *string `access:"authentication"`
+ FirstNameAttribute *string `access:"authentication_ldap"`
+ LastNameAttribute *string `access:"authentication_ldap"`
+ EmailAttribute *string `access:"authentication_ldap"`
+ UsernameAttribute *string `access:"authentication_ldap"`
+ NicknameAttribute *string `access:"authentication_ldap"`
+ IdAttribute *string `access:"authentication_ldap"`
+ PositionAttribute *string `access:"authentication_ldap"`
+ LoginIdAttribute *string `access:"authentication_ldap"`
+ PictureAttribute *string `access:"authentication_ldap"`
// Synchronization
- SyncIntervalMinutes *int `access:"authentication"`
+ SyncIntervalMinutes *int `access:"authentication_ldap"`
// Advanced
- SkipCertificateVerification *bool `access:"authentication"`
- PublicCertificateFile *string `access:"authentication"`
- PrivateKeyFile *string `access:"authentication"`
- QueryTimeout *int `access:"authentication"`
- MaxPageSize *int `access:"authentication"`
+ SkipCertificateVerification *bool `access:"authentication_ldap"`
+ PublicCertificateFile *string `access:"authentication_ldap"`
+ PrivateKeyFile *string `access:"authentication_ldap"`
+ QueryTimeout *int `access:"authentication_ldap"`
+ MaxPageSize *int `access:"authentication_ldap"`
// Customization
- LoginFieldName *string `access:"authentication"`
+ LoginFieldName *string `access:"authentication_ldap"`
- LoginButtonColor *string `access:"authentication"`
- LoginButtonBorderColor *string `access:"authentication"`
- LoginButtonTextColor *string `access:"authentication"`
+ LoginButtonColor *string `access:"experimental_features"`
+ LoginButtonBorderColor *string `access:"experimental_features"`
+ LoginButtonTextColor *string `access:"experimental_features"`
- Trace *bool `access:"authentication"`
+ Trace *bool `access:"authentication_ldap"` // telemetry: none
}
func (s *LdapSettings) SetDefaults() {
@@ -2169,9 +2299,10 @@ func (s *LdapSettings) SetDefaults() {
}
type ComplianceSettings struct {
- Enable *bool `access:"compliance"`
- Directory *string `access:"compliance"`
- EnableDaily *bool `access:"compliance"`
+ Enable *bool `access:"compliance_compliance_monitoring"`
+ Directory *string `access:"compliance_compliance_monitoring"` // telemetry: none
+ EnableDaily *bool `access:"compliance_compliance_monitoring"`
+ BatchSize *int `access:"compliance_compliance_monitoring"` // telemetry: none
}
func (s *ComplianceSettings) SetDefaults() {
@@ -2186,12 +2317,16 @@ func (s *ComplianceSettings) SetDefaults() {
if s.EnableDaily == nil {
s.EnableDaily = NewBool(false)
}
+
+ if s.BatchSize == nil {
+ s.BatchSize = NewInt(30000)
+ }
}
type LocalizationSettings struct {
- DefaultServerLocale *string `access:"site"`
- DefaultClientLocale *string `access:"site"`
- AvailableLocales *string `access:"site"`
+ DefaultServerLocale *string `access:"site_localization"`
+ DefaultClientLocale *string `access:"site_localization"`
+ AvailableLocales *string `access:"site_localization"`
}
func (s *LocalizationSettings) SetDefaults() {
@@ -2210,49 +2345,49 @@ func (s *LocalizationSettings) SetDefaults() {
type SamlSettings struct {
// Basic
- Enable *bool `access:"authentication"`
- EnableSyncWithLdap *bool `access:"authentication"`
- EnableSyncWithLdapIncludeAuth *bool `access:"authentication"`
- IgnoreGuestsLdapSync *bool `access:"authentication"`
+ Enable *bool `access:"authentication_saml"`
+ EnableSyncWithLdap *bool `access:"authentication_saml"`
+ EnableSyncWithLdapIncludeAuth *bool `access:"authentication_saml"`
+ IgnoreGuestsLdapSync *bool `access:"authentication_saml"`
- Verify *bool `access:"authentication"`
- Encrypt *bool `access:"authentication"`
- SignRequest *bool `access:"authentication"`
+ Verify *bool `access:"authentication_saml"`
+ Encrypt *bool `access:"authentication_saml"`
+ SignRequest *bool `access:"authentication_saml"`
- IdpUrl *string `access:"authentication"`
- IdpDescriptorUrl *string `access:"authentication"`
- IdpMetadataUrl *string `access:"authentication"`
- ServiceProviderIdentifier *string `access:"authentication"`
- AssertionConsumerServiceURL *string `access:"authentication"`
+ IdpUrl *string `access:"authentication_saml"` // telemetry: none
+ IdpDescriptorUrl *string `access:"authentication_saml"` // telemetry: none
+ IdpMetadataUrl *string `access:"authentication_saml"` // telemetry: none
+ ServiceProviderIdentifier *string `access:"authentication_saml"` // telemetry: none
+ AssertionConsumerServiceURL *string `access:"authentication_saml"` // telemetry: none
- SignatureAlgorithm *string `access:"authentication"`
- CanonicalAlgorithm *string `access:"authentication"`
+ SignatureAlgorithm *string `access:"authentication_saml"`
+ CanonicalAlgorithm *string `access:"authentication_saml"`
- ScopingIDPProviderId *string `access:"authentication"`
- ScopingIDPName *string `access:"authentication"`
+ ScopingIDPProviderId *string `access:"authentication_saml"`
+ ScopingIDPName *string `access:"authentication_saml"`
- IdpCertificateFile *string `access:"authentication"`
- PublicCertificateFile *string `access:"authentication"`
- PrivateKeyFile *string `access:"authentication"`
+ IdpCertificateFile *string `access:"authentication_saml"` // telemetry: none
+ PublicCertificateFile *string `access:"authentication_saml"` // telemetry: none
+ PrivateKeyFile *string `access:"authentication_saml"` // telemetry: none
// User Mapping
- IdAttribute *string `access:"authentication"`
- GuestAttribute *string `access:"authentication"`
+ IdAttribute *string `access:"authentication_saml"`
+ GuestAttribute *string `access:"authentication_saml"`
EnableAdminAttribute *bool
AdminAttribute *string
- FirstNameAttribute *string `access:"authentication"`
- LastNameAttribute *string `access:"authentication"`
- EmailAttribute *string `access:"authentication"`
- UsernameAttribute *string `access:"authentication"`
- NicknameAttribute *string `access:"authentication"`
- LocaleAttribute *string `access:"authentication"`
- PositionAttribute *string `access:"authentication"`
+ FirstNameAttribute *string `access:"authentication_saml"`
+ LastNameAttribute *string `access:"authentication_saml"`
+ EmailAttribute *string `access:"authentication_saml"`
+ UsernameAttribute *string `access:"authentication_saml"`
+ NicknameAttribute *string `access:"authentication_saml"`
+ LocaleAttribute *string `access:"authentication_saml"`
+ PositionAttribute *string `access:"authentication_saml"`
- LoginButtonText *string `access:"authentication"`
+ LoginButtonText *string `access:"authentication_saml"`
- LoginButtonColor *string `access:"authentication"`
- LoginButtonBorderColor *string `access:"authentication"`
- LoginButtonTextColor *string `access:"authentication"`
+ LoginButtonColor *string `access:"experimental_features"`
+ LoginButtonBorderColor *string `access:"experimental_features"`
+ LoginButtonTextColor *string `access:"experimental_features"`
}
func (s *SamlSettings) SetDefaults() {
@@ -2396,9 +2531,10 @@ func (s *SamlSettings) SetDefaults() {
}
type NativeAppSettings struct {
- AppDownloadLink *string `access:"site,write_restrictable,cloud_restrictable"`
- AndroidAppDownloadLink *string `access:"site,write_restrictable,cloud_restrictable"`
- IosAppDownloadLink *string `access:"site,write_restrictable,cloud_restrictable"`
+ AppCustomURLSchemes []string `access:"site_customization,write_restrictable,cloud_restrictable"` // telemetry: none
+ AppDownloadLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
+ AndroidAppDownloadLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
+ IosAppDownloadLink *string `access:"site_customization,write_restrictable,cloud_restrictable"`
}
func (s *NativeAppSettings) SetDefaults() {
@@ -2413,30 +2549,34 @@ func (s *NativeAppSettings) SetDefaults() {
if s.IosAppDownloadLink == nil {
s.IosAppDownloadLink = NewString(NATIVEAPP_SETTINGS_DEFAULT_IOS_APP_DOWNLOAD_LINK)
}
+
+ if s.AppCustomURLSchemes == nil {
+ s.AppCustomURLSchemes = GetDefaultAppCustomURLSchemes()
+ }
}
type ElasticsearchSettings struct {
- ConnectionUrl *string `access:"environment,write_restrictable,cloud_restrictable"`
- Username *string `access:"environment,write_restrictable,cloud_restrictable"`
- Password *string `access:"environment,write_restrictable,cloud_restrictable"`
- EnableIndexing *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableSearching *bool `access:"environment,write_restrictable,cloud_restrictable"`
- EnableAutocomplete *bool `access:"environment,write_restrictable,cloud_restrictable"`
- Sniff *bool `access:"environment,write_restrictable,cloud_restrictable"`
- PostIndexReplicas *int `access:"environment,write_restrictable,cloud_restrictable"`
- PostIndexShards *int `access:"environment,write_restrictable,cloud_restrictable"`
- ChannelIndexReplicas *int `access:"environment,write_restrictable,cloud_restrictable"`
- ChannelIndexShards *int `access:"environment,write_restrictable,cloud_restrictable"`
- UserIndexReplicas *int `access:"environment,write_restrictable,cloud_restrictable"`
- UserIndexShards *int `access:"environment,write_restrictable,cloud_restrictable"`
- AggregatePostsAfterDays *int `access:"environment,write_restrictable,cloud_restrictable"`
- PostsAggregatorJobStartTime *string `access:"environment,write_restrictable,cloud_restrictable"`
- IndexPrefix *string `access:"environment,write_restrictable,cloud_restrictable"`
- LiveIndexingBatchSize *int `access:"environment,write_restrictable,cloud_restrictable"`
- BulkIndexingTimeWindowSeconds *int `access:"environment,write_restrictable,cloud_restrictable"`
- RequestTimeoutSeconds *int `access:"environment,write_restrictable,cloud_restrictable"`
- SkipTLSVerification *bool `access:"environment,write_restrictable,cloud_restrictable"`
- Trace *string `access:"environment,write_restrictable,cloud_restrictable"`
+ ConnectionUrl *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ Username *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ Password *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ EnableIndexing *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ EnableSearching *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ EnableAutocomplete *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ Sniff *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ PostIndexReplicas *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ PostIndexShards *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ ChannelIndexReplicas *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ ChannelIndexShards *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ UserIndexReplicas *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ UserIndexShards *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ AggregatePostsAfterDays *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` // telemetry: none
+ PostsAggregatorJobStartTime *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"` // telemetry: none
+ IndexPrefix *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ LiveIndexingBatchSize *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ BulkIndexingTimeWindowSeconds *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ RequestTimeoutSeconds *int `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ SkipTLSVerification *bool `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
+ Trace *string `access:"environment_elasticsearch,write_restrictable,cloud_restrictable"`
}
func (s *ElasticsearchSettings) SetDefaults() {
@@ -2526,11 +2666,11 @@ func (s *ElasticsearchSettings) SetDefaults() {
}
type BleveSettings struct {
- IndexDir *string `access:"experimental"`
- EnableIndexing *bool `access:"experimental"`
- EnableSearching *bool `access:"experimental"`
- EnableAutocomplete *bool `access:"experimental"`
- BulkIndexingTimeWindowSeconds *int `access:"experimental"`
+ IndexDir *string `access:"experimental_bleve"` // telemetry: none
+ EnableIndexing *bool `access:"experimental_bleve"`
+ EnableSearching *bool `access:"experimental_bleve"`
+ EnableAutocomplete *bool `access:"experimental_bleve"`
+ BulkIndexingTimeWindowSeconds *int `access:"experimental_bleve"`
}
func (bs *BleveSettings) SetDefaults() {
@@ -2556,11 +2696,12 @@ func (bs *BleveSettings) SetDefaults() {
}
type DataRetentionSettings struct {
- EnableMessageDeletion *bool `access:"compliance"`
- EnableFileDeletion *bool `access:"compliance"`
- MessageRetentionDays *int `access:"compliance"`
- FileRetentionDays *int `access:"compliance"`
- DeletionJobStartTime *string `access:"compliance"`
+ EnableMessageDeletion *bool `access:"compliance_data_retention_policy"`
+ EnableFileDeletion *bool `access:"compliance_data_retention_policy"`
+ MessageRetentionDays *int `access:"compliance_data_retention_policy"`
+ FileRetentionDays *int `access:"compliance_data_retention_policy"`
+ DeletionJobStartTime *string `access:"compliance_data_retention_policy"`
+ BatchSize *int `access:"compliance_data_retention_policy"`
}
func (s *DataRetentionSettings) SetDefaults() {
@@ -2583,6 +2724,10 @@ func (s *DataRetentionSettings) SetDefaults() {
if s.DeletionJobStartTime == nil {
s.DeletionJobStartTime = NewString(DATA_RETENTION_SETTINGS_DEFAULT_DELETION_JOB_START_TIME)
}
+
+ if s.BatchSize == nil {
+ s.BatchSize = NewInt(DATA_RETENTION_SETTINGS_DEFAULT_BATCH_SIZE)
+ }
}
type JobSettings struct {
@@ -2601,13 +2746,17 @@ func (s *JobSettings) SetDefaults() {
}
type CloudSettings struct {
- CWSUrl *string `access:"environment,write_restrictable"`
+ CWSUrl *string `access:"write_restrictable"`
+ CWSAPIUrl *string `access:"write_restrictable"`
}
func (s *CloudSettings) SetDefaults() {
if s.CWSUrl == nil {
s.CWSUrl = NewString(CLOUD_SETTINGS_DEFAULT_CWS_URL)
}
+ if s.CWSAPIUrl == nil {
+ s.CWSAPIUrl = NewString(CLOUD_SETTINGS_DEFAULT_CWS_API_URL)
+ }
}
type PluginState struct {
@@ -2619,16 +2768,17 @@ type PluginSettings struct {
EnableUploads *bool `access:"plugins,write_restrictable,cloud_restrictable"`
AllowInsecureDownloadUrl *bool `access:"plugins,write_restrictable,cloud_restrictable"`
EnableHealthCheck *bool `access:"plugins,write_restrictable,cloud_restrictable"`
- Directory *string `access:"plugins,write_restrictable,cloud_restrictable"`
- ClientDirectory *string `access:"plugins,write_restrictable,cloud_restrictable"`
- Plugins map[string]map[string]interface{} `access:"plugins"`
- PluginStates map[string]*PluginState `access:"plugins"`
+ Directory *string `access:"plugins,write_restrictable,cloud_restrictable"` // telemetry: none
+ ClientDirectory *string `access:"plugins,write_restrictable,cloud_restrictable"` // telemetry: none
+ Plugins map[string]map[string]interface{} `access:"plugins"` // telemetry: none
+ PluginStates map[string]*PluginState `access:"plugins"` // telemetry: none
EnableMarketplace *bool `access:"plugins,write_restrictable,cloud_restrictable"`
EnableRemoteMarketplace *bool `access:"plugins,write_restrictable,cloud_restrictable"`
AutomaticPrepackagedPlugins *bool `access:"plugins,write_restrictable,cloud_restrictable"`
RequirePluginSignature *bool `access:"plugins,write_restrictable,cloud_restrictable"`
MarketplaceUrl *string `access:"plugins,write_restrictable,cloud_restrictable"`
SignaturePublicKeyFiles []string `access:"plugins,write_restrictable,cloud_restrictable"`
+ ChimeraOAuthProxyUrl *string `access:"plugins,write_restrictable,cloud_restrictable"`
}
func (s *PluginSettings) SetDefaults(ls LogSettings) {
@@ -2702,14 +2852,18 @@ func (s *PluginSettings) SetDefaults(ls LogSettings) {
if s.SignaturePublicKeyFiles == nil {
s.SignaturePublicKeyFiles = []string{}
}
+
+ if s.ChimeraOAuthProxyUrl == nil {
+ s.ChimeraOAuthProxyUrl = NewString("")
+ }
}
type GlobalRelayMessageExportSettings struct {
- CustomerType *string `access:"compliance"` // must be either A9 or A10, dictates SMTP server url
- SmtpUsername *string `access:"compliance"`
- SmtpPassword *string `access:"compliance"`
- EmailAddress *string `access:"compliance"` // the address to send messages to
- SMTPServerTimeout *int `access:"compliance"`
+ CustomerType *string `access:"compliance_compliance_export"` // must be either A9 or A10, dictates SMTP server url
+ SmtpUsername *string `access:"compliance_compliance_export"`
+ SmtpPassword *string `access:"compliance_compliance_export"`
+ EmailAddress *string `access:"compliance_compliance_export"` // the address to send messages to
+ SMTPServerTimeout *int `access:"compliance_compliance_export"`
}
func (s *GlobalRelayMessageExportSettings) SetDefaults() {
@@ -2731,15 +2885,15 @@ func (s *GlobalRelayMessageExportSettings) SetDefaults() {
}
type MessageExportSettings struct {
- EnableExport *bool `access:"compliance"`
- ExportFormat *string `access:"compliance"`
- DailyRunTime *string `access:"compliance"`
- ExportFromTimestamp *int64 `access:"compliance"`
- BatchSize *int `access:"compliance"`
- DownloadExportResults *bool `access:"compliance"`
+ EnableExport *bool `access:"compliance_compliance_export"`
+ ExportFormat *string `access:"compliance_compliance_export"`
+ DailyRunTime *string `access:"compliance_compliance_export"`
+ ExportFromTimestamp *int64 `access:"compliance_compliance_export"`
+ BatchSize *int `access:"compliance_compliance_export"`
+ DownloadExportResults *bool `access:"compliance_compliance_export"`
// formatter-specific settings - these are only expected to be non-nil if ExportFormat is set to the associated format
- GlobalRelaySettings *GlobalRelayMessageExportSettings
+ GlobalRelaySettings *GlobalRelayMessageExportSettings `access:"compliance_compliance_export"`
}
func (s *MessageExportSettings) SetDefaults() {
@@ -2774,8 +2928,8 @@ func (s *MessageExportSettings) SetDefaults() {
}
type DisplaySettings struct {
- CustomUrlSchemes []string `access:"site"`
- ExperimentalTimezone *bool `access:"experimental"`
+ CustomUrlSchemes []string `access:"site_customization"`
+ ExperimentalTimezone *bool `access:"experimental_features"`
}
func (s *DisplaySettings) SetDefaults() {
@@ -2790,10 +2944,10 @@ func (s *DisplaySettings) SetDefaults() {
}
type GuestAccountsSettings struct {
- Enable *bool `access:"authentication"`
- AllowEmailAccounts *bool `access:"authentication"`
- EnforceMultifactorAuthentication *bool `access:"authentication"`
- RestrictCreationToDomains *string `access:"authentication"`
+ Enable *bool `access:"authentication_guest_access"`
+ AllowEmailAccounts *bool `access:"authentication_guest_access"`
+ EnforceMultifactorAuthentication *bool `access:"authentication_guest_access"`
+ RestrictCreationToDomains *string `access:"authentication_guest_access"`
}
func (s *GuestAccountsSettings) SetDefaults() {
@@ -2815,10 +2969,10 @@ func (s *GuestAccountsSettings) SetDefaults() {
}
type ImageProxySettings struct {
- Enable *bool `access:"environment"`
- ImageProxyType *string `access:"environment"`
- RemoteImageProxyURL *string `access:"environment"`
- RemoteImageProxyOptions *string `access:"environment"`
+ Enable *bool `access:"environment_image_proxy"`
+ ImageProxyType *string `access:"environment_image_proxy"`
+ RemoteImageProxyURL *string `access:"environment_image_proxy"`
+ RemoteImageProxyOptions *string `access:"environment_image_proxy"`
}
func (s *ImageProxySettings) SetDefaults(ss ServiceSettings) {
@@ -2855,19 +3009,89 @@ func (s *ImageProxySettings) SetDefaults(ss ServiceSettings) {
}
}
+// ImportSettings defines configuration settings for file imports.
+type ImportSettings struct {
+ // The directory where to store the imported files.
+ Directory *string
+ // The number of days to retain the imported files before deleting them.
+ RetentionDays *int
+}
+
+func (s *ImportSettings) isValid() *AppError {
+ if *s.Directory == "" {
+ return NewAppError("Config.IsValid", "model.config.is_valid.import.directory.app_error", nil, "", http.StatusBadRequest)
+ }
+
+ if *s.RetentionDays <= 0 {
+ return NewAppError("Config.IsValid", "model.config.is_valid.import.retention_days_too_low.app_error", nil, "", http.StatusBadRequest)
+ }
+
+ return nil
+}
+
+// SetDefaults applies the default settings to the struct.
+func (s *ImportSettings) SetDefaults() {
+ if s.Directory == nil || *s.Directory == "" {
+ s.Directory = NewString(IMPORT_SETTINGS_DEFAULT_DIRECTORY)
+ }
+
+ if s.RetentionDays == nil {
+ s.RetentionDays = NewInt(IMPORT_SETTINGS_DEFAULT_RETENTION_DAYS)
+ }
+}
+
+// ExportSettings defines configuration settings for file exports.
+type ExportSettings struct {
+ // The directory where to store the exported files.
+ Directory *string // telemetry: none
+ // The number of days to retain the exported files before deleting them.
+ RetentionDays *int
+}
+
+func (s *ExportSettings) isValid() *AppError {
+ if *s.Directory == "" {
+ return NewAppError("Config.IsValid", "model.config.is_valid.export.directory.app_error", nil, "", http.StatusBadRequest)
+ }
+
+ if *s.RetentionDays <= 0 {
+ return NewAppError("Config.IsValid", "model.config.is_valid.export.retention_days_too_low.app_error", nil, "", http.StatusBadRequest)
+ }
+
+ return nil
+}
+
+// SetDefaults applies the default settings to the struct.
+func (s *ExportSettings) SetDefaults() {
+ if s.Directory == nil || *s.Directory == "" {
+ s.Directory = NewString(EXPORT_SETTINGS_DEFAULT_DIRECTORY)
+ }
+
+ if s.RetentionDays == nil {
+ s.RetentionDays = NewInt(EXPORT_SETTINGS_DEFAULT_RETENTION_DAYS)
+ }
+}
+
type ConfigFunc func() *Config
const ConfigAccessTagType = "access"
const ConfigAccessTagWriteRestrictable = "write_restrictable"
const ConfigAccessTagCloudRestrictable = "cloud_restrictable"
+// Allows read access if any PERMISSION_SYSCONSOLE_READ_* is allowed
+const ConfigAccessTagAnySysConsoleRead = "*_read"
+
// Config fields support the 'access' tag with the following values corresponding to the suffix of the associated
// PERMISSION_SYSCONSOLE_*_* permission Id: 'about', 'reporting', 'user_management_users',
// 'user_management_groups', 'user_management_teams', 'user_management_channels',
-// 'user_management_permissions', 'environment', 'site', 'authentication', 'plugins',
+// 'user_management_permissions', 'environment_web_server', 'environment_database', 'environment_elasticsearch',
+// 'environment_file_storage', 'environment_image_proxy', 'environment_smtp', 'environment_push_notification_server',
+// 'environment_high_availability', 'environment_rate_limiting', 'environment_logging', 'environment_session_lengths',
+// 'environment_performance_monitoring', 'environment_developer', 'site', 'authentication', 'plugins',
// 'integrations', 'compliance', 'plugins', and 'experimental'. They grant read and/or write access to the config field
// to roles without PERMISSION_MANAGE_SYSTEM.
//
+// The 'access' tag '*_read' checks for any SYSCONSOLE read permission and grants access if any read permission is allowed.
+//
// By default config values can be written with PERMISSION_MANAGE_SYSTEM, but if ExperimentalSettings.RestrictSystemAdmin is true
// and the access tag contains the value 'write_restrictable', then even PERMISSION_MANAGE_SYSTEM does not grant write access.
//
@@ -2910,6 +3134,7 @@ type Config struct {
GitLabSettings SSOSettings
GoogleSettings SSOSettings
Office365Settings Office365Settings
+ OpenIdSettings SSOSettings
LdapSettings LdapSettings
ComplianceSettings ComplianceSettings
LocalizationSettings LocalizationSettings
@@ -2923,13 +3148,15 @@ type Config struct {
BleveSettings BleveSettings
DataRetentionSettings DataRetentionSettings
MessageExportSettings MessageExportSettings
- JobSettings JobSettings
+ JobSettings JobSettings // telemetry: none
PluginSettings PluginSettings
DisplaySettings DisplaySettings
GuestAccountsSettings GuestAccountsSettings
ImageProxySettings ImageProxySettings
- CloudSettings CloudSettings
- FeatureFlags *FeatureFlags `json:",omitempty"`
+ CloudSettings CloudSettings // telemetry: none
+ FeatureFlags *FeatureFlags `access:"*_read" json:",omitempty"`
+ ImportSettings ImportSettings // telemetry: none
+ ExportSettings ExportSettings
}
func (o *Config) Clone() *Config {
@@ -2965,6 +3192,8 @@ func (o *Config) GetSSOService(service string) *SSOSettings {
return &o.GoogleSettings
case SERVICE_OFFICE365:
return o.Office365Settings.SSOSettings()
+ case SERVICE_OPENID:
+ return &o.OpenIdSettings
}
return nil
@@ -3000,8 +3229,10 @@ func (o *Config) SetDefaults() {
o.EmailSettings.SetDefaults(isUpdate)
o.PrivacySettings.setDefaults()
o.Office365Settings.setDefaults()
- o.GitLabSettings.setDefaults("", "", "", "")
- o.GoogleSettings.setDefaults(GOOGLE_SETTINGS_DEFAULT_SCOPE, GOOGLE_SETTINGS_DEFAULT_AUTH_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_TOKEN_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_USER_API_ENDPOINT)
+ o.Office365Settings.setDefaults()
+ o.GitLabSettings.setDefaults("", "", "", "", "")
+ o.GoogleSettings.setDefaults(GOOGLE_SETTINGS_DEFAULT_SCOPE, GOOGLE_SETTINGS_DEFAULT_AUTH_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_TOKEN_ENDPOINT, GOOGLE_SETTINGS_DEFAULT_USER_API_ENDPOINT, "")
+ o.OpenIdSettings.setDefaults(OPENID_SETTINGS_DEFAULT_SCOPE, "", "", "", "#145DBF")
o.ServiceSettings.SetDefaults(isUpdate)
o.PasswordSettings.SetDefaults()
o.TeamSettings.SetDefaults()
@@ -3033,10 +3264,12 @@ func (o *Config) SetDefaults() {
o.FeatureFlags = &FeatureFlags{}
o.FeatureFlags.SetDefaults()
}
+ o.ImportSettings.SetDefaults()
+ o.ExportSettings.SetDefaults()
}
func (o *Config) IsValid() *AppError {
- if len(*o.ServiceSettings.SiteURL) == 0 && *o.EmailSettings.EnableEmailBatching {
+ if *o.ServiceSettings.SiteURL == "" && *o.EmailSettings.EnableEmailBatching {
return NewAppError("Config.IsValid", "model.config.is_valid.site_url_email_batching.app_error", nil, "", http.StatusBadRequest)
}
@@ -3044,7 +3277,7 @@ func (o *Config) IsValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.cluster_email_batching.app_error", nil, "", http.StatusBadRequest)
}
- if len(*o.ServiceSettings.SiteURL) == 0 && *o.ServiceSettings.AllowCookiesForSubdomains {
+ if *o.ServiceSettings.SiteURL == "" && *o.ServiceSettings.AllowCookiesForSubdomains {
return NewAppError("Config.IsValid", "model.config.is_valid.allow_cookies_for_subdomains.app_error", nil, "", http.StatusBadRequest)
}
@@ -3100,7 +3333,7 @@ func (o *Config) IsValid() *AppError {
return err
}
- if err := o.MessageExportSettings.isValid(o.FileSettings); err != nil {
+ if err := o.MessageExportSettings.isValid(); err != nil {
return err
}
@@ -3111,6 +3344,10 @@ func (o *Config) IsValid() *AppError {
if err := o.ImageProxySettings.isValid(); err != nil {
return err
}
+
+ if err := o.ImportSettings.isValid(); err != nil {
+ return err
+ }
return nil
}
@@ -3159,11 +3396,15 @@ func (s *SqlSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.sql_conn_max_lifetime_milliseconds.app_error", nil, "", http.StatusBadRequest)
}
+ if *s.ConnMaxIdleTimeMilliseconds < 0 {
+ return NewAppError("Config.IsValid", "model.config.is_valid.sql_conn_max_idle_time_milliseconds.app_error", nil, "", http.StatusBadRequest)
+ }
+
if *s.QueryTimeout <= 0 {
return NewAppError("Config.IsValid", "model.config.is_valid.sql_query_timeout.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.DataSource) == 0 {
+ if *s.DataSource == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.sql_data_src.app_error", nil, "", http.StatusBadRequest)
}
@@ -3292,47 +3533,47 @@ func (s *LdapSettings) isValid() *AppError {
func (s *SamlSettings) isValid() *AppError {
if *s.Enable {
- if len(*s.IdpUrl) == 0 || !IsValidHttpUrl(*s.IdpUrl) {
+ if *s.IdpUrl == "" || !IsValidHttpUrl(*s.IdpUrl) {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_idp_url.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.IdpDescriptorUrl) == 0 || !IsValidHttpUrl(*s.IdpDescriptorUrl) {
+ if *s.IdpDescriptorUrl == "" || !IsValidHttpUrl(*s.IdpDescriptorUrl) {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_idp_descriptor_url.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.IdpCertificateFile) == 0 {
+ if *s.IdpCertificateFile == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_idp_cert.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.EmailAttribute) == 0 {
+ if *s.EmailAttribute == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_email_attribute.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.UsernameAttribute) == 0 {
+ if *s.UsernameAttribute == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_username_attribute.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.ServiceProviderIdentifier) == 0 {
+ if *s.ServiceProviderIdentifier == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_spidentifier_attribute.app_error", nil, "", http.StatusBadRequest)
}
if *s.Verify {
- if len(*s.AssertionConsumerServiceURL) == 0 || !IsValidHttpUrl(*s.AssertionConsumerServiceURL) {
+ if *s.AssertionConsumerServiceURL == "" || !IsValidHttpUrl(*s.AssertionConsumerServiceURL) {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_assertion_consumer_service_url.app_error", nil, "", http.StatusBadRequest)
}
}
if *s.Encrypt {
- if len(*s.PrivateKeyFile) == 0 {
+ if *s.PrivateKeyFile == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_private_key.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.PublicCertificateFile) == 0 {
+ if *s.PublicCertificateFile == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_public_cert.app_error", nil, "", http.StatusBadRequest)
}
}
- if len(*s.EmailAttribute) == 0 {
+ if *s.EmailAttribute == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_email_attribute.app_error", nil, "", http.StatusBadRequest)
}
@@ -3343,7 +3584,7 @@ func (s *SamlSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_canonical_algorithm.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.GuestAttribute) > 0 {
+ if *s.GuestAttribute != "" {
if !(strings.Contains(*s.GuestAttribute, "=")) {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_guest_attribute.app_error", nil, "", http.StatusBadRequest)
}
@@ -3352,7 +3593,7 @@ func (s *SamlSettings) isValid() *AppError {
}
}
- if len(*s.AdminAttribute) > 0 {
+ if *s.AdminAttribute != "" {
if !(strings.Contains(*s.AdminAttribute, "=")) {
return NewAppError("Config.IsValid", "model.config.is_valid.saml_admin_attribute.app_error", nil, "", http.StatusBadRequest)
}
@@ -3371,7 +3612,7 @@ func (s *ServiceSettings) isValid() *AppError {
}
if *s.ConnectionSecurity == CONN_SECURITY_TLS && !*s.UseLetsEncrypt {
- appErr := NewAppError("Config.IsValid", "model.config.is_valid.tls_cert_file.app_error", nil, "", http.StatusBadRequest)
+ appErr := NewAppError("Config.IsValid", "model.config.is_valid.tls_cert_file_missing.app_error", nil, "", http.StatusBadRequest)
if *s.TLSCertFile == "" {
return appErr
@@ -3379,7 +3620,7 @@ func (s *ServiceSettings) isValid() *AppError {
return appErr
}
- appErr = NewAppError("Config.IsValid", "model.config.is_valid.tls_key_file.app_error", nil, "", http.StatusBadRequest)
+ appErr = NewAppError("Config.IsValid", "model.config.is_valid.tls_key_file_missing.app_error", nil, "", http.StatusBadRequest)
if *s.TLSKeyFile == "" {
return appErr
@@ -3412,13 +3653,13 @@ func (s *ServiceSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.login_attempts.app_error", nil, "", http.StatusBadRequest)
}
- if len(*s.SiteURL) != 0 {
+ if *s.SiteURL != "" {
if _, err := url.ParseRequestURI(*s.SiteURL); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.site_url.app_error", nil, "", http.StatusBadRequest)
}
}
- if len(*s.WebsocketURL) != 0 {
+ if *s.WebsocketURL != "" {
if _, err := url.ParseRequestURI(*s.WebsocketURL); err != nil {
return NewAppError("Config.IsValid", "model.config.is_valid.websocket_url.app_error", nil, "", http.StatusBadRequest)
}
@@ -3442,12 +3683,22 @@ func (s *ServiceSettings) isValid() *AppError {
return NewAppError("Config.IsValid", "model.config.is_valid.group_unread_channels.app_error", nil, "", http.StatusBadRequest)
}
+ if *s.CollapsedThreads != COLLAPSED_THREADS_DISABLED && !*s.ThreadAutoFollow {
+ return NewAppError("Config.IsValid", "model.config.is_valid.collapsed_threads.autofollow.app_error", nil, "", http.StatusBadRequest)
+ }
+
+ if *s.CollapsedThreads != COLLAPSED_THREADS_DISABLED &&
+ *s.CollapsedThreads != COLLAPSED_THREADS_DEFAULT_ON &&
+ *s.CollapsedThreads != COLLAPSED_THREADS_DEFAULT_OFF {
+ return NewAppError("Config.IsValid", "model.config.is_valid.collapsed_threads.app_error", nil, "", http.StatusBadRequest)
+ }
+
return nil
}
func (s *ElasticsearchSettings) isValid() *AppError {
if *s.EnableIndexing {
- if len(*s.ConnectionUrl) == 0 {
+ if *s.ConnectionUrl == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.elastic_search.connection_url.app_error", nil, "", http.StatusBadRequest)
}
}
@@ -3485,7 +3736,7 @@ func (s *ElasticsearchSettings) isValid() *AppError {
func (bs *BleveSettings) isValid() *AppError {
if *bs.EnableIndexing {
- if len(*bs.IndexDir) == 0 {
+ if *bs.IndexDir == "" {
return NewAppError("Config.IsValid", "model.config.is_valid.bleve_search.filename.app_error", nil, "", http.StatusBadRequest)
}
} else {
@@ -3520,7 +3771,7 @@ func (s *DataRetentionSettings) isValid() *AppError {
}
func (s *LocalizationSettings) isValid() *AppError {
- if len(*s.AvailableLocales) > 0 {
+ if *s.AvailableLocales != "" {
if !strings.Contains(*s.AvailableLocales, *s.DefaultClientLocale) {
return NewAppError("Config.IsValid", "model.config.is_valid.localization.available_locales.app_error", nil, "", http.StatusBadRequest)
}
@@ -3529,7 +3780,7 @@ func (s *LocalizationSettings) isValid() *AppError {
return nil
}
-func (s *MessageExportSettings) isValid(fs FileSettings) *AppError {
+func (s *MessageExportSettings) isValid() *AppError {
if s.EnableExport == nil {
return NewAppError("Config.IsValid", "model.config.is_valid.message_export.enable.app_error", nil, "", http.StatusBadRequest)
}
@@ -3615,32 +3866,36 @@ func (o *Config) GetSanitizeOptions() map[string]bool {
}
func (o *Config) Sanitize() {
- if o.LdapSettings.BindPassword != nil && len(*o.LdapSettings.BindPassword) > 0 {
+ if o.LdapSettings.BindPassword != nil && *o.LdapSettings.BindPassword != "" {
*o.LdapSettings.BindPassword = FAKE_SETTING
}
*o.FileSettings.PublicLinkSalt = FAKE_SETTING
- if len(*o.FileSettings.AmazonS3SecretAccessKey) > 0 {
+ if *o.FileSettings.AmazonS3SecretAccessKey != "" {
*o.FileSettings.AmazonS3SecretAccessKey = FAKE_SETTING
}
- if o.EmailSettings.SMTPPassword != nil && len(*o.EmailSettings.SMTPPassword) > 0 {
+ if o.EmailSettings.SMTPPassword != nil && *o.EmailSettings.SMTPPassword != "" {
*o.EmailSettings.SMTPPassword = FAKE_SETTING
}
- if len(*o.GitLabSettings.Secret) > 0 {
+ if *o.GitLabSettings.Secret != "" {
*o.GitLabSettings.Secret = FAKE_SETTING
}
- if o.GoogleSettings.Secret != nil && len(*o.GoogleSettings.Secret) > 0 {
+ if o.GoogleSettings.Secret != nil && *o.GoogleSettings.Secret != "" {
*o.GoogleSettings.Secret = FAKE_SETTING
}
- if o.Office365Settings.Secret != nil && len(*o.Office365Settings.Secret) > 0 {
+ if o.Office365Settings.Secret != nil && *o.Office365Settings.Secret != "" {
*o.Office365Settings.Secret = FAKE_SETTING
}
+ if o.OpenIdSettings.Secret != nil && *o.OpenIdSettings.Secret != "" {
+ *o.OpenIdSettings.Secret = FAKE_SETTING
+ }
+
*o.SqlSettings.DataSource = FAKE_SETTING
*o.SqlSettings.AtRestEncryptKey = FAKE_SETTING
@@ -3654,11 +3909,11 @@ func (o *Config) Sanitize() {
o.SqlSettings.DataSourceSearchReplicas[i] = FAKE_SETTING
}
- if o.MessageExportSettings.GlobalRelaySettings.SmtpPassword != nil && len(*o.MessageExportSettings.GlobalRelaySettings.SmtpPassword) > 0 {
+ if o.MessageExportSettings.GlobalRelaySettings.SmtpPassword != nil && *o.MessageExportSettings.GlobalRelaySettings.SmtpPassword != "" {
*o.MessageExportSettings.GlobalRelaySettings.SmtpPassword = FAKE_SETTING
}
- if o.ServiceSettings.GfycatApiSecret != nil && len(*o.ServiceSettings.GfycatApiSecret) > 0 {
+ if o.ServiceSettings.GfycatApiSecret != nil && *o.ServiceSettings.GfycatApiSecret != "" {
*o.ServiceSettings.GfycatApiSecret = FAKE_SETTING
}
@@ -3670,7 +3925,7 @@ func (o *Config) Sanitize() {
func structToMapFilteredByTag(t interface{}, typeOfTag, filterTag string) map[string]interface{} {
defer func() {
if r := recover(); r != nil {
- mlog.Error("Panicked in structToMapFilteredByTag. This should never happen.", mlog.Any("recover", r))
+ mlog.Warn("Panicked in structToMapFilteredByTag. This should never happen.", mlog.Any("recover", r))
}
}()
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/custom_status.go b/vendor/github.com/mattermost/mattermost-server/v5/model/custom_status.go
new file mode 100644
index 00000000..9898ce6c
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/custom_status.go
@@ -0,0 +1,141 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "time"
+)
+
+const (
+ UserPropsKeyCustomStatus = "customStatus"
+
+ CustomStatusTextMaxRunes = 100
+ MaxRecentCustomStatuses = 5
+ DefaultCustomStatusEmoji = "speech_balloon"
+)
+
+var validCustomStatusDuration = map[string]bool{
+ "thirty_minutes": true,
+ "one_hour": true,
+ "four_hours": true,
+ "today": true,
+ "this_week": true,
+ "date_and_time": true,
+}
+
+type CustomStatus struct {
+ Emoji string `json:"emoji"`
+ Text string `json:"text"`
+ Duration string `json:"duration"`
+ ExpiresAt time.Time `json:"expires_at"`
+}
+
+func (cs *CustomStatus) PreSave() {
+ if cs.Emoji == "" {
+ cs.Emoji = DefaultCustomStatusEmoji
+ }
+
+ if cs.Duration == "" && !cs.ExpiresAt.Before(time.Now()) {
+ cs.Duration = "date_and_time"
+ }
+
+ runes := []rune(cs.Text)
+ if len(runes) > CustomStatusTextMaxRunes {
+ cs.Text = string(runes[:CustomStatusTextMaxRunes])
+ }
+}
+
+func (cs *CustomStatus) ToJson() string {
+ csCopy := *cs
+ b, _ := json.Marshal(csCopy)
+ return string(b)
+}
+
+func (cs *CustomStatus) AreDurationAndExpirationTimeValid() bool {
+ if cs.Duration == "" && (cs.ExpiresAt.IsZero() || !cs.ExpiresAt.Before(time.Now())) {
+ return true
+ }
+
+ if validCustomStatusDuration[cs.Duration] && !cs.ExpiresAt.Before(time.Now()) {
+ return true
+ }
+
+ return false
+}
+
+func CustomStatusFromJson(data io.Reader) *CustomStatus {
+ var cs *CustomStatus
+ _ = json.NewDecoder(data).Decode(&cs)
+ return cs
+}
+
+func RuneToHexadecimalString(r rune) string {
+ return fmt.Sprintf("%04x", r)
+}
+
+type RecentCustomStatuses []CustomStatus
+
+func (rcs *RecentCustomStatuses) Contains(cs *CustomStatus) bool {
+ var csJSON = cs.ToJson()
+
+ // status is empty
+ if cs == nil || csJSON == "" || (cs.Emoji == "" && cs.Text == "") {
+ return false
+ }
+
+ for _, status := range *rcs {
+ if status.ToJson() == csJSON {
+ return true
+ }
+ }
+
+ return false
+}
+
+func (rcs *RecentCustomStatuses) Add(cs *CustomStatus) *RecentCustomStatuses {
+ newRCS := (*rcs)[:0]
+
+ // if same `text` exists in existing recent custom statuses, modify existing status
+ for _, status := range *rcs {
+ if status.Text != cs.Text {
+ newRCS = append(newRCS, status)
+ }
+ }
+ newRCS = append(RecentCustomStatuses{*cs}, newRCS...)
+ if len(newRCS) > MaxRecentCustomStatuses {
+ newRCS = newRCS[:MaxRecentCustomStatuses]
+ }
+ return &newRCS
+}
+
+func (rcs *RecentCustomStatuses) Remove(cs *CustomStatus) *RecentCustomStatuses {
+ var csJSON = cs.ToJson()
+ if csJSON == "" || (cs.Emoji == "" && cs.Text == "") {
+ return rcs
+ }
+
+ newRCS := (*rcs)[:0]
+ for _, status := range *rcs {
+ if status.ToJson() != csJSON {
+ newRCS = append(newRCS, status)
+ }
+ }
+
+ return &newRCS
+}
+
+func (rcs *RecentCustomStatuses) ToJson() string {
+ rcsCopy := *rcs
+ b, _ := json.Marshal(rcsCopy)
+ return string(b)
+}
+
+func RecentCustomStatusesFromJson(data io.Reader) *RecentCustomStatuses {
+ var rcs *RecentCustomStatuses
+ _ = json.NewDecoder(data).Decode(&rcs)
+ return rcs
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/data_retention_policy.go b/vendor/github.com/mattermost/mattermost-server/v5/model/data_retention_policy.go
index a39ff911..3f984d1b 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/data_retention_policy.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/data_retention_policy.go
@@ -8,20 +8,125 @@ import (
"io"
)
-type DataRetentionPolicy struct {
+type GlobalRetentionPolicy struct {
MessageDeletionEnabled bool `json:"message_deletion_enabled"`
FileDeletionEnabled bool `json:"file_deletion_enabled"`
MessageRetentionCutoff int64 `json:"message_retention_cutoff"`
FileRetentionCutoff int64 `json:"file_retention_cutoff"`
}
-func (me *DataRetentionPolicy) ToJson() string {
- b, _ := json.Marshal(me)
- return string(b)
+type RetentionPolicy struct {
+ ID string `db:"Id" json:"id"`
+ DisplayName string `json:"display_name"`
+ PostDuration *int64 `json:"post_duration"`
}
-func DataRetentionPolicyFromJson(data io.Reader) *DataRetentionPolicy {
- var me *DataRetentionPolicy
- json.NewDecoder(data).Decode(&me)
- return me
+type RetentionPolicyWithTeamAndChannelIDs struct {
+ RetentionPolicy
+ TeamIDs []string `json:"team_ids"`
+ ChannelIDs []string `json:"channel_ids"`
+}
+
+type RetentionPolicyWithTeamAndChannelCounts struct {
+ RetentionPolicy
+ ChannelCount int64 `json:"channel_count"`
+ TeamCount int64 `json:"team_count"`
+}
+
+type RetentionPolicyChannel struct {
+ PolicyID string `db:"PolicyId"`
+ ChannelID string `db:"ChannelId"`
+}
+
+type RetentionPolicyTeam struct {
+ PolicyID string `db:"PolicyId"`
+ TeamID string `db:"TeamId"`
+}
+
+type RetentionPolicyWithTeamAndChannelCountsList struct {
+ Policies []*RetentionPolicyWithTeamAndChannelCounts `json:"policies"`
+ TotalCount int64 `json:"total_count"`
+}
+
+type RetentionPolicyForTeam struct {
+ TeamID string `db:"Id" json:"team_id"`
+ PostDuration int64 `json:"post_duration"`
+}
+
+type RetentionPolicyForTeamList struct {
+ Policies []*RetentionPolicyForTeam `json:"policies"`
+ TotalCount int64 `json:"total_count"`
+}
+
+type RetentionPolicyForChannel struct {
+ ChannelID string `db:"Id" json:"channel_id"`
+ PostDuration int64 `json:"post_duration"`
+}
+
+type RetentionPolicyForChannelList struct {
+ Policies []*RetentionPolicyForChannel `json:"policies"`
+ TotalCount int64 `json:"total_count"`
+}
+
+type RetentionPolicyCursor struct {
+ ChannelPoliciesDone bool
+ TeamPoliciesDone bool
+ GlobalPoliciesDone bool
+}
+
+func (rp *GlobalRetentionPolicy) ToJson() []byte {
+ b, _ := json.Marshal(rp)
+ return b
+}
+
+func GlobalRetentionPolicyFromJson(data io.Reader) *GlobalRetentionPolicy {
+ var grp *GlobalRetentionPolicy
+ json.NewDecoder(data).Decode(&grp)
+ return grp
+}
+
+func RetentionPolicyWithTeamAndChannelCountsFromJson(data io.Reader) (*RetentionPolicyWithTeamAndChannelCounts, error) {
+ var rp RetentionPolicyWithTeamAndChannelCounts
+ err := json.NewDecoder(data).Decode(&rp)
+ return &rp, err
+}
+
+func (rp *RetentionPolicyWithTeamAndChannelCounts) ToJson() []byte {
+ b, _ := json.Marshal(rp)
+ return b
+}
+
+func RetentionPolicyWithTeamAndChannelCountsListFromJson(data io.Reader) (*RetentionPolicyWithTeamAndChannelCountsList, error) {
+ var rpList *RetentionPolicyWithTeamAndChannelCountsList
+ err := json.NewDecoder(data).Decode(&rpList)
+ if err != nil {
+ return nil, err
+ }
+ return rpList, nil
+}
+
+func (rpList *RetentionPolicyWithTeamAndChannelCountsList) ToJson() []byte {
+ b, _ := json.Marshal(rpList)
+ return b
+}
+
+func RetentionPolicyWithTeamAndChannelIdsFromJson(data io.Reader) (*RetentionPolicyWithTeamAndChannelIDs, error) {
+ var rp *RetentionPolicyWithTeamAndChannelIDs
+ err := json.NewDecoder(data).Decode(&rp)
+ return rp, err
+}
+
+func (rp *RetentionPolicyWithTeamAndChannelIDs) ToJson() []byte {
+ b, _ := json.Marshal(rp)
+ return b
+}
+
+func (lst *RetentionPolicyForTeamList) ToJson() []byte {
+ b, _ := json.Marshal(lst)
+ return b
+}
+
+func (lst *RetentionPolicyForChannelList) ToJson() []byte {
+ b, _ := json.Marshal(lst)
+ return b
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/emoji.go b/vendor/github.com/mattermost/mattermost-server/v5/model/emoji.go
index aeee9b38..f990c670 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/emoji.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/emoji.go
@@ -8,6 +8,7 @@ import (
"io"
"net/http"
"regexp"
+ "sort"
)
const (
@@ -15,7 +16,9 @@ const (
EMOJI_SORT_BY_NAME = "name"
)
-var EMOJI_PATTERN = regexp.MustCompile(`:[a-zA-Z0-9_-]+:`)
+var EMOJI_PATTERN = regexp.MustCompile(`:[a-zA-Z0-9_+-]+:`)
+
+var ReverseSystemEmojisMap = makeReverseEmojiMap()
type Emoji struct {
Id string `json:"id"`
@@ -36,6 +39,26 @@ func GetSystemEmojiId(emojiName string) (string, bool) {
return id, found
}
+func makeReverseEmojiMap() map[string][]string {
+ reverseEmojiMap := make(map[string][]string)
+ for key, value := range SystemEmojis {
+ emojiNames := reverseEmojiMap[value]
+ emojiNames = append(emojiNames, key)
+ sort.Strings(emojiNames)
+ reverseEmojiMap[value] = emojiNames
+ }
+
+ return reverseEmojiMap
+}
+
+func GetEmojiNameFromUnicode(unicode string) (emojiName string, count int) {
+ if emojiNames, found := ReverseSystemEmojisMap[unicode]; found {
+ return emojiNames[0], len(emojiNames)
+ }
+
+ return "", 0
+}
+
func (emoji *Emoji) IsValid() *AppError {
if !IsValidId(emoji.Id) {
return NewAppError("Emoji.IsValid", "model.emoji.id.app_error", nil, "", http.StatusBadRequest)
@@ -57,7 +80,7 @@ func (emoji *Emoji) IsValid() *AppError {
}
func IsValidEmojiName(name string) *AppError {
- if len(name) == 0 || len(name) > EMOJI_NAME_MAX_LENGTH || !IsValidAlphaNumHyphenUnderscore(name, false) || inSystemEmoji(name) {
+ if name == "" || len(name) > EMOJI_NAME_MAX_LENGTH || !IsValidAlphaNumHyphenUnderscorePlus(name) || inSystemEmoji(name) {
return NewAppError("Emoji.IsValid", "model.emoji.name.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/emoji_data.go b/vendor/github.com/mattermost/mattermost-server/v5/model/emoji_data.go
index 807f6abb..849c2046 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/emoji_data.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/emoji_data.go
@@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+// This file is automatically generated via `make emojis`. Do not modify it manually.
package model
-var SystemEmojis = map[string]string{"policewoman": "1f46e-200d-2640-fe0f", "family_man_girl_medium_skin_tone": "1f468-1f3fd", "man_technologist": "1f468-200d-1f4bb", "family_woman_girl_medium_light_skin_tone": "1f469-1f3fc", "massage_woman_medium_light_skin_tone": "1f486-1f3fc-200d-2640-fe0f", "family_woman_woman_boy": "1f469-200d-1f469-200d-1f466", "rice_scene": "1f391", "notes": "1f3b6", "burundi": "1f1e7-1f1ee", "woman_medium_skin_tone": "1f469-1f3fd", "tipping_hand_man_medium_dark_skin_tone": "1f481-1f3fe-200d-2642-fe0f", "new_moon": "1f311", "belize": "1f1e7-1f1ff", "bhutan": "1f1e7-1f1f9", "eu": "1f1ea-1f1fa", "point_up_dark_skin_tone": "261d-1f3ff", "older_man_medium_light_skin_tone": "1f474-1f3fc", "prince": "1f934", "walking_man": "1f6b6", "telephone_receiver": "1f4de", "arrow_upper_right": "2197-fe0f", "taiwan": "1f1f9-1f1fc", "-1_light_skin_tone": "1f44e-1f3fb", "bear": "1f43b", "derelict_house": "1f3da", "blue_book": "1f4d8", "ok": "1f197", "woman_farmer_medium_light_skin_tone": "1f469-1f3fc", "man_shrugging_light_skin_tone": "1f937-1f3fb-200d-2642-fe0f", "dancing_women": "1f46f", "cd": "1f4bf", "tada": "1f389", "virgo": "264d-fe0f", "white_flower": "1f4ae", "guardswoman_medium_dark_skin_tone": "1f482-1f3fe-200d-2640-fe0f", "performing_arts": "1f3ad", "prayer_beads": "1f4ff", "congo_brazzaville": "1f1e8-1f1ec", "point_down_medium_skin_tone": "1f447-1f3fd", "raised_hand_with_fingers_splayed_light_skin_tone": "1f590-1f3fb", "man_playing_water_polo_medium_skin_tone": "1f93d-1f3fd-200d-2642-fe0f", "four_leaf_clover": "1f340", "microphone": "1f3a4", "heartpulse": "1f497", "north_korea": "1f1f0-1f1f5", "neutral_face": "1f610", "volleyball": "1f3d0", "man_playing_water_polo": "1f93d-200d-2642-fe0f", "uk": "1f1ec-1f1e7", "wallis_futuna": "1f1fc-1f1eb", "earth_africa": "1f30d", "droplet": "1f4a7", "construction_worker_man_medium_dark_skin_tone": "1f477-1f3fe-200d-2640-fe0f", "family_woman_woman_girl_boy_medium_light_skin_tone": "1f469-1f3fc", "mountain_biking_man_medium_dark_skin_tone": "1f6b5-1f3fe-200d-2640-fe0f", "vulcan_salute_light_skin_tone": "1f596-1f3fb", "woman_shrugging_dark_skin_tone": "1f937-1f3ff-200d-2640-fe0f", "walking_man_medium_light_skin_tone": "1f6b6-1f3fc-200d-2640-fe0f", "wave": "1f44b", "framed_picture": "1f5bc", "mag": "1f50d", "fist_left": "1f91b", "building_construction": "1f3d7", "clock9": "1f558", "cayman_islands": "1f1f0-1f1fe", "laos": "1f1f1-1f1e6", "woman_playing_handball_dark_skin_tone": "1f93e-1f3ff-200d-2640-fe0f", "man_office_worker": "1f468-200d-1f4bc", "family_man_woman_girl": "1f468-200d-1f469-200d-1f467", "wilted_flower": "1f940", "books": "1f4da", "rage": "1f621", "rice_ball": "1f359", "desert": "1f3dc", "malta": "1f1f2-1f1f9", "haircut_woman_dark_skin_tone": "1f487-1f3ff-200d-2640-fe0f", "symbols": "1f523", "marshall_islands": "1f1f2-1f1ed", "sierra_leone": "1f1f8-1f1f1", "crossed_fingers_medium_dark_skin_tone": "1f91e-1f3fe", "man_judge_medium_skin_tone": "1f468-1f3fd", "bamboo": "1f38d", "keyboard": "2328-fe0f", "clock10": "1f559", "massage_man_medium_skin_tone": "1f486-1f3fd-200d-2642-fe0f", "tipping_hand_man_dark_skin_tone": "1f481-1f3ff-200d-2642-fe0f", "man_facepalming_light_skin_tone": "1f926-1f3fb-200d-2642-fe0f", "train": "1f68b", "traffic_light": "1f6a5", "vietnam": "1f1fb-1f1f3", "boy_medium_light_skin_tone": "1f466-1f3fc", "man_farmer_light_skin_tone": "1f468-1f3fb", "man_singer_medium_dark_skin_tone": "1f468-1f3fe", "woman_cartwheeling_medium_light_skin_tone": "1f938-1f3fc-200d-2640-fe0f", "top": "1f51d", "gb": "1f1ec-1f1e7", "mouse2": "1f401", "do_not_litter": "1f6af", "south_sudan": "1f1f8-1f1f8", "bowing_woman_light_skin_tone": "1f647-1f3fb-200d-2640-fe0f", "family_man_man_girl_girl_medium_light_skin_tone": "1f468-1f3fc", "japanese_goblin": "1f47a", "camel": "1f42b", "taurus": "2649-fe0f", "mute": "1f507", "woman_mechanic_medium_dark_skin_tone": "1f469-1f3fe", "surfer": "1f3c4", "tipping_hand_man": "1f481-200d-2642-fe0f", "family_woman_woman_boy_boy": "1f469-200d-1f469-200d-1f466-200d-1f466", "floppy_disk": "1f4be", "atm": "1f3e7", "clock230": "1f55d", "prince_light_skin_tone": "1f934-1f3fb", "name_badge": "1f4db", "octocat": "octocat", "family_woman_woman_girl_girl_dark_skin_tone": "1f469-1f3ff", "christmas_tree": "1f384", "waxing_gibbous_moon": "1f314", "mountain_cableway": "1f6a0", "woman_scientist_medium_dark_skin_tone": "1f469-1f3fe", "haircut_man_medium_dark_skin_tone": "1f487-1f3fe-200d-2642-fe0f", "basketball_woman_medium_dark_skin_tone": "26f9-1f3fe-200d-2640-fe0f", "family_man_man_boy_medium_light_skin_tone": "1f468-1f3fc", "rowing_woman_medium_dark_skin_tone": "1f6a3-1f3fe-200d-2640-fe0f", "bowling": "1f3b3", "shinto_shrine": "26e9", "round_pushpin": "1f4cd", "cyprus": "1f1e8-1f1fe", "open_hands_dark_skin_tone": "1f450-1f3ff", "clap_medium_skin_tone": "1f44f-1f3fd", "bath_medium_dark_skin_tone": "1f6c0-1f3fe", "briefcase": "1f4bc", "tiger": "1f42f", "morocco": "1f1f2-1f1e6", "open_hands_light_skin_tone": "1f450-1f3fb", "hand_light_skin_tone": "270b-1f3fb", "weight_lifting_man_medium_dark_skin_tone": "1f3cb-1f3fe-200d-2640-fe0f", "mans_shoe": "1f45e", "poland": "1f1f5-1f1f1", "raised_hands_medium_skin_tone": "1f64c-1f3fd", "family_man_woman_girl_boy_light_skin_tone": "1f468-1f3fb", "woman_playing_handball_medium_skin_tone": "1f93e-1f3fd-200d-2640-fe0f", "office": "1f3e2", "woman_singer_medium_dark_skin_tone": "1f469-1f3fe", "family_woman_woman_boy_boy_medium_light_skin_tone": "1f469-1f3fc", "scorpion": "1f982", "tomato": "1f345", "goal_net": "1f945", "chad": "1f1f9-1f1e9", "family_man_woman_girl_boy_medium_skin_tone": "1f468-1f3fd", "mountain_biking_man_light_skin_tone": "1f6b5-1f3fb-200d-2640-fe0f", "weight_lifting_man_dark_skin_tone": "1f3cb-1f3ff-200d-2640-fe0f", "eyeglasses": "1f453", "golfing_woman": "1f3cc-fe0f-200d-2640-fe0f", "dvd": "1f4c0", "clipboard": "1f4cb", "ireland": "1f1ee-1f1ea", "woman_student_dark_skin_tone": "1f469-1f3ff", "angry": "1f620", "baby": "1f476", "women_wrestling": "1f93c-200d-2640-fe0f", "black_square_button": "1f532", "male_detective_medium_light_skin_tone": "1f575-1f3fc-200d-2640-fe0f", "dancer_dark_skin_tone": "1f483-1f3ff", "id": "1f194", "vibration_mode": "1f4f3", "handshake": "1f91d", "tiger2": "1f405", "leaves": "1f343", "baseball": "26be-fe0f", "golf": "26f3-fe0f", "toilet": "1f6bd", "male_detective_dark_skin_tone": "1f575-1f3ff-200d-2640-fe0f", "family_woman_boy": "1f469-200d-1f466", "duck": "1f986", "writing_hand_medium_dark_skin_tone": "270d-1f3fe", "woman_singer_medium_light_skin_tone": "1f469-1f3fc", "man_teacher_medium_skin_tone": "1f468-1f3fd", "lips": "1f444", "octopus": "1f419", "policeman_medium_dark_skin_tone": "1f46e-1f3fe-200d-2640-fe0f", "man_factory_worker_dark_skin_tone": "1f468-1f3ff", "man_astronaut_light_skin_tone": "1f468-1f3fb", "ok_man_dark_skin_tone": "1f646-1f3ff-200d-2642-fe0f", "couple_with_heart": "1f491", "pray_medium_skin_tone": "1f64f-1f3fd", "woman_health_worker_light_skin_tone": "1f469-1f3fb", "tipping_hand_woman_medium_light_skin_tone": "1f481-1f3fc-200d-2640-fe0f", "no_good_woman_dark_skin_tone": "1f645-1f3ff-200d-2640-fe0f", "no_good_woman_medium_dark_skin_tone": "1f645-1f3fe-200d-2640-fe0f", "thumbsdown": "1f44e", "fist": "270a", "camera_flash": "1f4f8", "azerbaijan": "1f1e6-1f1ff", "woman_with_turban_medium_light_skin_tone": "1f473-1f3fc-200d-2640-fe0f", "man_singer_medium_skin_tone": "1f468-1f3fd", "mali": "1f1f2-1f1f1", "blonde_woman_medium_dark_skin_tone": "1f471-1f3fe-200d-2640-fe0f", "family_man_man_girl_light_skin_tone": "1f468-1f3fb", "biking_woman_medium_skin_tone": "1f6b4-1f3fd-200d-2640-fe0f", "crab": "1f980", "green_salad": "1f957", "men_wrestling": "1f93c-200d-2642-fe0f", "-1_medium_dark_skin_tone": "1f44e-1f3fe", "baby_dark_skin_tone": "1f476-1f3ff", "surfing_woman_light_skin_tone": "1f3c4-1f3fb-200d-2640-fe0f", "stuck_out_tongue_winking_eye": "1f61c", "plate_with_cutlery": "1f37d", "swimmer": "1f3ca", "blonde_woman_medium_light_skin_tone": "1f471-1f3fc-200d-2640-fe0f", "curly_loop": "27b0", "india": "1f1ee-1f1f3", "norfolk_island": "1f1f3-1f1eb", "mountain_biking_woman_dark_skin_tone": "1f6b5-1f3ff-200d-2640-fe0f", "ghost": "1f47b", "boar": "1f417", "railway_track": "1f6e4", "100": "1f4af", "metal_medium_dark_skin_tone": "1f918-1f3fe", "woman_playing_handball_light_skin_tone": "1f93e-1f3fb-200d-2640-fe0f", "barber": "1f488", "clock730": "1f562", "equatorial_guinea": "1f1ec-1f1f6", "maldives": "1f1f2-1f1fb", "weight_lifting_woman_medium_dark_skin_tone": "1f3cb-1f3fe-200d-2640-fe0f", "eagle": "1f985", "tea": "1f375", "tanabata_tree": "1f38b", "night_with_stars": "1f303", "balloon": "1f388", "on": "1f51b", "lizard": "1f98e", "beer": "1f37a", "part_alternation_mark": "303d-fe0f", "white_square_button": "1f533", "clock430": "1f55f", "gibraltar": "1f1ec-1f1ee", "massage_woman_medium_skin_tone": "1f486-1f3fd-200d-2640-fe0f", "sweat": "1f613", "athletic_shoe": "1f45f", "joystick": "1f579", "biohazard": "2623-fe0f", "muscle_medium_light_skin_tone": "1f4aa-1f3fc", "bride_with_veil_medium_light_skin_tone": "1f470-1f3fc", "parasol_on_ground": "26f1", "costa_rica": "1f1e8-1f1f7", "woman_student_light_skin_tone": "1f469-1f3fb", "massage_woman_medium_dark_skin_tone": "1f486-1f3fe-200d-2640-fe0f", "surfing_woman_medium_dark_skin_tone": "1f3c4-1f3fe-200d-2640-fe0f", "rowing_woman": "1f6a3-200d-2640-fe0f", "guardsman_light_skin_tone": "1f482-1f3fb-200d-2640-fe0f", "construction_worker_man_light_skin_tone": "1f477-1f3fb-200d-2640-fe0f", "family_woman_boy_boy": "1f469-200d-1f466-200d-1f466", "small_airplane": "1f6e9", "baggage_claim": "1f6c4", "bosnia_herzegovina": "1f1e7-1f1e6", "falkland_islands": "1f1eb-1f1f0", "crossed_fingers_medium_light_skin_tone": "1f91e-1f3fc", "man_scientist_medium_light_skin_tone": "1f468-1f3fc", "family_woman_girl_boy_medium_skin_tone": "1f469-1f3fd", "satisfied": "1f606", "u5408": "1f234", "cn": "1f1e8-1f1f3", "isle_of_man": "1f1ee-1f1f2", "fist_raised_medium_light_skin_tone": "270a-1f3fc", "family_man_woman_girl_dark_skin_tone": "1f468-1f3ff", "family_woman_girl_dark_skin_tone": "1f469-1f3ff", "family_man_boy_medium_skin_tone": "1f468-1f3fd", "money_mouth_face": "1f911", "syringe": "1f489", "hand_medium_light_skin_tone": "270b-1f3fc", "writing_hand_medium_skin_tone": "270d-1f3fd", "man_farmer_medium_light_skin_tone": "1f468-1f3fc", "woman_artist_dark_skin_tone": "1f469-1f3ff", "tickets": "1f39f", "man_cartwheeling_light_skin_tone": "1f938-1f3fb-200d-2642-fe0f", "squid": "1f991", "fish": "1f41f", "memo": "1f4dd", "eye_speech_bubble": "1f441-200d-1f5e8", "+1_light_skin_tone": "1f44d-1f3fb", "tulip": "1f337", "blossom": "1f33c", "family_woman_woman_girl_medium_dark_skin_tone": "1f469-1f3fe", "triumph": "1f624", "rooster": "1f413", "ng": "1f196", "blonde_man_medium_light_skin_tone": "1f471-1f3fc-200d-2640-fe0f", "policeman_light_skin_tone": "1f46e-1f3fb-200d-2640-fe0f", "woman_cook_dark_skin_tone": "1f469-1f3ff", "pray_dark_skin_tone": "1f64f-1f3ff", "point_up_2_medium_skin_tone": "1f446-1f3fd", "busts_in_silhouette": "1f465", "tornado": "1f32a", "woman_juggling": "1f939-200d-2640-fe0f", "cupid": "1f498", "white_check_mark": "2705", "aruba": "1f1e6-1f1fc", "family_man_boy_boy_medium_dark_skin_tone": "1f468-1f3fe", "woman_cartwheeling_dark_skin_tone": "1f938-1f3ff-200d-2640-fe0f", "woman_playing_water_polo_dark_skin_tone": "1f93d-1f3ff-200d-2640-fe0f", "relaxed": "263a-fe0f", "birthday": "1f382", "high_brightness": "1f506", "couple_with_heart_woman_woman_medium_light_skin_tone": "1f469-1f3fc", "biking_man_dark_skin_tone": "1f6b4-1f3ff-200d-2640-fe0f", "disappointed_relieved": "1f625", "canary_islands": "1f1ee-1f1e8", "st_pierre_miquelon": "1f1f5-1f1f2", "trinidad_tobago": "1f1f9-1f1f9", "turkmenistan": "1f1f9-1f1f2", "pouting_woman_medium_skin_tone": "1f64e-1f3fd-200d-2640-fe0f", "man_student_dark_skin_tone": "1f468-1f3ff", "princess_dark_skin_tone": "1f478-1f3ff", "family_woman_boy_boy_medium_skin_tone": "1f469-1f3fd", "old_key": "1f5dd", "muscle_medium_skin_tone": "1f4aa-1f3fd", "ear_medium_dark_skin_tone": "1f442-1f3fe", "girl_medium_dark_skin_tone": "1f467-1f3fe", "man_pilot_dark_skin_tone": "1f468-1f3ff", "wolf": "1f43a", "gem": "1f48e", "arrow_double_up": "23eb", "woman_factory_worker_light_skin_tone": "1f469-1f3fb", "woman_mechanic_medium_skin_tone": "1f469-1f3fd", "woman_firefighter_light_skin_tone": "1f469-1f3fb", "sunglasses": "1f60e", "snake": "1f40d", "pen": "1f58a", "nose_medium_skin_tone": "1f443-1f3fd", "weight_lifting_man": "1f3cb-fe0f", "alarm_clock": "23f0", "golfing_woman_medium_light_skin_tone": "1f3cc-1f3fc-200d-2640-fe0f", "vulcan_salute": "1f596", "earth_asia": "1f30f", "+1_dark_skin_tone": "1f44d-1f3ff", "family_woman_boy_medium_dark_skin_tone": "1f469-1f3fe", "family_woman_girl_girl_light_skin_tone": "1f469-1f3fb", "weight_lifting_man_medium_light_skin_tone": "1f3cb-1f3fc-200d-2640-fe0f", "angel": "1f47c", "peach": "1f351", "truck": "1f69a", "tajikistan": "1f1f9-1f1ef", "tr": "1f1f9-1f1f7", "running_woman_medium_skin_tone": "1f3c3-1f3fd-200d-2640-fe0f", "wrench": "1f527", "black_flag": "1f3f4", "cape_verde": "1f1e8-1f1fb", "man_technologist_medium_light_skin_tone": "1f468-1f3fc", "mountain_biking_woman_medium_light_skin_tone": "1f6b5-1f3fc-200d-2640-fe0f", "man_astronaut_medium_skin_tone": "1f468-1f3fd", "man_in_tuxedo_medium_light_skin_tone": "1f935-1f3fc", "see_no_evil": "1f648", "egg": "1f95a", "1234": "1f522", "lesotho": "1f1f1-1f1f8", "middle_finger_medium_skin_tone": "1f595-1f3fd", "woman_health_worker_medium_light_skin_tone": "1f469-1f3fc", "sneezing_face": "1f927", "man_cook": "1f468-200d-1f373", "mortar_board": "1f393", "candle": "1f56f", "basketball_man_medium_skin_tone": "26f9-1f3fd-200d-2640-fe0f", "ferris_wheel": "1f3a1", "martinique": "1f1f2-1f1f6", "st_vincent_grenadines": "1f1fb-1f1e8", "yemen": "1f1fe-1f1ea", "pray_light_skin_tone": "1f64f-1f3fb", "man_in_tuxedo_medium_skin_tone": "1f935-1f3fd", "woman_pilot_medium_dark_skin_tone": "1f469-1f3fe", "pregnant_woman_dark_skin_tone": "1f930-1f3ff", "fu": "1f595", "haircut": "1f487", "boxing_glove": "1f94a", "page_with_curl": "1f4c3", "muscle_light_skin_tone": "1f4aa-1f3fb", "woman_firefighter_dark_skin_tone": "1f469-1f3ff", "ok_woman_light_skin_tone": "1f646-1f3fb-200d-2640-fe0f", "family_man_woman_boy_boy_medium_light_skin_tone": "1f468-1f3fc", "family_woman_boy_dark_skin_tone": "1f469-1f3ff", "weight_lifting_man_light_skin_tone": "1f3cb-1f3fb-200d-2640-fe0f", "blonde_man": "1f471", "woman_technologist": "1f469-200d-1f4bb", "boom": "1f4a5", "1st_place_medal": "1f947", "nine": "0039-fe0f-20e3", "czech_republic": "1f1e8-1f1ff", "meat_on_bone": "1f356", "hamburger": "1f354", "video_game": "1f3ae", "clock2": "1f551", "woman_facepalming_dark_skin_tone": "1f926-1f3ff-200d-2640-fe0f", "couplekiss_man_man_medium_dark_skin_tone": "1f468-1f3fe", "arrow_lower_right": "2198-fe0f", "haircut_woman_light_skin_tone": "1f487-1f3fb-200d-2640-fe0f", "woman_dark_skin_tone": "1f469-1f3ff", "older_man_light_skin_tone": "1f474-1f3fb", "first_quarter_moon_with_face": "1f31b", "fries": "1f35f", "restroom": "1f6bb", "zero": "0030-fe0f-20e3", "fr": "1f1eb-1f1f7", "kuwait": "1f1f0-1f1fc", "man_health_worker_medium_skin_tone": "1f468-1f3fd", "woman_judge_light_skin_tone": "1f469-1f3fb", "man_judge_dark_skin_tone": "1f468-1f3ff", "ok_woman_medium_skin_tone": "1f646-1f3fd-200d-2640-fe0f", "bike": "1f6b2", "registered": "00ae-fe0f", "blonde_woman_medium_skin_tone": "1f471-1f3fd-200d-2640-fe0f", "stuck_out_tongue_closed_eyes": "1f61d", "collision": "1f4a5", "wheelchair": "267f-fe0f", "black_circle": "26ab-fe0f", "point_up_2_light_skin_tone": "1f446-1f3fb", "older_man": "1f474", "suspension_railway": "1f69f", "libra": "264e-fe0f", "crossed_flags": "1f38c", "man_cartwheeling_medium_dark_skin_tone": "1f938-1f3fe-200d-2642-fe0f", "man_playing_water_polo_dark_skin_tone": "1f93d-1f3ff-200d-2642-fe0f", "scream": "1f631", "no_good_man": "1f645-200d-2642-fe0f", "timer_clock": "23f2", "venezuela": "1f1fb-1f1ea", "raised_back_of_hand_light_skin_tone": "1f91a-1f3fb", "woman_technologist_medium_skin_tone": "1f469-1f3fd", "popcorn": "1f37f", "romania": "1f1f7-1f1f4", "togo": "1f1f9-1f1ec", "writing_hand_dark_skin_tone": "270d-1f3ff", "woman_singer_dark_skin_tone": "1f469-1f3ff", "pouting_woman_medium_dark_skin_tone": "1f64e-1f3fe-200d-2640-fe0f", "man_health_worker_light_skin_tone": "1f468-1f3fb", "dancer_medium_light_skin_tone": "1f483-1f3fc", "phone": "260e-fe0f", "chart": "1f4b9", "repeat": "1f501", "mahjong": "1f004-fe0f", "liberia": "1f1f1-1f1f7", "rage3": "rage3", "person_frowning": "1f64d", "open_hands_medium_skin_tone": "1f450-1f3fd", "man_dark_skin_tone": "1f468-1f3ff", "man_factory_worker_medium_light_skin_tone": "1f468-1f3fc", "man_astronaut_medium_light_skin_tone": "1f468-1f3fc", "ring": "1f48d", "ok_hand_medium_skin_tone": "1f44c-1f3fd", "santa": "1f385", "beach_umbrella": "1f3d6", "finland": "1f1eb-1f1ee", "woman_facepalming_medium_skin_tone": "1f926-1f3fd-200d-2640-fe0f", "woman_shrugging_medium_light_skin_tone": "1f937-1f3fc-200d-2640-fe0f", "sunflower": "1f33b", "ok_hand_dark_skin_tone": "1f44c-1f3ff", "santa_medium_skin_tone": "1f385-1f3fd", "call_me_hand_medium_skin_tone": "1f919-1f3fd", "man_firefighter_light_skin_tone": "1f468-1f3fb", "kiss": "1f48b", "mandarin": "1f34a", "dollar": "1f4b5", "clock3": "1f552", "argentina": "1f1e6-1f1f7", "fist_left_light_skin_tone": "1f91b-1f3fb", "santa_light_skin_tone": "1f385-1f3fb", "family_man_girl_boy_medium_light_skin_tone": "1f468-1f3fc", "sushi": "1f363", "rice": "1f35a", "mailbox_with_mail": "1f4ec", "woman_cook_medium_dark_skin_tone": "1f469-1f3fe", "family_man_woman_girl_girl_medium_dark_skin_tone": "1f468-1f3fe", "straight_ruler": "1f4cf", "blue_heart": "1f499", "slightly_frowning_face": "1f641", "crossed_fingers": "1f91e", "seedling": "1f331", "herb": "1f33f", "medal_military": "1f396", "camping": "1f3d5", "arrow_backward": "25c0-fe0f", "heavy_multiplication_x": "2716-fe0f", "icecream": "1f366", "heavy_dollar_sign": "1f4b2", "frowning_woman_dark_skin_tone": "1f64d-1f3ff-200d-2640-fe0f", "family_man_woman_boy_boy_medium_dark_skin_tone": "1f468-1f3fe", "brazil": "1f1e7-1f1f7", "fist_right_medium_light_skin_tone": "1f91c-1f3fc", "man_scientist_medium_dark_skin_tone": "1f468-1f3fe", "family_woman_girl_light_skin_tone": "1f469-1f3fb", "swimming_man_medium_dark_skin_tone": "1f3ca-1f3fe-200d-2640-fe0f", "man": "1f468", "lemon": "1f34b", "japanese_castle": "1f3ef", "cinema": "1f3a6", "wave_light_skin_tone": "1f44b-1f3fb", "middle_finger_medium_light_skin_tone": "1f595-1f3fc", "five": "0035-fe0f-20e3", "boy_medium_dark_skin_tone": "1f466-1f3fe", "woman_technologist_dark_skin_tone": "1f469-1f3ff", "man_playing_handball_light_skin_tone": "1f93e-1f3fb-200d-2642-fe0f", "construction_worker_man": "1f477", "stadium": "1f3df", "biking_woman_dark_skin_tone": "1f6b4-1f3ff-200d-2640-fe0f", "trophy": "1f3c6", "arrow_left": "2b05-fe0f", "boy_dark_skin_tone": "1f466-1f3ff", "no_good_woman_light_skin_tone": "1f645-1f3fb-200d-2640-fe0f", "skull_and_crossbones": "2620-fe0f", "couple_with_heart_woman_woman": "1f469-200d-2764-fe0f-200d-1f469", "no_bicycles": "1f6b3", "bell": "1f514", "feelsgood": "feelsgood", "bowing_man_dark_skin_tone": "1f647-1f3ff-200d-2640-fe0f", "mouse": "1f42d", "anchor": "2693-fe0f", "cyclone": "1f300", "solomon_islands": "1f1f8-1f1e7", "basketball": "1f3c0", "notebook_with_decorative_cover": "1f4d4", "family_man_girl_girl_dark_skin_tone": "1f468-1f3ff", "singapore": "1f1f8-1f1ec", "golfing_man_medium_dark_skin_tone": "1f3cc-1f3fe-200d-2640-fe0f", "woman": "1f469", "fried_shrimp": "1f364", "construction": "1f6a7", "eight_pointed_black_star": "2734-fe0f", "black_joker": "1f0cf", "cambodia": "1f1f0-1f1ed", "mount_fuji": "1f5fb", "link": "1f517", "womens": "1f6ba", "family_man_man_boy_boy_medium_skin_tone": "1f468-1f3fd", "joy": "1f602", "crying_cat_face": "1f63f", "parking": "1f17f-fe0f", "barbados": "1f1e7-1f1e7", "bowing_woman_dark_skin_tone": "1f647-1f3ff-200d-2640-fe0f", "angel_medium_light_skin_tone": "1f47c-1f3fc", "waning_gibbous_moon": "1f316", "synagogue": "1f54d", "american_samoa": "1f1e6-1f1f8", "basketball_woman_medium_light_skin_tone": "26f9-1f3fc-200d-2640-fe0f", "bug": "1f41b", "woman_farmer_light_skin_tone": "1f469-1f3fb", "door": "1f6aa", "place_of_worship": "1f6d0", "eight_spoked_asterisk": "2733-fe0f", "mrs_claus_dark_skin_tone": "1f936-1f3ff", "u7a7a": "1f233", "man_astronaut_medium_dark_skin_tone": "1f468-1f3fe", "jack_o_lantern": "1f383", "lock_with_ink_pen": "1f50f", "male_detective_medium_skin_tone": "1f575-1f3fd-200d-2640-fe0f", "woman_firefighter_medium_dark_skin_tone": "1f469-1f3fe", "smiling_imp": "1f608", "tv": "1f4fa", "pouting_man": "1f64e-200d-2642-fe0f", "e-mail": "1f4e7", "package": "1f4e6", "clock130": "1f55c", "family_man_boy_light_skin_tone": "1f468-1f3fb", "cat2": "1f408", "mountain_biking_woman_medium_dark_skin_tone": "1f6b5-1f3fe-200d-2640-fe0f", "nauseated_face": "1f922", "fountain": "26f2-fe0f", "middle_finger": "1f595", "dancers": "1f46f", "cactus": "1f335", "man_student_light_skin_tone": "1f468-1f3fb", "family_man_man_girl_dark_skin_tone": "1f468-1f3ff", "family_man_girl_girl_medium_skin_tone": "1f468-1f3fd", "us_virgin_islands": "1f1fb-1f1ee", "woman_astronaut_medium_dark_skin_tone": "1f469-1f3fe", "honeybee": "1f41d", "bouquet": "1f490", "golfing_man": "1f3cc-fe0f", "u7981": "1f232", "french_guiana": "1f1ec-1f1eb", "kenya": "1f1f0-1f1ea", "melon": "1f348", "nicaragua": "1f1f3-1f1ee", "raised_hand_with_fingers_splayed_medium_light_skin_tone": "1f590-1f3fc", "bath_light_skin_tone": "1f6c0-1f3fb", "man_pilot_medium_light_skin_tone": "1f468-1f3fc", "european_post_office": "1f3e4", "mobile_phone_off": "1f4f4", "no_smoking": "1f6ad", "family_woman_girl_girl_medium_light_skin_tone": "1f469-1f3fc", "family_woman_girl_medium_dark_skin_tone": "1f469-1f3fe", "man_juggling_medium_dark_skin_tone": "1f939-1f3fe-200d-2642-fe0f", "expressionless": "1f611", "school_satchel": "1f392", "film_strip": "1f39e", "running_man_light_skin_tone": "1f3c3-1f3fb-200d-2640-fe0f", "family_man_woman_girl_medium_dark_skin_tone": "1f468-1f3fe", "family_woman_woman_boy_boy_light_skin_tone": "1f469-1f3fb", "smiley_cat": "1f63a", "chestnut": "1f330", "girl_dark_skin_tone": "1f467-1f3ff", "bride_with_veil_medium_dark_skin_tone": "1f470-1f3fe", "family_man_man_boy_boy_light_skin_tone": "1f468-1f3fb", "family_man_boy_boy_medium_light_skin_tone": "1f468-1f3fc", "wink": "1f609", "carrot": "1f955", "credit_card": "1f4b3", "triangular_ruler": "1f4d0", "question": "2753", "+1_medium_dark_skin_tone": "1f44d-1f3fe", "man_teacher_medium_dark_skin_tone": "1f468-1f3fe", "family_man_girl_girl_medium_light_skin_tone": "1f468-1f3fc", "kimono": "1f458", "bellhop_bell": "1f6ce", "red_circle": "1f534", "call_me_hand_light_skin_tone": "1f919-1f3fb", "nail_care_medium_skin_tone": "1f485-1f3fd", "woman_teacher_medium_skin_tone": "1f469-1f3fd", "woman_juggling_dark_skin_tone": "1f939-1f3ff-200d-2640-fe0f", "runner": "1f3c3", "heavy_check_mark": "2714-fe0f", "family_man_girl_girl_medium_dark_skin_tone": "1f468-1f3fe", "tent": "26fa-fe0f", "card_index_dividers": "1f5c2", "man_singer_dark_skin_tone": "1f468-1f3ff", "man_firefighter_medium_dark_skin_tone": "1f468-1f3fe", "man_playing_handball_medium_dark_skin_tone": "1f93e-1f3fe-200d-2642-fe0f", "female_detective_medium_dark_skin_tone": "1f575-1f3fe-200d-2640-fe0f", "metal": "1f918", "dark_sunglasses": "1f576", "vertical_traffic_light": "1f6a6", "four": "0034-fe0f-20e3", "wavy_dash": "3030-fe0f", "ear_medium_light_skin_tone": "1f442-1f3fc", "man_juggling_dark_skin_tone": "1f939-1f3ff-200d-2642-fe0f", "kissing_heart": "1f618", "sweet_potato": "1f360", "gift_heart": "1f49d", "man_technologist_light_skin_tone": "1f468-1f3fb", "prince_medium_dark_skin_tone": "1f934-1f3fe", "ok_man_medium_skin_tone": "1f646-1f3fd-200d-2642-fe0f", "womans_clothes": "1f45a", "roller_coaster": "1f3a2", "woman_student_medium_light_skin_tone": "1f469-1f3fc", "zipper_mouth_face": "1f910", "person_with_blond_hair": "1f471", "leftwards_arrow_with_hook": "21a9-fe0f", "white_circle": "26aa-fe0f", "afghanistan": "1f1e6-1f1eb", "face_with_thermometer": "1f912", "bow": "1f647", "kr": "1f1f0-1f1f7", "finnadie": "finnadie", "girl_light_skin_tone": "1f467-1f3fb", "woman_farmer_medium_skin_tone": "1f469-1f3fd", "umbrella": "2614-fe0f", "ice_cream": "1f368", "point_down_medium_light_skin_tone": "1f447-1f3fc", "woman_health_worker_dark_skin_tone": "1f469-1f3ff", "rowing_woman_medium_light_skin_tone": "1f6a3-1f3fc-200d-2640-fe0f", "money_with_wings": "1f4b8", "dolls": "1f38e", "surfing_man_medium_dark_skin_tone": "1f3c4-1f3fe-200d-2640-fe0f", "mrs_claus_medium_skin_tone": "1f936-1f3fd", "basketball_man_dark_skin_tone": "26f9-1f3ff-200d-2640-fe0f", "dragon_face": "1f432", "woman_cartwheeling": "1f938-200d-2640-fe0f", "aquarius": "2652-fe0f", "sos": "1f198", "clock1230": "1f567", "haiti": "1f1ed-1f1f9", "woman_facepalming": "1f926-200d-2640-fe0f", "clinking_glasses": "1f942", "trollface": "trollface", "mrs_claus_light_skin_tone": "1f936-1f3fb", "clap": "1f44f", "couplekiss_man_man": "1f468-200d-2764-fe0f-200d-1f48b-200d-1f468", "page_facing_up": "1f4c4", "belgium": "1f1e7-1f1ea", "curacao": "1f1e8-1f1fc", "family_woman_woman_boy_dark_skin_tone": "1f469-1f3ff", "two_men_holding_hands": "1f46c", "mountain_snow": "1f3d4", "wind_chime": "1f390", "person_with_pouting_face": "1f64e", "cityscape": "1f3d9", "bride_with_veil_dark_skin_tone": "1f470-1f3ff", "frowning_woman_light_skin_tone": "1f64d-1f3fb-200d-2640-fe0f", "bath_medium_light_skin_tone": "1f6c0-1f3fc", "sheep": "1f411", "sparkler": "1f387", "frowning_woman": "1f64d", "rat": "1f400", "custard": "1f36e", "video_camera": "1f4f9", "open_umbrella": "2602-fe0f", "man_with_turban_medium_light_skin_tone": "1f473-1f3fc-200d-2640-fe0f", "woman_student_medium_dark_skin_tone": "1f469-1f3fe", "ok_woman_medium_light_skin_tone": "1f646-1f3fc-200d-2640-fe0f", "swimming_man_dark_skin_tone": "1f3ca-1f3ff-200d-2640-fe0f", "man_cook_light_skin_tone": "1f468-1f3fb", "running_woman_light_skin_tone": "1f3c3-1f3fb-200d-2640-fe0f", "rabbit": "1f430", "ox": "1f402", "corn": "1f33d", "mozambique": "1f1f2-1f1ff", "point_right_light_skin_tone": "1f449-1f3fb", "nail_care_light_skin_tone": "1f485-1f3fb", "smiley": "1f603", "new_moon_with_face": "1f31a", "croatia": "1f1ed-1f1f7", "man_judge_medium_dark_skin_tone": "1f468-1f3fe", "fist_raised": "270a", "man_astronaut": "1f468-200d-1f680", "clock1130": "1f566", "st_lucia": "1f1f1-1f1e8", "princess": "1f478", "fist_left_medium_light_skin_tone": "1f91b-1f3fc", "point_left_medium_dark_skin_tone": "1f448-1f3fe", "woman_factory_worker_medium_skin_tone": "1f469-1f3fd", "angel_dark_skin_tone": "1f47c-1f3ff", "woman_cook": "1f469-200d-1f373", "koala": "1f428", "satellite": "1f4e1", "book": "1f4d6", "large_orange_diamond": "1f536", "monaco": "1f1f2-1f1e8", "spiral_notepad": "1f5d2", "capricorn": "2651-fe0f", "bacon": "1f953", "blonde_man_medium_dark_skin_tone": "1f471-1f3fe-200d-2640-fe0f", "business_suit_levitating_dark_skin_tone": "1f574-1f3ff", "call_me_hand_medium_light_skin_tone": "1f919-1f3fc", "female_detective_medium_light_skin_tone": "1f575-1f3fc-200d-2640-fe0f", "haircut_woman_medium_light_skin_tone": "1f487-1f3fc-200d-2640-fe0f", "alien": "1f47d", "baguette_bread": "1f956", "northern_mariana_islands": "1f1f2-1f1f5", "ukraine": "1f1fa-1f1e6", "flushed": "1f633", "man_scientist": "1f468-200d-1f52c", "trident": "1f531", "family_woman_woman_girl_boy_medium_skin_tone": "1f469-1f3fd", "family_man_boy_boy": "1f468-200d-1f466-200d-1f466", "tennis": "1f3be", "fire_engine": "1f692", "pushpin": "1f4cc", "man_health_worker_medium_dark_skin_tone": "1f468-1f3fe", "boy": "1f466", "headphones": "1f3a7", "fuelpump": "26fd-fe0f", "u6709": "1f236", "man_cook_medium_skin_tone": "1f468-1f3fd", "bride_with_veil_medium_skin_tone": "1f470-1f3fd", "point_up": "261d-fe0f", "necktie": "1f454", "control_knobs": "1f39b", "austria": "1f1e6-1f1f9", "papua_new_guinea": "1f1f5-1f1ec", "alembic": "2697-fe0f", "cook_islands": "1f1e8-1f1f0", "iceland": "1f1ee-1f1f8", "car": "1f697", "potable_water": "1f6b0", "haircut_man_medium_light_skin_tone": "1f487-1f3fc-200d-2642-fe0f", "couplekiss_woman_woman_medium_light_skin_tone": "1f469-1f3fc", "couplekiss_man_man_medium_skin_tone": "1f468-1f3fd", "cookie": "1f36a", "flight_departure": "1f6eb", "muscle_dark_skin_tone": "1f4aa-1f3ff", "construction_worker_man_medium_skin_tone": "1f477-1f3fd-200d-2640-fe0f", "black_medium_small_square": "25fe-fe0f", "guyana": "1f1ec-1f1fe", "file_folder": "1f4c1", "fountain_pen": "1f58b", "construction_worker_woman_medium_skin_tone": "1f477-1f3fd-200d-2640-fe0f", "family_man_woman_girl_boy_medium_light_skin_tone": "1f468-1f3fc", "poultry_leg": "1f357", "ski": "1f3bf", "guardswoman_medium_skin_tone": "1f482-1f3fd-200d-2640-fe0f", "family_man_man_girl_medium_dark_skin_tone": "1f468-1f3fe", "family_woman_boy_light_skin_tone": "1f469-1f3fb", "trumpet": "1f3ba", "no_pedestrians": "1f6b7", "heavy_minus_sign": "2796", "fist_oncoming": "1f44a", "ambulance": "1f691", "man_artist_dark_skin_tone": "1f468-1f3ff", "drum": "1f941", "train2": "1f686", "u7121": "1f21a-fe0f", "burkina_faso": "1f1e7-1f1eb", "nose_light_skin_tone": "1f443-1f3fb", "policewoman_medium_dark_skin_tone": "1f46e-1f3fe-200d-2640-fe0f", "lantern": "1f3ee", "metal_light_skin_tone": "1f918-1f3fb", "male_detective_light_skin_tone": "1f575-1f3fb-200d-2640-fe0f", "woman_juggling_medium_dark_skin_tone": "1f939-1f3fe-200d-2640-fe0f", "rowing_man_light_skin_tone": "1f6a3-1f3fb-200d-2640-fe0f", "lying_face": "1f925", "point_left": "1f448", "rosette": "1f3f5", "houses": "1f3d8", "repeat_one": "1f502", "liechtenstein": "1f1f1-1f1ee", "cloud_with_lightning": "1f329", "man_cartwheeling": "1f938-200d-2642-fe0f", "pause_button": "23f8", "arrows_clockwise": "1f503", "raised_hand_with_fingers_splayed_dark_skin_tone": "1f590-1f3ff", "clap_dark_skin_tone": "1f44f-1f3ff", "raising_hand_man_medium_skin_tone": "1f64b-1f3fd-200d-2642-fe0f", "family_woman_woman_girl_girl_medium_dark_skin_tone": "1f469-1f3fe", "dog": "1f436", "pouting_man_medium_dark_skin_tone": "1f64e-1f3fe-200d-2642-fe0f", "surfing_woman_medium_skin_tone": "1f3c4-1f3fd-200d-2640-fe0f", "confused": "1f615", "detective": "1f575-fe0f", "studio_microphone": "1f399", "fist_oncoming_medium_light_skin_tone": "1f44a-1f3fc", "man_firefighter_medium_skin_tone": "1f468-1f3fd", "tshirt": "1f455", "trolleybus": "1f68e", "norway": "1f1f3-1f1f4", "neckbeard": "neckbeard", "three": "0033-fe0f-20e3", "point_right_medium_skin_tone": "1f449-1f3fd", "man_medium_dark_skin_tone": "1f468-1f3fe", "pouting_man_medium_light_skin_tone": "1f64e-1f3fc-200d-2642-fe0f", "clock630": "1f561", "fist_raised_medium_skin_tone": "270a-1f3fd", "anguished": "1f627", "eye": "1f441", "bride_with_veil": "1f470", "hear_no_evil": "1f649", "wine_glass": "1f377", "soon": "1f51c", "family_man_boy_boy_light_skin_tone": "1f468-1f3fb", "family_woman_boy_boy_medium_light_skin_tone": "1f469-1f3fc", "dromedary_camel": "1f42a", "chipmunk": "1f43f", "soccer": "26bd-fe0f", "man_with_gua_pi_mao_medium_light_skin_tone": "1f472-1f3fc", "business_suit_levitating_medium_light_skin_tone": "1f574-1f3fc", "running_woman_medium_dark_skin_tone": "1f3c3-1f3fe-200d-2640-fe0f", "speaking_head": "1f5e3", "menorah": "1f54e", "non-potable_water": "1f6b1", "woman_with_turban_dark_skin_tone": "1f473-1f3ff-200d-2640-fe0f", "woman_shrugging_medium_skin_tone": "1f937-1f3fd-200d-2640-fe0f", "frowning_woman_medium_light_skin_tone": "1f64d-1f3fc-200d-2640-fe0f", "biking_man_medium_light_skin_tone": "1f6b4-1f3fc-200d-2640-fe0f", "woman_shrugging": "1f937-200d-2640-fe0f", "arrow_upper_left": "2196-fe0f", "metal_medium_skin_tone": "1f918-1f3fd", "woman_factory_worker_dark_skin_tone": "1f469-1f3ff", "hotsprings": "2668-fe0f", "ear_dark_skin_tone": "1f442-1f3ff", "girl_medium_skin_tone": "1f467-1f3fd", "woman_farmer_dark_skin_tone": "1f469-1f3ff", "man_student_medium_skin_tone": "1f468-1f3fd", "biking_man_medium_skin_tone": "1f6b4-1f3fd-200d-2640-fe0f", "woman_scientist": "1f469-200d-1f52c", "vs": "1f19a", "weight_lifting_man_medium_skin_tone": "1f3cb-1f3fd-200d-2640-fe0f", "arrow_right": "27a1-fe0f", "woman_juggling_medium_light_skin_tone": "1f939-1f3fc-200d-2640-fe0f", "racehorse": "1f40e", "sun_behind_large_cloud": "1f325", "convenience_store": "1f3ea", "namibia": "1f1f3-1f1e6", "raised_hands_medium_dark_skin_tone": "1f64c-1f3fe", "man_judge_medium_light_skin_tone": "1f468-1f3fc", "dancer_medium_skin_tone": "1f483-1f3fd", "fearful": "1f628", "frog": "1f438", "shopping_cart": "1f6d2", "family_man_boy_medium_light_skin_tone": "1f468-1f3fc", "basketball_man_medium_dark_skin_tone": "26f9-1f3fe-200d-2640-fe0f", "oman": "1f1f4-1f1f2", "paraguay": "1f1f5-1f1fe", "horse": "1f434", "tram": "1f68a", "wastebasket": "1f5d1", "yen": "1f4b4", "heavy_exclamation_mark": "2757-fe0f", "arrow_double_down": "23ec", "walking_woman_dark_skin_tone": "1f6b6-1f3ff-200d-2640-fe0f", "shoe": "1f45e", "ear_of_rice": "1f33e", "mountain": "26f0", "uzbekistan": "1f1fa-1f1ff", "baby_light_skin_tone": "1f476-1f3fb", "haircut_woman_medium_dark_skin_tone": "1f487-1f3fe-200d-2640-fe0f", "golfing_woman_medium_skin_tone": "1f3cc-1f3fd-200d-2640-fe0f", "earth_americas": "1f30e", "woman_playing_water_polo_medium_light_skin_tone": "1f93d-1f3fc-200d-2640-fe0f", "walking_woman": "1f6b6-200d-2640-fe0f", "fried_egg": "1f373", "rocket": "1f680", "artificial_satellite": "1f6f0", "man_shrugging_medium_skin_tone": "1f937-1f3fd-200d-2642-fe0f", "golfing_man_dark_skin_tone": "1f3cc-1f3ff-200d-2640-fe0f", "older_woman_medium_skin_tone": "1f475-1f3fd", "man_with_gua_pi_mao_medium_dark_skin_tone": "1f472-1f3fe", "persevere": "1f623", "raising_hand_woman": "1f64b", "pig": "1f437", "european_castle": "1f3f0", "department_store": "1f3ec", "fist_right_light_skin_tone": "1f91c-1f3fb", "raising_hand_woman_dark_skin_tone": "1f64b-1f3ff-200d-2640-fe0f", "paw_prints": "1f43e", "moon": "1f314", "man_medium_skin_tone": "1f468-1f3fd", "rowing_man_dark_skin_tone": "1f6a3-1f3ff-200d-2640-fe0f", "sleepy": "1f62a", "light_rail": "1f688", "peace_symbol": "262e-fe0f", "m": "24c2-fe0f", "woman_pilot_medium_skin_tone": "1f469-1f3fd", "dango": "1f361", "minibus": "1f690", "family_man_man_girl_girl_medium_dark_skin_tone": "1f468-1f3fe", "dizzy_face": "1f635", "bowing_woman": "1f647-200d-2640-fe0f", "pig2": "1f416", "factory": "1f3ed", "small_red_triangle": "1f53a", "ok_man_light_skin_tone": "1f646-1f3fb-200d-2642-fe0f", "two_women_holding_hands": "1f46d", "funeral_urn": "26b1-fe0f", "cocos_islands": "1f1e8-1f1e8", "lipstick": "1f484", "fleur_de_lis": "269c-fe0f", "man_with_gua_pi_mao_dark_skin_tone": "1f472-1f3ff", "woman_factory_worker_medium_dark_skin_tone": "1f469-1f3fe", "no_good_man_medium_light_skin_tone": "1f645-1f3fc-200d-2642-fe0f", "horse_racing_medium_dark_skin_tone": "1f3c7-1f3fe", "clock1030": "1f565", "couplekiss_man_man_dark_skin_tone": "1f468-1f3ff", "frowning_man": "1f64d-200d-2642-fe0f", "family_woman_boy_boy_dark_skin_tone": "1f469-1f3ff", "family_man_girl_boy_light_skin_tone": "1f468-1f3fb", "smile": "1f604", "clock7": "1f556", "massage_man": "1f486-200d-2642-fe0f", "guardswoman_dark_skin_tone": "1f482-1f3ff-200d-2640-fe0f", "raising_hand_man_dark_skin_tone": "1f64b-1f3ff-200d-2642-fe0f", "woman_with_turban_medium_dark_skin_tone": "1f473-1f3fe-200d-2640-fe0f", "worried": "1f61f", "no_good": "1f645", "card_index": "1f4c7", "aland_islands": "1f1e6-1f1fd", "lion": "1f981", "hammer": "1f528", "bomb": "1f4a3", "reunion": "1f1f7-1f1ea", "walking_man_light_skin_tone": "1f6b6-1f3fb-200d-2640-fe0f", "family_woman_boy_medium_light_skin_tone": "1f469-1f3fc", "pouting_cat": "1f63e", "cow": "1f42e", "motor_scooter": "1f6f5", "hong_kong": "1f1ed-1f1f0", "family_man_girl_medium_dark_skin_tone": "1f468-1f3fe", "sailboat": "26f5-fe0f", "fiji": "1f1eb-1f1ef", "raised_hands_medium_light_skin_tone": "1f64c-1f3fc", "woman_office_worker_dark_skin_tone": "1f469-1f3ff", "family_man_woman_girl_girl_medium_light_skin_tone": "1f468-1f3fc", "arrow_up": "2b06-fe0f", "walking_woman_medium_light_skin_tone": "1f6b6-1f3fc-200d-2640-fe0f", "nose_medium_light_skin_tone": "1f443-1f3fc", "basketball_woman": "26f9-fe0f-200d-2640-fe0f", "+1_medium_light_skin_tone": "1f44d-1f3fc", "crossed_fingers_medium_skin_tone": "1f91e-1f3fd", "raised_back_of_hand_dark_skin_tone": "1f91a-1f3ff", "swimming_woman_medium_light_skin_tone": "1f3ca-1f3fc-200d-2640-fe0f", "construction_worker_woman": "1f477-200d-2640-fe0f", "rugby_football": "1f3c9", "micronesia": "1f1eb-1f1f2", "point_up_2_medium_light_skin_tone": "1f446-1f3fc", "running_man_dark_skin_tone": "1f3c3-1f3ff-200d-2640-fe0f", "woman_playing_handball_medium_light_skin_tone": "1f93e-1f3fc-200d-2640-fe0f", "speaker": "1f508", "jersey": "1f1ef-1f1ea", "laughing": "1f606", "pregnant_woman": "1f930", "haircut_woman": "1f487", "blue_car": "1f699", "microscope": "1f52c", "postbox": "1f4ee", "man_firefighter_dark_skin_tone": "1f468-1f3ff", "sunny": "2600-fe0f", "beginner": "1f530", "clap_medium_light_skin_tone": "1f44f-1f3fc", "man_with_turban_dark_skin_tone": "1f473-1f3ff-200d-2640-fe0f", "rotating_light": "1f6a8", "saudi_arabia": "1f1f8-1f1e6", "family_woman_woman_girl_girl_medium_skin_tone": "1f469-1f3fd", "family_woman_girl_boy_light_skin_tone": "1f469-1f3fb", "man_with_gua_pi_mao": "1f472", "electric_plug": "1f50c", "panama": "1f1f5-1f1e6", "family_woman_woman_girl_light_skin_tone": "1f469-1f3fb", "thinking": "1f914", "point_down": "1f447", "spider": "1f577", "cloud_with_lightning_and_rain": "26c8", "ice_skate": "26f8", "ok_man_medium_dark_skin_tone": "1f646-1f3fe-200d-2642-fe0f", "netherlands": "1f1f3-1f1f1", "family_man_woman_boy": "1f46a", "orange": "1f34a", "snowboarder": "1f3c2", "passenger_ship": "1f6f3", "arrows_counterclockwise": "1f504", "tractor": "1f69c", "gambia": "1f1ec-1f1f2", "middle_finger_dark_skin_tone": "1f595-1f3ff", "tipping_hand_woman_medium_dark_skin_tone": "1f481-1f3fe-200d-2640-fe0f", "family_man_man_girl_boy_medium_light_skin_tone": "1f468-1f3fc", "thumbsup": "1f44d", "couple": "1f46b", "pouch": "1f45d", "asterisk": "002a-fe0f-20e3", "anguilla": "1f1e6-1f1ee", "woman_cook_light_skin_tone": "1f469-1f3fb", "kissing_cat": "1f63d", "nose": "1f443", "point_left_medium_skin_tone": "1f448-1f3fd", "baby_chick": "1f424", "deciduous_tree": "1f333", "u7533": "1f238", "surfing_woman_dark_skin_tone": "1f3c4-1f3ff-200d-2640-fe0f", "woman_shrugging_medium_dark_skin_tone": "1f937-1f3fe-200d-2640-fe0f", "family_woman_woman_boy_boy_dark_skin_tone": "1f469-1f3ff", "cloud_with_rain": "1f327", "oden": "1f362", "botswana": "1f1e7-1f1fc", "greenland": "1f1ec-1f1f1", "man_office_worker_light_skin_tone": "1f468-1f3fb", "raising_hand_woman_medium_dark_skin_tone": "1f64b-1f3fe-200d-2640-fe0f", "family_man_man_girl_boy_medium_dark_skin_tone": "1f468-1f3fe", "school": "1f3eb", "woman_astronaut_light_skin_tone": "1f469-1f3fb", "woman_judge_medium_skin_tone": "1f469-1f3fd", "dancing_men": "1f46f-200d-2642-fe0f", "paperclips": "1f587", "underage": "1f51e", "ok_woman_dark_skin_tone": "1f646-1f3ff-200d-2640-fe0f", "man_playing_handball_dark_skin_tone": "1f93e-1f3ff-200d-2642-fe0f", "family_man_girl_girl": "1f468-200d-1f467-200d-1f467", "wind_face": "1f32c", "banana": "1f34c", "eight": "0038-fe0f-20e3", "man_technologist_medium_dark_skin_tone": "1f468-1f3fe", "man_office_worker_medium_skin_tone": "1f468-1f3fd", "walking_man_dark_skin_tone": "1f6b6-1f3ff-200d-2640-fe0f", "family_man_man_girl_girl_medium_skin_tone": "1f468-1f3fd", "snowman": "26c4-fe0f", "basketball_man": "26f9-fe0f", "information_source": "2139-fe0f", "cote_divoire": "1f1e8-1f1ee", "man_in_tuxedo_light_skin_tone": "1f935-1f3fb", "walking_woman_light_skin_tone": "1f6b6-1f3fb-200d-2640-fe0f", "woman_playing_water_polo_light_skin_tone": "1f93d-1f3fb-200d-2640-fe0f", "bird": "1f426", "o": "2b55-fe0f", "family_woman_girl_medium_skin_tone": "1f469-1f3fd", "rowing_woman_dark_skin_tone": "1f6a3-1f3ff-200d-2640-fe0f", "facepunch": "1f44a", "railway_car": "1f683", "wave_dark_skin_tone": "1f44b-1f3ff", "man_cook_medium_dark_skin_tone": "1f468-1f3fe", "prince_medium_light_skin_tone": "1f934-1f3fc", "cowboy_hat_face": "1f920", "handbag": "1f45c", "hourglass": "231b-fe0f", "albania": "1f1e6-1f1f1", "chile": "1f1e8-1f1f1", "woman_singer_medium_skin_tone": "1f469-1f3fd", "ear_medium_skin_tone": "1f442-1f3fd", "pouting_man_medium_skin_tone": "1f64e-1f3fd-200d-2642-fe0f", "surfing_man_medium_light_skin_tone": "1f3c4-1f3fc-200d-2640-fe0f", "eggplant": "1f346", "next_track_button": "23ed", "gabon": "1f1ec-1f1e6", "western_sahara": "1f1ea-1f1ed", "raised_hands_light_skin_tone": "1f64c-1f3fb", "older_woman_medium_light_skin_tone": "1f475-1f3fc", "joy_cat": "1f639", "feet": "1f43e", "partly_sunny": "26c5-fe0f", "pig_nose": "1f43d", "wc": "1f6be", "malaysia": "1f1f2-1f1fe", "girl_medium_light_skin_tone": "1f467-1f3fc", "man_office_worker_medium_dark_skin_tone": "1f468-1f3fe", "man_mechanic_medium_light_skin_tone": "1f468-1f3fc", "shamrock": "2618-fe0f", "tumbler_glass": "1f943", "palestinian_territories": "1f1f5-1f1f8", "kissing": "1f617", "city_sunset": "1f306", "pencil2": "270f-fe0f", "cool": "1f192", "australia": "1f1e6-1f1fa", "green_heart": "1f49a", "sparkle": "2747-fe0f", "ng_woman": "1f645", "high_heel": "1f460", "hamster": "1f439", "last_quarter_moon": "1f317", "stopwatch": "23f1", "date": "1f4c5", "nail_care_dark_skin_tone": "1f485-1f3ff", "santa_dark_skin_tone": "1f385-1f3ff", "astonished": "1f632", "mushroom": "1f344", "radio": "1f4fb", "hammer_and_wrench": "1f6e0", "arrow_down": "2b07-fe0f", "speech_balloon": "1f4ac", "couple_with_heart_man_man_medium_skin_tone": "1f468-1f3fd", "euro": "1f4b6", "es": "1f1ea-1f1f8", "woman_factory_worker_medium_light_skin_tone": "1f469-1f3fc", "pouting_woman_dark_skin_tone": "1f64e-1f3ff-200d-2640-fe0f", "massage_woman": "1f486", "spades": "2660-fe0f", "blonde_woman_dark_skin_tone": "1f471-1f3ff-200d-2640-fe0f", "man_farmer_medium_skin_tone": "1f468-1f3fd", "man_mechanic_medium_skin_tone": "1f468-1f3fd", "family_man_boy_dark_skin_tone": "1f468-1f3ff", "man_juggling_medium_light_skin_tone": "1f939-1f3fc-200d-2642-fe0f", "hearts": "2665-fe0f", "clock930": "1f564", "central_african_republic": "1f1e8-1f1eb", "boy_medium_skin_tone": "1f466-1f3fd", "pregnant_woman_medium_skin_tone": "1f930-1f3fd", "woman_facepalming_medium_light_skin_tone": "1f926-1f3fc-200d-2640-fe0f", "palm_tree": "1f334", "rose": "1f339", "beers": "1f37b", "red_car": "1f697", "no_entry": "26d4-fe0f", "candy": "1f36c", "fist_oncoming_medium_skin_tone": "1f44a-1f3fd", "rowing_woman_medium_skin_tone": "1f6a3-1f3fd-200d-2640-fe0f", "sake": "1f376", "oncoming_police_car": "1f694", "woman_teacher_medium_dark_skin_tone": "1f469-1f3fe", "family_man_woman_girl_girl_medium_skin_tone": "1f468-1f3fd", "kissing_closed_eyes": "1f61a", "pager": "1f4df", "pencil": "1f4dd", "copyright": "00a9-fe0f", "wave_medium_skin_tone": "1f44b-1f3fd", "loud_sound": "1f50a", "luxembourg": "1f1f1-1f1fa", "policewoman_dark_skin_tone": "1f46e-1f3ff-200d-2640-fe0f", "woman_cartwheeling_medium_skin_tone": "1f938-1f3fd-200d-2640-fe0f", "swimming_woman_medium_dark_skin_tone": "1f3ca-1f3fe-200d-2640-fe0f", "family_man_man_girl_boy": "1f468-200d-1f468-200d-1f467-200d-1f466", "police_car": "1f693", "mailbox_with_no_mail": "1f4ed", "middle_finger_light_skin_tone": "1f595-1f3fb", "pregnant_woman_medium_light_skin_tone": "1f930-1f3fc", "raising_hand_woman_medium_skin_tone": "1f64b-1f3fd-200d-2640-fe0f", "running": "1f3c3", "sun_with_face": "1f31e", "man_teacher_dark_skin_tone": "1f468-1f3ff", "family_man_woman_girl_girl_dark_skin_tone": "1f468-1f3ff", "izakaya_lantern": "1f3ee", "comoros": "1f1f0-1f1f2", "fist_oncoming_medium_dark_skin_tone": "1f44a-1f3fe", "man_singer": "1f468-200d-1f3a4", "mountain_bicyclist": "1f6b5", "point_down_light_skin_tone": "1f447-1f3fb", "family_man_woman_girl_boy_medium_dark_skin_tone": "1f468-1f3fe", "sob": "1f62d", "ophiuchus": "26ce", "greece": "1f1ec-1f1f7", "raised_back_of_hand_medium_skin_tone": "1f91a-1f3fd", "family_man_man_boy_light_skin_tone": "1f468-1f3fb", "woman_cartwheeling_light_skin_tone": "1f938-1f3fb-200d-2640-fe0f", "massage_woman_light_skin_tone": "1f486-1f3fb-200d-2640-fe0f", "fishing_pole_and_fish": "1f3a3", "two_hearts": "1f495", "armenia": "1f1e6-1f1f2", "south_africa": "1f1ff-1f1e6", "boy_light_skin_tone": "1f466-1f3fb", "man_in_tuxedo_medium_dark_skin_tone": "1f935-1f3fe", "kiribati": "1f1f0-1f1ee", "v_dark_skin_tone": "270c-1f3ff", "frowning_man_medium_light_skin_tone": "1f64d-1f3fc-200d-2642-fe0f", "family_woman_woman_girl_boy": "1f469-200d-1f469-200d-1f467-200d-1f466", "family_woman_girl_boy_medium_dark_skin_tone": "1f469-1f3fe", "leopard": "1f406", "fireworks": "1f386", "clock6": "1f555", "bowing_man_medium_light_skin_tone": "1f647-1f3fc-200d-2640-fe0f", "raising_hand": "1f64b", "family_man_woman_girl_girl_light_skin_tone": "1f468-1f3fb", "vulcan_salute_medium_light_skin_tone": "1f596-1f3fc", "guardswoman_medium_light_skin_tone": "1f482-1f3fc-200d-2640-fe0f", "muscle": "1f4aa", "full_moon": "1f315", "pisces": "2653-fe0f", "kosovo": "1f1fd-1f1f0", "fist_left_dark_skin_tone": "1f91b-1f3ff", "point_up_2_dark_skin_tone": "1f446-1f3ff", "man_technologist_dark_skin_tone": "1f468-1f3ff", "spoon": "1f944", "nigeria": "1f1f3-1f1ec", "raised_back_of_hand_medium_light_skin_tone": "1f91a-1f3fc", "blonde_woman_light_skin_tone": "1f471-1f3fb-200d-2640-fe0f", "man_dancing_light_skin_tone": "1f57a-1f3fb", "shrimp": "1f990", "mountain_biking_man": "1f6b5", "boat": "26f5-fe0f", "egypt": "1f1ea-1f1ec", "family_woman_woman_boy_light_skin_tone": "1f469-1f3fb", "man_playing_water_polo_light_skin_tone": "1f93d-1f3fb-200d-2642-fe0f", "family_man_man_boy_boy": "1f468-200d-1f468-200d-1f466-200d-1f466", "foggy": "1f301", "construction_worker_woman_medium_light_skin_tone": "1f477-1f3fc-200d-2640-fe0f", "princess_medium_skin_tone": "1f478-1f3fd", "man_dancing_medium_dark_skin_tone": "1f57a-1f3fe", "couple_with_heart_man_man_dark_skin_tone": "1f468-1f3ff", "carousel_horse": "1f3a0", "crayon": "1f58d", "niue": "1f1f3-1f1fa", "woman_office_worker_medium_skin_tone": "1f469-1f3fd", "swimming_man_medium_skin_tone": "1f3ca-1f3fd-200d-2640-fe0f", "pensive": "1f614", "fire": "1f525", "monorail": "1f69d", "guam": "1f1ec-1f1fa", "older_woman_light_skin_tone": "1f475-1f3fb", "man_facepalming_medium_light_skin_tone": "1f926-1f3fc-200d-2642-fe0f", "family_man_man_girl": "1f468-200d-1f468-200d-1f467", "hammer_and_pick": "2692", "space_invader": "1f47e", "waning_crescent_moon": "1f318", "love_letter": "1f48c", "star_and_crescent": "262a-fe0f", "man_with_turban_light_skin_tone": "1f473-1f3fb-200d-2640-fe0f", "tipping_hand_woman_light_skin_tone": "1f481-1f3fb-200d-2640-fe0f", "dress": "1f457", "rainbow": "1f308", "cheese": "1f9c0", "bento": "1f371", "gear": "2699-fe0f", "-1_medium_skin_tone": "1f44e-1f3fd", "family_man_girl_boy_dark_skin_tone": "1f468-1f3ff", "fish_cake": "1f365", "desert_island": "1f3dd", "crystal_ball": "1f52e", "lock": "1f512", "no_good_man_medium_skin_tone": "1f645-1f3fd-200d-2642-fe0f", "small_blue_diamond": "1f539", "fist_raised_medium_dark_skin_tone": "270a-1f3fe", "man_health_worker_medium_light_skin_tone": "1f468-1f3fc", "ok_man_medium_light_skin_tone": "1f646-1f3fc-200d-2642-fe0f", "man_cartwheeling_dark_skin_tone": "1f938-1f3ff-200d-2642-fe0f", "policeman": "1f46e", "closed_lock_with_key": "1f510", "koko": "1f201", "guardswoman": "1f482-200d-2640-fe0f", "mailbox": "1f4eb", "weight_lifting_woman_light_skin_tone": "1f3cb-1f3fb-200d-2640-fe0f", "drooling_face": "1f924", "motorway": "1f6e3", "orthodox_cross": "2626-fe0f", "peru": "1f1f5-1f1ea", "woman_firefighter_medium_light_skin_tone": "1f469-1f3fc", "atom_symbol": "269b-fe0f", "benin": "1f1e7-1f1ef", "montenegro": "1f1f2-1f1ea", "tonga": "1f1f9-1f1f4", "family_man_boy_boy_medium_skin_tone": "1f468-1f3fd", "man_mechanic_light_skin_tone": "1f468-1f3fb", "female_detective": "1f575-fe0f-200d-2640-fe0f", "closed_umbrella": "1f302", "cow2": "1f404", "ballot_box": "1f5f3", "construction_worker_man_dark_skin_tone": "1f477-1f3ff-200d-2640-fe0f", "woman_technologist_medium_dark_skin_tone": "1f469-1f3fe", "indonesia": "1f1ee-1f1e9", "woman_pilot_medium_light_skin_tone": "1f469-1f3fc", "family_man_man_boy_boy_medium_light_skin_tone": "1f468-1f3fc", "call_me_hand": "1f919", "sun_behind_small_cloud": "1f324", "national_park": "1f3de", "radio_button": "1f518", "selfie_medium_light_skin_tone": "1f933-1f3fc", "woman_firefighter": "1f469-200d-1f692", "metal_dark_skin_tone": "1f918-1f3ff", "older_woman": "1f475", "man_factory_worker_medium_skin_tone": "1f468-1f3fd", "pick": "26cf", "woman_student_medium_skin_tone": "1f469-1f3fd", "mountain_biking_woman_light_skin_tone": "1f6b5-1f3fb-200d-2640-fe0f", "flags": "1f38f", "black_nib": "2712-fe0f", "rwanda": "1f1f7-1f1fc", "surfing_man_light_skin_tone": "1f3c4-1f3fb-200d-2640-fe0f", "first_quarter_moon": "1f313", "oil_drum": "1f6e2", "heart_decoration": "1f49f", "jp": "1f1ef-1f1f5", "woman_pilot": "1f469-200d-2708-fe0f", "city_sunrise": "1f307", "leo": "264c-fe0f", "arrow_up_down": "2195-fe0f", "selfie_medium_skin_tone": "1f933-1f3fd", "surfing_man_medium_skin_tone": "1f3c4-1f3fd-200d-2640-fe0f", "ramen": "1f35c", "up": "1f199", "woman_medium_light_skin_tone": "1f469-1f3fc", "woman_artist": "1f469-200d-1f3a8", "football": "1f3c8", "shopping": "1f6cd", "small_red_triangle_down": "1f53b", "crossed_fingers_light_skin_tone": "1f91e-1f3fb", "woman_artist_medium_dark_skin_tone": "1f469-1f3fe", "milk_glass": "1f95b", "clapper": "1f3ac", "star_of_david": "2721-fe0f", "dominican_republic": "1f1e9-1f1f4", "woman_teacher_light_skin_tone": "1f469-1f3fb", "man_juggling_medium_skin_tone": "1f939-1f3fd-200d-2642-fe0f", "-1": "1f44e", "wedding": "1f492", "faroe_islands": "1f1eb-1f1f4", "raising_hand_man_medium_dark_skin_tone": "1f64b-1f3fe-200d-2642-fe0f", "gemini": "264a-fe0f", "st_helena": "1f1f8-1f1ed", "running_woman_medium_light_skin_tone": "1f3c3-1f3fc-200d-2640-fe0f", "biking_woman_light_skin_tone": "1f6b4-1f3fb-200d-2640-fe0f", "paperclip": "1f4ce", "wave_medium_light_skin_tone": "1f44b-1f3fc", "man_factory_worker_medium_dark_skin_tone": "1f468-1f3fe", "woman_cartwheeling_medium_dark_skin_tone": "1f938-1f3fe-200d-2640-fe0f", "clock12": "1f55b", "ru": "1f1f7-1f1fa", "clown_face": "1f921", "pizza": "1f355", "hole": "1f573", "incoming_envelope": "1f4e8", "yin_yang": "262f-fe0f", "warning": "26a0-fe0f", "family_man_man_girl_boy_dark_skin_tone": "1f468-1f3ff", "man_cartwheeling_medium_skin_tone": "1f938-1f3fd-200d-2642-fe0f", "ram": "1f40f", "cucumber": "1f952", "heartbeat": "1f493", "swaziland": "1f1f8-1f1ff", "nail_care_medium_dark_skin_tone": "1f485-1f3fe", "bath_medium_skin_tone": "1f6c0-1f3fd", "strawberry": "1f353", "peanuts": "1f95c", "field_hockey": "1f3d1", "cricket": "1f3cf", "woman_farmer_medium_dark_skin_tone": "1f469-1f3fe", "family_man_man_girl_girl_light_skin_tone": "1f468-1f3fb", "penguin": "1f427", "star": "2b50-fe0f", "woman_shrugging_light_skin_tone": "1f937-1f3fb-200d-2640-fe0f", "golfing_man_light_skin_tone": "1f3cc-1f3fb-200d-2640-fe0f", "innocent": "1f607", "mosque": "1f54c", "calendar": "1f4c6", "canada": "1f1e8-1f1e6", "rage4": "rage4", "woman_office_worker_medium_dark_skin_tone": "1f469-1f3fe", "poodle": "1f429", "grapes": "1f347", "love_hotel": "1f3e9", "vulcan_salute_medium_skin_tone": "1f596-1f3fd", "guardsman_medium_dark_skin_tone": "1f482-1f3fe-200d-2640-fe0f", "raising_hand_man_light_skin_tone": "1f64b-1f3fb-200d-2642-fe0f", "sleeping": "1f634", "nail_care": "1f485", "monkey": "1f412", "sao_tome_principe": "1f1f8-1f1f9", "dancer_medium_dark_skin_tone": "1f483-1f3fe", "classical_building": "1f3db", "swimming_woman_medium_skin_tone": "1f3ca-1f3fd-200d-2640-fe0f", "ok_hand": "1f44c", "rice_cracker": "1f358", "moyai": "1f5ff", "rage2": "rage2", "angel_light_skin_tone": "1f47c-1f3fb", "family_man_man_boy_boy_dark_skin_tone": "1f468-1f3ff", "smile_cat": "1f638", "angola": "1f1e6-1f1f4", "cameroon": "1f1e8-1f1f2", "man_student_medium_dark_skin_tone": "1f468-1f3fe", "weight_lifting_woman_medium_light_skin_tone": "1f3cb-1f3fc-200d-2640-fe0f", "waxing_crescent_moon": "1f312", "articulated_lorry": "1f69b", "pouting_woman_light_skin_tone": "1f64e-1f3fb-200d-2640-fe0f", "running_man_medium_dark_skin_tone": "1f3c3-1f3fe-200d-2640-fe0f", "couple_with_heart_woman_woman_light_skin_tone": "1f469-1f3fb", "horse_racing_light_skin_tone": "1f3c7-1f3fb", "raised_back_of_hand": "1f91a", "saxophone": "1f3b7", "right_anger_bubble": "1f5ef", "tokelau": "1f1f9-1f1f0", "no_good_woman_medium_light_skin_tone": "1f645-1f3fc-200d-2640-fe0f", "walking_woman_medium_skin_tone": "1f6b6-1f3fd-200d-2640-fe0f", "family_woman_girl_girl": "1f469-200d-1f467-200d-1f467", "cake": "1f370", "abcd": "1f521", "tuvalu": "1f1f9-1f1fb", "suspect": "suspect", "mattermost": "mattermost", "swimming_woman_light_skin_tone": "1f3ca-1f3fb-200d-2640-fe0f", "white_medium_square": "25fb-fe0f", "haircut_woman_medium_skin_tone": "1f487-1f3fd-200d-2640-fe0f", "massage_woman_dark_skin_tone": "1f486-1f3ff-200d-2640-fe0f", "family_man_woman_girl_light_skin_tone": "1f468-1f3fb", "turks_caicos_islands": "1f1f9-1f1e8", "point_left_dark_skin_tone": "1f448-1f3ff", "family_man_man_boy_medium_dark_skin_tone": "1f468-1f3fe", "hand": "270b", "coffee": "2615-fe0f", "somalia": "1f1f8-1f1f4", "mountain_biking_man_dark_skin_tone": "1f6b5-1f3ff-200d-2640-fe0f", "hatching_chick": "1f423", "pear": "1f350", "baby_bottle": "1f37c", "ribbon": "1f380", "st_kitts_nevis": "1f1f0-1f1f3", "radioactive": "2622-fe0f", "end": "1f51a", "hand_medium_skin_tone": "270b-1f3fd", "family_woman_woman_girl_medium_light_skin_tone": "1f469-1f3fc", "3rd_place_medal": "1f949", "fist_left_medium_dark_skin_tone": "1f91b-1f3fe", "bolivia": "1f1e7-1f1f4", "point_up_light_skin_tone": "261d-1f3fb", "cherries": "1f352", "inbox_tray": "1f4e5", "pitcairn_islands": "1f1f5-1f1f3", "rage1": "rage1", "man_farmer_medium_dark_skin_tone": "1f468-1f3fe", "woman_with_turban": "1f473-200d-2640-fe0f", "unicorn": "1f984", "butterfly": "1f98b", "watch": "231a-fe0f", "arrow_up_small": "1f53c", "triangular_flag_on_post": "1f6a9", "heart_eyes": "1f60d", "shallow_pan_of_food": "1f958", "broken_heart": "1f494", "family_man_boy_boy_dark_skin_tone": "1f468-1f3ff", "golfing_woman_dark_skin_tone": "1f3cc-1f3ff-200d-2640-fe0f", "bath_dark_skin_tone": "1f6c0-1f3ff", "selfie": "1f933", "congratulations": "3297-fe0f", "baby_medium_light_skin_tone": "1f476-1f3fc", "woman_health_worker_medium_skin_tone": "1f469-1f3fd", "man_juggling": "1f939-200d-2642-fe0f", "arrow_down_small": "1f53d", "writing_hand_medium_light_skin_tone": "270d-1f3fc", "blonde_woman": "1f471-200d-2640-fe0f", "massage": "1f486", "metro": "1f687", "bath": "1f6c0", "female_detective_light_skin_tone": "1f575-1f3fb-200d-2640-fe0f", "haircut_man_light_skin_tone": "1f487-1f3fb-200d-2642-fe0f", "bowing_woman_medium_dark_skin_tone": "1f647-1f3fe-200d-2640-fe0f", "family_woman_woman_boy_medium_dark_skin_tone": "1f469-1f3fe", "shell": "1f41a", "seychelles": "1f1f8-1f1e8", "tipping_hand_man_medium_skin_tone": "1f481-1f3fd-200d-2642-fe0f", "panda_face": "1f43c", "sint_maarten": "1f1f8-1f1fd", "face_with_head_bandage": "1f915", "checkered_flag": "1f3c1", "samoa": "1f1fc-1f1f8", "v_medium_skin_tone": "270c-1f3fd", "couple_with_heart_man_man": "1f468-200d-2764-fe0f-200d-1f468", "shaved_ice": "1f367", "badminton": "1f3f8", "clock530": "1f560", "man_playing_water_polo_medium_dark_skin_tone": "1f93d-1f3fe-200d-2642-fe0f", "bulgaria": "1f1e7-1f1ec", "hurtrealbad": "hurtrealbad", "fist_oncoming_dark_skin_tone": "1f44a-1f3ff", "bat": "1f987", "signal_strength": "1f4f6", "iran": "1f1ee-1f1f7", "construction_worker_woman_medium_dark_skin_tone": "1f477-1f3fe-200d-2640-fe0f", "kiwi_fruit": "1f95d", "2nd_place_medal": "1f948", "kaaba": "1f54b", "knife": "1f52a", "ok_hand_light_skin_tone": "1f44c-1f3fb", "angel_medium_dark_skin_tone": "1f47c-1f3fe", "spider_web": "1f578", "oncoming_taxi": "1f696", "bookmark": "1f516", "u6307": "1f22f-fe0f", "za": "1f1ff-1f1e6", "fist_raised_light_skin_tone": "270a-1f3fb", "mag_right": "1f50e", "guinea": "1f1ec-1f1f3", "family_woman_woman_girl_dark_skin_tone": "1f469-1f3ff", "man_playing_handball_medium_light_skin_tone": "1f93e-1f3fc-200d-2642-fe0f", "game_die": "1f3b2", "bullettrain_front": "1f685", "speedboat": "1f6a4", "hand_dark_skin_tone": "270b-1f3ff", "selfie_light_skin_tone": "1f933-1f3fb", "family_man_woman_boy_boy_dark_skin_tone": "1f468-1f3ff", "running_man": "1f3c3", "couplekiss_woman_woman": "1f469-200d-2764-fe0f-200d-1f48b-200d-1f469", "woman_teacher": "1f469-200d-1f3eb", "running_shirt_with_sash": "1f3bd", "bowing_man_medium_skin_tone": "1f647-1f3fd-200d-2640-fe0f", "point_right_medium_dark_skin_tone": "1f449-1f3fe", "man_cartwheeling_medium_light_skin_tone": "1f938-1f3fc-200d-2642-fe0f", "pouting_man_light_skin_tone": "1f64e-1f3fb-200d-2642-fe0f", "biking_man_light_skin_tone": "1f6b4-1f3fb-200d-2640-fe0f", "oncoming_automobile": "1f698", "steam_locomotive": "1f682", "newspaper": "1f4f0", "antigua_barbuda": "1f1e6-1f1ec", "macau": "1f1f2-1f1f4", "niger": "1f1f3-1f1ea", "chicken": "1f414", "flashlight": "1f526", "family_man_woman_boy_boy_medium_skin_tone": "1f468-1f3fd", "mens": "1f6b9", "it": "1f1ee-1f1f9", "new_caledonia": "1f1f3-1f1e8", "pray_medium_light_skin_tone": "1f64f-1f3fc", "nose_medium_dark_skin_tone": "1f443-1f3fe", "man_facepalming_medium_dark_skin_tone": "1f926-1f3fe-200d-2642-fe0f", "poop": "1f4a9", "clap_light_skin_tone": "1f44f-1f3fb", "guardsman_medium_skin_tone": "1f482-1f3fd-200d-2640-fe0f", "woman_teacher_dark_skin_tone": "1f469-1f3ff", "grinning": "1f600", "aries": "2648-fe0f", "mrs_claus": "1f936", "green_book": "1f4d7", "middle_finger_medium_dark_skin_tone": "1f595-1f3fe", "rowing_woman_light_skin_tone": "1f6a3-1f3fb-200d-2640-fe0f", "tokyo_tower": "1f5fc", "printer": "1f5a8", "put_litter_in_its_place": "1f6ae", "suriname": "1f1f8-1f1f7", "woman_light_skin_tone": "1f469-1f3fb", "man_playing_water_polo_medium_light_skin_tone": "1f93d-1f3fc-200d-2642-fe0f", "dove": "1f54a", "latin_cross": "271d-fe0f", "exclamation": "2757-fe0f", "man_health_worker_dark_skin_tone": "1f468-1f3ff", "bride_with_veil_light_skin_tone": "1f470-1f3fb", "rowboat": "1f6a3", "world_map": "1f5fa", "sleeping_bed": "1f6cc", "haircut_man_dark_skin_tone": "1f487-1f3ff-200d-2642-fe0f", "surfing_man_dark_skin_tone": "1f3c4-1f3ff-200d-2640-fe0f", "couple_with_heart_woman_man": "1f491", "chart_with_upwards_trend": "1f4c8", "fist_right_dark_skin_tone": "1f91c-1f3ff", "raised_hand_with_fingers_splayed_medium_skin_tone": "1f590-1f3fd", "older_woman_medium_dark_skin_tone": "1f475-1f3fe", "couplekiss_woman_woman_medium_dark_skin_tone": "1f469-1f3fe", "hatched_chick": "1f425", "running_man_medium_skin_tone": "1f3c3-1f3fd-200d-2640-fe0f", "chocolate_bar": "1f36b", "grenada": "1f1ec-1f1e9", "man_farmer_dark_skin_tone": "1f468-1f3ff", "milky_way": "1f30c", "slovakia": "1f1f8-1f1f0", "selfie_dark_skin_tone": "1f933-1f3ff", "prince_medium_skin_tone": "1f934-1f3fd", "family_man_boy": "1f468-200d-1f466", "chains": "26d3", "british_virgin_islands": "1f1fb-1f1ec", "bow_and_arrow": "1f3f9", "ferry": "26f4", "o2": "1f17e-fe0f", "st_barthelemy": "1f1e7-1f1f1", "policewoman_medium_skin_tone": "1f46e-1f3fd-200d-2640-fe0f", "imp": "1f47f", "bathtub": "1f6c1", "anger": "1f4a2", "previous_track_button": "23ee", "pouting_woman_medium_light_skin_tone": "1f64e-1f3fc-200d-2640-fe0f", "rabbit2": "1f407", "newspaper_roll": "1f5de", "one": "0031-fe0f-20e3", "family_man_man_girl_medium_skin_tone": "1f468-1f3fd", "pouting_woman": "1f64e", "moneybag": "1f4b0", "guardsman_dark_skin_tone": "1f482-1f3ff-200d-2640-fe0f", "man_shrugging_medium_light_skin_tone": "1f937-1f3fc-200d-2642-fe0f", "smirk": "1f60f", "woman_farmer": "1f469-200d-1f33e", "ocean": "1f30a", "sweat_drops": "1f4a6", "x": "274c", "woman_judge_medium_dark_skin_tone": "1f469-1f3fe", "tropical_drink": "1f379", "brunei": "1f1e7-1f1f3", "woman_artist_medium_light_skin_tone": "1f469-1f3fc", "pregnant_woman_medium_dark_skin_tone": "1f930-1f3fe", "basketball_woman_light_skin_tone": "26f9-1f3fb-200d-2640-fe0f", "evergreen_tree": "1f332", "fax": "1f4e0", "woman_medium_dark_skin_tone": "1f469-1f3fe", "walking_woman_medium_dark_skin_tone": "1f6b6-1f3fe-200d-2640-fe0f", "lollipop": "1f36d", "bicyclist": "1f6b4", "bulb": "1f4a1", "computer": "1f4bb", "frowning_man_dark_skin_tone": "1f64d-1f3ff-200d-2642-fe0f", "guardsman_medium_light_skin_tone": "1f482-1f3fc-200d-2640-fe0f", "dancer_light_skin_tone": "1f483-1f3fb", "no_good_woman": "1f645", "cherry_blossom": "1f338", "woman_playing_water_polo": "1f93d-200d-2640-fe0f", "heavy_division_sign": "2797", "sri_lanka": "1f1f1-1f1f0", "-1_medium_light_skin_tone": "1f44e-1f3fc", "family_woman_girl_girl_dark_skin_tone": "1f469-1f3ff", "raised_hands": "1f64c", "sandal": "1f461", "rhinoceros": "1f98f", "swimming_man": "1f3ca", "scissors": "2702-fe0f", "horse_racing_dark_skin_tone": "1f3c7-1f3ff", "coffin": "26b0-fe0f", "clock1": "1f550", "eritrea": "1f1ea-1f1f7", "qatar": "1f1f6-1f1e6", "tanzania": "1f1f9-1f1ff", "pregnant_woman_light_skin_tone": "1f930-1f3fb", "cop": "1f46e", "tipping_hand_woman": "1f481", "estonia": "1f1ea-1f1ea", "man_singer_light_skin_tone": "1f468-1f3fb", "woman_judge_dark_skin_tone": "1f469-1f3ff", "business_suit_levitating_medium_skin_tone": "1f574-1f3fd", "blowfish": "1f421", "mountain_railway": "1f69e", "fast_forward": "23e9", "+1_medium_skin_tone": "1f44d-1f3fd", "goat": "1f410", "congo_kinshasa": "1f1e8-1f1e9", "point_down_dark_skin_tone": "1f447-1f3ff", "basketball_man_light_skin_tone": "26f9-1f3fb-200d-2640-fe0f", "woman_playing_handball_medium_dark_skin_tone": "1f93e-1f3fe-200d-2640-fe0f", "doughnut": "1f369", "musical_keyboard": "1f3b9", "couplekiss_woman_woman_medium_skin_tone": "1f469-1f3fd", "heavy_heart_exclamation": "2763-fe0f", "u6e80": "1f235", "woman_with_turban_medium_skin_tone": "1f473-1f3fd-200d-2640-fe0f", "horse_racing_medium_skin_tone": "1f3c7-1f3fd", "ear": "1f442", "canoe": "1f6f6", "andorra": "1f1e6-1f1e9", "ca": "1f1e8-1f1e6", "family_man_man_boy": "1f468-200d-1f468-200d-1f466", "ticket": "1f3ab", "station": "1f689", "large_blue_circle": "1f535", "palau": "1f1f5-1f1fc", "blush": "1f60a", "man_student": "1f468-200d-1f393", "woman_singer": "1f469-200d-1f3a4", "house_with_garden": "1f3e1", "smoking": "1f6ac", "b": "1f171-fe0f", "golfing_woman_light_skin_tone": "1f3cc-1f3fb-200d-2640-fe0f", "man_artist_light_skin_tone": "1f468-1f3fb", "unamused": "1f612", "japanese_ogre": "1f479", "film_projector": "1f4fd", "ballot_box_with_check": "2611-fe0f", "goberserk": "goberserk", "metal_medium_light_skin_tone": "1f918-1f3fc", "latvia": "1f1f1-1f1fb", "moldova": "1f1f2-1f1e9", "mask": "1f637", "bowing_man": "1f647", "man_shrugging": "1f937-200d-2642-fe0f", "ping_pong": "1f3d3", "trackball": "1f5b2", "six": "0036-fe0f-20e3", "point_up_medium_skin_tone": "261d-1f3fd", "hotel": "1f3e8", "bookmark_tabs": "1f4d1", "chart_with_downwards_trend": "1f4c9", "v_light_skin_tone": "270c-1f3fb", "tipping_hand_woman_medium_skin_tone": "1f481-1f3fd-200d-2640-fe0f", "heart_eyes_cat": "1f63b", "dancer": "1f483", "movie_camera": "1f3a5", "two": "0032-fe0f-20e3", "clap_medium_dark_skin_tone": "1f44f-1f3fe", "woman_astronaut_medium_skin_tone": "1f469-1f3fd", "frowning": "1f626", "cry": "1f622", "no_bell": "1f515", "hand_medium_dark_skin_tone": "270b-1f3fe", "ear_light_skin_tone": "1f442-1f3fb", "family_man_girl_boy": "1f468-200d-1f467-200d-1f466", "swimming_woman": "1f3ca-200d-2640-fe0f", "mountain_biking_woman": "1f6b5-200d-2640-fe0f", "mantelpiece_clock": "1f570", "bermuda": "1f1e7-1f1f2", "new_zealand": "1f1f3-1f1ff", "massage_man_medium_dark_skin_tone": "1f486-1f3fe-200d-2642-fe0f", "crown": "1f451", "biking_man": "1f6b4", "woman_playing_water_polo_medium_skin_tone": "1f93d-1f3fd-200d-2640-fe0f", "man_in_tuxedo_dark_skin_tone": "1f935-1f3ff", "no_entry_sign": "1f6ab", "hash": "0023-fe0f-20e3", "white_small_square": "25ab-fe0f", "iraq": "1f1ee-1f1f6", "switzerland": "1f1e8-1f1ed", "woman_mechanic_light_skin_tone": "1f469-1f3fb", "squirrel": "shipit", "woman_cook_medium_light_skin_tone": "1f469-1f3fc", "confounded": "1f616", "+1": "1f44d", "rowing_man": "1f6a3", "mailbox_closed": "1f4ea", "customs": "1f6c3", "mayotte": "1f1fe-1f1f9", "man_mechanic_medium_dark_skin_tone": "1f468-1f3fe", "man_artist_medium_skin_tone": "1f468-1f3fd", "man_playing_handball_medium_skin_tone": "1f93e-1f3fd-200d-2642-fe0f", "grimacing": "1f62c", "dart": "1f3af", "wave_medium_dark_skin_tone": "1f44b-1f3fe", "slightly_smiling_face": "1f642", "medal_sports": "1f3c5", "bank": "1f3e6", "man_student_medium_light_skin_tone": "1f468-1f3fc", "man_pilot_light_skin_tone": "1f468-1f3fb", "weight_lifting_woman_medium_skin_tone": "1f3cb-1f3fd-200d-2640-fe0f", "dash": "1f4a8", "volcano": "1f30b", "antarctica": "1f1e6-1f1f6", "woman_facepalming_light_skin_tone": "1f926-1f3fb-200d-2640-fe0f", "man_dancing_medium_light_skin_tone": "1f57a-1f3fc", "scream_cat": "1f640", "fog": "1f32b", "fist_oncoming_light_skin_tone": "1f44a-1f3fb", "man_dancing_medium_skin_tone": "1f57a-1f3fd", "burrito": "1f32f", "thought_balloon": "1f4ad", "massage_man_medium_light_skin_tone": "1f486-1f3fc-200d-2642-fe0f", "couple_with_heart_woman_woman_dark_skin_tone": "1f469-1f3ff", "writing_hand": "270d-fe0f", "zap": "26a1-fe0f", "recycle": "267b-fe0f", "policewoman_medium_light_skin_tone": "1f46e-1f3fc-200d-2640-fe0f", "frowning_woman_medium_skin_tone": "1f64d-1f3fd-200d-2640-fe0f", "massage_man_light_skin_tone": "1f486-1f3fb-200d-2642-fe0f", "woman_student": "1f469-200d-1f393", "surfing_woman": "1f3c4-200d-2640-fe0f", "sunrise": "1f305", "open_file_folder": "1f4c2", "diamonds": "2666-fe0f", "family_man_woman_girl_girl": "1f468-200d-1f469-200d-1f467-200d-1f467", "airplane": "2708-fe0f", "arrow_heading_down": "2935-fe0f", "uruguay": "1f1fa-1f1fe", "point_down_medium_dark_skin_tone": "1f447-1f3fe", "family_man_man_boy_dark_skin_tone": "1f468-1f3ff", "family_man_woman_girl_boy": "1f468-200d-1f469-200d-1f467-200d-1f466", "confetti_ball": "1f38a", "flower_playing_cards": "1f3b4", "algeria": "1f1e9-1f1ff", "man_teacher_medium_light_skin_tone": "1f468-1f3fc", "woman_artist_light_skin_tone": "1f469-1f3fb", "family_man_woman_girl_medium_skin_tone": "1f468-1f3fd", "nerd_face": "1f913", "eyes": "1f440", "boot": "1f462", "unlock": "1f513", "zzz": "1f4a4", "vatican_city": "1f1fb-1f1e6", "hot_pepper": "1f336", "slot_machine": "1f3b0", "sunrise_over_mountains": "1f304", "haircut_man_medium_skin_tone": "1f487-1f3fd-200d-2642-fe0f", "stuck_out_tongue": "1f61b", "point_up_medium_dark_skin_tone": "261d-1f3fe", "vulcan_salute_medium_dark_skin_tone": "1f596-1f3fe", "family": "1f46a", "key": "1f511", "myanmar": "1f1f2-1f1f2", "policeman_medium_light_skin_tone": "1f46e-1f3fc-200d-2640-fe0f", "man_shrugging_medium_dark_skin_tone": "1f937-1f3fe-200d-2642-fe0f", "woman_health_worker": "1f469-200d-2695-fe0f", "woman_judge": "1f469-200d-2696-fe0f", "japan": "1f5fe", "dominica": "1f1e9-1f1f2", "dragon": "1f409", "open_book": "1f4d6", "raising_hand_man": "1f64b-200d-2642-fe0f", "bikini": "1f459", "loudspeaker": "1f4e2", "woman_astronaut_medium_light_skin_tone": "1f469-1f3fc", "envelope_with_arrow": "1f4e9", "thailand": "1f1f9-1f1ed", "point_up_medium_light_skin_tone": "261d-1f3fc", "baby_medium_dark_skin_tone": "1f476-1f3fe", "man_scientist_medium_skin_tone": "1f468-1f3fd", "bowing_woman_medium_light_skin_tone": "1f647-1f3fc-200d-2640-fe0f", "construction_worker": "1f477", "nut_and_bolt": "1f529", "sparkling_heart": "1f496", "couplekiss_woman_woman_dark_skin_tone": "1f469-1f3ff", "elephant": "1f418", "bar_chart": "1f4ca", "nose_dark_skin_tone": "1f443-1f3ff", "stop_button": "23f9", "family_man_woman_boy_boy_light_skin_tone": "1f468-1f3fb", "family_man_girl_medium_light_skin_tone": "1f468-1f3fc", "relieved": "1f60c", "man_in_tuxedo": "1f935", "kick_scooter": "1f6f4", "statue_of_liberty": "1f5fd", "information_desk_person": "1f481", "sa": "1f202-fe0f", "abc": "1f524", "robot": "1f916", "cat": "1f431", "accept": "1f251", "upside_down_face": "1f643", "cloud": "2601-fe0f", "frowning_man_light_skin_tone": "1f64d-1f3fb-200d-2642-fe0f", "walking_man_medium_skin_tone": "1f6b6-1f3fd-200d-2640-fe0f", "sparkles": "2728", "u5272": "1f239", "globe_with_meridians": "1f310", "frowning_woman_medium_dark_skin_tone": "1f64d-1f3fe-200d-2640-fe0f", "grey_exclamation": "2755", "tm": "2122-fe0f", "massage_man_dark_skin_tone": "1f486-1f3ff-200d-2642-fe0f", "family_woman_woman_girl_boy_dark_skin_tone": "1f469-1f3ff", "paintbrush": "1f58c", "arrow_right_hook": "21aa-fe0f", "mauritania": "1f1f2-1f1f7", "man_scientist_light_skin_tone": "1f468-1f3fb", "woman_juggling_light_skin_tone": "1f939-1f3fb-200d-2640-fe0f", "ok_woman": "1f646", "snail": "1f40c", "hocho": "1f52a", "arrow_forward": "25b6-fe0f", "french_southern_territories": "1f1f9-1f1eb", "iphone": "1f4f1", "princess_medium_light_skin_tone": "1f478-1f3fc", "maple_leaf": "1f341", "open_hands": "1f450", "racing_car": "1f3ce", "pill": "1f48a", "cuba": "1f1e8-1f1fa", "fist_raised_dark_skin_tone": "270a-1f3ff", "blonde_man_dark_skin_tone": "1f471-1f3ff-200d-2640-fe0f", "family_woman_girl_boy_dark_skin_tone": "1f469-1f3ff", "fox_face": "1f98a", "man_playing_handball": "1f93e-200d-2642-fe0f", "bullettrain_side": "1f684", "black_small_square": "25aa-fe0f", "kazakhstan": "1f1f0-1f1ff", "vanuatu": "1f1fb-1f1fa", "older_man_medium_skin_tone": "1f474-1f3fd", "man_teacher": "1f468-200d-1f3eb", "family_man_man_boy_boy_medium_dark_skin_tone": "1f468-1f3fe", "back": "1f519", "point_up_2_medium_dark_skin_tone": "1f446-1f3fe", "woman_teacher_medium_light_skin_tone": "1f469-1f3fc", "family_woman_boy_boy_medium_dark_skin_tone": "1f469-1f3fe", "surfing_woman_medium_light_skin_tone": "1f3c4-1f3fc-200d-2640-fe0f", "portugal": "1f1f5-1f1f9", "construction_worker_woman_dark_skin_tone": "1f477-1f3ff-200d-2640-fe0f", "family_man_man_boy_medium_skin_tone": "1f468-1f3fd", "family_man_girl_dark_skin_tone": "1f468-1f3ff", "woman_mechanic": "1f469-200d-1f527", "arrow_heading_up": "2934-fe0f", "clock330": "1f55e", "malawi": "1f1f2-1f1fc", "ok_hand_medium_dark_skin_tone": "1f44c-1f3fe", "prince_dark_skin_tone": "1f934-1f3ff", "ice_hockey": "1f3d2", "pk": "1f1f5-1f1f0", "san_marino": "1f1f8-1f1f2", "point_left_light_skin_tone": "1f448-1f3fb", "woman_office_worker_medium_light_skin_tone": "1f469-1f3fc", "swimming_man_medium_light_skin_tone": "1f3ca-1f3fc-200d-2640-fe0f", "stuffed_flatbread": "1f959", "aerial_tramway": "1f6a1", "family_man_man_girl_girl_dark_skin_tone": "1f468-1f3ff", "family_woman_girl_girl_medium_dark_skin_tone": "1f469-1f3fe", "closed_book": "1f4d5", "family_woman_girl_boy_medium_light_skin_tone": "1f469-1f3fc", "family_man_man_girl_boy_medium_skin_tone": "1f468-1f3fd", "v": "270c-fe0f", "play_or_pause_button": "23ef", "el_salvador": "1f1f8-1f1fb", "woman_judge_medium_light_skin_tone": "1f469-1f3fc", "santa_medium_light_skin_tone": "1f385-1f3fc", "couplekiss_man_man_light_skin_tone": "1f468-1f3fb", "blonde_man_light_skin_tone": "1f471-1f3fb-200d-2640-fe0f", "fist_right": "1f91c", "man_with_turban": "1f473", "cancer": "264b-fe0f", "tunisia": "1f1f9-1f1f3", "open_hands_medium_light_skin_tone": "1f450-1f3fc", "call_me_hand_medium_dark_skin_tone": "1f919-1f3fe", "tired_face": "1f62b", "tongue": "1f445", "shower": "1f6bf", "british_indian_ocean_territory": "1f1ee-1f1f4", "man_firefighter_medium_light_skin_tone": "1f468-1f3fc", "couple_with_heart_woman_woman_medium_dark_skin_tone": "1f469-1f3fe", "crescent_moon": "1f319", "ecuador": "1f1ea-1f1e8", "french_polynesia": "1f1f5-1f1eb", "man_light_skin_tone": "1f468-1f3fb", "mountain_biking_woman_medium_skin_tone": "1f6b5-1f3fd-200d-2640-fe0f", "pakistan": "1f1f5-1f1f0", "open_hands_medium_dark_skin_tone": "1f450-1f3fe", "telephone": "260e-fe0f", "envelope": "2709-fe0f", "revolving_hearts": "1f49e", "mega": "1f4e3", "montserrat": "1f1f2-1f1f8", "uganda": "1f1fa-1f1ec", "tropical_fish": "1f420", "hibiscus": "1f33a", "rainbow_flag": "1f3f3-fe0f-200d-1f308", "bangladesh": "1f1e7-1f1e9", "shipit": "shipit", "no_good_man_dark_skin_tone": "1f645-1f3ff-200d-2642-fe0f", "no_mouth": "1f636", "man_farmer": "1f468-200d-1f33e", "speak_no_evil": "1f64a", "level_slider": "1f39a", "guatemala": "1f1ec-1f1f9", "woman_factory_worker": "1f469-200d-1f3ed", "fork_and_knife": "1f374", "belarus": "1f1e7-1f1fe", "family_woman_woman_girl_boy_medium_dark_skin_tone": "1f469-1f3fe", "yum": "1f60b", "helicopter": "1f681", "busstop": "1f68f", "policewoman_light_skin_tone": "1f46e-1f3fb-200d-2640-fe0f", "man_technologist_medium_skin_tone": "1f468-1f3fd", "man_with_gua_pi_mao_light_skin_tone": "1f472-1f3fb", "man_astronaut_dark_skin_tone": "1f468-1f3ff", "skull": "1f480", "smirk_cat": "1f63c", "jeans": "1f456", "flipper": "1f42c", "dizzy": "1f4ab", "cocktail": "1f378", "basketball_woman_medium_skin_tone": "26f9-1f3fd-200d-2640-fe0f", "v_medium_light_skin_tone": "270c-1f3fc", "secret": "3299-fe0f", "seven": "0037-fe0f-20e3", "ghana": "1f1ec-1f1ed", "guernsey": "1f1ec-1f1ec", "kyrgyzstan": "1f1f0-1f1ec", "godmode": "godmode", "female_detective_dark_skin_tone": "1f575-1f3ff-200d-2640-fe0f", "fallen_leaf": "1f342", "snowflake": "2744-fe0f", "raised_hand_with_fingers_splayed_medium_dark_skin_tone": "1f590-1f3fe", "woman_health_worker_medium_dark_skin_tone": "1f469-1f3fe", "man_shrugging_dark_skin_tone": "1f937-1f3ff-200d-2642-fe0f", "pout": "1f621", "stars": "1f320", "family_woman_girl_boy": "1f469-200d-1f467-200d-1f466", "gun": "1f52b", "woman_scientist_dark_skin_tone": "1f469-1f3ff", "basketball_woman_dark_skin_tone": "26f9-1f3ff-200d-2640-fe0f", "biking_woman_medium_light_skin_tone": "1f6b4-1f3fc-200d-2640-fe0f", "family_man_girl_boy_medium_dark_skin_tone": "1f468-1f3fe", "oncoming_bus": "1f68d", "seat": "1f4ba", "vhs": "1f4fc", "lithuania": "1f1f1-1f1f9", "v_medium_dark_skin_tone": "270c-1f3fe", "man_with_gua_pi_mao_medium_skin_tone": "1f472-1f3fd", "frowning_face": "2639-fe0f", "shit": "1f4a9", "ab": "1f18e", "couple_with_heart_woman_woman_medium_skin_tone": "1f469-1f3fd", "family_woman_woman_girl_girl": "1f469-200d-1f469-200d-1f467-200d-1f467", "potato": "1f954", "minidisc": "1f4bd", "libya": "1f1f1-1f1fe", "point_right_dark_skin_tone": "1f449-1f3ff", "man_artist": "1f468-200d-1f3a8", "pineapple": "1f34d", "spaghetti": "1f35d", "couch_and_lamp": "1f6cb", "free": "1f193", "jamaica": "1f1ef-1f1f2", "woman_astronaut_dark_skin_tone": "1f469-1f3ff", "man_mechanic": "1f468-200d-1f527", "curry": "1f35b", "small_orange_diamond": "1f538", "pray": "1f64f", "hotdog": "1f32d", "currency_exchange": "1f4b1", "-1_dark_skin_tone": "1f44e-1f3ff", "man_office_worker_dark_skin_tone": "1f468-1f3ff", "clock830": "1f563", "policeman_medium_skin_tone": "1f46e-1f3fd-200d-2640-fe0f", "grin": "1f601", "water_buffalo": "1f403", "older_man_dark_skin_tone": "1f474-1f3ff", "business_suit_levitating_medium_dark_skin_tone": "1f574-1f3fe", "couple_with_heart_man_man_medium_light_skin_tone": "1f468-1f3fc", "rowing_man_medium_light_skin_tone": "1f6a3-1f3fc-200d-2640-fe0f", "purse": "1f45b", "slovenia": "1f1f8-1f1ee", "tipping_hand_man_medium_light_skin_tone": "1f481-1f3fc-200d-2642-fe0f", "madagascar": "1f1f2-1f1ec", "south_georgia_south_sandwich_islands": "1f1ec-1f1f8", "punch": "1f44a", "man_pilot": "1f468-200d-2708-fe0f", "owl": "1f989", "croissant": "1f950", "email": "2709-fe0f", "outbox_tray": "1f4e4", "construction_worker_man_medium_light_skin_tone": "1f477-1f3fc-200d-2640-fe0f", "mrs_claus_medium_dark_skin_tone": "1f936-1f3fe", "family_man_woman_girl_boy_dark_skin_tone": "1f468-1f3ff", "file_cabinet": "1f5c4", "hungary": "1f1ed-1f1fa", "pray_medium_dark_skin_tone": "1f64f-1f3fe", "woman_mechanic_dark_skin_tone": "1f469-1f3ff", "angel_medium_skin_tone": "1f47c-1f3fd", "man_dancing": "1f57a", "pound": "1f4b7", "macedonia": "1f1f2-1f1f0", "man_facepalming_medium_skin_tone": "1f926-1f3fd-200d-2642-fe0f", "scroll": "1f4dc", "rescue_worker_helmet": "26d1", "desktop_computer": "1f5a5", "heavy_plus_sign": "2795", "man_with_turban_medium_skin_tone": "1f473-1f3fd-200d-2640-fe0f", "horse_racing": "1f3c7", "low_brightness": "1f505", "loop": "27bf", "man_with_turban_medium_dark_skin_tone": "1f473-1f3fe-200d-2640-fe0f", "champagne": "1f37e", "construction_worker_woman_light_skin_tone": "1f477-1f3fb-200d-2640-fe0f", "man_teacher_light_skin_tone": "1f468-1f3fb", "family_woman_woman_girl_girl_medium_light_skin_tone": "1f469-1f3fc", "footprints": "1f463", "cloud_with_snow": "1f328", "man_cook_medium_light_skin_tone": "1f468-1f3fc", "woman_mechanic_medium_light_skin_tone": "1f469-1f3fc", "point_up_2": "1f446", "circus_tent": "1f3aa", "serbia": "1f1f7-1f1f8", "fist_right_medium_dark_skin_tone": "1f91c-1f3fe", "weight_lifting_woman_dark_skin_tone": "1f3cb-1f3ff-200d-2640-fe0f", "musical_score": "1f3bc", "violin": "1f3bb", "card_file_box": "1f5c3", "tipping_hand_woman_dark_skin_tone": "1f481-1f3ff-200d-2640-fe0f", "man_facepalming_dark_skin_tone": "1f926-1f3ff-200d-2642-fe0f", "open_mouth": "1f62e", "left_right_arrow": "2194-fe0f", "no_good_man_light_skin_tone": "1f645-1f3fb-200d-2642-fe0f", "man_factory_worker": "1f468-200d-1f3ed", "man_judge": "1f468-200d-2696-fe0f", "negative_squared_cross_mark": "274e", "bowing_woman_medium_skin_tone": "1f647-1f3fd-200d-2640-fe0f", "family_woman_boy_boy_light_skin_tone": "1f469-1f3fb", "battery": "1f50b", "couplekiss_man_man_medium_light_skin_tone": "1f468-1f3fc", "clock5": "1f554", "white_flag": "1f3f3-fe0f", "guadeloupe": "1f1ec-1f1f5", "muscle_medium_dark_skin_tone": "1f4aa-1f3fe", "man_scientist_dark_skin_tone": "1f468-1f3ff", "business_suit_levitating_light_skin_tone": "1f574-1f3fb", "woman_office_worker": "1f469-200d-1f4bc", "gift": "1f381", "sound": "1f509", "clubs": "2663-fe0f", "woman_scientist_medium_light_skin_tone": "1f469-1f3fc", "female_detective_medium_skin_tone": "1f575-1f3fd-200d-2640-fe0f", "man_singer_medium_light_skin_tone": "1f468-1f3fc", "family_man_girl": "1f468-200d-1f467", "bee": "1f41d", "full_moon_with_face": "1f31d", "black_medium_square": "25fc-fe0f", "zambia": "1f1ff-1f1f2", "raised_hands_dark_skin_tone": "1f64c-1f3ff", "family_woman_woman_boy_boy_medium_skin_tone": "1f469-1f3fd", "bread": "1f35e", "clock11": "1f55a", "man_office_worker_medium_light_skin_tone": "1f468-1f3fc", "woman_firefighter_medium_skin_tone": "1f469-1f3fd", "man_dancing_dark_skin_tone": "1f57a-1f3ff", "family_man_boy_medium_dark_skin_tone": "1f468-1f3fe", "hugs": "1f917", "roll_eyes": "1f644", "raised_hand": "270b", "tangerine": "1f34a", "grey_question": "2754", "princess_light_skin_tone": "1f478-1f3fb", "motor_boat": "1f6e5", "passport_control": "1f6c2", "man_artist_medium_dark_skin_tone": "1f468-1f3fe", "golfing_man_medium_skin_tone": "1f3cc-1f3fd-200d-2640-fe0f", "shirt": "1f455", "whale": "1f433", "apple": "1f34e", "ethiopia": "1f1ea-1f1f9", "jordan": "1f1ef-1f1f4", "biking_woman_medium_dark_skin_tone": "1f6b4-1f3fe-200d-2640-fe0f", "family_woman_girl_girl_medium_skin_tone": "1f469-1f3fd", "turkey": "1f983", "snowman_with_snow": "2603-fe0f", "fist_left_medium_skin_tone": "1f91b-1f3fd", "woman_with_turban_light_skin_tone": "1f473-1f3fb-200d-2640-fe0f", "woman_pilot_dark_skin_tone": "1f469-1f3ff", "family_woman_woman_boy_medium_skin_tone": "1f469-1f3fd", "purple_heart": "1f49c", "black_heart": "1f5a4", "haircut_man": "1f487-200d-2642-fe0f", "arrow_lower_left": "2199-fe0f", "guinea_bissau": "1f1ec-1f1fc", "sudan": "1f1f8-1f1e9", "woman_scientist_light_skin_tone": "1f469-1f3fb", "bust_in_silhouette": "1f464", "walking": "1f6b6", "european_union": "1f1ea-1f1fa", "running_woman_dark_skin_tone": "1f3c3-1f3ff-200d-2640-fe0f", "om": "1f549", "rowing_man_medium_skin_tone": "1f6a3-1f3fd-200d-2640-fe0f", "ideograph_advantage": "1f250", "nepal": "1f1f3-1f1f5", "syria": "1f1f8-1f1fe", "man_pilot_medium_dark_skin_tone": "1f468-1f3fe", "princess_medium_dark_skin_tone": "1f478-1f3fe", "watermelon": "1f349", "left_luggage": "1f6c5", "us": "1f1fa-1f1f8", "point_left_medium_light_skin_tone": "1f448-1f3fc", "family_man_girl_boy_medium_skin_tone": "1f468-1f3fd", "biking_man_medium_dark_skin_tone": "1f6b4-1f3fe-200d-2640-fe0f", "keycap_ten": "1f51f", "man_medium_light_skin_tone": "1f468-1f3fc", "couple_with_heart_man_man_light_skin_tone": "1f468-1f3fb", "family_man_man_girl_boy_light_skin_tone": "1f468-1f3fb", "dog2": "1f415", "art": "1f3a8", "taxi": "1f695", "motorcycle": "1f3cd", "diamond_shape_with_a_dot_inside": "1f4a0", "writing_hand_light_skin_tone": "270d-1f3fb", "woman_playing_water_polo_medium_dark_skin_tone": "1f93d-1f3fe-200d-2640-fe0f", "martial_arts_uniform": "1f94b", "spiral_calendar": "1f5d3", "older_man_medium_dark_skin_tone": "1f474-1f3fe", "woman_artist_medium_skin_tone": "1f469-1f3fd", "no_good_man_medium_dark_skin_tone": "1f645-1f3fe-200d-2642-fe0f", "family_woman_woman_boy_medium_light_skin_tone": "1f469-1f3fc", "ship": "1f6a2", "bangbang": "203c-fe0f", "israel": "1f1ee-1f1f1", "rowing_man_medium_dark_skin_tone": "1f6a3-1f3fe-200d-2640-fe0f", "calling": "1f4f2", "scorpius": "264f-fe0f", "vulcan_salute_dark_skin_tone": "1f596-1f3ff", "woman_office_worker_light_skin_tone": "1f469-1f3fb", "man_judge_light_skin_tone": "1f468-1f3fb", "family_woman_woman_boy_boy_medium_dark_skin_tone": "1f469-1f3fe", "woman_playing_handball": "1f93e-200d-2640-fe0f", "bridge_at_night": "1f309", "stop_sign": "1f6d1", "8ball": "1f3b1", "orange_book": "1f4d9", "couplekiss_man_woman": "1f48f", "no_mobile_phones": "1f4f5", "pouting_man_dark_skin_tone": "1f64e-1f3ff-200d-2642-fe0f", "man_juggling_light_skin_tone": "1f939-1f3fb-200d-2642-fe0f", "cold_sweat": "1f630", "star2": "1f31f", "taco": "1f32e", "point_right_medium_light_skin_tone": "1f449-1f3fc", "selfie_medium_dark_skin_tone": "1f933-1f3fe", "family_woman_woman_girl_boy_light_skin_tone": "1f469-1f3fb", "hankey": "1f4a9", "monkey_face": "1f435", "sweden": "1f1f8-1f1ea", "crocodile": "1f40a", "last_quarter_moon_with_face": "1f31c", "comet": "2604-fe0f", "caribbean_netherlands": "1f1e7-1f1f6", "walking_man_medium_dark_skin_tone": "1f6b6-1f3fe-200d-2640-fe0f", "basketball_man_medium_light_skin_tone": "26f9-1f3fc-200d-2640-fe0f", "deer": "1f98c", "clock4": "1f553", "christmas_island": "1f1e8-1f1fd", "fist_right_medium_skin_tone": "1f91c-1f3fd", "man_cook_dark_skin_tone": "1f468-1f3ff", "family_man_man_girl_medium_light_skin_tone": "1f468-1f3fc", "whale2": "1f40b", "sagittarius": "2650-fe0f", "children_crossing": "1f6b8", "call_me_hand_dark_skin_tone": "1f919-1f3ff", "ok_woman_medium_dark_skin_tone": "1f646-1f3fe-200d-2640-fe0f", "man_firefighter": "1f468-200d-1f692", "rewind": "23ea", "guardswoman_light_skin_tone": "1f482-1f3fb-200d-2640-fe0f", "woman_technologist_light_skin_tone": "1f469-1f3fb", "woman_pilot_light_skin_tone": "1f469-1f3fb", "raising_hand_woman_light_skin_tone": "1f64b-1f3fb-200d-2640-fe0f", "bowing_man_light_skin_tone": "1f647-1f3fb-200d-2640-fe0f", "frowning_man_medium_skin_tone": "1f64d-1f3fd-200d-2642-fe0f", "shark": "1f988", "sun_behind_rain_cloud": "1f326", "dagger": "1f5e1", "musical_note": "1f3b5", "crossed_fingers_dark_skin_tone": "1f91e-1f3ff", "man_pilot_medium_skin_tone": "1f468-1f3fd", "family_woman_boy_medium_skin_tone": "1f469-1f3fd", "golfing_man_medium_light_skin_tone": "1f3cc-1f3fc-200d-2640-fe0f", "girl": "1f467", "family_man_woman_boy_boy": "1f468-200d-1f469-200d-1f466-200d-1f466", "biking_woman": "1f6b4-200d-2640-fe0f", "cl": "1f191", "raised_back_of_hand_medium_dark_skin_tone": "1f91a-1f3fe", "raising_hand_woman_medium_light_skin_tone": "1f64b-1f3fc-200d-2640-fe0f", "baby_medium_skin_tone": "1f476-1f3fd", "guardsman": "1f482", "woman_astronaut": "1f469-200d-1f680", "tophat": "1f3a9", "honduras": "1f1ed-1f1f3", "mexico": "1f1f2-1f1fd", "nauru": "1f1f3-1f1f7", "mrs_claus_medium_light_skin_tone": "1f936-1f3fc", "weary": "1f629", "womans_hat": "1f452", "person_fencing": "1f93a", "u6708": "1f237-fe0f", "a": "1f170-fe0f", "de": "1f1e9-1f1ea", "lebanon": "1f1f1-1f1e7", "puerto_rico": "1f1f5-1f1f7", "man_mechanic_dark_skin_tone": "1f468-1f3ff", "policeman_dark_skin_tone": "1f46e-1f3ff-200d-2640-fe0f", "kissing_smiling_eyes": "1f619", "avocado": "1f951", "six_pointed_star": "1f52f", "record_button": "23fa", "family_woman_woman_girl_girl_light_skin_tone": "1f469-1f3fb", "mountain_biking_man_medium_light_skin_tone": "1f6b5-1f3fc-200d-2640-fe0f", "couple_with_heart_man_man_medium_dark_skin_tone": "1f468-1f3fe", "family_man_girl_girl_light_skin_tone": "1f468-1f3fb", "post_office": "1f3e3", "telescope": "1f52d", "baby_symbol": "1f6bc", "capital_abcd": "1f520", "woman_singer_light_skin_tone": "1f469-1f3fb", "woman_facepalming_medium_dark_skin_tone": "1f926-1f3fe-200d-2640-fe0f", "ant": "1f41c", "house": "1f3e0", "shield": "1f6e1", "yellow_heart": "1f49b", "u55b6": "1f23a", "senegal": "1f1f8-1f1f3", "united_arab_emirates": "1f1e6-1f1ea", "no_good_woman_medium_skin_tone": "1f645-1f3fd-200d-2640-fe0f", "running_man_medium_light_skin_tone": "1f3c3-1f3fc-200d-2640-fe0f", "beetle": "1f41e", "bus": "1f68c", "flight_arrival": "1f6ec", "black_large_square": "2b1b-fe0f", "white_large_square": "2b1c-fe0f", "woman_technologist_medium_light_skin_tone": "1f469-1f3fc", "skier": "26f7", "ok_hand_medium_light_skin_tone": "1f44c-1f3fc", "rofl": "1f923", "hushed": "1f62f", "ng_man": "1f645-200d-2642-fe0f", "running_woman": "1f3c3-200d-2640-fe0f", "family_man_man_girl_girl": "1f468-200d-1f468-200d-1f467-200d-1f467", "gorilla": "1f98d", "horse_racing_medium_light_skin_tone": "1f3c7-1f3fc", "mountain_biking_man_medium_skin_tone": "1f6b5-1f3fd-200d-2640-fe0f", "disappointed": "1f61e", "dolphin": "1f42c", "green_apple": "1f34f", "honey_pot": "1f36f", "georgia": "1f1ec-1f1ea", "business_suit_levitating": "1f574", "camera": "1f4f7", "ledger": "1f4d2", "woman_cook_medium_skin_tone": "1f469-1f3fd", "bahamas": "1f1e7-1f1f8", "family_woman_woman_girl": "1f469-200d-1f469-200d-1f467", "man_factory_worker_light_skin_tone": "1f468-1f3fb", "golfing_woman_medium_dark_skin_tone": "1f3cc-1f3fe-200d-2640-fe0f", "family_woman_girl": "1f469-200d-1f467", "turtle": "1f422", "mauritius": "1f1f2-1f1fa", "family_man_girl_light_skin_tone": "1f468-1f3fb", "hospital": "1f3e5", "church": "26ea-fe0f", "wheel_of_dharma": "2638-fe0f", "mongolia": "1f1f2-1f1f3", "man_facepalming": "1f926-200d-2642-fe0f", "bed": "1f6cf", "man_artist_medium_light_skin_tone": "1f468-1f3fc", "santa_medium_dark_skin_tone": "1f385-1f3fe", "family_man_woman_girl_medium_light_skin_tone": "1f468-1f3fc", "large_blue_diamond": "1f537", "colombia": "1f1e8-1f1f4", "philippines": "1f1f5-1f1ed", "older_woman_dark_skin_tone": "1f475-1f3ff", "woman_scientist_medium_skin_tone": "1f469-1f3fd", "couplekiss_woman_woman_light_skin_tone": "1f469-1f3fb", "male_detective": "1f575-fe0f", "crossed_swords": "2694-fe0f", "notebook": "1f4d3", "nail_care_medium_light_skin_tone": "1f485-1f3fc", "blonde_man_medium_skin_tone": "1f471-1f3fd-200d-2640-fe0f", "tipping_hand_man_light_skin_tone": "1f481-1f3fb-200d-2642-fe0f", "sweat_smile": "1f605", "white_medium_small_square": "25fd-fe0f", "bowtie": "bowtie", "reminder_ribbon": "1f397", "clamp": "1f5dc", "balance_scale": "2696-fe0f", "postal_horn": "1f4ef", "swimming_woman_dark_skin_tone": "1f3ca-1f3ff-200d-2640-fe0f", "raised_hand_with_fingers_splayed": "1f590", "ok_man": "1f646-200d-2642-fe0f", "new": "1f195", "male_detective_medium_dark_skin_tone": "1f575-1f3fe-200d-2640-fe0f", "computer_mouse": "1f5b1", "hourglass_flowing_sand": "23f3", "bahrain": "1f1e7-1f1ed", "djibouti": "1f1e9-1f1ef", "zimbabwe": "1f1ff-1f1fc", "swimming_man_light_skin_tone": "1f3ca-1f3fb-200d-2640-fe0f", "interrobang": "2049-fe0f", "clock8": "1f557", "pancakes": "1f95e", "thermometer": "1f321", "label": "1f3f7", "denmark": "1f1e9-1f1f0", "raising_hand_man_medium_light_skin_tone": "1f64b-1f3fc-200d-2642-fe0f", "frowning_man_medium_dark_skin_tone": "1f64d-1f3fe-200d-2642-fe0f", "point_right": "1f449", "guitar": "1f3b8", "family_woman_woman_girl_medium_skin_tone": "1f469-1f3fd", "woman_juggling_medium_skin_tone": "1f939-1f3fd-200d-2640-fe0f", "man_health_worker": "1f468-200d-2695-fe0f", "stew": "1f372", "surfing_man": "1f3c4", "twisted_rightwards_arrows": "1f500", "timor_leste": "1f1f9-1f1f1", "weight_lifting_woman": "1f3cb-fe0f-200d-2640-fe0f", "amphora": "1f3fa", "heart": "2764-fe0f", "bowing_man_medium_dark_skin_tone": "1f647-1f3fe-200d-2640-fe0f"}
+var SystemEmojis = map[string]string{"grinning": "1f600", "smiley": "1f603", "smile": "1f604", "grin": "1f601", "laughing": "1f606", "satisfied": "1f606", "sweat_smile": "1f605", "rolling_on_the_floor_laughing": "1f923", "rofl": "1f923", "joy": "1f602", "slightly_smiling_face": "1f642", "upside_down_face": "1f643", "wink": "1f609", "blush": "1f60a", "innocent": "1f607", "smiling_face_with_3_hearts": "1f970", "heart_eyes": "1f60d", "star-struck": "1f929", "grinning_face_with_star_eyes": "1f929", "kissing_heart": "1f618", "kissing": "1f617", "relaxed": "263a-fe0f", "kissing_closed_eyes": "1f61a", "kissing_smiling_eyes": "1f619", "smiling_face_with_tear": "1f972", "yum": "1f60b", "stuck_out_tongue": "1f61b", "stuck_out_tongue_winking_eye": "1f61c", "zany_face": "1f92a", "grinning_face_with_one_large_and_one_small_eye": "1f92a", "stuck_out_tongue_closed_eyes": "1f61d", "money_mouth_face": "1f911", "hugging_face": "1f917", "hugs": "1f917", "face_with_hand_over_mouth": "1f92d", "smiling_face_with_smiling_eyes_and_hand_covering_mouth": "1f92d", "shushing_face": "1f92b", "face_with_finger_covering_closed_lips": "1f92b", "thinking_face": "1f914", "thinking": "1f914", "zipper_mouth_face": "1f910", "face_with_raised_eyebrow": "1f928", "face_with_one_eyebrow_raised": "1f928", "neutral_face": "1f610", "expressionless": "1f611", "no_mouth": "1f636", "smirk": "1f60f", "unamused": "1f612", "face_with_rolling_eyes": "1f644", "roll_eyes": "1f644", "grimacing": "1f62c", "lying_face": "1f925", "relieved": "1f60c", "pensive": "1f614", "sleepy": "1f62a", "drooling_face": "1f924", "sleeping": "1f634", "mask": "1f637", "face_with_thermometer": "1f912", "face_with_head_bandage": "1f915", "nauseated_face": "1f922", "face_vomiting": "1f92e", "face_with_open_mouth_vomiting": "1f92e", "sneezing_face": "1f927", "hot_face": "1f975", "cold_face": "1f976", "woozy_face": "1f974", "dizzy_face": "1f635", "exploding_head": "1f92f", "shocked_face_with_exploding_head": "1f92f", "face_with_cowboy_hat": "1f920", "cowboy_hat_face": "1f920", "partying_face": "1f973", "disguised_face": "1f978", "sunglasses": "1f60e", "nerd_face": "1f913", "face_with_monocle": "1f9d0", "confused": "1f615", "worried": "1f61f", "slightly_frowning_face": "1f641", "white_frowning_face": "2639-fe0f", "frowning_face": "2639-fe0f", "open_mouth": "1f62e", "hushed": "1f62f", "astonished": "1f632", "flushed": "1f633", "pleading_face": "1f97a", "frowning": "1f626", "anguished": "1f627", "fearful": "1f628", "cold_sweat": "1f630", "disappointed_relieved": "1f625", "cry": "1f622", "sob": "1f62d", "scream": "1f631", "confounded": "1f616", "persevere": "1f623", "disappointed": "1f61e", "sweat": "1f613", "weary": "1f629", "tired_face": "1f62b", "yawning_face": "1f971", "triumph": "1f624", "rage": "1f621", "pout": "1f621", "angry": "1f620", "face_with_symbols_on_mouth": "1f92c", "serious_face_with_symbols_covering_mouth": "1f92c", "smiling_imp": "1f608", "imp": "1f47f", "skull": "1f480", "skull_and_crossbones": "2620-fe0f", "hankey": "1f4a9", "poop": "1f4a9", "shit": "1f4a9", "clown_face": "1f921", "japanese_ogre": "1f479", "japanese_goblin": "1f47a", "ghost": "1f47b", "alien": "1f47d", "space_invader": "1f47e", "robot_face": "1f916", "robot": "1f916", "smiley_cat": "1f63a", "smile_cat": "1f638", "joy_cat": "1f639", "heart_eyes_cat": "1f63b", "smirk_cat": "1f63c", "kissing_cat": "1f63d", "scream_cat": "1f640", "crying_cat_face": "1f63f", "pouting_cat": "1f63e", "see_no_evil": "1f648", "hear_no_evil": "1f649", "speak_no_evil": "1f64a", "kiss": "1f48b", "love_letter": "1f48c", "cupid": "1f498", "gift_heart": "1f49d", "sparkling_heart": "1f496", "heartpulse": "1f497", "heartbeat": "1f493", "revolving_hearts": "1f49e", "two_hearts": "1f495", "heart_decoration": "1f49f", "heavy_heart_exclamation_mark_ornament": "2763-fe0f", "heavy_heart_exclamation": "2763-fe0f", "broken_heart": "1f494", "heart": "2764-fe0f", "orange_heart": "1f9e1", "yellow_heart": "1f49b", "green_heart": "1f49a", "blue_heart": "1f499", "purple_heart": "1f49c", "brown_heart": "1f90e", "black_heart": "1f5a4", "white_heart": "1f90d", "100": "1f4af", "anger": "1f4a2", "boom": "1f4a5", "collision": "1f4a5", "dizzy": "1f4ab", "sweat_drops": "1f4a6", "dash": "1f4a8", "hole": "1f573-fe0f", "bomb": "1f4a3", "speech_balloon": "1f4ac", "eye-in-speech-bubble": "1f441-fe0f-200d-1f5e8-fe0f", "left_speech_bubble": "1f5e8-fe0f", "right_anger_bubble": "1f5ef-fe0f", "thought_balloon": "1f4ad", "zzz": "1f4a4", "wave": "1f44b", "raised_back_of_hand": "1f91a", "raised_hand_with_fingers_splayed": "1f590-fe0f", "hand": "270b", "raised_hand": "270b", "spock-hand": "1f596", "vulcan_salute": "1f596", "ok_hand": "1f44c", "pinched_fingers": "1f90c", "pinching_hand": "1f90f", "v": "270c-fe0f", "crossed_fingers": "1f91e", "hand_with_index_and_middle_fingers_crossed": "1f91e", "i_love_you_hand_sign": "1f91f", "the_horns": "1f918", "sign_of_the_horns": "1f918", "metal": "1f918", "call_me_hand": "1f919", "point_left": "1f448", "point_right": "1f449", "point_up_2": "1f446", "middle_finger": "1f595", "reversed_hand_with_middle_finger_extended": "1f595", "fu": "1f595", "point_down": "1f447", "point_up": "261d-fe0f", "+1": "1f44d", "thumbsup": "1f44d", "-1": "1f44e", "thumbsdown": "1f44e", "fist": "270a", "fist_raised": "270a", "facepunch": "1f44a", "punch": "1f44a", "fist_oncoming": "1f44a", "left-facing_fist": "1f91b", "fist_left": "1f91b", "right-facing_fist": "1f91c", "fist_right": "1f91c", "clap": "1f44f", "raised_hands": "1f64c", "open_hands": "1f450", "palms_up_together": "1f932", "handshake": "1f91d", "pray": "1f64f", "writing_hand": "270d-fe0f", "nail_care": "1f485", "selfie": "1f933", "muscle": "1f4aa", "mechanical_arm": "1f9be", "mechanical_leg": "1f9bf", "leg": "1f9b5", "foot": "1f9b6", "ear": "1f442", "ear_with_hearing_aid": "1f9bb", "nose": "1f443", "brain": "1f9e0", "anatomical_heart": "1fac0", "lungs": "1fac1", "tooth": "1f9b7", "bone": "1f9b4", "eyes": "1f440", "eye": "1f441-fe0f", "tongue": "1f445", "lips": "1f444", "baby": "1f476", "child": "1f9d2", "boy": "1f466", "girl": "1f467", "adult": "1f9d1", "person_with_blond_hair": "1f471", "man": "1f468", "bearded_person": "1f9d4", "red_haired_man": "1f468-200d-1f9b0", "curly_haired_man": "1f468-200d-1f9b1", "white_haired_man": "1f468-200d-1f9b3", "bald_man": "1f468-200d-1f9b2", "woman": "1f469", "red_haired_woman": "1f469-200d-1f9b0", "red_haired_person": "1f9d1-200d-1f9b0", "curly_haired_woman": "1f469-200d-1f9b1", "curly_haired_person": "1f9d1-200d-1f9b1", "white_haired_woman": "1f469-200d-1f9b3", "white_haired_person": "1f9d1-200d-1f9b3", "bald_woman": "1f469-200d-1f9b2", "bald_person": "1f9d1-200d-1f9b2", "blond-haired-woman": "1f471-200d-2640-fe0f", "blonde_woman": "1f471-200d-2640-fe0f", "blond-haired-man": "1f471-200d-2642-fe0f", "blonde_man": "1f471-200d-2642-fe0f", "older_adult": "1f9d3", "older_man": "1f474", "older_woman": "1f475", "person_frowning": "1f64d", "man-frowning": "1f64d-200d-2642-fe0f", "frowning_man": "1f64d-200d-2642-fe0f", "woman-frowning": "1f64d-200d-2640-fe0f", "frowning_woman": "1f64d-200d-2640-fe0f", "person_with_pouting_face": "1f64e", "man-pouting": "1f64e-200d-2642-fe0f", "pouting_man": "1f64e-200d-2642-fe0f", "woman-pouting": "1f64e-200d-2640-fe0f", "pouting_woman": "1f64e-200d-2640-fe0f", "no_good": "1f645", "man-gesturing-no": "1f645-200d-2642-fe0f", "ng_man": "1f645-200d-2642-fe0f", "no_good_man": "1f645-200d-2642-fe0f", "woman-gesturing-no": "1f645-200d-2640-fe0f", "no_good_woman": "1f645-200d-2640-fe0f", "ng_woman": "1f645-200d-2640-fe0f", "ok_woman": "1f646", "man-gesturing-ok": "1f646-200d-2642-fe0f", "ok_man": "1f646-200d-2642-fe0f", "woman-gesturing-ok": "1f646-200d-2640-fe0f", "information_desk_person": "1f481", "man-tipping-hand": "1f481-200d-2642-fe0f", "tipping_hand_man": "1f481-200d-2642-fe0f", "woman-tipping-hand": "1f481-200d-2640-fe0f", "tipping_hand_woman": "1f481-200d-2640-fe0f", "raising_hand": "1f64b", "man-raising-hand": "1f64b-200d-2642-fe0f", "raising_hand_man": "1f64b-200d-2642-fe0f", "woman-raising-hand": "1f64b-200d-2640-fe0f", "raising_hand_woman": "1f64b-200d-2640-fe0f", "deaf_person": "1f9cf", "deaf_man": "1f9cf-200d-2642-fe0f", "deaf_woman": "1f9cf-200d-2640-fe0f", "bow": "1f647", "man-bowing": "1f647-200d-2642-fe0f", "bowing_man": "1f647-200d-2642-fe0f", "woman-bowing": "1f647-200d-2640-fe0f", "bowing_woman": "1f647-200d-2640-fe0f", "face_palm": "1f926", "man-facepalming": "1f926-200d-2642-fe0f", "man_facepalming": "1f926-200d-2642-fe0f", "woman-facepalming": "1f926-200d-2640-fe0f", "woman_facepalming": "1f926-200d-2640-fe0f", "shrug": "1f937", "man-shrugging": "1f937-200d-2642-fe0f", "man_shrugging": "1f937-200d-2642-fe0f", "woman-shrugging": "1f937-200d-2640-fe0f", "woman_shrugging": "1f937-200d-2640-fe0f", "health_worker": "1f9d1-200d-2695-fe0f", "male-doctor": "1f468-200d-2695-fe0f", "man_health_worker": "1f468-200d-2695-fe0f", "female-doctor": "1f469-200d-2695-fe0f", "woman_health_worker": "1f469-200d-2695-fe0f", "student": "1f9d1-200d-1f393", "male-student": "1f468-200d-1f393", "man_student": "1f468-200d-1f393", "female-student": "1f469-200d-1f393", "woman_student": "1f469-200d-1f393", "teacher": "1f9d1-200d-1f3eb", "male-teacher": "1f468-200d-1f3eb", "man_teacher": "1f468-200d-1f3eb", "female-teacher": "1f469-200d-1f3eb", "woman_teacher": "1f469-200d-1f3eb", "judge": "1f9d1-200d-2696-fe0f", "male-judge": "1f468-200d-2696-fe0f", "man_judge": "1f468-200d-2696-fe0f", "female-judge": "1f469-200d-2696-fe0f", "woman_judge": "1f469-200d-2696-fe0f", "farmer": "1f9d1-200d-1f33e", "male-farmer": "1f468-200d-1f33e", "man_farmer": "1f468-200d-1f33e", "female-farmer": "1f469-200d-1f33e", "woman_farmer": "1f469-200d-1f33e", "cook": "1f9d1-200d-1f373", "male-cook": "1f468-200d-1f373", "man_cook": "1f468-200d-1f373", "female-cook": "1f469-200d-1f373", "woman_cook": "1f469-200d-1f373", "mechanic": "1f9d1-200d-1f527", "male-mechanic": "1f468-200d-1f527", "man_mechanic": "1f468-200d-1f527", "female-mechanic": "1f469-200d-1f527", "woman_mechanic": "1f469-200d-1f527", "factory_worker": "1f9d1-200d-1f3ed", "male-factory-worker": "1f468-200d-1f3ed", "man_factory_worker": "1f468-200d-1f3ed", "female-factory-worker": "1f469-200d-1f3ed", "woman_factory_worker": "1f469-200d-1f3ed", "office_worker": "1f9d1-200d-1f4bc", "male-office-worker": "1f468-200d-1f4bc", "man_office_worker": "1f468-200d-1f4bc", "female-office-worker": "1f469-200d-1f4bc", "woman_office_worker": "1f469-200d-1f4bc", "scientist": "1f9d1-200d-1f52c", "male-scientist": "1f468-200d-1f52c", "man_scientist": "1f468-200d-1f52c", "female-scientist": "1f469-200d-1f52c", "woman_scientist": "1f469-200d-1f52c", "technologist": "1f9d1-200d-1f4bb", "male-technologist": "1f468-200d-1f4bb", "man_technologist": "1f468-200d-1f4bb", "female-technologist": "1f469-200d-1f4bb", "woman_technologist": "1f469-200d-1f4bb", "singer": "1f9d1-200d-1f3a4", "male-singer": "1f468-200d-1f3a4", "man_singer": "1f468-200d-1f3a4", "female-singer": "1f469-200d-1f3a4", "woman_singer": "1f469-200d-1f3a4", "artist": "1f9d1-200d-1f3a8", "male-artist": "1f468-200d-1f3a8", "man_artist": "1f468-200d-1f3a8", "female-artist": "1f469-200d-1f3a8", "woman_artist": "1f469-200d-1f3a8", "pilot": "1f9d1-200d-2708-fe0f", "male-pilot": "1f468-200d-2708-fe0f", "man_pilot": "1f468-200d-2708-fe0f", "female-pilot": "1f469-200d-2708-fe0f", "woman_pilot": "1f469-200d-2708-fe0f", "astronaut": "1f9d1-200d-1f680", "male-astronaut": "1f468-200d-1f680", "man_astronaut": "1f468-200d-1f680", "female-astronaut": "1f469-200d-1f680", "woman_astronaut": "1f469-200d-1f680", "firefighter": "1f9d1-200d-1f692", "male-firefighter": "1f468-200d-1f692", "man_firefighter": "1f468-200d-1f692", "female-firefighter": "1f469-200d-1f692", "woman_firefighter": "1f469-200d-1f692", "cop": "1f46e", "male-police-officer": "1f46e-200d-2642-fe0f", "policeman": "1f46e-200d-2642-fe0f", "female-police-officer": "1f46e-200d-2640-fe0f", "policewoman": "1f46e-200d-2640-fe0f", "sleuth_or_spy": "1f575-fe0f", "detective": "1f575-fe0f", "male-detective": "1f575-fe0f-200d-2642-fe0f", "male_detective": "1f575-fe0f-200d-2642-fe0f", "female-detective": "1f575-fe0f-200d-2640-fe0f", "female_detective": "1f575-fe0f-200d-2640-fe0f", "guardsman": "1f482", "male-guard": "1f482-200d-2642-fe0f", "female-guard": "1f482-200d-2640-fe0f", "guardswoman": "1f482-200d-2640-fe0f", "ninja": "1f977", "construction_worker": "1f477", "male-construction-worker": "1f477-200d-2642-fe0f", "construction_worker_man": "1f477-200d-2642-fe0f", "female-construction-worker": "1f477-200d-2640-fe0f", "construction_worker_woman": "1f477-200d-2640-fe0f", "prince": "1f934", "princess": "1f478", "man_with_turban": "1f473", "man-wearing-turban": "1f473-200d-2642-fe0f", "woman-wearing-turban": "1f473-200d-2640-fe0f", "woman_with_turban": "1f473-200d-2640-fe0f", "man_with_gua_pi_mao": "1f472", "person_with_headscarf": "1f9d5", "person_in_tuxedo": "1f935", "man_in_tuxedo": "1f935-200d-2642-fe0f", "woman_in_tuxedo": "1f935-200d-2640-fe0f", "bride_with_veil": "1f470", "man_with_veil": "1f470-200d-2642-fe0f", "woman_with_veil": "1f470-200d-2640-fe0f", "pregnant_woman": "1f930", "breast-feeding": "1f931", "woman_feeding_baby": "1f469-200d-1f37c", "man_feeding_baby": "1f468-200d-1f37c", "person_feeding_baby": "1f9d1-200d-1f37c", "angel": "1f47c", "santa": "1f385", "mrs_claus": "1f936", "mother_christmas": "1f936", "mx_claus": "1f9d1-200d-1f384", "superhero": "1f9b8", "male_superhero": "1f9b8-200d-2642-fe0f", "female_superhero": "1f9b8-200d-2640-fe0f", "supervillain": "1f9b9", "male_supervillain": "1f9b9-200d-2642-fe0f", "female_supervillain": "1f9b9-200d-2640-fe0f", "mage": "1f9d9", "male_mage": "1f9d9-200d-2642-fe0f", "female_mage": "1f9d9-200d-2640-fe0f", "fairy": "1f9da", "male_fairy": "1f9da-200d-2642-fe0f", "female_fairy": "1f9da-200d-2640-fe0f", "vampire": "1f9db", "male_vampire": "1f9db-200d-2642-fe0f", "female_vampire": "1f9db-200d-2640-fe0f", "merperson": "1f9dc", "merman": "1f9dc-200d-2642-fe0f", "mermaid": "1f9dc-200d-2640-fe0f", "elf": "1f9dd", "male_elf": "1f9dd-200d-2642-fe0f", "female_elf": "1f9dd-200d-2640-fe0f", "genie": "1f9de", "male_genie": "1f9de-200d-2642-fe0f", "female_genie": "1f9de-200d-2640-fe0f", "zombie": "1f9df", "male_zombie": "1f9df-200d-2642-fe0f", "female_zombie": "1f9df-200d-2640-fe0f", "massage": "1f486", "man-getting-massage": "1f486-200d-2642-fe0f", "massage_man": "1f486-200d-2642-fe0f", "woman-getting-massage": "1f486-200d-2640-fe0f", "massage_woman": "1f486-200d-2640-fe0f", "haircut": "1f487", "man-getting-haircut": "1f487-200d-2642-fe0f", "haircut_man": "1f487-200d-2642-fe0f", "woman-getting-haircut": "1f487-200d-2640-fe0f", "haircut_woman": "1f487-200d-2640-fe0f", "walking": "1f6b6", "man-walking": "1f6b6-200d-2642-fe0f", "walking_man": "1f6b6-200d-2642-fe0f", "woman-walking": "1f6b6-200d-2640-fe0f", "walking_woman": "1f6b6-200d-2640-fe0f", "standing_person": "1f9cd", "man_standing": "1f9cd-200d-2642-fe0f", "woman_standing": "1f9cd-200d-2640-fe0f", "kneeling_person": "1f9ce", "man_kneeling": "1f9ce-200d-2642-fe0f", "woman_kneeling": "1f9ce-200d-2640-fe0f", "person_with_probing_cane": "1f9d1-200d-1f9af", "man_with_probing_cane": "1f468-200d-1f9af", "woman_with_probing_cane": "1f469-200d-1f9af", "person_in_motorized_wheelchair": "1f9d1-200d-1f9bc", "man_in_motorized_wheelchair": "1f468-200d-1f9bc", "woman_in_motorized_wheelchair": "1f469-200d-1f9bc", "person_in_manual_wheelchair": "1f9d1-200d-1f9bd", "man_in_manual_wheelchair": "1f468-200d-1f9bd", "woman_in_manual_wheelchair": "1f469-200d-1f9bd", "runner": "1f3c3", "running": "1f3c3", "man-running": "1f3c3-200d-2642-fe0f", "running_man": "1f3c3-200d-2642-fe0f", "woman-running": "1f3c3-200d-2640-fe0f", "running_woman": "1f3c3-200d-2640-fe0f", "dancer": "1f483", "man_dancing": "1f57a", "man_in_business_suit_levitating": "1f574-fe0f", "business_suit_levitating": "1f574-fe0f", "dancers": "1f46f", "man-with-bunny-ears-partying": "1f46f-200d-2642-fe0f", "dancing_men": "1f46f-200d-2642-fe0f", "woman-with-bunny-ears-partying": "1f46f-200d-2640-fe0f", "dancing_women": "1f46f-200d-2640-fe0f", "person_in_steamy_room": "1f9d6", "man_in_steamy_room": "1f9d6-200d-2642-fe0f", "woman_in_steamy_room": "1f9d6-200d-2640-fe0f", "person_climbing": "1f9d7", "man_climbing": "1f9d7-200d-2642-fe0f", "woman_climbing": "1f9d7-200d-2640-fe0f", "fencer": "1f93a", "person_fencing": "1f93a", "horse_racing": "1f3c7", "skier": "26f7-fe0f", "snowboarder": "1f3c2", "golfer": "1f3cc-fe0f", "man-golfing": "1f3cc-fe0f-200d-2642-fe0f", "golfing_man": "1f3cc-fe0f-200d-2642-fe0f", "woman-golfing": "1f3cc-fe0f-200d-2640-fe0f", "golfing_woman": "1f3cc-fe0f-200d-2640-fe0f", "surfer": "1f3c4", "man-surfing": "1f3c4-200d-2642-fe0f", "surfing_man": "1f3c4-200d-2642-fe0f", "woman-surfing": "1f3c4-200d-2640-fe0f", "surfing_woman": "1f3c4-200d-2640-fe0f", "rowboat": "1f6a3", "man-rowing-boat": "1f6a3-200d-2642-fe0f", "rowing_man": "1f6a3-200d-2642-fe0f", "woman-rowing-boat": "1f6a3-200d-2640-fe0f", "rowing_woman": "1f6a3-200d-2640-fe0f", "swimmer": "1f3ca", "man-swimming": "1f3ca-200d-2642-fe0f", "swimming_man": "1f3ca-200d-2642-fe0f", "woman-swimming": "1f3ca-200d-2640-fe0f", "swimming_woman": "1f3ca-200d-2640-fe0f", "person_with_ball": "26f9-fe0f", "man-bouncing-ball": "26f9-fe0f-200d-2642-fe0f", "basketball_man": "26f9-fe0f-200d-2642-fe0f", "woman-bouncing-ball": "26f9-fe0f-200d-2640-fe0f", "basketball_woman": "26f9-fe0f-200d-2640-fe0f", "weight_lifter": "1f3cb-fe0f", "man-lifting-weights": "1f3cb-fe0f-200d-2642-fe0f", "weight_lifting_man": "1f3cb-fe0f-200d-2642-fe0f", "woman-lifting-weights": "1f3cb-fe0f-200d-2640-fe0f", "weight_lifting_woman": "1f3cb-fe0f-200d-2640-fe0f", "bicyclist": "1f6b4", "man-biking": "1f6b4-200d-2642-fe0f", "biking_man": "1f6b4-200d-2642-fe0f", "woman-biking": "1f6b4-200d-2640-fe0f", "biking_woman": "1f6b4-200d-2640-fe0f", "mountain_bicyclist": "1f6b5", "man-mountain-biking": "1f6b5-200d-2642-fe0f", "mountain_biking_man": "1f6b5-200d-2642-fe0f", "woman-mountain-biking": "1f6b5-200d-2640-fe0f", "mountain_biking_woman": "1f6b5-200d-2640-fe0f", "person_doing_cartwheel": "1f938", "man-cartwheeling": "1f938-200d-2642-fe0f", "man_cartwheeling": "1f938-200d-2642-fe0f", "woman-cartwheeling": "1f938-200d-2640-fe0f", "woman_cartwheeling": "1f938-200d-2640-fe0f", "wrestlers": "1f93c", "man-wrestling": "1f93c-200d-2642-fe0f", "men_wrestling": "1f93c-200d-2642-fe0f", "woman-wrestling": "1f93c-200d-2640-fe0f", "women_wrestling": "1f93c-200d-2640-fe0f", "water_polo": "1f93d", "man-playing-water-polo": "1f93d-200d-2642-fe0f", "man_playing_water_polo": "1f93d-200d-2642-fe0f", "woman-playing-water-polo": "1f93d-200d-2640-fe0f", "woman_playing_water_polo": "1f93d-200d-2640-fe0f", "handball": "1f93e", "man-playing-handball": "1f93e-200d-2642-fe0f", "man_playing_handball": "1f93e-200d-2642-fe0f", "woman-playing-handball": "1f93e-200d-2640-fe0f", "woman_playing_handball": "1f93e-200d-2640-fe0f", "juggling": "1f939", "man-juggling": "1f939-200d-2642-fe0f", "man_juggling": "1f939-200d-2642-fe0f", "woman-juggling": "1f939-200d-2640-fe0f", "woman_juggling": "1f939-200d-2640-fe0f", "person_in_lotus_position": "1f9d8", "man_in_lotus_position": "1f9d8-200d-2642-fe0f", "woman_in_lotus_position": "1f9d8-200d-2640-fe0f", "bath": "1f6c0", "sleeping_accommodation": "1f6cc", "sleeping_bed": "1f6cc", "people_holding_hands": "1f9d1-200d-1f91d-200d-1f9d1", "two_women_holding_hands": "1f46d", "women_holding_hands": "1f46d", "man_and_woman_holding_hands": "1f46b", "woman_and_man_holding_hands": "1f46b", "couple": "1f46b", "two_men_holding_hands": "1f46c", "men_holding_hands": "1f46c", "couplekiss": "1f48f", "woman-kiss-man": "1f469-200d-2764-fe0f-200d-1f48b-200d-1f468", "couplekiss_man_woman": "1f469-200d-2764-fe0f-200d-1f48b-200d-1f468", "man-kiss-man": "1f468-200d-2764-fe0f-200d-1f48b-200d-1f468", "couplekiss_man_man": "1f468-200d-2764-fe0f-200d-1f48b-200d-1f468", "woman-kiss-woman": "1f469-200d-2764-fe0f-200d-1f48b-200d-1f469", "couplekiss_woman_woman": "1f469-200d-2764-fe0f-200d-1f48b-200d-1f469", "couple_with_heart": "1f491", "woman-heart-man": "1f469-200d-2764-fe0f-200d-1f468", "couple_with_heart_woman_man": "1f469-200d-2764-fe0f-200d-1f468", "man-heart-man": "1f468-200d-2764-fe0f-200d-1f468", "couple_with_heart_man_man": "1f468-200d-2764-fe0f-200d-1f468", "woman-heart-woman": "1f469-200d-2764-fe0f-200d-1f469", "couple_with_heart_woman_woman": "1f469-200d-2764-fe0f-200d-1f469", "family": "1f46a", "man-woman-boy": "1f468-200d-1f469-200d-1f466", "family_man_woman_boy": "1f468-200d-1f469-200d-1f466", "man-woman-girl": "1f468-200d-1f469-200d-1f467", "family_man_woman_girl": "1f468-200d-1f469-200d-1f467", "man-woman-girl-boy": "1f468-200d-1f469-200d-1f467-200d-1f466", "family_man_woman_girl_boy": "1f468-200d-1f469-200d-1f467-200d-1f466", "man-woman-boy-boy": "1f468-200d-1f469-200d-1f466-200d-1f466", "family_man_woman_boy_boy": "1f468-200d-1f469-200d-1f466-200d-1f466", "man-woman-girl-girl": "1f468-200d-1f469-200d-1f467-200d-1f467", "family_man_woman_girl_girl": "1f468-200d-1f469-200d-1f467-200d-1f467", "man-man-boy": "1f468-200d-1f468-200d-1f466", "family_man_man_boy": "1f468-200d-1f468-200d-1f466", "man-man-girl": "1f468-200d-1f468-200d-1f467", "family_man_man_girl": "1f468-200d-1f468-200d-1f467", "man-man-girl-boy": "1f468-200d-1f468-200d-1f467-200d-1f466", "family_man_man_girl_boy": "1f468-200d-1f468-200d-1f467-200d-1f466", "man-man-boy-boy": "1f468-200d-1f468-200d-1f466-200d-1f466", "family_man_man_boy_boy": "1f468-200d-1f468-200d-1f466-200d-1f466", "man-man-girl-girl": "1f468-200d-1f468-200d-1f467-200d-1f467", "family_man_man_girl_girl": "1f468-200d-1f468-200d-1f467-200d-1f467", "woman-woman-boy": "1f469-200d-1f469-200d-1f466", "family_woman_woman_boy": "1f469-200d-1f469-200d-1f466", "woman-woman-girl": "1f469-200d-1f469-200d-1f467", "family_woman_woman_girl": "1f469-200d-1f469-200d-1f467", "woman-woman-girl-boy": "1f469-200d-1f469-200d-1f467-200d-1f466", "family_woman_woman_girl_boy": "1f469-200d-1f469-200d-1f467-200d-1f466", "woman-woman-boy-boy": "1f469-200d-1f469-200d-1f466-200d-1f466", "family_woman_woman_boy_boy": "1f469-200d-1f469-200d-1f466-200d-1f466", "woman-woman-girl-girl": "1f469-200d-1f469-200d-1f467-200d-1f467", "family_woman_woman_girl_girl": "1f469-200d-1f469-200d-1f467-200d-1f467", "man-boy": "1f468-200d-1f466", "family_man_boy": "1f468-200d-1f466", "man-boy-boy": "1f468-200d-1f466-200d-1f466", "family_man_boy_boy": "1f468-200d-1f466-200d-1f466", "man-girl": "1f468-200d-1f467", "family_man_girl": "1f468-200d-1f467", "man-girl-boy": "1f468-200d-1f467-200d-1f466", "family_man_girl_boy": "1f468-200d-1f467-200d-1f466", "man-girl-girl": "1f468-200d-1f467-200d-1f467", "family_man_girl_girl": "1f468-200d-1f467-200d-1f467", "woman-boy": "1f469-200d-1f466", "family_woman_boy": "1f469-200d-1f466", "woman-boy-boy": "1f469-200d-1f466-200d-1f466", "family_woman_boy_boy": "1f469-200d-1f466-200d-1f466", "woman-girl": "1f469-200d-1f467", "family_woman_girl": "1f469-200d-1f467", "woman-girl-boy": "1f469-200d-1f467-200d-1f466", "family_woman_girl_boy": "1f469-200d-1f467-200d-1f466", "woman-girl-girl": "1f469-200d-1f467-200d-1f467", "family_woman_girl_girl": "1f469-200d-1f467-200d-1f467", "speaking_head_in_silhouette": "1f5e3-fe0f", "speaking_head": "1f5e3-fe0f", "bust_in_silhouette": "1f464", "busts_in_silhouette": "1f465", "people_hugging": "1fac2", "footprints": "1f463", "skin-tone-2": "1f3fb", "skin-tone-3": "1f3fc", "skin-tone-4": "1f3fd", "skin-tone-5": "1f3fe", "skin-tone-6": "1f3ff", "monkey_face": "1f435", "monkey": "1f412", "gorilla": "1f98d", "orangutan": "1f9a7", "dog": "1f436", "dog2": "1f415", "guide_dog": "1f9ae", "service_dog": "1f415-200d-1f9ba", "poodle": "1f429", "wolf": "1f43a", "fox_face": "1f98a", "raccoon": "1f99d", "cat": "1f431", "cat2": "1f408", "black_cat": "1f408-200d-2b1b", "lion_face": "1f981", "lion": "1f981", "tiger": "1f42f", "tiger2": "1f405", "leopard": "1f406", "horse": "1f434", "racehorse": "1f40e", "unicorn_face": "1f984", "unicorn": "1f984", "zebra_face": "1f993", "deer": "1f98c", "bison": "1f9ac", "cow": "1f42e", "ox": "1f402", "water_buffalo": "1f403", "cow2": "1f404", "pig": "1f437", "pig2": "1f416", "boar": "1f417", "pig_nose": "1f43d", "ram": "1f40f", "sheep": "1f411", "goat": "1f410", "dromedary_camel": "1f42a", "camel": "1f42b", "llama": "1f999", "giraffe_face": "1f992", "elephant": "1f418", "mammoth": "1f9a3", "rhinoceros": "1f98f", "hippopotamus": "1f99b", "mouse": "1f42d", "mouse2": "1f401", "rat": "1f400", "hamster": "1f439", "rabbit": "1f430", "rabbit2": "1f407", "chipmunk": "1f43f-fe0f", "beaver": "1f9ab", "hedgehog": "1f994", "bat": "1f987", "bear": "1f43b", "polar_bear": "1f43b-200d-2744-fe0f", "koala": "1f428", "panda_face": "1f43c", "sloth": "1f9a5", "otter": "1f9a6", "skunk": "1f9a8", "kangaroo": "1f998", "badger": "1f9a1", "feet": "1f43e", "paw_prints": "1f43e", "turkey": "1f983", "chicken": "1f414", "rooster": "1f413", "hatching_chick": "1f423", "baby_chick": "1f424", "hatched_chick": "1f425", "bird": "1f426", "penguin": "1f427", "dove_of_peace": "1f54a-fe0f", "dove": "1f54a-fe0f", "eagle": "1f985", "duck": "1f986", "swan": "1f9a2", "owl": "1f989", "dodo": "1f9a4", "feather": "1fab6", "flamingo": "1f9a9", "peacock": "1f99a", "parrot": "1f99c", "frog": "1f438", "crocodile": "1f40a", "turtle": "1f422", "lizard": "1f98e", "snake": "1f40d", "dragon_face": "1f432", "dragon": "1f409", "sauropod": "1f995", "t-rex": "1f996", "whale": "1f433", "whale2": "1f40b", "dolphin": "1f42c", "flipper": "1f42c", "seal": "1f9ad", "fish": "1f41f", "tropical_fish": "1f420", "blowfish": "1f421", "shark": "1f988", "octopus": "1f419", "shell": "1f41a", "snail": "1f40c", "butterfly": "1f98b", "bug": "1f41b", "ant": "1f41c", "bee": "1f41d", "honeybee": "1f41d", "beetle": "1fab2", "ladybug": "1f41e", "lady_beetle": "1f41e", "cricket": "1f997", "cockroach": "1fab3", "spider": "1f577-fe0f", "spider_web": "1f578-fe0f", "scorpion": "1f982", "mosquito": "1f99f", "fly": "1fab0", "worm": "1fab1", "microbe": "1f9a0", "bouquet": "1f490", "cherry_blossom": "1f338", "white_flower": "1f4ae", "rosette": "1f3f5-fe0f", "rose": "1f339", "wilted_flower": "1f940", "hibiscus": "1f33a", "sunflower": "1f33b", "blossom": "1f33c", "tulip": "1f337", "seedling": "1f331", "potted_plant": "1fab4", "evergreen_tree": "1f332", "deciduous_tree": "1f333", "palm_tree": "1f334", "cactus": "1f335", "ear_of_rice": "1f33e", "herb": "1f33f", "shamrock": "2618-fe0f", "four_leaf_clover": "1f340", "maple_leaf": "1f341", "fallen_leaf": "1f342", "leaves": "1f343", "grapes": "1f347", "melon": "1f348", "watermelon": "1f349", "tangerine": "1f34a", "mandarin": "1f34a", "orange": "1f34a", "lemon": "1f34b", "banana": "1f34c", "pineapple": "1f34d", "mango": "1f96d", "apple": "1f34e", "green_apple": "1f34f", "pear": "1f350", "peach": "1f351", "cherries": "1f352", "strawberry": "1f353", "blueberries": "1fad0", "kiwifruit": "1f95d", "kiwi_fruit": "1f95d", "tomato": "1f345", "olive": "1fad2", "coconut": "1f965", "avocado": "1f951", "eggplant": "1f346", "potato": "1f954", "carrot": "1f955", "corn": "1f33d", "hot_pepper": "1f336-fe0f", "bell_pepper": "1fad1", "cucumber": "1f952", "leafy_green": "1f96c", "broccoli": "1f966", "garlic": "1f9c4", "onion": "1f9c5", "mushroom": "1f344", "peanuts": "1f95c", "chestnut": "1f330", "bread": "1f35e", "croissant": "1f950", "baguette_bread": "1f956", "flatbread": "1fad3", "pretzel": "1f968", "bagel": "1f96f", "pancakes": "1f95e", "waffle": "1f9c7", "cheese_wedge": "1f9c0", "cheese": "1f9c0", "meat_on_bone": "1f356", "poultry_leg": "1f357", "cut_of_meat": "1f969", "bacon": "1f953", "hamburger": "1f354", "fries": "1f35f", "pizza": "1f355", "hotdog": "1f32d", "sandwich": "1f96a", "taco": "1f32e", "burrito": "1f32f", "tamale": "1fad4", "stuffed_flatbread": "1f959", "falafel": "1f9c6", "egg": "1f95a", "fried_egg": "1f373", "cooking": "1f373", "shallow_pan_of_food": "1f958", "stew": "1f372", "fondue": "1fad5", "bowl_with_spoon": "1f963", "green_salad": "1f957", "popcorn": "1f37f", "butter": "1f9c8", "salt": "1f9c2", "canned_food": "1f96b", "bento": "1f371", "rice_cracker": "1f358", "rice_ball": "1f359", "rice": "1f35a", "curry": "1f35b", "ramen": "1f35c", "spaghetti": "1f35d", "sweet_potato": "1f360", "oden": "1f362", "sushi": "1f363", "fried_shrimp": "1f364", "fish_cake": "1f365", "moon_cake": "1f96e", "dango": "1f361", "dumpling": "1f95f", "fortune_cookie": "1f960", "takeout_box": "1f961", "crab": "1f980", "lobster": "1f99e", "shrimp": "1f990", "squid": "1f991", "oyster": "1f9aa", "icecream": "1f366", "shaved_ice": "1f367", "ice_cream": "1f368", "doughnut": "1f369", "cookie": "1f36a", "birthday": "1f382", "cake": "1f370", "cupcake": "1f9c1", "pie": "1f967", "chocolate_bar": "1f36b", "candy": "1f36c", "lollipop": "1f36d", "custard": "1f36e", "honey_pot": "1f36f", "baby_bottle": "1f37c", "glass_of_milk": "1f95b", "milk_glass": "1f95b", "coffee": "2615", "teapot": "1fad6", "tea": "1f375", "sake": "1f376", "champagne": "1f37e", "wine_glass": "1f377", "cocktail": "1f378", "tropical_drink": "1f379", "beer": "1f37a", "beers": "1f37b", "clinking_glasses": "1f942", "tumbler_glass": "1f943", "cup_with_straw": "1f964", "bubble_tea": "1f9cb", "beverage_box": "1f9c3", "mate_drink": "1f9c9", "ice_cube": "1f9ca", "chopsticks": "1f962", "knife_fork_plate": "1f37d-fe0f", "plate_with_cutlery": "1f37d-fe0f", "fork_and_knife": "1f374", "spoon": "1f944", "hocho": "1f52a", "knife": "1f52a", "amphora": "1f3fa", "earth_africa": "1f30d", "earth_americas": "1f30e", "earth_asia": "1f30f", "globe_with_meridians": "1f310", "world_map": "1f5fa-fe0f", "japan": "1f5fe", "compass": "1f9ed", "snow_capped_mountain": "1f3d4-fe0f", "mountain_snow": "1f3d4-fe0f", "mountain": "26f0-fe0f", "volcano": "1f30b", "mount_fuji": "1f5fb", "camping": "1f3d5-fe0f", "beach_with_umbrella": "1f3d6-fe0f", "beach_umbrella": "1f3d6-fe0f", "desert": "1f3dc-fe0f", "desert_island": "1f3dd-fe0f", "national_park": "1f3de-fe0f", "stadium": "1f3df-fe0f", "classical_building": "1f3db-fe0f", "building_construction": "1f3d7-fe0f", "bricks": "1f9f1", "rock": "1faa8", "wood": "1fab5", "hut": "1f6d6", "house_buildings": "1f3d8-fe0f", "houses": "1f3d8-fe0f", "derelict_house_building": "1f3da-fe0f", "derelict_house": "1f3da-fe0f", "house": "1f3e0", "house_with_garden": "1f3e1", "office": "1f3e2", "post_office": "1f3e3", "european_post_office": "1f3e4", "hospital": "1f3e5", "bank": "1f3e6", "hotel": "1f3e8", "love_hotel": "1f3e9", "convenience_store": "1f3ea", "school": "1f3eb", "department_store": "1f3ec", "factory": "1f3ed", "japanese_castle": "1f3ef", "european_castle": "1f3f0", "wedding": "1f492", "tokyo_tower": "1f5fc", "statue_of_liberty": "1f5fd", "church": "26ea", "mosque": "1f54c", "hindu_temple": "1f6d5", "synagogue": "1f54d", "shinto_shrine": "26e9-fe0f", "kaaba": "1f54b", "fountain": "26f2", "tent": "26fa", "foggy": "1f301", "night_with_stars": "1f303", "cityscape": "1f3d9-fe0f", "sunrise_over_mountains": "1f304", "sunrise": "1f305", "city_sunset": "1f306", "city_sunrise": "1f307", "bridge_at_night": "1f309", "hotsprings": "2668-fe0f", "carousel_horse": "1f3a0", "ferris_wheel": "1f3a1", "roller_coaster": "1f3a2", "barber": "1f488", "circus_tent": "1f3aa", "steam_locomotive": "1f682", "railway_car": "1f683", "bullettrain_side": "1f684", "bullettrain_front": "1f685", "train2": "1f686", "metro": "1f687", "light_rail": "1f688", "station": "1f689", "tram": "1f68a", "monorail": "1f69d", "mountain_railway": "1f69e", "train": "1f68b", "bus": "1f68c", "oncoming_bus": "1f68d", "trolleybus": "1f68e", "minibus": "1f690", "ambulance": "1f691", "fire_engine": "1f692", "police_car": "1f693", "oncoming_police_car": "1f694", "taxi": "1f695", "oncoming_taxi": "1f696", "car": "1f697", "red_car": "1f697", "oncoming_automobile": "1f698", "blue_car": "1f699", "pickup_truck": "1f6fb", "truck": "1f69a", "articulated_lorry": "1f69b", "tractor": "1f69c", "racing_car": "1f3ce-fe0f", "racing_motorcycle": "1f3cd-fe0f", "motorcycle": "1f3cd-fe0f", "motor_scooter": "1f6f5", "manual_wheelchair": "1f9bd", "motorized_wheelchair": "1f9bc", "auto_rickshaw": "1f6fa", "bike": "1f6b2", "scooter": "1f6f4", "kick_scooter": "1f6f4", "skateboard": "1f6f9", "roller_skate": "1f6fc", "busstop": "1f68f", "motorway": "1f6e3-fe0f", "railway_track": "1f6e4-fe0f", "oil_drum": "1f6e2-fe0f", "fuelpump": "26fd", "rotating_light": "1f6a8", "traffic_light": "1f6a5", "vertical_traffic_light": "1f6a6", "octagonal_sign": "1f6d1", "stop_sign": "1f6d1", "construction": "1f6a7", "anchor": "2693", "boat": "26f5", "sailboat": "26f5", "canoe": "1f6f6", "speedboat": "1f6a4", "passenger_ship": "1f6f3-fe0f", "ferry": "26f4-fe0f", "motor_boat": "1f6e5-fe0f", "ship": "1f6a2", "airplane": "2708-fe0f", "small_airplane": "1f6e9-fe0f", "airplane_departure": "1f6eb", "flight_departure": "1f6eb", "airplane_arriving": "1f6ec", "flight_arrival": "1f6ec", "parachute": "1fa82", "seat": "1f4ba", "helicopter": "1f681", "suspension_railway": "1f69f", "mountain_cableway": "1f6a0", "aerial_tramway": "1f6a1", "satellite": "1f6f0-fe0f", "artificial_satellite": "1f6f0-fe0f", "rocket": "1f680", "flying_saucer": "1f6f8", "bellhop_bell": "1f6ce-fe0f", "luggage": "1f9f3", "hourglass": "231b", "hourglass_flowing_sand": "23f3", "watch": "231a", "alarm_clock": "23f0", "stopwatch": "23f1-fe0f", "timer_clock": "23f2-fe0f", "mantelpiece_clock": "1f570-fe0f", "clock12": "1f55b", "clock1230": "1f567", "clock1": "1f550", "clock130": "1f55c", "clock2": "1f551", "clock230": "1f55d", "clock3": "1f552", "clock330": "1f55e", "clock4": "1f553", "clock430": "1f55f", "clock5": "1f554", "clock530": "1f560", "clock6": "1f555", "clock630": "1f561", "clock7": "1f556", "clock730": "1f562", "clock8": "1f557", "clock830": "1f563", "clock9": "1f558", "clock930": "1f564", "clock10": "1f559", "clock1030": "1f565", "clock11": "1f55a", "clock1130": "1f566", "new_moon": "1f311", "waxing_crescent_moon": "1f312", "first_quarter_moon": "1f313", "moon": "1f314", "waxing_gibbous_moon": "1f314", "full_moon": "1f315", "waning_gibbous_moon": "1f316", "last_quarter_moon": "1f317", "waning_crescent_moon": "1f318", "crescent_moon": "1f319", "new_moon_with_face": "1f31a", "first_quarter_moon_with_face": "1f31b", "last_quarter_moon_with_face": "1f31c", "thermometer": "1f321-fe0f", "sunny": "2600-fe0f", "full_moon_with_face": "1f31d", "sun_with_face": "1f31e", "ringed_planet": "1fa90", "star": "2b50", "star2": "1f31f", "stars": "1f320", "milky_way": "1f30c", "cloud": "2601-fe0f", "partly_sunny": "26c5", "thunder_cloud_and_rain": "26c8-fe0f", "cloud_with_lightning_and_rain": "26c8-fe0f", "mostly_sunny": "1f324-fe0f", "sun_small_cloud": "1f324-fe0f", "sun_behind_small_cloud": "1f324-fe0f", "barely_sunny": "1f325-fe0f", "sun_behind_cloud": "1f325-fe0f", "sun_behind_large_cloud": "1f325-fe0f", "partly_sunny_rain": "1f326-fe0f", "sun_behind_rain_cloud": "1f326-fe0f", "rain_cloud": "1f327-fe0f", "cloud_with_rain": "1f327-fe0f", "snow_cloud": "1f328-fe0f", "cloud_with_snow": "1f328-fe0f", "lightning": "1f329-fe0f", "lightning_cloud": "1f329-fe0f", "cloud_with_lightning": "1f329-fe0f", "tornado": "1f32a-fe0f", "tornado_cloud": "1f32a-fe0f", "fog": "1f32b-fe0f", "wind_blowing_face": "1f32c-fe0f", "wind_face": "1f32c-fe0f", "cyclone": "1f300", "rainbow": "1f308", "closed_umbrella": "1f302", "umbrella": "2602-fe0f", "open_umbrella": "2602-fe0f", "umbrella_with_rain_drops": "2614", "umbrella_on_ground": "26f1-fe0f", "parasol_on_ground": "26f1-fe0f", "zap": "26a1", "snowflake": "2744-fe0f", "snowman": "2603-fe0f", "snowman_with_snow": "2603-fe0f", "snowman_without_snow": "26c4", "comet": "2604-fe0f", "fire": "1f525", "droplet": "1f4a7", "ocean": "1f30a", "jack_o_lantern": "1f383", "christmas_tree": "1f384", "fireworks": "1f386", "sparkler": "1f387", "firecracker": "1f9e8", "sparkles": "2728", "balloon": "1f388", "tada": "1f389", "confetti_ball": "1f38a", "tanabata_tree": "1f38b", "bamboo": "1f38d", "dolls": "1f38e", "flags": "1f38f", "wind_chime": "1f390", "rice_scene": "1f391", "red_envelope": "1f9e7", "ribbon": "1f380", "gift": "1f381", "reminder_ribbon": "1f397-fe0f", "admission_tickets": "1f39f-fe0f", "tickets": "1f39f-fe0f", "ticket": "1f3ab", "medal": "1f396-fe0f", "medal_military": "1f396-fe0f", "trophy": "1f3c6", "sports_medal": "1f3c5", "medal_sports": "1f3c5", "first_place_medal": "1f947", "1st_place_medal": "1f947", "second_place_medal": "1f948", "2nd_place_medal": "1f948", "third_place_medal": "1f949", "3rd_place_medal": "1f949", "soccer": "26bd", "baseball": "26be", "softball": "1f94e", "basketball": "1f3c0", "volleyball": "1f3d0", "football": "1f3c8", "rugby_football": "1f3c9", "tennis": "1f3be", "flying_disc": "1f94f", "bowling": "1f3b3", "cricket_bat_and_ball": "1f3cf", "field_hockey_stick_and_ball": "1f3d1", "field_hockey": "1f3d1", "ice_hockey_stick_and_puck": "1f3d2", "ice_hockey": "1f3d2", "lacrosse": "1f94d", "table_tennis_paddle_and_ball": "1f3d3", "ping_pong": "1f3d3", "badminton_racquet_and_shuttlecock": "1f3f8", "badminton": "1f3f8", "boxing_glove": "1f94a", "martial_arts_uniform": "1f94b", "goal_net": "1f945", "golf": "26f3", "ice_skate": "26f8-fe0f", "fishing_pole_and_fish": "1f3a3", "diving_mask": "1f93f", "running_shirt_with_sash": "1f3bd", "ski": "1f3bf", "sled": "1f6f7", "curling_stone": "1f94c", "dart": "1f3af", "yo-yo": "1fa80", "kite": "1fa81", "8ball": "1f3b1", "crystal_ball": "1f52e", "magic_wand": "1fa84", "nazar_amulet": "1f9ff", "video_game": "1f3ae", "joystick": "1f579-fe0f", "slot_machine": "1f3b0", "game_die": "1f3b2", "jigsaw": "1f9e9", "teddy_bear": "1f9f8", "pinata": "1fa85", "nesting_dolls": "1fa86", "spades": "2660-fe0f", "hearts": "2665-fe0f", "diamonds": "2666-fe0f", "clubs": "2663-fe0f", "chess_pawn": "265f-fe0f", "black_joker": "1f0cf", "mahjong": "1f004", "flower_playing_cards": "1f3b4", "performing_arts": "1f3ad", "frame_with_picture": "1f5bc-fe0f", "framed_picture": "1f5bc-fe0f", "art": "1f3a8", "thread": "1f9f5", "sewing_needle": "1faa1", "yarn": "1f9f6", "knot": "1faa2", "eyeglasses": "1f453", "dark_sunglasses": "1f576-fe0f", "goggles": "1f97d", "lab_coat": "1f97c", "safety_vest": "1f9ba", "necktie": "1f454", "shirt": "1f455", "tshirt": "1f455", "jeans": "1f456", "scarf": "1f9e3", "gloves": "1f9e4", "coat": "1f9e5", "socks": "1f9e6", "dress": "1f457", "kimono": "1f458", "sari": "1f97b", "one-piece_swimsuit": "1fa71", "briefs": "1fa72", "shorts": "1fa73", "bikini": "1f459", "womans_clothes": "1f45a", "purse": "1f45b", "handbag": "1f45c", "pouch": "1f45d", "shopping_bags": "1f6cd-fe0f", "shopping": "1f6cd-fe0f", "school_satchel": "1f392", "thong_sandal": "1fa74", "mans_shoe": "1f45e", "shoe": "1f45e", "athletic_shoe": "1f45f", "hiking_boot": "1f97e", "womans_flat_shoe": "1f97f", "high_heel": "1f460", "sandal": "1f461", "ballet_shoes": "1fa70", "boot": "1f462", "crown": "1f451", "womans_hat": "1f452", "tophat": "1f3a9", "mortar_board": "1f393", "billed_cap": "1f9e2", "military_helmet": "1fa96", "helmet_with_white_cross": "26d1-fe0f", "rescue_worker_helmet": "26d1-fe0f", "prayer_beads": "1f4ff", "lipstick": "1f484", "ring": "1f48d", "gem": "1f48e", "mute": "1f507", "speaker": "1f508", "sound": "1f509", "loud_sound": "1f50a", "loudspeaker": "1f4e2", "mega": "1f4e3", "postal_horn": "1f4ef", "bell": "1f514", "no_bell": "1f515", "musical_score": "1f3bc", "musical_note": "1f3b5", "notes": "1f3b6", "studio_microphone": "1f399-fe0f", "level_slider": "1f39a-fe0f", "control_knobs": "1f39b-fe0f", "microphone": "1f3a4", "headphones": "1f3a7", "radio": "1f4fb", "saxophone": "1f3b7", "accordion": "1fa97", "guitar": "1f3b8", "musical_keyboard": "1f3b9", "trumpet": "1f3ba", "violin": "1f3bb", "banjo": "1fa95", "drum_with_drumsticks": "1f941", "drum": "1f941", "long_drum": "1fa98", "iphone": "1f4f1", "calling": "1f4f2", "phone": "260e-fe0f", "telephone": "260e-fe0f", "telephone_receiver": "1f4de", "pager": "1f4df", "fax": "1f4e0", "battery": "1f50b", "electric_plug": "1f50c", "computer": "1f4bb", "desktop_computer": "1f5a5-fe0f", "printer": "1f5a8-fe0f", "keyboard": "2328-fe0f", "three_button_mouse": "1f5b1-fe0f", "computer_mouse": "1f5b1-fe0f", "trackball": "1f5b2-fe0f", "minidisc": "1f4bd", "floppy_disk": "1f4be", "cd": "1f4bf", "dvd": "1f4c0", "abacus": "1f9ee", "movie_camera": "1f3a5", "film_frames": "1f39e-fe0f", "film_strip": "1f39e-fe0f", "film_projector": "1f4fd-fe0f", "clapper": "1f3ac", "tv": "1f4fa", "camera": "1f4f7", "camera_with_flash": "1f4f8", "camera_flash": "1f4f8", "video_camera": "1f4f9", "vhs": "1f4fc", "mag": "1f50d", "mag_right": "1f50e", "candle": "1f56f-fe0f", "bulb": "1f4a1", "flashlight": "1f526", "izakaya_lantern": "1f3ee", "lantern": "1f3ee", "diya_lamp": "1fa94", "notebook_with_decorative_cover": "1f4d4", "closed_book": "1f4d5", "book": "1f4d6", "open_book": "1f4d6", "green_book": "1f4d7", "blue_book": "1f4d8", "orange_book": "1f4d9", "books": "1f4da", "notebook": "1f4d3", "ledger": "1f4d2", "page_with_curl": "1f4c3", "scroll": "1f4dc", "page_facing_up": "1f4c4", "newspaper": "1f4f0", "rolled_up_newspaper": "1f5de-fe0f", "newspaper_roll": "1f5de-fe0f", "bookmark_tabs": "1f4d1", "bookmark": "1f516", "label": "1f3f7-fe0f", "moneybag": "1f4b0", "coin": "1fa99", "yen": "1f4b4", "dollar": "1f4b5", "euro": "1f4b6", "pound": "1f4b7", "money_with_wings": "1f4b8", "credit_card": "1f4b3", "receipt": "1f9fe", "chart": "1f4b9", "email": "2709-fe0f", "envelope": "2709-fe0f", "e-mail": "1f4e7", "incoming_envelope": "1f4e8", "envelope_with_arrow": "1f4e9", "outbox_tray": "1f4e4", "inbox_tray": "1f4e5", "package": "1f4e6", "mailbox": "1f4eb", "mailbox_closed": "1f4ea", "mailbox_with_mail": "1f4ec", "mailbox_with_no_mail": "1f4ed", "postbox": "1f4ee", "ballot_box_with_ballot": "1f5f3-fe0f", "ballot_box": "1f5f3-fe0f", "pencil2": "270f-fe0f", "black_nib": "2712-fe0f", "lower_left_fountain_pen": "1f58b-fe0f", "fountain_pen": "1f58b-fe0f", "lower_left_ballpoint_pen": "1f58a-fe0f", "pen": "1f58a-fe0f", "lower_left_paintbrush": "1f58c-fe0f", "paintbrush": "1f58c-fe0f", "lower_left_crayon": "1f58d-fe0f", "crayon": "1f58d-fe0f", "memo": "1f4dd", "pencil": "1f4dd", "briefcase": "1f4bc", "file_folder": "1f4c1", "open_file_folder": "1f4c2", "card_index_dividers": "1f5c2-fe0f", "date": "1f4c5", "calendar": "1f4c6", "spiral_note_pad": "1f5d2-fe0f", "spiral_notepad": "1f5d2-fe0f", "spiral_calendar_pad": "1f5d3-fe0f", "spiral_calendar": "1f5d3-fe0f", "card_index": "1f4c7", "chart_with_upwards_trend": "1f4c8", "chart_with_downwards_trend": "1f4c9", "bar_chart": "1f4ca", "clipboard": "1f4cb", "pushpin": "1f4cc", "round_pushpin": "1f4cd", "paperclip": "1f4ce", "linked_paperclips": "1f587-fe0f", "paperclips": "1f587-fe0f", "straight_ruler": "1f4cf", "triangular_ruler": "1f4d0", "scissors": "2702-fe0f", "card_file_box": "1f5c3-fe0f", "file_cabinet": "1f5c4-fe0f", "wastebasket": "1f5d1-fe0f", "lock": "1f512", "unlock": "1f513", "lock_with_ink_pen": "1f50f", "closed_lock_with_key": "1f510", "key": "1f511", "old_key": "1f5dd-fe0f", "hammer": "1f528", "axe": "1fa93", "pick": "26cf-fe0f", "hammer_and_pick": "2692-fe0f", "hammer_and_wrench": "1f6e0-fe0f", "dagger_knife": "1f5e1-fe0f", "dagger": "1f5e1-fe0f", "crossed_swords": "2694-fe0f", "gun": "1f52b", "boomerang": "1fa83", "bow_and_arrow": "1f3f9", "shield": "1f6e1-fe0f", "carpentry_saw": "1fa9a", "wrench": "1f527", "screwdriver": "1fa9b", "nut_and_bolt": "1f529", "gear": "2699-fe0f", "compression": "1f5dc-fe0f", "clamp": "1f5dc-fe0f", "scales": "2696-fe0f", "balance_scale": "2696-fe0f", "probing_cane": "1f9af", "link": "1f517", "chains": "26d3-fe0f", "hook": "1fa9d", "toolbox": "1f9f0", "magnet": "1f9f2", "ladder": "1fa9c", "alembic": "2697-fe0f", "test_tube": "1f9ea", "petri_dish": "1f9eb", "dna": "1f9ec", "microscope": "1f52c", "telescope": "1f52d", "satellite_antenna": "1f4e1", "syringe": "1f489", "drop_of_blood": "1fa78", "pill": "1f48a", "adhesive_bandage": "1fa79", "stethoscope": "1fa7a", "door": "1f6aa", "elevator": "1f6d7", "mirror": "1fa9e", "window": "1fa9f", "bed": "1f6cf-fe0f", "couch_and_lamp": "1f6cb-fe0f", "chair": "1fa91", "toilet": "1f6bd", "plunger": "1faa0", "shower": "1f6bf", "bathtub": "1f6c1", "mouse_trap": "1faa4", "razor": "1fa92", "lotion_bottle": "1f9f4", "safety_pin": "1f9f7", "broom": "1f9f9", "basket": "1f9fa", "roll_of_paper": "1f9fb", "bucket": "1faa3", "soap": "1f9fc", "toothbrush": "1faa5", "sponge": "1f9fd", "fire_extinguisher": "1f9ef", "shopping_trolley": "1f6d2", "shopping_cart": "1f6d2", "smoking": "1f6ac", "coffin": "26b0-fe0f", "headstone": "1faa6", "funeral_urn": "26b1-fe0f", "moyai": "1f5ff", "placard": "1faa7", "atm": "1f3e7", "put_litter_in_its_place": "1f6ae", "potable_water": "1f6b0", "wheelchair": "267f", "mens": "1f6b9", "womens": "1f6ba", "restroom": "1f6bb", "baby_symbol": "1f6bc", "wc": "1f6be", "passport_control": "1f6c2", "customs": "1f6c3", "baggage_claim": "1f6c4", "left_luggage": "1f6c5", "warning": "26a0-fe0f", "children_crossing": "1f6b8", "no_entry": "26d4", "no_entry_sign": "1f6ab", "no_bicycles": "1f6b3", "no_smoking": "1f6ad", "do_not_litter": "1f6af", "non-potable_water": "1f6b1", "no_pedestrians": "1f6b7", "no_mobile_phones": "1f4f5", "underage": "1f51e", "radioactive_sign": "2622-fe0f", "radioactive": "2622-fe0f", "biohazard_sign": "2623-fe0f", "biohazard": "2623-fe0f", "arrow_up": "2b06-fe0f", "arrow_upper_right": "2197-fe0f", "arrow_right": "27a1-fe0f", "arrow_lower_right": "2198-fe0f", "arrow_down": "2b07-fe0f", "arrow_lower_left": "2199-fe0f", "arrow_left": "2b05-fe0f", "arrow_upper_left": "2196-fe0f", "arrow_up_down": "2195-fe0f", "left_right_arrow": "2194-fe0f", "leftwards_arrow_with_hook": "21a9-fe0f", "arrow_right_hook": "21aa-fe0f", "arrow_heading_up": "2934-fe0f", "arrow_heading_down": "2935-fe0f", "arrows_clockwise": "1f503", "arrows_counterclockwise": "1f504", "back": "1f519", "end": "1f51a", "on": "1f51b", "soon": "1f51c", "top": "1f51d", "place_of_worship": "1f6d0", "atom_symbol": "269b-fe0f", "om_symbol": "1f549-fe0f", "om": "1f549-fe0f", "star_of_david": "2721-fe0f", "wheel_of_dharma": "2638-fe0f", "yin_yang": "262f-fe0f", "latin_cross": "271d-fe0f", "orthodox_cross": "2626-fe0f", "star_and_crescent": "262a-fe0f", "peace_symbol": "262e-fe0f", "menorah_with_nine_branches": "1f54e", "menorah": "1f54e", "six_pointed_star": "1f52f", "aries": "2648", "taurus": "2649", "gemini": "264a", "cancer": "264b", "leo": "264c", "virgo": "264d", "libra": "264e", "scorpius": "264f", "sagittarius": "2650", "capricorn": "2651", "aquarius": "2652", "pisces": "2653", "ophiuchus": "26ce", "twisted_rightwards_arrows": "1f500", "repeat": "1f501", "repeat_one": "1f502", "arrow_forward": "25b6-fe0f", "fast_forward": "23e9", "black_right_pointing_double_triangle_with_vertical_bar": "23ed-fe0f", "next_track_button": "23ed-fe0f", "black_right_pointing_triangle_with_double_vertical_bar": "23ef-fe0f", "play_or_pause_button": "23ef-fe0f", "arrow_backward": "25c0-fe0f", "rewind": "23ea", "black_left_pointing_double_triangle_with_vertical_bar": "23ee-fe0f", "previous_track_button": "23ee-fe0f", "arrow_up_small": "1f53c", "arrow_double_up": "23eb", "arrow_down_small": "1f53d", "arrow_double_down": "23ec", "double_vertical_bar": "23f8-fe0f", "pause_button": "23f8-fe0f", "black_square_for_stop": "23f9-fe0f", "stop_button": "23f9-fe0f", "black_circle_for_record": "23fa-fe0f", "record_button": "23fa-fe0f", "eject": "23cf-fe0f", "cinema": "1f3a6", "low_brightness": "1f505", "high_brightness": "1f506", "signal_strength": "1f4f6", "vibration_mode": "1f4f3", "mobile_phone_off": "1f4f4", "female_sign": "2640-fe0f", "male_sign": "2642-fe0f", "transgender_symbol": "26a7-fe0f", "heavy_multiplication_x": "2716-fe0f", "heavy_plus_sign": "2795", "heavy_minus_sign": "2796", "heavy_division_sign": "2797", "infinity": "267e-fe0f", "bangbang": "203c-fe0f", "interrobang": "2049-fe0f", "question": "2753", "grey_question": "2754", "grey_exclamation": "2755", "exclamation": "2757", "heavy_exclamation_mark": "2757", "wavy_dash": "3030-fe0f", "currency_exchange": "1f4b1", "heavy_dollar_sign": "1f4b2", "medical_symbol": "2695-fe0f", "staff_of_aesculapius": "2695-fe0f", "recycle": "267b-fe0f", "fleur_de_lis": "269c-fe0f", "trident": "1f531", "name_badge": "1f4db", "beginner": "1f530", "o": "2b55", "white_check_mark": "2705", "ballot_box_with_check": "2611-fe0f", "heavy_check_mark": "2714-fe0f", "x": "274c", "negative_squared_cross_mark": "274e", "curly_loop": "27b0", "loop": "27bf", "part_alternation_mark": "303d-fe0f", "eight_spoked_asterisk": "2733-fe0f", "eight_pointed_black_star": "2734-fe0f", "sparkle": "2747-fe0f", "copyright": "00a9-fe0f", "registered": "00ae-fe0f", "tm": "2122-fe0f", "hash": "0023-fe0f-20e3", "keycap_star": "002a-fe0f-20e3", "asterisk": "002a-fe0f-20e3", "zero": "0030-fe0f-20e3", "one": "0031-fe0f-20e3", "two": "0032-fe0f-20e3", "three": "0033-fe0f-20e3", "four": "0034-fe0f-20e3", "five": "0035-fe0f-20e3", "six": "0036-fe0f-20e3", "seven": "0037-fe0f-20e3", "eight": "0038-fe0f-20e3", "nine": "0039-fe0f-20e3", "keycap_ten": "1f51f", "capital_abcd": "1f520", "abcd": "1f521", "1234": "1f522", "symbols": "1f523", "abc": "1f524", "a": "1f170-fe0f", "ab": "1f18e", "b": "1f171-fe0f", "cl": "1f191", "cool": "1f192", "free": "1f193", "information_source": "2139-fe0f", "id": "1f194", "m": "24c2-fe0f", "new": "1f195", "ng": "1f196", "o2": "1f17e-fe0f", "ok": "1f197", "parking": "1f17f-fe0f", "sos": "1f198", "up": "1f199", "vs": "1f19a", "koko": "1f201", "sa": "1f202-fe0f", "u6708": "1f237-fe0f", "u6709": "1f236", "u6307": "1f22f", "ideograph_advantage": "1f250", "u5272": "1f239", "u7121": "1f21a", "u7981": "1f232", "accept": "1f251", "u7533": "1f238", "u5408": "1f234", "u7a7a": "1f233", "congratulations": "3297-fe0f", "secret": "3299-fe0f", "u55b6": "1f23a", "u6e80": "1f235", "red_circle": "1f534", "large_orange_circle": "1f7e0", "large_yellow_circle": "1f7e1", "large_green_circle": "1f7e2", "large_blue_circle": "1f535", "large_purple_circle": "1f7e3", "large_brown_circle": "1f7e4", "black_circle": "26ab", "white_circle": "26aa", "large_red_square": "1f7e5", "large_orange_square": "1f7e7", "large_yellow_square": "1f7e8", "large_green_square": "1f7e9", "large_blue_square": "1f7e6", "large_purple_square": "1f7ea", "large_brown_square": "1f7eb", "black_large_square": "2b1b", "white_large_square": "2b1c", "black_medium_square": "25fc-fe0f", "white_medium_square": "25fb-fe0f", "black_medium_small_square": "25fe", "white_medium_small_square": "25fd", "black_small_square": "25aa-fe0f", "white_small_square": "25ab-fe0f", "large_orange_diamond": "1f536", "large_blue_diamond": "1f537", "small_orange_diamond": "1f538", "small_blue_diamond": "1f539", "small_red_triangle": "1f53a", "small_red_triangle_down": "1f53b", "diamond_shape_with_a_dot_inside": "1f4a0", "radio_button": "1f518", "white_square_button": "1f533", "black_square_button": "1f532", "checkered_flag": "1f3c1", "triangular_flag_on_post": "1f6a9", "crossed_flags": "1f38c", "waving_black_flag": "1f3f4", "black_flag": "1f3f4", "waving_white_flag": "1f3f3-fe0f", "white_flag": "1f3f3-fe0f", "rainbow-flag": "1f3f3-fe0f-200d-1f308", "rainbow_flag": "1f3f3-fe0f-200d-1f308", "transgender_flag": "1f3f3-fe0f-200d-26a7-fe0f", "pirate_flag": "1f3f4-200d-2620-fe0f", "flag-ac": "1f1e6-1f1e8", "flag-ad": "1f1e6-1f1e9", "andorra": "1f1e6-1f1e9", "flag-ae": "1f1e6-1f1ea", "united_arab_emirates": "1f1e6-1f1ea", "flag-af": "1f1e6-1f1eb", "afghanistan": "1f1e6-1f1eb", "flag-ag": "1f1e6-1f1ec", "antigua_barbuda": "1f1e6-1f1ec", "flag-ai": "1f1e6-1f1ee", "anguilla": "1f1e6-1f1ee", "flag-al": "1f1e6-1f1f1", "albania": "1f1e6-1f1f1", "flag-am": "1f1e6-1f1f2", "armenia": "1f1e6-1f1f2", "flag-ao": "1f1e6-1f1f4", "angola": "1f1e6-1f1f4", "flag-aq": "1f1e6-1f1f6", "antarctica": "1f1e6-1f1f6", "flag-ar": "1f1e6-1f1f7", "argentina": "1f1e6-1f1f7", "flag-as": "1f1e6-1f1f8", "american_samoa": "1f1e6-1f1f8", "flag-at": "1f1e6-1f1f9", "austria": "1f1e6-1f1f9", "flag-au": "1f1e6-1f1fa", "australia": "1f1e6-1f1fa", "flag-aw": "1f1e6-1f1fc", "aruba": "1f1e6-1f1fc", "flag-ax": "1f1e6-1f1fd", "aland_islands": "1f1e6-1f1fd", "flag-az": "1f1e6-1f1ff", "azerbaijan": "1f1e6-1f1ff", "flag-ba": "1f1e7-1f1e6", "bosnia_herzegovina": "1f1e7-1f1e6", "flag-bb": "1f1e7-1f1e7", "barbados": "1f1e7-1f1e7", "flag-bd": "1f1e7-1f1e9", "bangladesh": "1f1e7-1f1e9", "flag-be": "1f1e7-1f1ea", "belgium": "1f1e7-1f1ea", "flag-bf": "1f1e7-1f1eb", "burkina_faso": "1f1e7-1f1eb", "flag-bg": "1f1e7-1f1ec", "bulgaria": "1f1e7-1f1ec", "flag-bh": "1f1e7-1f1ed", "bahrain": "1f1e7-1f1ed", "flag-bi": "1f1e7-1f1ee", "burundi": "1f1e7-1f1ee", "flag-bj": "1f1e7-1f1ef", "benin": "1f1e7-1f1ef", "flag-bl": "1f1e7-1f1f1", "st_barthelemy": "1f1e7-1f1f1", "flag-bm": "1f1e7-1f1f2", "bermuda": "1f1e7-1f1f2", "flag-bn": "1f1e7-1f1f3", "brunei": "1f1e7-1f1f3", "flag-bo": "1f1e7-1f1f4", "bolivia": "1f1e7-1f1f4", "flag-bq": "1f1e7-1f1f6", "caribbean_netherlands": "1f1e7-1f1f6", "flag-br": "1f1e7-1f1f7", "brazil": "1f1e7-1f1f7", "flag-bs": "1f1e7-1f1f8", "bahamas": "1f1e7-1f1f8", "flag-bt": "1f1e7-1f1f9", "bhutan": "1f1e7-1f1f9", "flag-bv": "1f1e7-1f1fb", "flag-bw": "1f1e7-1f1fc", "botswana": "1f1e7-1f1fc", "flag-by": "1f1e7-1f1fe", "belarus": "1f1e7-1f1fe", "flag-bz": "1f1e7-1f1ff", "belize": "1f1e7-1f1ff", "flag-ca": "1f1e8-1f1e6", "ca": "1f1e8-1f1e6", "canada": "1f1e8-1f1e6", "flag-cc": "1f1e8-1f1e8", "cocos_islands": "1f1e8-1f1e8", "flag-cd": "1f1e8-1f1e9", "congo_kinshasa": "1f1e8-1f1e9", "flag-cf": "1f1e8-1f1eb", "central_african_republic": "1f1e8-1f1eb", "flag-cg": "1f1e8-1f1ec", "congo_brazzaville": "1f1e8-1f1ec", "flag-ch": "1f1e8-1f1ed", "switzerland": "1f1e8-1f1ed", "flag-ci": "1f1e8-1f1ee", "cote_divoire": "1f1e8-1f1ee", "flag-ck": "1f1e8-1f1f0", "cook_islands": "1f1e8-1f1f0", "flag-cl": "1f1e8-1f1f1", "chile": "1f1e8-1f1f1", "flag-cm": "1f1e8-1f1f2", "cameroon": "1f1e8-1f1f2", "cn": "1f1e8-1f1f3", "flag-cn": "1f1e8-1f1f3", "flag-co": "1f1e8-1f1f4", "colombia": "1f1e8-1f1f4", "flag-cp": "1f1e8-1f1f5", "flag-cr": "1f1e8-1f1f7", "costa_rica": "1f1e8-1f1f7", "flag-cu": "1f1e8-1f1fa", "cuba": "1f1e8-1f1fa", "flag-cv": "1f1e8-1f1fb", "cape_verde": "1f1e8-1f1fb", "flag-cw": "1f1e8-1f1fc", "curacao": "1f1e8-1f1fc", "flag-cx": "1f1e8-1f1fd", "christmas_island": "1f1e8-1f1fd", "flag-cy": "1f1e8-1f1fe", "cyprus": "1f1e8-1f1fe", "flag-cz": "1f1e8-1f1ff", "czech_republic": "1f1e8-1f1ff", "de": "1f1e9-1f1ea", "flag-de": "1f1e9-1f1ea", "flag-dg": "1f1e9-1f1ec", "flag-dj": "1f1e9-1f1ef", "djibouti": "1f1e9-1f1ef", "flag-dk": "1f1e9-1f1f0", "denmark": "1f1e9-1f1f0", "flag-dm": "1f1e9-1f1f2", "dominica": "1f1e9-1f1f2", "flag-do": "1f1e9-1f1f4", "dominican_republic": "1f1e9-1f1f4", "flag-dz": "1f1e9-1f1ff", "algeria": "1f1e9-1f1ff", "flag-ea": "1f1ea-1f1e6", "flag-ec": "1f1ea-1f1e8", "ecuador": "1f1ea-1f1e8", "flag-ee": "1f1ea-1f1ea", "estonia": "1f1ea-1f1ea", "flag-eg": "1f1ea-1f1ec", "egypt": "1f1ea-1f1ec", "flag-eh": "1f1ea-1f1ed", "western_sahara": "1f1ea-1f1ed", "flag-er": "1f1ea-1f1f7", "eritrea": "1f1ea-1f1f7", "es": "1f1ea-1f1f8", "flag-es": "1f1ea-1f1f8", "flag-et": "1f1ea-1f1f9", "ethiopia": "1f1ea-1f1f9", "flag-eu": "1f1ea-1f1fa", "eu": "1f1ea-1f1fa", "european_union": "1f1ea-1f1fa", "flag-fi": "1f1eb-1f1ee", "finland": "1f1eb-1f1ee", "flag-fj": "1f1eb-1f1ef", "fiji": "1f1eb-1f1ef", "flag-fk": "1f1eb-1f1f0", "falkland_islands": "1f1eb-1f1f0", "flag-fm": "1f1eb-1f1f2", "micronesia": "1f1eb-1f1f2", "flag-fo": "1f1eb-1f1f4", "faroe_islands": "1f1eb-1f1f4", "fr": "1f1eb-1f1f7", "flag-fr": "1f1eb-1f1f7", "flag-ga": "1f1ec-1f1e6", "gabon": "1f1ec-1f1e6", "gb": "1f1ec-1f1e7", "uk": "1f1ec-1f1e7", "flag-gb": "1f1ec-1f1e7", "flag-gd": "1f1ec-1f1e9", "grenada": "1f1ec-1f1e9", "flag-ge": "1f1ec-1f1ea", "georgia": "1f1ec-1f1ea", "flag-gf": "1f1ec-1f1eb", "french_guiana": "1f1ec-1f1eb", "flag-gg": "1f1ec-1f1ec", "guernsey": "1f1ec-1f1ec", "flag-gh": "1f1ec-1f1ed", "ghana": "1f1ec-1f1ed", "flag-gi": "1f1ec-1f1ee", "gibraltar": "1f1ec-1f1ee", "flag-gl": "1f1ec-1f1f1", "greenland": "1f1ec-1f1f1", "flag-gm": "1f1ec-1f1f2", "gambia": "1f1ec-1f1f2", "flag-gn": "1f1ec-1f1f3", "guinea": "1f1ec-1f1f3", "flag-gp": "1f1ec-1f1f5", "guadeloupe": "1f1ec-1f1f5", "flag-gq": "1f1ec-1f1f6", "equatorial_guinea": "1f1ec-1f1f6", "flag-gr": "1f1ec-1f1f7", "greece": "1f1ec-1f1f7", "flag-gs": "1f1ec-1f1f8", "south_georgia_south_sandwich_islands": "1f1ec-1f1f8", "flag-gt": "1f1ec-1f1f9", "guatemala": "1f1ec-1f1f9", "flag-gu": "1f1ec-1f1fa", "guam": "1f1ec-1f1fa", "flag-gw": "1f1ec-1f1fc", "guinea_bissau": "1f1ec-1f1fc", "flag-gy": "1f1ec-1f1fe", "guyana": "1f1ec-1f1fe", "flag-hk": "1f1ed-1f1f0", "hong_kong": "1f1ed-1f1f0", "flag-hm": "1f1ed-1f1f2", "flag-hn": "1f1ed-1f1f3", "honduras": "1f1ed-1f1f3", "flag-hr": "1f1ed-1f1f7", "croatia": "1f1ed-1f1f7", "flag-ht": "1f1ed-1f1f9", "haiti": "1f1ed-1f1f9", "flag-hu": "1f1ed-1f1fa", "hungary": "1f1ed-1f1fa", "flag-ic": "1f1ee-1f1e8", "canary_islands": "1f1ee-1f1e8", "flag-id": "1f1ee-1f1e9", "indonesia": "1f1ee-1f1e9", "flag-ie": "1f1ee-1f1ea", "ireland": "1f1ee-1f1ea", "flag-il": "1f1ee-1f1f1", "israel": "1f1ee-1f1f1", "flag-im": "1f1ee-1f1f2", "isle_of_man": "1f1ee-1f1f2", "flag-in": "1f1ee-1f1f3", "india": "1f1ee-1f1f3", "flag-io": "1f1ee-1f1f4", "british_indian_ocean_territory": "1f1ee-1f1f4", "flag-iq": "1f1ee-1f1f6", "iraq": "1f1ee-1f1f6", "flag-ir": "1f1ee-1f1f7", "iran": "1f1ee-1f1f7", "flag-is": "1f1ee-1f1f8", "iceland": "1f1ee-1f1f8", "it": "1f1ee-1f1f9", "flag-it": "1f1ee-1f1f9", "flag-je": "1f1ef-1f1ea", "jersey": "1f1ef-1f1ea", "flag-jm": "1f1ef-1f1f2", "jamaica": "1f1ef-1f1f2", "flag-jo": "1f1ef-1f1f4", "jordan": "1f1ef-1f1f4", "jp": "1f1ef-1f1f5", "flag-jp": "1f1ef-1f1f5", "flag-ke": "1f1f0-1f1ea", "kenya": "1f1f0-1f1ea", "flag-kg": "1f1f0-1f1ec", "kyrgyzstan": "1f1f0-1f1ec", "flag-kh": "1f1f0-1f1ed", "cambodia": "1f1f0-1f1ed", "flag-ki": "1f1f0-1f1ee", "kiribati": "1f1f0-1f1ee", "flag-km": "1f1f0-1f1f2", "comoros": "1f1f0-1f1f2", "flag-kn": "1f1f0-1f1f3", "st_kitts_nevis": "1f1f0-1f1f3", "flag-kp": "1f1f0-1f1f5", "north_korea": "1f1f0-1f1f5", "kr": "1f1f0-1f1f7", "flag-kr": "1f1f0-1f1f7", "flag-kw": "1f1f0-1f1fc", "kuwait": "1f1f0-1f1fc", "flag-ky": "1f1f0-1f1fe", "cayman_islands": "1f1f0-1f1fe", "flag-kz": "1f1f0-1f1ff", "kazakhstan": "1f1f0-1f1ff", "flag-la": "1f1f1-1f1e6", "laos": "1f1f1-1f1e6", "flag-lb": "1f1f1-1f1e7", "lebanon": "1f1f1-1f1e7", "flag-lc": "1f1f1-1f1e8", "st_lucia": "1f1f1-1f1e8", "flag-li": "1f1f1-1f1ee", "liechtenstein": "1f1f1-1f1ee", "flag-lk": "1f1f1-1f1f0", "sri_lanka": "1f1f1-1f1f0", "flag-lr": "1f1f1-1f1f7", "liberia": "1f1f1-1f1f7", "flag-ls": "1f1f1-1f1f8", "lesotho": "1f1f1-1f1f8", "flag-lt": "1f1f1-1f1f9", "lithuania": "1f1f1-1f1f9", "flag-lu": "1f1f1-1f1fa", "luxembourg": "1f1f1-1f1fa", "flag-lv": "1f1f1-1f1fb", "latvia": "1f1f1-1f1fb", "flag-ly": "1f1f1-1f1fe", "libya": "1f1f1-1f1fe", "flag-ma": "1f1f2-1f1e6", "morocco": "1f1f2-1f1e6", "flag-mc": "1f1f2-1f1e8", "monaco": "1f1f2-1f1e8", "flag-md": "1f1f2-1f1e9", "moldova": "1f1f2-1f1e9", "flag-me": "1f1f2-1f1ea", "montenegro": "1f1f2-1f1ea", "flag-mf": "1f1f2-1f1eb", "flag-mg": "1f1f2-1f1ec", "madagascar": "1f1f2-1f1ec", "flag-mh": "1f1f2-1f1ed", "marshall_islands": "1f1f2-1f1ed", "flag-mk": "1f1f2-1f1f0", "macedonia": "1f1f2-1f1f0", "flag-ml": "1f1f2-1f1f1", "mali": "1f1f2-1f1f1", "flag-mm": "1f1f2-1f1f2", "myanmar": "1f1f2-1f1f2", "flag-mn": "1f1f2-1f1f3", "mongolia": "1f1f2-1f1f3", "flag-mo": "1f1f2-1f1f4", "macau": "1f1f2-1f1f4", "flag-mp": "1f1f2-1f1f5", "northern_mariana_islands": "1f1f2-1f1f5", "flag-mq": "1f1f2-1f1f6", "martinique": "1f1f2-1f1f6", "flag-mr": "1f1f2-1f1f7", "mauritania": "1f1f2-1f1f7", "flag-ms": "1f1f2-1f1f8", "montserrat": "1f1f2-1f1f8", "flag-mt": "1f1f2-1f1f9", "malta": "1f1f2-1f1f9", "flag-mu": "1f1f2-1f1fa", "mauritius": "1f1f2-1f1fa", "flag-mv": "1f1f2-1f1fb", "maldives": "1f1f2-1f1fb", "flag-mw": "1f1f2-1f1fc", "malawi": "1f1f2-1f1fc", "flag-mx": "1f1f2-1f1fd", "mexico": "1f1f2-1f1fd", "flag-my": "1f1f2-1f1fe", "malaysia": "1f1f2-1f1fe", "flag-mz": "1f1f2-1f1ff", "mozambique": "1f1f2-1f1ff", "flag-na": "1f1f3-1f1e6", "namibia": "1f1f3-1f1e6", "flag-nc": "1f1f3-1f1e8", "new_caledonia": "1f1f3-1f1e8", "flag-ne": "1f1f3-1f1ea", "niger": "1f1f3-1f1ea", "flag-nf": "1f1f3-1f1eb", "norfolk_island": "1f1f3-1f1eb", "flag-ng": "1f1f3-1f1ec", "nigeria": "1f1f3-1f1ec", "flag-ni": "1f1f3-1f1ee", "nicaragua": "1f1f3-1f1ee", "flag-nl": "1f1f3-1f1f1", "netherlands": "1f1f3-1f1f1", "flag-no": "1f1f3-1f1f4", "norway": "1f1f3-1f1f4", "flag-np": "1f1f3-1f1f5", "nepal": "1f1f3-1f1f5", "flag-nr": "1f1f3-1f1f7", "nauru": "1f1f3-1f1f7", "flag-nu": "1f1f3-1f1fa", "niue": "1f1f3-1f1fa", "flag-nz": "1f1f3-1f1ff", "new_zealand": "1f1f3-1f1ff", "flag-om": "1f1f4-1f1f2", "oman": "1f1f4-1f1f2", "flag-pa": "1f1f5-1f1e6", "panama": "1f1f5-1f1e6", "flag-pe": "1f1f5-1f1ea", "peru": "1f1f5-1f1ea", "flag-pf": "1f1f5-1f1eb", "french_polynesia": "1f1f5-1f1eb", "flag-pg": "1f1f5-1f1ec", "papua_new_guinea": "1f1f5-1f1ec", "flag-ph": "1f1f5-1f1ed", "philippines": "1f1f5-1f1ed", "flag-pk": "1f1f5-1f1f0", "pakistan": "1f1f5-1f1f0", "pk": "1f1f5-1f1f0", "flag-pl": "1f1f5-1f1f1", "poland": "1f1f5-1f1f1", "flag-pm": "1f1f5-1f1f2", "st_pierre_miquelon": "1f1f5-1f1f2", "flag-pn": "1f1f5-1f1f3", "pitcairn_islands": "1f1f5-1f1f3", "flag-pr": "1f1f5-1f1f7", "puerto_rico": "1f1f5-1f1f7", "flag-ps": "1f1f5-1f1f8", "palestinian_territories": "1f1f5-1f1f8", "flag-pt": "1f1f5-1f1f9", "portugal": "1f1f5-1f1f9", "flag-pw": "1f1f5-1f1fc", "palau": "1f1f5-1f1fc", "flag-py": "1f1f5-1f1fe", "paraguay": "1f1f5-1f1fe", "flag-qa": "1f1f6-1f1e6", "qatar": "1f1f6-1f1e6", "flag-re": "1f1f7-1f1ea", "reunion": "1f1f7-1f1ea", "flag-ro": "1f1f7-1f1f4", "romania": "1f1f7-1f1f4", "flag-rs": "1f1f7-1f1f8", "serbia": "1f1f7-1f1f8", "ru": "1f1f7-1f1fa", "flag-ru": "1f1f7-1f1fa", "flag-rw": "1f1f7-1f1fc", "rwanda": "1f1f7-1f1fc", "flag-sa": "1f1f8-1f1e6", "saudi_arabia": "1f1f8-1f1e6", "flag-sb": "1f1f8-1f1e7", "solomon_islands": "1f1f8-1f1e7", "flag-sc": "1f1f8-1f1e8", "seychelles": "1f1f8-1f1e8", "flag-sd": "1f1f8-1f1e9", "sudan": "1f1f8-1f1e9", "flag-se": "1f1f8-1f1ea", "sweden": "1f1f8-1f1ea", "flag-sg": "1f1f8-1f1ec", "singapore": "1f1f8-1f1ec", "flag-sh": "1f1f8-1f1ed", "st_helena": "1f1f8-1f1ed", "flag-si": "1f1f8-1f1ee", "slovenia": "1f1f8-1f1ee", "flag-sj": "1f1f8-1f1ef", "flag-sk": "1f1f8-1f1f0", "slovakia": "1f1f8-1f1f0", "flag-sl": "1f1f8-1f1f1", "sierra_leone": "1f1f8-1f1f1", "flag-sm": "1f1f8-1f1f2", "san_marino": "1f1f8-1f1f2", "flag-sn": "1f1f8-1f1f3", "senegal": "1f1f8-1f1f3", "flag-so": "1f1f8-1f1f4", "somalia": "1f1f8-1f1f4", "flag-sr": "1f1f8-1f1f7", "suriname": "1f1f8-1f1f7", "flag-ss": "1f1f8-1f1f8", "south_sudan": "1f1f8-1f1f8", "flag-st": "1f1f8-1f1f9", "sao_tome_principe": "1f1f8-1f1f9", "flag-sv": "1f1f8-1f1fb", "el_salvador": "1f1f8-1f1fb", "flag-sx": "1f1f8-1f1fd", "sint_maarten": "1f1f8-1f1fd", "flag-sy": "1f1f8-1f1fe", "syria": "1f1f8-1f1fe", "flag-sz": "1f1f8-1f1ff", "swaziland": "1f1f8-1f1ff", "flag-ta": "1f1f9-1f1e6", "flag-tc": "1f1f9-1f1e8", "turks_caicos_islands": "1f1f9-1f1e8", "flag-td": "1f1f9-1f1e9", "chad": "1f1f9-1f1e9", "flag-tf": "1f1f9-1f1eb", "french_southern_territories": "1f1f9-1f1eb", "flag-tg": "1f1f9-1f1ec", "togo": "1f1f9-1f1ec", "flag-th": "1f1f9-1f1ed", "thailand": "1f1f9-1f1ed", "flag-tj": "1f1f9-1f1ef", "tajikistan": "1f1f9-1f1ef", "flag-tk": "1f1f9-1f1f0", "tokelau": "1f1f9-1f1f0", "flag-tl": "1f1f9-1f1f1", "timor_leste": "1f1f9-1f1f1", "flag-tm": "1f1f9-1f1f2", "turkmenistan": "1f1f9-1f1f2", "flag-tn": "1f1f9-1f1f3", "tunisia": "1f1f9-1f1f3", "flag-to": "1f1f9-1f1f4", "tonga": "1f1f9-1f1f4", "flag-tr": "1f1f9-1f1f7", "tr": "1f1f9-1f1f7", "flag-tt": "1f1f9-1f1f9", "trinidad_tobago": "1f1f9-1f1f9", "flag-tv": "1f1f9-1f1fb", "tuvalu": "1f1f9-1f1fb", "flag-tw": "1f1f9-1f1fc", "taiwan": "1f1f9-1f1fc", "flag-tz": "1f1f9-1f1ff", "tanzania": "1f1f9-1f1ff", "flag-ua": "1f1fa-1f1e6", "ukraine": "1f1fa-1f1e6", "flag-ug": "1f1fa-1f1ec", "uganda": "1f1fa-1f1ec", "flag-um": "1f1fa-1f1f2", "flag-un": "1f1fa-1f1f3", "us": "1f1fa-1f1f8", "flag-us": "1f1fa-1f1f8", "flag-uy": "1f1fa-1f1fe", "uruguay": "1f1fa-1f1fe", "flag-uz": "1f1fa-1f1ff", "uzbekistan": "1f1fa-1f1ff", "flag-va": "1f1fb-1f1e6", "vatican_city": "1f1fb-1f1e6", "flag-vc": "1f1fb-1f1e8", "st_vincent_grenadines": "1f1fb-1f1e8", "flag-ve": "1f1fb-1f1ea", "venezuela": "1f1fb-1f1ea", "flag-vg": "1f1fb-1f1ec", "british_virgin_islands": "1f1fb-1f1ec", "flag-vi": "1f1fb-1f1ee", "us_virgin_islands": "1f1fb-1f1ee", "flag-vn": "1f1fb-1f1f3", "vietnam": "1f1fb-1f1f3", "flag-vu": "1f1fb-1f1fa", "vanuatu": "1f1fb-1f1fa", "flag-wf": "1f1fc-1f1eb", "wallis_futuna": "1f1fc-1f1eb", "flag-ws": "1f1fc-1f1f8", "samoa": "1f1fc-1f1f8", "flag-xk": "1f1fd-1f1f0", "kosovo": "1f1fd-1f1f0", "flag-ye": "1f1fe-1f1ea", "yemen": "1f1fe-1f1ea", "flag-yt": "1f1fe-1f1f9", "mayotte": "1f1fe-1f1f9", "flag-za": "1f1ff-1f1e6", "south_africa": "1f1ff-1f1e6", "za": "1f1ff-1f1e6", "flag-zm": "1f1ff-1f1f2", "zambia": "1f1ff-1f1f2", "flag-zw": "1f1ff-1f1fc", "zimbabwe": "1f1ff-1f1fc", "flag-england": "1f3f4-e0067-e0062-e0065-e006e-e0067-e007f", "flag-scotland": "1f3f4-e0067-e0062-e0073-e0063-e0074-e007f", "flag-wales": "1f3f4-e0067-e0062-e0077-e006c-e0073-e007f", "santa_light_skin_tone": "1f385-1f3fb", "santa_medium_light_skin_tone": "1f385-1f3fc", "santa_medium_skin_tone": "1f385-1f3fd", "santa_medium_dark_skin_tone": "1f385-1f3fe", "santa_dark_skin_tone": "1f385-1f3ff", "snowboarder_light_skin_tone": "1f3c2-1f3fb", "snowboarder_medium_light_skin_tone": "1f3c2-1f3fc", "snowboarder_medium_skin_tone": "1f3c2-1f3fd", "snowboarder_medium_dark_skin_tone": "1f3c2-1f3fe", "snowboarder_dark_skin_tone": "1f3c2-1f3ff", "woman-running_light_skin_tone": "1f3c3-1f3fb-200d-2640-fe0f", "running_woman_light_skin_tone": "1f3c3-1f3fb-200d-2640-fe0f", "woman-running_medium_light_skin_tone": "1f3c3-1f3fc-200d-2640-fe0f", "running_woman_medium_light_skin_tone": "1f3c3-1f3fc-200d-2640-fe0f", "woman-running_medium_skin_tone": "1f3c3-1f3fd-200d-2640-fe0f", "running_woman_medium_skin_tone": "1f3c3-1f3fd-200d-2640-fe0f", "woman-running_medium_dark_skin_tone": "1f3c3-1f3fe-200d-2640-fe0f", "running_woman_medium_dark_skin_tone": "1f3c3-1f3fe-200d-2640-fe0f", "woman-running_dark_skin_tone": "1f3c3-1f3ff-200d-2640-fe0f", "running_woman_dark_skin_tone": "1f3c3-1f3ff-200d-2640-fe0f", "man-running_light_skin_tone": "1f3c3-1f3fb-200d-2642-fe0f", "running_man_light_skin_tone": "1f3c3-1f3fb-200d-2642-fe0f", "man-running_medium_light_skin_tone": "1f3c3-1f3fc-200d-2642-fe0f", "running_man_medium_light_skin_tone": "1f3c3-1f3fc-200d-2642-fe0f", "man-running_medium_skin_tone": "1f3c3-1f3fd-200d-2642-fe0f", "running_man_medium_skin_tone": "1f3c3-1f3fd-200d-2642-fe0f", "man-running_medium_dark_skin_tone": "1f3c3-1f3fe-200d-2642-fe0f", "running_man_medium_dark_skin_tone": "1f3c3-1f3fe-200d-2642-fe0f", "man-running_dark_skin_tone": "1f3c3-1f3ff-200d-2642-fe0f", "running_man_dark_skin_tone": "1f3c3-1f3ff-200d-2642-fe0f", "runner_light_skin_tone": "1f3c3-1f3fb", "running_light_skin_tone": "1f3c3-1f3fb", "runner_medium_light_skin_tone": "1f3c3-1f3fc", "running_medium_light_skin_tone": "1f3c3-1f3fc", "runner_medium_skin_tone": "1f3c3-1f3fd", "running_medium_skin_tone": "1f3c3-1f3fd", "runner_medium_dark_skin_tone": "1f3c3-1f3fe", "running_medium_dark_skin_tone": "1f3c3-1f3fe", "runner_dark_skin_tone": "1f3c3-1f3ff", "running_dark_skin_tone": "1f3c3-1f3ff", "woman-surfing_light_skin_tone": "1f3c4-1f3fb-200d-2640-fe0f", "surfing_woman_light_skin_tone": "1f3c4-1f3fb-200d-2640-fe0f", "woman-surfing_medium_light_skin_tone": "1f3c4-1f3fc-200d-2640-fe0f", "surfing_woman_medium_light_skin_tone": "1f3c4-1f3fc-200d-2640-fe0f", "woman-surfing_medium_skin_tone": "1f3c4-1f3fd-200d-2640-fe0f", "surfing_woman_medium_skin_tone": "1f3c4-1f3fd-200d-2640-fe0f", "woman-surfing_medium_dark_skin_tone": "1f3c4-1f3fe-200d-2640-fe0f", "surfing_woman_medium_dark_skin_tone": "1f3c4-1f3fe-200d-2640-fe0f", "woman-surfing_dark_skin_tone": "1f3c4-1f3ff-200d-2640-fe0f", "surfing_woman_dark_skin_tone": "1f3c4-1f3ff-200d-2640-fe0f", "man-surfing_light_skin_tone": "1f3c4-1f3fb-200d-2642-fe0f", "surfing_man_light_skin_tone": "1f3c4-1f3fb-200d-2642-fe0f", "man-surfing_medium_light_skin_tone": "1f3c4-1f3fc-200d-2642-fe0f", "surfing_man_medium_light_skin_tone": "1f3c4-1f3fc-200d-2642-fe0f", "man-surfing_medium_skin_tone": "1f3c4-1f3fd-200d-2642-fe0f", "surfing_man_medium_skin_tone": "1f3c4-1f3fd-200d-2642-fe0f", "man-surfing_medium_dark_skin_tone": "1f3c4-1f3fe-200d-2642-fe0f", "surfing_man_medium_dark_skin_tone": "1f3c4-1f3fe-200d-2642-fe0f", "man-surfing_dark_skin_tone": "1f3c4-1f3ff-200d-2642-fe0f", "surfing_man_dark_skin_tone": "1f3c4-1f3ff-200d-2642-fe0f", "surfer_light_skin_tone": "1f3c4-1f3fb", "surfer_medium_light_skin_tone": "1f3c4-1f3fc", "surfer_medium_skin_tone": "1f3c4-1f3fd", "surfer_medium_dark_skin_tone": "1f3c4-1f3fe", "surfer_dark_skin_tone": "1f3c4-1f3ff", "horse_racing_light_skin_tone": "1f3c7-1f3fb", "horse_racing_medium_light_skin_tone": "1f3c7-1f3fc", "horse_racing_medium_skin_tone": "1f3c7-1f3fd", "horse_racing_medium_dark_skin_tone": "1f3c7-1f3fe", "horse_racing_dark_skin_tone": "1f3c7-1f3ff", "woman-swimming_light_skin_tone": "1f3ca-1f3fb-200d-2640-fe0f", "swimming_woman_light_skin_tone": "1f3ca-1f3fb-200d-2640-fe0f", "woman-swimming_medium_light_skin_tone": "1f3ca-1f3fc-200d-2640-fe0f", "swimming_woman_medium_light_skin_tone": "1f3ca-1f3fc-200d-2640-fe0f", "woman-swimming_medium_skin_tone": "1f3ca-1f3fd-200d-2640-fe0f", "swimming_woman_medium_skin_tone": "1f3ca-1f3fd-200d-2640-fe0f", "woman-swimming_medium_dark_skin_tone": "1f3ca-1f3fe-200d-2640-fe0f", "swimming_woman_medium_dark_skin_tone": "1f3ca-1f3fe-200d-2640-fe0f", "woman-swimming_dark_skin_tone": "1f3ca-1f3ff-200d-2640-fe0f", "swimming_woman_dark_skin_tone": "1f3ca-1f3ff-200d-2640-fe0f", "man-swimming_light_skin_tone": "1f3ca-1f3fb-200d-2642-fe0f", "swimming_man_light_skin_tone": "1f3ca-1f3fb-200d-2642-fe0f", "man-swimming_medium_light_skin_tone": "1f3ca-1f3fc-200d-2642-fe0f", "swimming_man_medium_light_skin_tone": "1f3ca-1f3fc-200d-2642-fe0f", "man-swimming_medium_skin_tone": "1f3ca-1f3fd-200d-2642-fe0f", "swimming_man_medium_skin_tone": "1f3ca-1f3fd-200d-2642-fe0f", "man-swimming_medium_dark_skin_tone": "1f3ca-1f3fe-200d-2642-fe0f", "swimming_man_medium_dark_skin_tone": "1f3ca-1f3fe-200d-2642-fe0f", "man-swimming_dark_skin_tone": "1f3ca-1f3ff-200d-2642-fe0f", "swimming_man_dark_skin_tone": "1f3ca-1f3ff-200d-2642-fe0f", "swimmer_light_skin_tone": "1f3ca-1f3fb", "swimmer_medium_light_skin_tone": "1f3ca-1f3fc", "swimmer_medium_skin_tone": "1f3ca-1f3fd", "swimmer_medium_dark_skin_tone": "1f3ca-1f3fe", "swimmer_dark_skin_tone": "1f3ca-1f3ff", "woman-lifting-weights_light_skin_tone": "1f3cb-1f3fb-200d-2640-fe0f", "weight_lifting_woman_light_skin_tone": "1f3cb-1f3fb-200d-2640-fe0f", "woman-lifting-weights_medium_light_skin_tone": "1f3cb-1f3fc-200d-2640-fe0f", "weight_lifting_woman_medium_light_skin_tone": "1f3cb-1f3fc-200d-2640-fe0f", "woman-lifting-weights_medium_skin_tone": "1f3cb-1f3fd-200d-2640-fe0f", "weight_lifting_woman_medium_skin_tone": "1f3cb-1f3fd-200d-2640-fe0f", "woman-lifting-weights_medium_dark_skin_tone": "1f3cb-1f3fe-200d-2640-fe0f", "weight_lifting_woman_medium_dark_skin_tone": "1f3cb-1f3fe-200d-2640-fe0f", "woman-lifting-weights_dark_skin_tone": "1f3cb-1f3ff-200d-2640-fe0f", "weight_lifting_woman_dark_skin_tone": "1f3cb-1f3ff-200d-2640-fe0f", "man-lifting-weights_light_skin_tone": "1f3cb-1f3fb-200d-2642-fe0f", "weight_lifting_man_light_skin_tone": "1f3cb-1f3fb-200d-2642-fe0f", "man-lifting-weights_medium_light_skin_tone": "1f3cb-1f3fc-200d-2642-fe0f", "weight_lifting_man_medium_light_skin_tone": "1f3cb-1f3fc-200d-2642-fe0f", "man-lifting-weights_medium_skin_tone": "1f3cb-1f3fd-200d-2642-fe0f", "weight_lifting_man_medium_skin_tone": "1f3cb-1f3fd-200d-2642-fe0f", "man-lifting-weights_medium_dark_skin_tone": "1f3cb-1f3fe-200d-2642-fe0f", "weight_lifting_man_medium_dark_skin_tone": "1f3cb-1f3fe-200d-2642-fe0f", "man-lifting-weights_dark_skin_tone": "1f3cb-1f3ff-200d-2642-fe0f", "weight_lifting_man_dark_skin_tone": "1f3cb-1f3ff-200d-2642-fe0f", "weight_lifter_light_skin_tone": "1f3cb-1f3fb", "weight_lifter_medium_light_skin_tone": "1f3cb-1f3fc", "weight_lifter_medium_skin_tone": "1f3cb-1f3fd", "weight_lifter_medium_dark_skin_tone": "1f3cb-1f3fe", "weight_lifter_dark_skin_tone": "1f3cb-1f3ff", "woman-golfing_light_skin_tone": "1f3cc-1f3fb-200d-2640-fe0f", "golfing_woman_light_skin_tone": "1f3cc-1f3fb-200d-2640-fe0f", "woman-golfing_medium_light_skin_tone": "1f3cc-1f3fc-200d-2640-fe0f", "golfing_woman_medium_light_skin_tone": "1f3cc-1f3fc-200d-2640-fe0f", "woman-golfing_medium_skin_tone": "1f3cc-1f3fd-200d-2640-fe0f", "golfing_woman_medium_skin_tone": "1f3cc-1f3fd-200d-2640-fe0f", "woman-golfing_medium_dark_skin_tone": "1f3cc-1f3fe-200d-2640-fe0f", "golfing_woman_medium_dark_skin_tone": "1f3cc-1f3fe-200d-2640-fe0f", "woman-golfing_dark_skin_tone": "1f3cc-1f3ff-200d-2640-fe0f", "golfing_woman_dark_skin_tone": "1f3cc-1f3ff-200d-2640-fe0f", "man-golfing_light_skin_tone": "1f3cc-1f3fb-200d-2642-fe0f", "golfing_man_light_skin_tone": "1f3cc-1f3fb-200d-2642-fe0f", "man-golfing_medium_light_skin_tone": "1f3cc-1f3fc-200d-2642-fe0f", "golfing_man_medium_light_skin_tone": "1f3cc-1f3fc-200d-2642-fe0f", "man-golfing_medium_skin_tone": "1f3cc-1f3fd-200d-2642-fe0f", "golfing_man_medium_skin_tone": "1f3cc-1f3fd-200d-2642-fe0f", "man-golfing_medium_dark_skin_tone": "1f3cc-1f3fe-200d-2642-fe0f", "golfing_man_medium_dark_skin_tone": "1f3cc-1f3fe-200d-2642-fe0f", "man-golfing_dark_skin_tone": "1f3cc-1f3ff-200d-2642-fe0f", "golfing_man_dark_skin_tone": "1f3cc-1f3ff-200d-2642-fe0f", "golfer_light_skin_tone": "1f3cc-1f3fb", "golfer_medium_light_skin_tone": "1f3cc-1f3fc", "golfer_medium_skin_tone": "1f3cc-1f3fd", "golfer_medium_dark_skin_tone": "1f3cc-1f3fe", "golfer_dark_skin_tone": "1f3cc-1f3ff", "ear_light_skin_tone": "1f442-1f3fb", "ear_medium_light_skin_tone": "1f442-1f3fc", "ear_medium_skin_tone": "1f442-1f3fd", "ear_medium_dark_skin_tone": "1f442-1f3fe", "ear_dark_skin_tone": "1f442-1f3ff", "nose_light_skin_tone": "1f443-1f3fb", "nose_medium_light_skin_tone": "1f443-1f3fc", "nose_medium_skin_tone": "1f443-1f3fd", "nose_medium_dark_skin_tone": "1f443-1f3fe", "nose_dark_skin_tone": "1f443-1f3ff", "point_up_2_light_skin_tone": "1f446-1f3fb", "point_up_2_medium_light_skin_tone": "1f446-1f3fc", "point_up_2_medium_skin_tone": "1f446-1f3fd", "point_up_2_medium_dark_skin_tone": "1f446-1f3fe", "point_up_2_dark_skin_tone": "1f446-1f3ff", "point_down_light_skin_tone": "1f447-1f3fb", "point_down_medium_light_skin_tone": "1f447-1f3fc", "point_down_medium_skin_tone": "1f447-1f3fd", "point_down_medium_dark_skin_tone": "1f447-1f3fe", "point_down_dark_skin_tone": "1f447-1f3ff", "point_left_light_skin_tone": "1f448-1f3fb", "point_left_medium_light_skin_tone": "1f448-1f3fc", "point_left_medium_skin_tone": "1f448-1f3fd", "point_left_medium_dark_skin_tone": "1f448-1f3fe", "point_left_dark_skin_tone": "1f448-1f3ff", "point_right_light_skin_tone": "1f449-1f3fb", "point_right_medium_light_skin_tone": "1f449-1f3fc", "point_right_medium_skin_tone": "1f449-1f3fd", "point_right_medium_dark_skin_tone": "1f449-1f3fe", "point_right_dark_skin_tone": "1f449-1f3ff", "facepunch_light_skin_tone": "1f44a-1f3fb", "punch_light_skin_tone": "1f44a-1f3fb", "fist_oncoming_light_skin_tone": "1f44a-1f3fb", "facepunch_medium_light_skin_tone": "1f44a-1f3fc", "punch_medium_light_skin_tone": "1f44a-1f3fc", "fist_oncoming_medium_light_skin_tone": "1f44a-1f3fc", "facepunch_medium_skin_tone": "1f44a-1f3fd", "punch_medium_skin_tone": "1f44a-1f3fd", "fist_oncoming_medium_skin_tone": "1f44a-1f3fd", "facepunch_medium_dark_skin_tone": "1f44a-1f3fe", "punch_medium_dark_skin_tone": "1f44a-1f3fe", "fist_oncoming_medium_dark_skin_tone": "1f44a-1f3fe", "facepunch_dark_skin_tone": "1f44a-1f3ff", "punch_dark_skin_tone": "1f44a-1f3ff", "fist_oncoming_dark_skin_tone": "1f44a-1f3ff", "wave_light_skin_tone": "1f44b-1f3fb", "wave_medium_light_skin_tone": "1f44b-1f3fc", "wave_medium_skin_tone": "1f44b-1f3fd", "wave_medium_dark_skin_tone": "1f44b-1f3fe", "wave_dark_skin_tone": "1f44b-1f3ff", "ok_hand_light_skin_tone": "1f44c-1f3fb", "ok_hand_medium_light_skin_tone": "1f44c-1f3fc", "ok_hand_medium_skin_tone": "1f44c-1f3fd", "ok_hand_medium_dark_skin_tone": "1f44c-1f3fe", "ok_hand_dark_skin_tone": "1f44c-1f3ff", "+1_light_skin_tone": "1f44d-1f3fb", "thumbsup_light_skin_tone": "1f44d-1f3fb", "+1_medium_light_skin_tone": "1f44d-1f3fc", "thumbsup_medium_light_skin_tone": "1f44d-1f3fc", "+1_medium_skin_tone": "1f44d-1f3fd", "thumbsup_medium_skin_tone": "1f44d-1f3fd", "+1_medium_dark_skin_tone": "1f44d-1f3fe", "thumbsup_medium_dark_skin_tone": "1f44d-1f3fe", "+1_dark_skin_tone": "1f44d-1f3ff", "thumbsup_dark_skin_tone": "1f44d-1f3ff", "-1_light_skin_tone": "1f44e-1f3fb", "thumbsdown_light_skin_tone": "1f44e-1f3fb", "-1_medium_light_skin_tone": "1f44e-1f3fc", "thumbsdown_medium_light_skin_tone": "1f44e-1f3fc", "-1_medium_skin_tone": "1f44e-1f3fd", "thumbsdown_medium_skin_tone": "1f44e-1f3fd", "-1_medium_dark_skin_tone": "1f44e-1f3fe", "thumbsdown_medium_dark_skin_tone": "1f44e-1f3fe", "-1_dark_skin_tone": "1f44e-1f3ff", "thumbsdown_dark_skin_tone": "1f44e-1f3ff", "clap_light_skin_tone": "1f44f-1f3fb", "clap_medium_light_skin_tone": "1f44f-1f3fc", "clap_medium_skin_tone": "1f44f-1f3fd", "clap_medium_dark_skin_tone": "1f44f-1f3fe", "clap_dark_skin_tone": "1f44f-1f3ff", "open_hands_light_skin_tone": "1f450-1f3fb", "open_hands_medium_light_skin_tone": "1f450-1f3fc", "open_hands_medium_skin_tone": "1f450-1f3fd", "open_hands_medium_dark_skin_tone": "1f450-1f3fe", "open_hands_dark_skin_tone": "1f450-1f3ff", "boy_light_skin_tone": "1f466-1f3fb", "boy_medium_light_skin_tone": "1f466-1f3fc", "boy_medium_skin_tone": "1f466-1f3fd", "boy_medium_dark_skin_tone": "1f466-1f3fe", "boy_dark_skin_tone": "1f466-1f3ff", "girl_light_skin_tone": "1f467-1f3fb", "girl_medium_light_skin_tone": "1f467-1f3fc", "girl_medium_skin_tone": "1f467-1f3fd", "girl_medium_dark_skin_tone": "1f467-1f3fe", "girl_dark_skin_tone": "1f467-1f3ff", "male-farmer_light_skin_tone": "1f468-1f3fb-200d-1f33e", "man_farmer_light_skin_tone": "1f468-1f3fb-200d-1f33e", "male-farmer_medium_light_skin_tone": "1f468-1f3fc-200d-1f33e", "man_farmer_medium_light_skin_tone": "1f468-1f3fc-200d-1f33e", "male-farmer_medium_skin_tone": "1f468-1f3fd-200d-1f33e", "man_farmer_medium_skin_tone": "1f468-1f3fd-200d-1f33e", "male-farmer_medium_dark_skin_tone": "1f468-1f3fe-200d-1f33e", "man_farmer_medium_dark_skin_tone": "1f468-1f3fe-200d-1f33e", "male-farmer_dark_skin_tone": "1f468-1f3ff-200d-1f33e", "man_farmer_dark_skin_tone": "1f468-1f3ff-200d-1f33e", "male-cook_light_skin_tone": "1f468-1f3fb-200d-1f373", "man_cook_light_skin_tone": "1f468-1f3fb-200d-1f373", "male-cook_medium_light_skin_tone": "1f468-1f3fc-200d-1f373", "man_cook_medium_light_skin_tone": "1f468-1f3fc-200d-1f373", "male-cook_medium_skin_tone": "1f468-1f3fd-200d-1f373", "man_cook_medium_skin_tone": "1f468-1f3fd-200d-1f373", "male-cook_medium_dark_skin_tone": "1f468-1f3fe-200d-1f373", "man_cook_medium_dark_skin_tone": "1f468-1f3fe-200d-1f373", "male-cook_dark_skin_tone": "1f468-1f3ff-200d-1f373", "man_cook_dark_skin_tone": "1f468-1f3ff-200d-1f373", "man_feeding_baby_light_skin_tone": "1f468-1f3fb-200d-1f37c", "man_feeding_baby_medium_light_skin_tone": "1f468-1f3fc-200d-1f37c", "man_feeding_baby_medium_skin_tone": "1f468-1f3fd-200d-1f37c", "man_feeding_baby_medium_dark_skin_tone": "1f468-1f3fe-200d-1f37c", "man_feeding_baby_dark_skin_tone": "1f468-1f3ff-200d-1f37c", "male-student_light_skin_tone": "1f468-1f3fb-200d-1f393", "man_student_light_skin_tone": "1f468-1f3fb-200d-1f393", "male-student_medium_light_skin_tone": "1f468-1f3fc-200d-1f393", "man_student_medium_light_skin_tone": "1f468-1f3fc-200d-1f393", "male-student_medium_skin_tone": "1f468-1f3fd-200d-1f393", "man_student_medium_skin_tone": "1f468-1f3fd-200d-1f393", "male-student_medium_dark_skin_tone": "1f468-1f3fe-200d-1f393", "man_student_medium_dark_skin_tone": "1f468-1f3fe-200d-1f393", "male-student_dark_skin_tone": "1f468-1f3ff-200d-1f393", "man_student_dark_skin_tone": "1f468-1f3ff-200d-1f393", "male-singer_light_skin_tone": "1f468-1f3fb-200d-1f3a4", "man_singer_light_skin_tone": "1f468-1f3fb-200d-1f3a4", "male-singer_medium_light_skin_tone": "1f468-1f3fc-200d-1f3a4", "man_singer_medium_light_skin_tone": "1f468-1f3fc-200d-1f3a4", "male-singer_medium_skin_tone": "1f468-1f3fd-200d-1f3a4", "man_singer_medium_skin_tone": "1f468-1f3fd-200d-1f3a4", "male-singer_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3a4", "man_singer_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3a4", "male-singer_dark_skin_tone": "1f468-1f3ff-200d-1f3a4", "man_singer_dark_skin_tone": "1f468-1f3ff-200d-1f3a4", "male-artist_light_skin_tone": "1f468-1f3fb-200d-1f3a8", "man_artist_light_skin_tone": "1f468-1f3fb-200d-1f3a8", "male-artist_medium_light_skin_tone": "1f468-1f3fc-200d-1f3a8", "man_artist_medium_light_skin_tone": "1f468-1f3fc-200d-1f3a8", "male-artist_medium_skin_tone": "1f468-1f3fd-200d-1f3a8", "man_artist_medium_skin_tone": "1f468-1f3fd-200d-1f3a8", "male-artist_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3a8", "man_artist_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3a8", "male-artist_dark_skin_tone": "1f468-1f3ff-200d-1f3a8", "man_artist_dark_skin_tone": "1f468-1f3ff-200d-1f3a8", "male-teacher_light_skin_tone": "1f468-1f3fb-200d-1f3eb", "man_teacher_light_skin_tone": "1f468-1f3fb-200d-1f3eb", "male-teacher_medium_light_skin_tone": "1f468-1f3fc-200d-1f3eb", "man_teacher_medium_light_skin_tone": "1f468-1f3fc-200d-1f3eb", "male-teacher_medium_skin_tone": "1f468-1f3fd-200d-1f3eb", "man_teacher_medium_skin_tone": "1f468-1f3fd-200d-1f3eb", "male-teacher_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3eb", "man_teacher_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3eb", "male-teacher_dark_skin_tone": "1f468-1f3ff-200d-1f3eb", "man_teacher_dark_skin_tone": "1f468-1f3ff-200d-1f3eb", "male-factory-worker_light_skin_tone": "1f468-1f3fb-200d-1f3ed", "man_factory_worker_light_skin_tone": "1f468-1f3fb-200d-1f3ed", "male-factory-worker_medium_light_skin_tone": "1f468-1f3fc-200d-1f3ed", "man_factory_worker_medium_light_skin_tone": "1f468-1f3fc-200d-1f3ed", "male-factory-worker_medium_skin_tone": "1f468-1f3fd-200d-1f3ed", "man_factory_worker_medium_skin_tone": "1f468-1f3fd-200d-1f3ed", "male-factory-worker_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3ed", "man_factory_worker_medium_dark_skin_tone": "1f468-1f3fe-200d-1f3ed", "male-factory-worker_dark_skin_tone": "1f468-1f3ff-200d-1f3ed", "man_factory_worker_dark_skin_tone": "1f468-1f3ff-200d-1f3ed", "male-technologist_light_skin_tone": "1f468-1f3fb-200d-1f4bb", "man_technologist_light_skin_tone": "1f468-1f3fb-200d-1f4bb", "male-technologist_medium_light_skin_tone": "1f468-1f3fc-200d-1f4bb", "man_technologist_medium_light_skin_tone": "1f468-1f3fc-200d-1f4bb", "male-technologist_medium_skin_tone": "1f468-1f3fd-200d-1f4bb", "man_technologist_medium_skin_tone": "1f468-1f3fd-200d-1f4bb", "male-technologist_medium_dark_skin_tone": "1f468-1f3fe-200d-1f4bb", "man_technologist_medium_dark_skin_tone": "1f468-1f3fe-200d-1f4bb", "male-technologist_dark_skin_tone": "1f468-1f3ff-200d-1f4bb", "man_technologist_dark_skin_tone": "1f468-1f3ff-200d-1f4bb", "male-office-worker_light_skin_tone": "1f468-1f3fb-200d-1f4bc", "man_office_worker_light_skin_tone": "1f468-1f3fb-200d-1f4bc", "male-office-worker_medium_light_skin_tone": "1f468-1f3fc-200d-1f4bc", "man_office_worker_medium_light_skin_tone": "1f468-1f3fc-200d-1f4bc", "male-office-worker_medium_skin_tone": "1f468-1f3fd-200d-1f4bc", "man_office_worker_medium_skin_tone": "1f468-1f3fd-200d-1f4bc", "male-office-worker_medium_dark_skin_tone": "1f468-1f3fe-200d-1f4bc", "man_office_worker_medium_dark_skin_tone": "1f468-1f3fe-200d-1f4bc", "male-office-worker_dark_skin_tone": "1f468-1f3ff-200d-1f4bc", "man_office_worker_dark_skin_tone": "1f468-1f3ff-200d-1f4bc", "male-mechanic_light_skin_tone": "1f468-1f3fb-200d-1f527", "man_mechanic_light_skin_tone": "1f468-1f3fb-200d-1f527", "male-mechanic_medium_light_skin_tone": "1f468-1f3fc-200d-1f527", "man_mechanic_medium_light_skin_tone": "1f468-1f3fc-200d-1f527", "male-mechanic_medium_skin_tone": "1f468-1f3fd-200d-1f527", "man_mechanic_medium_skin_tone": "1f468-1f3fd-200d-1f527", "male-mechanic_medium_dark_skin_tone": "1f468-1f3fe-200d-1f527", "man_mechanic_medium_dark_skin_tone": "1f468-1f3fe-200d-1f527", "male-mechanic_dark_skin_tone": "1f468-1f3ff-200d-1f527", "man_mechanic_dark_skin_tone": "1f468-1f3ff-200d-1f527", "male-scientist_light_skin_tone": "1f468-1f3fb-200d-1f52c", "man_scientist_light_skin_tone": "1f468-1f3fb-200d-1f52c", "male-scientist_medium_light_skin_tone": "1f468-1f3fc-200d-1f52c", "man_scientist_medium_light_skin_tone": "1f468-1f3fc-200d-1f52c", "male-scientist_medium_skin_tone": "1f468-1f3fd-200d-1f52c", "man_scientist_medium_skin_tone": "1f468-1f3fd-200d-1f52c", "male-scientist_medium_dark_skin_tone": "1f468-1f3fe-200d-1f52c", "man_scientist_medium_dark_skin_tone": "1f468-1f3fe-200d-1f52c", "male-scientist_dark_skin_tone": "1f468-1f3ff-200d-1f52c", "man_scientist_dark_skin_tone": "1f468-1f3ff-200d-1f52c", "male-astronaut_light_skin_tone": "1f468-1f3fb-200d-1f680", "man_astronaut_light_skin_tone": "1f468-1f3fb-200d-1f680", "male-astronaut_medium_light_skin_tone": "1f468-1f3fc-200d-1f680", "man_astronaut_medium_light_skin_tone": "1f468-1f3fc-200d-1f680", "male-astronaut_medium_skin_tone": "1f468-1f3fd-200d-1f680", "man_astronaut_medium_skin_tone": "1f468-1f3fd-200d-1f680", "male-astronaut_medium_dark_skin_tone": "1f468-1f3fe-200d-1f680", "man_astronaut_medium_dark_skin_tone": "1f468-1f3fe-200d-1f680", "male-astronaut_dark_skin_tone": "1f468-1f3ff-200d-1f680", "man_astronaut_dark_skin_tone": "1f468-1f3ff-200d-1f680", "male-firefighter_light_skin_tone": "1f468-1f3fb-200d-1f692", "man_firefighter_light_skin_tone": "1f468-1f3fb-200d-1f692", "male-firefighter_medium_light_skin_tone": "1f468-1f3fc-200d-1f692", "man_firefighter_medium_light_skin_tone": "1f468-1f3fc-200d-1f692", "male-firefighter_medium_skin_tone": "1f468-1f3fd-200d-1f692", "man_firefighter_medium_skin_tone": "1f468-1f3fd-200d-1f692", "male-firefighter_medium_dark_skin_tone": "1f468-1f3fe-200d-1f692", "man_firefighter_medium_dark_skin_tone": "1f468-1f3fe-200d-1f692", "male-firefighter_dark_skin_tone": "1f468-1f3ff-200d-1f692", "man_firefighter_dark_skin_tone": "1f468-1f3ff-200d-1f692", "man_with_probing_cane_light_skin_tone": "1f468-1f3fb-200d-1f9af", "man_with_probing_cane_medium_light_skin_tone": "1f468-1f3fc-200d-1f9af", "man_with_probing_cane_medium_skin_tone": "1f468-1f3fd-200d-1f9af", "man_with_probing_cane_medium_dark_skin_tone": "1f468-1f3fe-200d-1f9af", "man_with_probing_cane_dark_skin_tone": "1f468-1f3ff-200d-1f9af", "red_haired_man_light_skin_tone": "1f468-1f3fb-200d-1f9b0", "red_haired_man_medium_light_skin_tone": "1f468-1f3fc-200d-1f9b0", "red_haired_man_medium_skin_tone": "1f468-1f3fd-200d-1f9b0", "red_haired_man_medium_dark_skin_tone": "1f468-1f3fe-200d-1f9b0", "red_haired_man_dark_skin_tone": "1f468-1f3ff-200d-1f9b0", "curly_haired_man_light_skin_tone": "1f468-1f3fb-200d-1f9b1", "curly_haired_man_medium_light_skin_tone": "1f468-1f3fc-200d-1f9b1", "curly_haired_man_medium_skin_tone": "1f468-1f3fd-200d-1f9b1", "curly_haired_man_medium_dark_skin_tone": "1f468-1f3fe-200d-1f9b1", "curly_haired_man_dark_skin_tone": "1f468-1f3ff-200d-1f9b1", "bald_man_light_skin_tone": "1f468-1f3fb-200d-1f9b2", "bald_man_medium_light_skin_tone": "1f468-1f3fc-200d-1f9b2", "bald_man_medium_skin_tone": "1f468-1f3fd-200d-1f9b2", "bald_man_medium_dark_skin_tone": "1f468-1f3fe-200d-1f9b2", "bald_man_dark_skin_tone": "1f468-1f3ff-200d-1f9b2", "white_haired_man_light_skin_tone": "1f468-1f3fb-200d-1f9b3", "white_haired_man_medium_light_skin_tone": "1f468-1f3fc-200d-1f9b3", "white_haired_man_medium_skin_tone": "1f468-1f3fd-200d-1f9b3", "white_haired_man_medium_dark_skin_tone": "1f468-1f3fe-200d-1f9b3", "white_haired_man_dark_skin_tone": "1f468-1f3ff-200d-1f9b3", "man_in_motorized_wheelchair_light_skin_tone": "1f468-1f3fb-200d-1f9bc", "man_in_motorized_wheelchair_medium_light_skin_tone": "1f468-1f3fc-200d-1f9bc", "man_in_motorized_wheelchair_medium_skin_tone": "1f468-1f3fd-200d-1f9bc", "man_in_motorized_wheelchair_medium_dark_skin_tone": "1f468-1f3fe-200d-1f9bc", "man_in_motorized_wheelchair_dark_skin_tone": "1f468-1f3ff-200d-1f9bc", "man_in_manual_wheelchair_light_skin_tone": "1f468-1f3fb-200d-1f9bd", "man_in_manual_wheelchair_medium_light_skin_tone": "1f468-1f3fc-200d-1f9bd", "man_in_manual_wheelchair_medium_skin_tone": "1f468-1f3fd-200d-1f9bd", "man_in_manual_wheelchair_medium_dark_skin_tone": "1f468-1f3fe-200d-1f9bd", "man_in_manual_wheelchair_dark_skin_tone": "1f468-1f3ff-200d-1f9bd", "male-doctor_light_skin_tone": "1f468-1f3fb-200d-2695-fe0f", "man_health_worker_light_skin_tone": "1f468-1f3fb-200d-2695-fe0f", "male-doctor_medium_light_skin_tone": "1f468-1f3fc-200d-2695-fe0f", "man_health_worker_medium_light_skin_tone": "1f468-1f3fc-200d-2695-fe0f", "male-doctor_medium_skin_tone": "1f468-1f3fd-200d-2695-fe0f", "man_health_worker_medium_skin_tone": "1f468-1f3fd-200d-2695-fe0f", "male-doctor_medium_dark_skin_tone": "1f468-1f3fe-200d-2695-fe0f", "man_health_worker_medium_dark_skin_tone": "1f468-1f3fe-200d-2695-fe0f", "male-doctor_dark_skin_tone": "1f468-1f3ff-200d-2695-fe0f", "man_health_worker_dark_skin_tone": "1f468-1f3ff-200d-2695-fe0f", "male-judge_light_skin_tone": "1f468-1f3fb-200d-2696-fe0f", "man_judge_light_skin_tone": "1f468-1f3fb-200d-2696-fe0f", "male-judge_medium_light_skin_tone": "1f468-1f3fc-200d-2696-fe0f", "man_judge_medium_light_skin_tone": "1f468-1f3fc-200d-2696-fe0f", "male-judge_medium_skin_tone": "1f468-1f3fd-200d-2696-fe0f", "man_judge_medium_skin_tone": "1f468-1f3fd-200d-2696-fe0f", "male-judge_medium_dark_skin_tone": "1f468-1f3fe-200d-2696-fe0f", "man_judge_medium_dark_skin_tone": "1f468-1f3fe-200d-2696-fe0f", "male-judge_dark_skin_tone": "1f468-1f3ff-200d-2696-fe0f", "man_judge_dark_skin_tone": "1f468-1f3ff-200d-2696-fe0f", "male-pilot_light_skin_tone": "1f468-1f3fb-200d-2708-fe0f", "man_pilot_light_skin_tone": "1f468-1f3fb-200d-2708-fe0f", "male-pilot_medium_light_skin_tone": "1f468-1f3fc-200d-2708-fe0f", "man_pilot_medium_light_skin_tone": "1f468-1f3fc-200d-2708-fe0f", "male-pilot_medium_skin_tone": "1f468-1f3fd-200d-2708-fe0f", "man_pilot_medium_skin_tone": "1f468-1f3fd-200d-2708-fe0f", "male-pilot_medium_dark_skin_tone": "1f468-1f3fe-200d-2708-fe0f", "man_pilot_medium_dark_skin_tone": "1f468-1f3fe-200d-2708-fe0f", "male-pilot_dark_skin_tone": "1f468-1f3ff-200d-2708-fe0f", "man_pilot_dark_skin_tone": "1f468-1f3ff-200d-2708-fe0f", "man_light_skin_tone": "1f468-1f3fb", "man_medium_light_skin_tone": "1f468-1f3fc", "man_medium_skin_tone": "1f468-1f3fd", "man_medium_dark_skin_tone": "1f468-1f3fe", "man_dark_skin_tone": "1f468-1f3ff", "female-farmer_light_skin_tone": "1f469-1f3fb-200d-1f33e", "woman_farmer_light_skin_tone": "1f469-1f3fb-200d-1f33e", "female-farmer_medium_light_skin_tone": "1f469-1f3fc-200d-1f33e", "woman_farmer_medium_light_skin_tone": "1f469-1f3fc-200d-1f33e", "female-farmer_medium_skin_tone": "1f469-1f3fd-200d-1f33e", "woman_farmer_medium_skin_tone": "1f469-1f3fd-200d-1f33e", "female-farmer_medium_dark_skin_tone": "1f469-1f3fe-200d-1f33e", "woman_farmer_medium_dark_skin_tone": "1f469-1f3fe-200d-1f33e", "female-farmer_dark_skin_tone": "1f469-1f3ff-200d-1f33e", "woman_farmer_dark_skin_tone": "1f469-1f3ff-200d-1f33e", "female-cook_light_skin_tone": "1f469-1f3fb-200d-1f373", "woman_cook_light_skin_tone": "1f469-1f3fb-200d-1f373", "female-cook_medium_light_skin_tone": "1f469-1f3fc-200d-1f373", "woman_cook_medium_light_skin_tone": "1f469-1f3fc-200d-1f373", "female-cook_medium_skin_tone": "1f469-1f3fd-200d-1f373", "woman_cook_medium_skin_tone": "1f469-1f3fd-200d-1f373", "female-cook_medium_dark_skin_tone": "1f469-1f3fe-200d-1f373", "woman_cook_medium_dark_skin_tone": "1f469-1f3fe-200d-1f373", "female-cook_dark_skin_tone": "1f469-1f3ff-200d-1f373", "woman_cook_dark_skin_tone": "1f469-1f3ff-200d-1f373", "woman_feeding_baby_light_skin_tone": "1f469-1f3fb-200d-1f37c", "woman_feeding_baby_medium_light_skin_tone": "1f469-1f3fc-200d-1f37c", "woman_feeding_baby_medium_skin_tone": "1f469-1f3fd-200d-1f37c", "woman_feeding_baby_medium_dark_skin_tone": "1f469-1f3fe-200d-1f37c", "woman_feeding_baby_dark_skin_tone": "1f469-1f3ff-200d-1f37c", "female-student_light_skin_tone": "1f469-1f3fb-200d-1f393", "woman_student_light_skin_tone": "1f469-1f3fb-200d-1f393", "female-student_medium_light_skin_tone": "1f469-1f3fc-200d-1f393", "woman_student_medium_light_skin_tone": "1f469-1f3fc-200d-1f393", "female-student_medium_skin_tone": "1f469-1f3fd-200d-1f393", "woman_student_medium_skin_tone": "1f469-1f3fd-200d-1f393", "female-student_medium_dark_skin_tone": "1f469-1f3fe-200d-1f393", "woman_student_medium_dark_skin_tone": "1f469-1f3fe-200d-1f393", "female-student_dark_skin_tone": "1f469-1f3ff-200d-1f393", "woman_student_dark_skin_tone": "1f469-1f3ff-200d-1f393", "female-singer_light_skin_tone": "1f469-1f3fb-200d-1f3a4", "woman_singer_light_skin_tone": "1f469-1f3fb-200d-1f3a4", "female-singer_medium_light_skin_tone": "1f469-1f3fc-200d-1f3a4", "woman_singer_medium_light_skin_tone": "1f469-1f3fc-200d-1f3a4", "female-singer_medium_skin_tone": "1f469-1f3fd-200d-1f3a4", "woman_singer_medium_skin_tone": "1f469-1f3fd-200d-1f3a4", "female-singer_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3a4", "woman_singer_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3a4", "female-singer_dark_skin_tone": "1f469-1f3ff-200d-1f3a4", "woman_singer_dark_skin_tone": "1f469-1f3ff-200d-1f3a4", "female-artist_light_skin_tone": "1f469-1f3fb-200d-1f3a8", "woman_artist_light_skin_tone": "1f469-1f3fb-200d-1f3a8", "female-artist_medium_light_skin_tone": "1f469-1f3fc-200d-1f3a8", "woman_artist_medium_light_skin_tone": "1f469-1f3fc-200d-1f3a8", "female-artist_medium_skin_tone": "1f469-1f3fd-200d-1f3a8", "woman_artist_medium_skin_tone": "1f469-1f3fd-200d-1f3a8", "female-artist_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3a8", "woman_artist_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3a8", "female-artist_dark_skin_tone": "1f469-1f3ff-200d-1f3a8", "woman_artist_dark_skin_tone": "1f469-1f3ff-200d-1f3a8", "female-teacher_light_skin_tone": "1f469-1f3fb-200d-1f3eb", "woman_teacher_light_skin_tone": "1f469-1f3fb-200d-1f3eb", "female-teacher_medium_light_skin_tone": "1f469-1f3fc-200d-1f3eb", "woman_teacher_medium_light_skin_tone": "1f469-1f3fc-200d-1f3eb", "female-teacher_medium_skin_tone": "1f469-1f3fd-200d-1f3eb", "woman_teacher_medium_skin_tone": "1f469-1f3fd-200d-1f3eb", "female-teacher_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3eb", "woman_teacher_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3eb", "female-teacher_dark_skin_tone": "1f469-1f3ff-200d-1f3eb", "woman_teacher_dark_skin_tone": "1f469-1f3ff-200d-1f3eb", "female-factory-worker_light_skin_tone": "1f469-1f3fb-200d-1f3ed", "woman_factory_worker_light_skin_tone": "1f469-1f3fb-200d-1f3ed", "female-factory-worker_medium_light_skin_tone": "1f469-1f3fc-200d-1f3ed", "woman_factory_worker_medium_light_skin_tone": "1f469-1f3fc-200d-1f3ed", "female-factory-worker_medium_skin_tone": "1f469-1f3fd-200d-1f3ed", "woman_factory_worker_medium_skin_tone": "1f469-1f3fd-200d-1f3ed", "female-factory-worker_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3ed", "woman_factory_worker_medium_dark_skin_tone": "1f469-1f3fe-200d-1f3ed", "female-factory-worker_dark_skin_tone": "1f469-1f3ff-200d-1f3ed", "woman_factory_worker_dark_skin_tone": "1f469-1f3ff-200d-1f3ed", "female-technologist_light_skin_tone": "1f469-1f3fb-200d-1f4bb", "woman_technologist_light_skin_tone": "1f469-1f3fb-200d-1f4bb", "female-technologist_medium_light_skin_tone": "1f469-1f3fc-200d-1f4bb", "woman_technologist_medium_light_skin_tone": "1f469-1f3fc-200d-1f4bb", "female-technologist_medium_skin_tone": "1f469-1f3fd-200d-1f4bb", "woman_technologist_medium_skin_tone": "1f469-1f3fd-200d-1f4bb", "female-technologist_medium_dark_skin_tone": "1f469-1f3fe-200d-1f4bb", "woman_technologist_medium_dark_skin_tone": "1f469-1f3fe-200d-1f4bb", "female-technologist_dark_skin_tone": "1f469-1f3ff-200d-1f4bb", "woman_technologist_dark_skin_tone": "1f469-1f3ff-200d-1f4bb", "female-office-worker_light_skin_tone": "1f469-1f3fb-200d-1f4bc", "woman_office_worker_light_skin_tone": "1f469-1f3fb-200d-1f4bc", "female-office-worker_medium_light_skin_tone": "1f469-1f3fc-200d-1f4bc", "woman_office_worker_medium_light_skin_tone": "1f469-1f3fc-200d-1f4bc", "female-office-worker_medium_skin_tone": "1f469-1f3fd-200d-1f4bc", "woman_office_worker_medium_skin_tone": "1f469-1f3fd-200d-1f4bc", "female-office-worker_medium_dark_skin_tone": "1f469-1f3fe-200d-1f4bc", "woman_office_worker_medium_dark_skin_tone": "1f469-1f3fe-200d-1f4bc", "female-office-worker_dark_skin_tone": "1f469-1f3ff-200d-1f4bc", "woman_office_worker_dark_skin_tone": "1f469-1f3ff-200d-1f4bc", "female-mechanic_light_skin_tone": "1f469-1f3fb-200d-1f527", "woman_mechanic_light_skin_tone": "1f469-1f3fb-200d-1f527", "female-mechanic_medium_light_skin_tone": "1f469-1f3fc-200d-1f527", "woman_mechanic_medium_light_skin_tone": "1f469-1f3fc-200d-1f527", "female-mechanic_medium_skin_tone": "1f469-1f3fd-200d-1f527", "woman_mechanic_medium_skin_tone": "1f469-1f3fd-200d-1f527", "female-mechanic_medium_dark_skin_tone": "1f469-1f3fe-200d-1f527", "woman_mechanic_medium_dark_skin_tone": "1f469-1f3fe-200d-1f527", "female-mechanic_dark_skin_tone": "1f469-1f3ff-200d-1f527", "woman_mechanic_dark_skin_tone": "1f469-1f3ff-200d-1f527", "female-scientist_light_skin_tone": "1f469-1f3fb-200d-1f52c", "woman_scientist_light_skin_tone": "1f469-1f3fb-200d-1f52c", "female-scientist_medium_light_skin_tone": "1f469-1f3fc-200d-1f52c", "woman_scientist_medium_light_skin_tone": "1f469-1f3fc-200d-1f52c", "female-scientist_medium_skin_tone": "1f469-1f3fd-200d-1f52c", "woman_scientist_medium_skin_tone": "1f469-1f3fd-200d-1f52c", "female-scientist_medium_dark_skin_tone": "1f469-1f3fe-200d-1f52c", "woman_scientist_medium_dark_skin_tone": "1f469-1f3fe-200d-1f52c", "female-scientist_dark_skin_tone": "1f469-1f3ff-200d-1f52c", "woman_scientist_dark_skin_tone": "1f469-1f3ff-200d-1f52c", "female-astronaut_light_skin_tone": "1f469-1f3fb-200d-1f680", "woman_astronaut_light_skin_tone": "1f469-1f3fb-200d-1f680", "female-astronaut_medium_light_skin_tone": "1f469-1f3fc-200d-1f680", "woman_astronaut_medium_light_skin_tone": "1f469-1f3fc-200d-1f680", "female-astronaut_medium_skin_tone": "1f469-1f3fd-200d-1f680", "woman_astronaut_medium_skin_tone": "1f469-1f3fd-200d-1f680", "female-astronaut_medium_dark_skin_tone": "1f469-1f3fe-200d-1f680", "woman_astronaut_medium_dark_skin_tone": "1f469-1f3fe-200d-1f680", "female-astronaut_dark_skin_tone": "1f469-1f3ff-200d-1f680", "woman_astronaut_dark_skin_tone": "1f469-1f3ff-200d-1f680", "female-firefighter_light_skin_tone": "1f469-1f3fb-200d-1f692", "woman_firefighter_light_skin_tone": "1f469-1f3fb-200d-1f692", "female-firefighter_medium_light_skin_tone": "1f469-1f3fc-200d-1f692", "woman_firefighter_medium_light_skin_tone": "1f469-1f3fc-200d-1f692", "female-firefighter_medium_skin_tone": "1f469-1f3fd-200d-1f692", "woman_firefighter_medium_skin_tone": "1f469-1f3fd-200d-1f692", "female-firefighter_medium_dark_skin_tone": "1f469-1f3fe-200d-1f692", "woman_firefighter_medium_dark_skin_tone": "1f469-1f3fe-200d-1f692", "female-firefighter_dark_skin_tone": "1f469-1f3ff-200d-1f692", "woman_firefighter_dark_skin_tone": "1f469-1f3ff-200d-1f692", "woman_with_probing_cane_light_skin_tone": "1f469-1f3fb-200d-1f9af", "woman_with_probing_cane_medium_light_skin_tone": "1f469-1f3fc-200d-1f9af", "woman_with_probing_cane_medium_skin_tone": "1f469-1f3fd-200d-1f9af", "woman_with_probing_cane_medium_dark_skin_tone": "1f469-1f3fe-200d-1f9af", "woman_with_probing_cane_dark_skin_tone": "1f469-1f3ff-200d-1f9af", "red_haired_woman_light_skin_tone": "1f469-1f3fb-200d-1f9b0", "red_haired_woman_medium_light_skin_tone": "1f469-1f3fc-200d-1f9b0", "red_haired_woman_medium_skin_tone": "1f469-1f3fd-200d-1f9b0", "red_haired_woman_medium_dark_skin_tone": "1f469-1f3fe-200d-1f9b0", "red_haired_woman_dark_skin_tone": "1f469-1f3ff-200d-1f9b0", "curly_haired_woman_light_skin_tone": "1f469-1f3fb-200d-1f9b1", "curly_haired_woman_medium_light_skin_tone": "1f469-1f3fc-200d-1f9b1", "curly_haired_woman_medium_skin_tone": "1f469-1f3fd-200d-1f9b1", "curly_haired_woman_medium_dark_skin_tone": "1f469-1f3fe-200d-1f9b1", "curly_haired_woman_dark_skin_tone": "1f469-1f3ff-200d-1f9b1", "bald_woman_light_skin_tone": "1f469-1f3fb-200d-1f9b2", "bald_woman_medium_light_skin_tone": "1f469-1f3fc-200d-1f9b2", "bald_woman_medium_skin_tone": "1f469-1f3fd-200d-1f9b2", "bald_woman_medium_dark_skin_tone": "1f469-1f3fe-200d-1f9b2", "bald_woman_dark_skin_tone": "1f469-1f3ff-200d-1f9b2", "white_haired_woman_light_skin_tone": "1f469-1f3fb-200d-1f9b3", "white_haired_woman_medium_light_skin_tone": "1f469-1f3fc-200d-1f9b3", "white_haired_woman_medium_skin_tone": "1f469-1f3fd-200d-1f9b3", "white_haired_woman_medium_dark_skin_tone": "1f469-1f3fe-200d-1f9b3", "white_haired_woman_dark_skin_tone": "1f469-1f3ff-200d-1f9b3", "woman_in_motorized_wheelchair_light_skin_tone": "1f469-1f3fb-200d-1f9bc", "woman_in_motorized_wheelchair_medium_light_skin_tone": "1f469-1f3fc-200d-1f9bc", "woman_in_motorized_wheelchair_medium_skin_tone": "1f469-1f3fd-200d-1f9bc", "woman_in_motorized_wheelchair_medium_dark_skin_tone": "1f469-1f3fe-200d-1f9bc", "woman_in_motorized_wheelchair_dark_skin_tone": "1f469-1f3ff-200d-1f9bc", "woman_in_manual_wheelchair_light_skin_tone": "1f469-1f3fb-200d-1f9bd", "woman_in_manual_wheelchair_medium_light_skin_tone": "1f469-1f3fc-200d-1f9bd", "woman_in_manual_wheelchair_medium_skin_tone": "1f469-1f3fd-200d-1f9bd", "woman_in_manual_wheelchair_medium_dark_skin_tone": "1f469-1f3fe-200d-1f9bd", "woman_in_manual_wheelchair_dark_skin_tone": "1f469-1f3ff-200d-1f9bd", "female-doctor_light_skin_tone": "1f469-1f3fb-200d-2695-fe0f", "woman_health_worker_light_skin_tone": "1f469-1f3fb-200d-2695-fe0f", "female-doctor_medium_light_skin_tone": "1f469-1f3fc-200d-2695-fe0f", "woman_health_worker_medium_light_skin_tone": "1f469-1f3fc-200d-2695-fe0f", "female-doctor_medium_skin_tone": "1f469-1f3fd-200d-2695-fe0f", "woman_health_worker_medium_skin_tone": "1f469-1f3fd-200d-2695-fe0f", "female-doctor_medium_dark_skin_tone": "1f469-1f3fe-200d-2695-fe0f", "woman_health_worker_medium_dark_skin_tone": "1f469-1f3fe-200d-2695-fe0f", "female-doctor_dark_skin_tone": "1f469-1f3ff-200d-2695-fe0f", "woman_health_worker_dark_skin_tone": "1f469-1f3ff-200d-2695-fe0f", "female-judge_light_skin_tone": "1f469-1f3fb-200d-2696-fe0f", "woman_judge_light_skin_tone": "1f469-1f3fb-200d-2696-fe0f", "female-judge_medium_light_skin_tone": "1f469-1f3fc-200d-2696-fe0f", "woman_judge_medium_light_skin_tone": "1f469-1f3fc-200d-2696-fe0f", "female-judge_medium_skin_tone": "1f469-1f3fd-200d-2696-fe0f", "woman_judge_medium_skin_tone": "1f469-1f3fd-200d-2696-fe0f", "female-judge_medium_dark_skin_tone": "1f469-1f3fe-200d-2696-fe0f", "woman_judge_medium_dark_skin_tone": "1f469-1f3fe-200d-2696-fe0f", "female-judge_dark_skin_tone": "1f469-1f3ff-200d-2696-fe0f", "woman_judge_dark_skin_tone": "1f469-1f3ff-200d-2696-fe0f", "female-pilot_light_skin_tone": "1f469-1f3fb-200d-2708-fe0f", "woman_pilot_light_skin_tone": "1f469-1f3fb-200d-2708-fe0f", "female-pilot_medium_light_skin_tone": "1f469-1f3fc-200d-2708-fe0f", "woman_pilot_medium_light_skin_tone": "1f469-1f3fc-200d-2708-fe0f", "female-pilot_medium_skin_tone": "1f469-1f3fd-200d-2708-fe0f", "woman_pilot_medium_skin_tone": "1f469-1f3fd-200d-2708-fe0f", "female-pilot_medium_dark_skin_tone": "1f469-1f3fe-200d-2708-fe0f", "woman_pilot_medium_dark_skin_tone": "1f469-1f3fe-200d-2708-fe0f", "female-pilot_dark_skin_tone": "1f469-1f3ff-200d-2708-fe0f", "woman_pilot_dark_skin_tone": "1f469-1f3ff-200d-2708-fe0f", "woman_light_skin_tone": "1f469-1f3fb", "woman_medium_light_skin_tone": "1f469-1f3fc", "woman_medium_skin_tone": "1f469-1f3fd", "woman_medium_dark_skin_tone": "1f469-1f3fe", "woman_dark_skin_tone": "1f469-1f3ff", "man_and_woman_holding_hands_light_skin_tone": "1f46b-1f3fb", "woman_and_man_holding_hands_light_skin_tone": "1f46b-1f3fb", "couple_light_skin_tone": "1f46b-1f3fb", "man_and_woman_holding_hands_medium_light_skin_tone": "1f46b-1f3fc", "woman_and_man_holding_hands_medium_light_skin_tone": "1f46b-1f3fc", "couple_medium_light_skin_tone": "1f46b-1f3fc", "man_and_woman_holding_hands_medium_skin_tone": "1f46b-1f3fd", "woman_and_man_holding_hands_medium_skin_tone": "1f46b-1f3fd", "couple_medium_skin_tone": "1f46b-1f3fd", "man_and_woman_holding_hands_medium_dark_skin_tone": "1f46b-1f3fe", "woman_and_man_holding_hands_medium_dark_skin_tone": "1f46b-1f3fe", "couple_medium_dark_skin_tone": "1f46b-1f3fe", "man_and_woman_holding_hands_dark_skin_tone": "1f46b-1f3ff", "woman_and_man_holding_hands_dark_skin_tone": "1f46b-1f3ff", "couple_dark_skin_tone": "1f46b-1f3ff", "man_and_woman_holding_hands_light_skin_tone_medium_light_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc", "woman_and_man_holding_hands_light_skin_tone_medium_light_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc", "couple_light_skin_tone_medium_light_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fc", "man_and_woman_holding_hands_light_skin_tone_medium_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd", "woman_and_man_holding_hands_light_skin_tone_medium_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd", "couple_light_skin_tone_medium_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fd", "man_and_woman_holding_hands_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe", "woman_and_man_holding_hands_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe", "couple_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3fe", "man_and_woman_holding_hands_light_skin_tone_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff", "woman_and_man_holding_hands_light_skin_tone_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff", "couple_light_skin_tone_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f468-1f3ff", "man_and_woman_holding_hands_medium_light_skin_tone_light_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb", "woman_and_man_holding_hands_medium_light_skin_tone_light_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb", "couple_medium_light_skin_tone_light_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fb", "man_and_woman_holding_hands_medium_light_skin_tone_medium_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd", "woman_and_man_holding_hands_medium_light_skin_tone_medium_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd", "couple_medium_light_skin_tone_medium_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fd", "man_and_woman_holding_hands_medium_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe", "woman_and_man_holding_hands_medium_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe", "couple_medium_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3fe", "man_and_woman_holding_hands_medium_light_skin_tone_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff", "woman_and_man_holding_hands_medium_light_skin_tone_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff", "couple_medium_light_skin_tone_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f468-1f3ff", "man_and_woman_holding_hands_medium_skin_tone_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb", "woman_and_man_holding_hands_medium_skin_tone_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb", "couple_medium_skin_tone_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fb", "man_and_woman_holding_hands_medium_skin_tone_medium_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc", "woman_and_man_holding_hands_medium_skin_tone_medium_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc", "couple_medium_skin_tone_medium_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fc", "man_and_woman_holding_hands_medium_skin_tone_medium_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe", "woman_and_man_holding_hands_medium_skin_tone_medium_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe", "couple_medium_skin_tone_medium_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3fe", "man_and_woman_holding_hands_medium_skin_tone_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff", "woman_and_man_holding_hands_medium_skin_tone_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff", "couple_medium_skin_tone_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f468-1f3ff", "man_and_woman_holding_hands_medium_dark_skin_tone_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb", "woman_and_man_holding_hands_medium_dark_skin_tone_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb", "couple_medium_dark_skin_tone_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fb", "man_and_woman_holding_hands_medium_dark_skin_tone_medium_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc", "woman_and_man_holding_hands_medium_dark_skin_tone_medium_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc", "couple_medium_dark_skin_tone_medium_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fc", "man_and_woman_holding_hands_medium_dark_skin_tone_medium_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd", "woman_and_man_holding_hands_medium_dark_skin_tone_medium_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd", "couple_medium_dark_skin_tone_medium_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3fd", "man_and_woman_holding_hands_medium_dark_skin_tone_dark_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff", "woman_and_man_holding_hands_medium_dark_skin_tone_dark_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff", "couple_medium_dark_skin_tone_dark_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f468-1f3ff", "man_and_woman_holding_hands_dark_skin_tone_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb", "woman_and_man_holding_hands_dark_skin_tone_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb", "couple_dark_skin_tone_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fb", "man_and_woman_holding_hands_dark_skin_tone_medium_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc", "woman_and_man_holding_hands_dark_skin_tone_medium_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc", "couple_dark_skin_tone_medium_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fc", "man_and_woman_holding_hands_dark_skin_tone_medium_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd", "woman_and_man_holding_hands_dark_skin_tone_medium_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd", "couple_dark_skin_tone_medium_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fd", "man_and_woman_holding_hands_dark_skin_tone_medium_dark_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe", "woman_and_man_holding_hands_dark_skin_tone_medium_dark_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe", "couple_dark_skin_tone_medium_dark_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f468-1f3fe", "two_men_holding_hands_light_skin_tone": "1f46c-1f3fb", "men_holding_hands_light_skin_tone": "1f46c-1f3fb", "two_men_holding_hands_medium_light_skin_tone": "1f46c-1f3fc", "men_holding_hands_medium_light_skin_tone": "1f46c-1f3fc", "two_men_holding_hands_medium_skin_tone": "1f46c-1f3fd", "men_holding_hands_medium_skin_tone": "1f46c-1f3fd", "two_men_holding_hands_medium_dark_skin_tone": "1f46c-1f3fe", "men_holding_hands_medium_dark_skin_tone": "1f46c-1f3fe", "two_men_holding_hands_dark_skin_tone": "1f46c-1f3ff", "men_holding_hands_dark_skin_tone": "1f46c-1f3ff", "two_men_holding_hands_light_skin_tone_medium_light_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc", "men_holding_hands_light_skin_tone_medium_light_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3fc", "two_men_holding_hands_light_skin_tone_medium_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd", "men_holding_hands_light_skin_tone_medium_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3fd", "two_men_holding_hands_light_skin_tone_medium_dark_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe", "men_holding_hands_light_skin_tone_medium_dark_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3fe", "two_men_holding_hands_light_skin_tone_dark_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff", "men_holding_hands_light_skin_tone_dark_skin_tone": "1f468-1f3fb-200d-1f91d-200d-1f468-1f3ff", "two_men_holding_hands_medium_light_skin_tone_light_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb", "men_holding_hands_medium_light_skin_tone_light_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3fb", "two_men_holding_hands_medium_light_skin_tone_medium_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd", "men_holding_hands_medium_light_skin_tone_medium_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3fd", "two_men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe", "men_holding_hands_medium_light_skin_tone_medium_dark_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3fe", "two_men_holding_hands_medium_light_skin_tone_dark_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff", "men_holding_hands_medium_light_skin_tone_dark_skin_tone": "1f468-1f3fc-200d-1f91d-200d-1f468-1f3ff", "two_men_holding_hands_medium_skin_tone_light_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb", "men_holding_hands_medium_skin_tone_light_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3fb", "two_men_holding_hands_medium_skin_tone_medium_light_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc", "men_holding_hands_medium_skin_tone_medium_light_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3fc", "two_men_holding_hands_medium_skin_tone_medium_dark_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe", "men_holding_hands_medium_skin_tone_medium_dark_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3fe", "two_men_holding_hands_medium_skin_tone_dark_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff", "men_holding_hands_medium_skin_tone_dark_skin_tone": "1f468-1f3fd-200d-1f91d-200d-1f468-1f3ff", "two_men_holding_hands_medium_dark_skin_tone_light_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb", "men_holding_hands_medium_dark_skin_tone_light_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3fb", "two_men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc", "men_holding_hands_medium_dark_skin_tone_medium_light_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3fc", "two_men_holding_hands_medium_dark_skin_tone_medium_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd", "men_holding_hands_medium_dark_skin_tone_medium_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3fd", "two_men_holding_hands_medium_dark_skin_tone_dark_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff", "men_holding_hands_medium_dark_skin_tone_dark_skin_tone": "1f468-1f3fe-200d-1f91d-200d-1f468-1f3ff", "two_men_holding_hands_dark_skin_tone_light_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb", "men_holding_hands_dark_skin_tone_light_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fb", "two_men_holding_hands_dark_skin_tone_medium_light_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc", "men_holding_hands_dark_skin_tone_medium_light_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fc", "two_men_holding_hands_dark_skin_tone_medium_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd", "men_holding_hands_dark_skin_tone_medium_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fd", "two_men_holding_hands_dark_skin_tone_medium_dark_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe", "men_holding_hands_dark_skin_tone_medium_dark_skin_tone": "1f468-1f3ff-200d-1f91d-200d-1f468-1f3fe", "two_women_holding_hands_light_skin_tone": "1f46d-1f3fb", "women_holding_hands_light_skin_tone": "1f46d-1f3fb", "two_women_holding_hands_medium_light_skin_tone": "1f46d-1f3fc", "women_holding_hands_medium_light_skin_tone": "1f46d-1f3fc", "two_women_holding_hands_medium_skin_tone": "1f46d-1f3fd", "women_holding_hands_medium_skin_tone": "1f46d-1f3fd", "two_women_holding_hands_medium_dark_skin_tone": "1f46d-1f3fe", "women_holding_hands_medium_dark_skin_tone": "1f46d-1f3fe", "two_women_holding_hands_dark_skin_tone": "1f46d-1f3ff", "women_holding_hands_dark_skin_tone": "1f46d-1f3ff", "two_women_holding_hands_light_skin_tone_medium_light_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc", "women_holding_hands_light_skin_tone_medium_light_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3fc", "two_women_holding_hands_light_skin_tone_medium_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd", "women_holding_hands_light_skin_tone_medium_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3fd", "two_women_holding_hands_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe", "women_holding_hands_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3fe", "two_women_holding_hands_light_skin_tone_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff", "women_holding_hands_light_skin_tone_dark_skin_tone": "1f469-1f3fb-200d-1f91d-200d-1f469-1f3ff", "two_women_holding_hands_medium_light_skin_tone_light_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb", "women_holding_hands_medium_light_skin_tone_light_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3fb", "two_women_holding_hands_medium_light_skin_tone_medium_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd", "women_holding_hands_medium_light_skin_tone_medium_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3fd", "two_women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe", "women_holding_hands_medium_light_skin_tone_medium_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3fe", "two_women_holding_hands_medium_light_skin_tone_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff", "women_holding_hands_medium_light_skin_tone_dark_skin_tone": "1f469-1f3fc-200d-1f91d-200d-1f469-1f3ff", "two_women_holding_hands_medium_skin_tone_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb", "women_holding_hands_medium_skin_tone_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3fb", "two_women_holding_hands_medium_skin_tone_medium_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc", "women_holding_hands_medium_skin_tone_medium_light_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3fc", "two_women_holding_hands_medium_skin_tone_medium_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe", "women_holding_hands_medium_skin_tone_medium_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3fe", "two_women_holding_hands_medium_skin_tone_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff", "women_holding_hands_medium_skin_tone_dark_skin_tone": "1f469-1f3fd-200d-1f91d-200d-1f469-1f3ff", "two_women_holding_hands_medium_dark_skin_tone_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb", "women_holding_hands_medium_dark_skin_tone_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3fb", "two_women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc", "women_holding_hands_medium_dark_skin_tone_medium_light_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3fc", "two_women_holding_hands_medium_dark_skin_tone_medium_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd", "women_holding_hands_medium_dark_skin_tone_medium_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3fd", "two_women_holding_hands_medium_dark_skin_tone_dark_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff", "women_holding_hands_medium_dark_skin_tone_dark_skin_tone": "1f469-1f3fe-200d-1f91d-200d-1f469-1f3ff", "two_women_holding_hands_dark_skin_tone_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb", "women_holding_hands_dark_skin_tone_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fb", "two_women_holding_hands_dark_skin_tone_medium_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc", "women_holding_hands_dark_skin_tone_medium_light_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fc", "two_women_holding_hands_dark_skin_tone_medium_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd", "women_holding_hands_dark_skin_tone_medium_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fd", "two_women_holding_hands_dark_skin_tone_medium_dark_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe", "women_holding_hands_dark_skin_tone_medium_dark_skin_tone": "1f469-1f3ff-200d-1f91d-200d-1f469-1f3fe", "female-police-officer_light_skin_tone": "1f46e-1f3fb-200d-2640-fe0f", "policewoman_light_skin_tone": "1f46e-1f3fb-200d-2640-fe0f", "female-police-officer_medium_light_skin_tone": "1f46e-1f3fc-200d-2640-fe0f", "policewoman_medium_light_skin_tone": "1f46e-1f3fc-200d-2640-fe0f", "female-police-officer_medium_skin_tone": "1f46e-1f3fd-200d-2640-fe0f", "policewoman_medium_skin_tone": "1f46e-1f3fd-200d-2640-fe0f", "female-police-officer_medium_dark_skin_tone": "1f46e-1f3fe-200d-2640-fe0f", "policewoman_medium_dark_skin_tone": "1f46e-1f3fe-200d-2640-fe0f", "female-police-officer_dark_skin_tone": "1f46e-1f3ff-200d-2640-fe0f", "policewoman_dark_skin_tone": "1f46e-1f3ff-200d-2640-fe0f", "male-police-officer_light_skin_tone": "1f46e-1f3fb-200d-2642-fe0f", "policeman_light_skin_tone": "1f46e-1f3fb-200d-2642-fe0f", "male-police-officer_medium_light_skin_tone": "1f46e-1f3fc-200d-2642-fe0f", "policeman_medium_light_skin_tone": "1f46e-1f3fc-200d-2642-fe0f", "male-police-officer_medium_skin_tone": "1f46e-1f3fd-200d-2642-fe0f", "policeman_medium_skin_tone": "1f46e-1f3fd-200d-2642-fe0f", "male-police-officer_medium_dark_skin_tone": "1f46e-1f3fe-200d-2642-fe0f", "policeman_medium_dark_skin_tone": "1f46e-1f3fe-200d-2642-fe0f", "male-police-officer_dark_skin_tone": "1f46e-1f3ff-200d-2642-fe0f", "policeman_dark_skin_tone": "1f46e-1f3ff-200d-2642-fe0f", "cop_light_skin_tone": "1f46e-1f3fb", "cop_medium_light_skin_tone": "1f46e-1f3fc", "cop_medium_skin_tone": "1f46e-1f3fd", "cop_medium_dark_skin_tone": "1f46e-1f3fe", "cop_dark_skin_tone": "1f46e-1f3ff", "woman_with_veil_light_skin_tone": "1f470-1f3fb-200d-2640-fe0f", "woman_with_veil_medium_light_skin_tone": "1f470-1f3fc-200d-2640-fe0f", "woman_with_veil_medium_skin_tone": "1f470-1f3fd-200d-2640-fe0f", "woman_with_veil_medium_dark_skin_tone": "1f470-1f3fe-200d-2640-fe0f", "woman_with_veil_dark_skin_tone": "1f470-1f3ff-200d-2640-fe0f", "man_with_veil_light_skin_tone": "1f470-1f3fb-200d-2642-fe0f", "man_with_veil_medium_light_skin_tone": "1f470-1f3fc-200d-2642-fe0f", "man_with_veil_medium_skin_tone": "1f470-1f3fd-200d-2642-fe0f", "man_with_veil_medium_dark_skin_tone": "1f470-1f3fe-200d-2642-fe0f", "man_with_veil_dark_skin_tone": "1f470-1f3ff-200d-2642-fe0f", "bride_with_veil_light_skin_tone": "1f470-1f3fb", "bride_with_veil_medium_light_skin_tone": "1f470-1f3fc", "bride_with_veil_medium_skin_tone": "1f470-1f3fd", "bride_with_veil_medium_dark_skin_tone": "1f470-1f3fe", "bride_with_veil_dark_skin_tone": "1f470-1f3ff", "blond-haired-woman_light_skin_tone": "1f471-1f3fb-200d-2640-fe0f", "blonde_woman_light_skin_tone": "1f471-1f3fb-200d-2640-fe0f", "blond-haired-woman_medium_light_skin_tone": "1f471-1f3fc-200d-2640-fe0f", "blonde_woman_medium_light_skin_tone": "1f471-1f3fc-200d-2640-fe0f", "blond-haired-woman_medium_skin_tone": "1f471-1f3fd-200d-2640-fe0f", "blonde_woman_medium_skin_tone": "1f471-1f3fd-200d-2640-fe0f", "blond-haired-woman_medium_dark_skin_tone": "1f471-1f3fe-200d-2640-fe0f", "blonde_woman_medium_dark_skin_tone": "1f471-1f3fe-200d-2640-fe0f", "blond-haired-woman_dark_skin_tone": "1f471-1f3ff-200d-2640-fe0f", "blonde_woman_dark_skin_tone": "1f471-1f3ff-200d-2640-fe0f", "blond-haired-man_light_skin_tone": "1f471-1f3fb-200d-2642-fe0f", "blonde_man_light_skin_tone": "1f471-1f3fb-200d-2642-fe0f", "blond-haired-man_medium_light_skin_tone": "1f471-1f3fc-200d-2642-fe0f", "blonde_man_medium_light_skin_tone": "1f471-1f3fc-200d-2642-fe0f", "blond-haired-man_medium_skin_tone": "1f471-1f3fd-200d-2642-fe0f", "blonde_man_medium_skin_tone": "1f471-1f3fd-200d-2642-fe0f", "blond-haired-man_medium_dark_skin_tone": "1f471-1f3fe-200d-2642-fe0f", "blonde_man_medium_dark_skin_tone": "1f471-1f3fe-200d-2642-fe0f", "blond-haired-man_dark_skin_tone": "1f471-1f3ff-200d-2642-fe0f", "blonde_man_dark_skin_tone": "1f471-1f3ff-200d-2642-fe0f", "person_with_blond_hair_light_skin_tone": "1f471-1f3fb", "person_with_blond_hair_medium_light_skin_tone": "1f471-1f3fc", "person_with_blond_hair_medium_skin_tone": "1f471-1f3fd", "person_with_blond_hair_medium_dark_skin_tone": "1f471-1f3fe", "person_with_blond_hair_dark_skin_tone": "1f471-1f3ff", "man_with_gua_pi_mao_light_skin_tone": "1f472-1f3fb", "man_with_gua_pi_mao_medium_light_skin_tone": "1f472-1f3fc", "man_with_gua_pi_mao_medium_skin_tone": "1f472-1f3fd", "man_with_gua_pi_mao_medium_dark_skin_tone": "1f472-1f3fe", "man_with_gua_pi_mao_dark_skin_tone": "1f472-1f3ff", "woman-wearing-turban_light_skin_tone": "1f473-1f3fb-200d-2640-fe0f", "woman_with_turban_light_skin_tone": "1f473-1f3fb-200d-2640-fe0f", "woman-wearing-turban_medium_light_skin_tone": "1f473-1f3fc-200d-2640-fe0f", "woman_with_turban_medium_light_skin_tone": "1f473-1f3fc-200d-2640-fe0f", "woman-wearing-turban_medium_skin_tone": "1f473-1f3fd-200d-2640-fe0f", "woman_with_turban_medium_skin_tone": "1f473-1f3fd-200d-2640-fe0f", "woman-wearing-turban_medium_dark_skin_tone": "1f473-1f3fe-200d-2640-fe0f", "woman_with_turban_medium_dark_skin_tone": "1f473-1f3fe-200d-2640-fe0f", "woman-wearing-turban_dark_skin_tone": "1f473-1f3ff-200d-2640-fe0f", "woman_with_turban_dark_skin_tone": "1f473-1f3ff-200d-2640-fe0f", "man-wearing-turban_light_skin_tone": "1f473-1f3fb-200d-2642-fe0f", "man-wearing-turban_medium_light_skin_tone": "1f473-1f3fc-200d-2642-fe0f", "man-wearing-turban_medium_skin_tone": "1f473-1f3fd-200d-2642-fe0f", "man-wearing-turban_medium_dark_skin_tone": "1f473-1f3fe-200d-2642-fe0f", "man-wearing-turban_dark_skin_tone": "1f473-1f3ff-200d-2642-fe0f", "man_with_turban_light_skin_tone": "1f473-1f3fb", "man_with_turban_medium_light_skin_tone": "1f473-1f3fc", "man_with_turban_medium_skin_tone": "1f473-1f3fd", "man_with_turban_medium_dark_skin_tone": "1f473-1f3fe", "man_with_turban_dark_skin_tone": "1f473-1f3ff", "older_man_light_skin_tone": "1f474-1f3fb", "older_man_medium_light_skin_tone": "1f474-1f3fc", "older_man_medium_skin_tone": "1f474-1f3fd", "older_man_medium_dark_skin_tone": "1f474-1f3fe", "older_man_dark_skin_tone": "1f474-1f3ff", "older_woman_light_skin_tone": "1f475-1f3fb", "older_woman_medium_light_skin_tone": "1f475-1f3fc", "older_woman_medium_skin_tone": "1f475-1f3fd", "older_woman_medium_dark_skin_tone": "1f475-1f3fe", "older_woman_dark_skin_tone": "1f475-1f3ff", "baby_light_skin_tone": "1f476-1f3fb", "baby_medium_light_skin_tone": "1f476-1f3fc", "baby_medium_skin_tone": "1f476-1f3fd", "baby_medium_dark_skin_tone": "1f476-1f3fe", "baby_dark_skin_tone": "1f476-1f3ff", "female-construction-worker_light_skin_tone": "1f477-1f3fb-200d-2640-fe0f", "construction_worker_woman_light_skin_tone": "1f477-1f3fb-200d-2640-fe0f", "female-construction-worker_medium_light_skin_tone": "1f477-1f3fc-200d-2640-fe0f", "construction_worker_woman_medium_light_skin_tone": "1f477-1f3fc-200d-2640-fe0f", "female-construction-worker_medium_skin_tone": "1f477-1f3fd-200d-2640-fe0f", "construction_worker_woman_medium_skin_tone": "1f477-1f3fd-200d-2640-fe0f", "female-construction-worker_medium_dark_skin_tone": "1f477-1f3fe-200d-2640-fe0f", "construction_worker_woman_medium_dark_skin_tone": "1f477-1f3fe-200d-2640-fe0f", "female-construction-worker_dark_skin_tone": "1f477-1f3ff-200d-2640-fe0f", "construction_worker_woman_dark_skin_tone": "1f477-1f3ff-200d-2640-fe0f", "male-construction-worker_light_skin_tone": "1f477-1f3fb-200d-2642-fe0f", "construction_worker_man_light_skin_tone": "1f477-1f3fb-200d-2642-fe0f", "male-construction-worker_medium_light_skin_tone": "1f477-1f3fc-200d-2642-fe0f", "construction_worker_man_medium_light_skin_tone": "1f477-1f3fc-200d-2642-fe0f", "male-construction-worker_medium_skin_tone": "1f477-1f3fd-200d-2642-fe0f", "construction_worker_man_medium_skin_tone": "1f477-1f3fd-200d-2642-fe0f", "male-construction-worker_medium_dark_skin_tone": "1f477-1f3fe-200d-2642-fe0f", "construction_worker_man_medium_dark_skin_tone": "1f477-1f3fe-200d-2642-fe0f", "male-construction-worker_dark_skin_tone": "1f477-1f3ff-200d-2642-fe0f", "construction_worker_man_dark_skin_tone": "1f477-1f3ff-200d-2642-fe0f", "construction_worker_light_skin_tone": "1f477-1f3fb", "construction_worker_medium_light_skin_tone": "1f477-1f3fc", "construction_worker_medium_skin_tone": "1f477-1f3fd", "construction_worker_medium_dark_skin_tone": "1f477-1f3fe", "construction_worker_dark_skin_tone": "1f477-1f3ff", "princess_light_skin_tone": "1f478-1f3fb", "princess_medium_light_skin_tone": "1f478-1f3fc", "princess_medium_skin_tone": "1f478-1f3fd", "princess_medium_dark_skin_tone": "1f478-1f3fe", "princess_dark_skin_tone": "1f478-1f3ff", "angel_light_skin_tone": "1f47c-1f3fb", "angel_medium_light_skin_tone": "1f47c-1f3fc", "angel_medium_skin_tone": "1f47c-1f3fd", "angel_medium_dark_skin_tone": "1f47c-1f3fe", "angel_dark_skin_tone": "1f47c-1f3ff", "woman-tipping-hand_light_skin_tone": "1f481-1f3fb-200d-2640-fe0f", "tipping_hand_woman_light_skin_tone": "1f481-1f3fb-200d-2640-fe0f", "woman-tipping-hand_medium_light_skin_tone": "1f481-1f3fc-200d-2640-fe0f", "tipping_hand_woman_medium_light_skin_tone": "1f481-1f3fc-200d-2640-fe0f", "woman-tipping-hand_medium_skin_tone": "1f481-1f3fd-200d-2640-fe0f", "tipping_hand_woman_medium_skin_tone": "1f481-1f3fd-200d-2640-fe0f", "woman-tipping-hand_medium_dark_skin_tone": "1f481-1f3fe-200d-2640-fe0f", "tipping_hand_woman_medium_dark_skin_tone": "1f481-1f3fe-200d-2640-fe0f", "woman-tipping-hand_dark_skin_tone": "1f481-1f3ff-200d-2640-fe0f", "tipping_hand_woman_dark_skin_tone": "1f481-1f3ff-200d-2640-fe0f", "man-tipping-hand_light_skin_tone": "1f481-1f3fb-200d-2642-fe0f", "tipping_hand_man_light_skin_tone": "1f481-1f3fb-200d-2642-fe0f", "man-tipping-hand_medium_light_skin_tone": "1f481-1f3fc-200d-2642-fe0f", "tipping_hand_man_medium_light_skin_tone": "1f481-1f3fc-200d-2642-fe0f", "man-tipping-hand_medium_skin_tone": "1f481-1f3fd-200d-2642-fe0f", "tipping_hand_man_medium_skin_tone": "1f481-1f3fd-200d-2642-fe0f", "man-tipping-hand_medium_dark_skin_tone": "1f481-1f3fe-200d-2642-fe0f", "tipping_hand_man_medium_dark_skin_tone": "1f481-1f3fe-200d-2642-fe0f", "man-tipping-hand_dark_skin_tone": "1f481-1f3ff-200d-2642-fe0f", "tipping_hand_man_dark_skin_tone": "1f481-1f3ff-200d-2642-fe0f", "information_desk_person_light_skin_tone": "1f481-1f3fb", "information_desk_person_medium_light_skin_tone": "1f481-1f3fc", "information_desk_person_medium_skin_tone": "1f481-1f3fd", "information_desk_person_medium_dark_skin_tone": "1f481-1f3fe", "information_desk_person_dark_skin_tone": "1f481-1f3ff", "female-guard_light_skin_tone": "1f482-1f3fb-200d-2640-fe0f", "guardswoman_light_skin_tone": "1f482-1f3fb-200d-2640-fe0f", "female-guard_medium_light_skin_tone": "1f482-1f3fc-200d-2640-fe0f", "guardswoman_medium_light_skin_tone": "1f482-1f3fc-200d-2640-fe0f", "female-guard_medium_skin_tone": "1f482-1f3fd-200d-2640-fe0f", "guardswoman_medium_skin_tone": "1f482-1f3fd-200d-2640-fe0f", "female-guard_medium_dark_skin_tone": "1f482-1f3fe-200d-2640-fe0f", "guardswoman_medium_dark_skin_tone": "1f482-1f3fe-200d-2640-fe0f", "female-guard_dark_skin_tone": "1f482-1f3ff-200d-2640-fe0f", "guardswoman_dark_skin_tone": "1f482-1f3ff-200d-2640-fe0f", "male-guard_light_skin_tone": "1f482-1f3fb-200d-2642-fe0f", "male-guard_medium_light_skin_tone": "1f482-1f3fc-200d-2642-fe0f", "male-guard_medium_skin_tone": "1f482-1f3fd-200d-2642-fe0f", "male-guard_medium_dark_skin_tone": "1f482-1f3fe-200d-2642-fe0f", "male-guard_dark_skin_tone": "1f482-1f3ff-200d-2642-fe0f", "guardsman_light_skin_tone": "1f482-1f3fb", "guardsman_medium_light_skin_tone": "1f482-1f3fc", "guardsman_medium_skin_tone": "1f482-1f3fd", "guardsman_medium_dark_skin_tone": "1f482-1f3fe", "guardsman_dark_skin_tone": "1f482-1f3ff", "dancer_light_skin_tone": "1f483-1f3fb", "dancer_medium_light_skin_tone": "1f483-1f3fc", "dancer_medium_skin_tone": "1f483-1f3fd", "dancer_medium_dark_skin_tone": "1f483-1f3fe", "dancer_dark_skin_tone": "1f483-1f3ff", "nail_care_light_skin_tone": "1f485-1f3fb", "nail_care_medium_light_skin_tone": "1f485-1f3fc", "nail_care_medium_skin_tone": "1f485-1f3fd", "nail_care_medium_dark_skin_tone": "1f485-1f3fe", "nail_care_dark_skin_tone": "1f485-1f3ff", "woman-getting-massage_light_skin_tone": "1f486-1f3fb-200d-2640-fe0f", "massage_woman_light_skin_tone": "1f486-1f3fb-200d-2640-fe0f", "woman-getting-massage_medium_light_skin_tone": "1f486-1f3fc-200d-2640-fe0f", "massage_woman_medium_light_skin_tone": "1f486-1f3fc-200d-2640-fe0f", "woman-getting-massage_medium_skin_tone": "1f486-1f3fd-200d-2640-fe0f", "massage_woman_medium_skin_tone": "1f486-1f3fd-200d-2640-fe0f", "woman-getting-massage_medium_dark_skin_tone": "1f486-1f3fe-200d-2640-fe0f", "massage_woman_medium_dark_skin_tone": "1f486-1f3fe-200d-2640-fe0f", "woman-getting-massage_dark_skin_tone": "1f486-1f3ff-200d-2640-fe0f", "massage_woman_dark_skin_tone": "1f486-1f3ff-200d-2640-fe0f", "man-getting-massage_light_skin_tone": "1f486-1f3fb-200d-2642-fe0f", "massage_man_light_skin_tone": "1f486-1f3fb-200d-2642-fe0f", "man-getting-massage_medium_light_skin_tone": "1f486-1f3fc-200d-2642-fe0f", "massage_man_medium_light_skin_tone": "1f486-1f3fc-200d-2642-fe0f", "man-getting-massage_medium_skin_tone": "1f486-1f3fd-200d-2642-fe0f", "massage_man_medium_skin_tone": "1f486-1f3fd-200d-2642-fe0f", "man-getting-massage_medium_dark_skin_tone": "1f486-1f3fe-200d-2642-fe0f", "massage_man_medium_dark_skin_tone": "1f486-1f3fe-200d-2642-fe0f", "man-getting-massage_dark_skin_tone": "1f486-1f3ff-200d-2642-fe0f", "massage_man_dark_skin_tone": "1f486-1f3ff-200d-2642-fe0f", "massage_light_skin_tone": "1f486-1f3fb", "massage_medium_light_skin_tone": "1f486-1f3fc", "massage_medium_skin_tone": "1f486-1f3fd", "massage_medium_dark_skin_tone": "1f486-1f3fe", "massage_dark_skin_tone": "1f486-1f3ff", "woman-getting-haircut_light_skin_tone": "1f487-1f3fb-200d-2640-fe0f", "haircut_woman_light_skin_tone": "1f487-1f3fb-200d-2640-fe0f", "woman-getting-haircut_medium_light_skin_tone": "1f487-1f3fc-200d-2640-fe0f", "haircut_woman_medium_light_skin_tone": "1f487-1f3fc-200d-2640-fe0f", "woman-getting-haircut_medium_skin_tone": "1f487-1f3fd-200d-2640-fe0f", "haircut_woman_medium_skin_tone": "1f487-1f3fd-200d-2640-fe0f", "woman-getting-haircut_medium_dark_skin_tone": "1f487-1f3fe-200d-2640-fe0f", "haircut_woman_medium_dark_skin_tone": "1f487-1f3fe-200d-2640-fe0f", "woman-getting-haircut_dark_skin_tone": "1f487-1f3ff-200d-2640-fe0f", "haircut_woman_dark_skin_tone": "1f487-1f3ff-200d-2640-fe0f", "man-getting-haircut_light_skin_tone": "1f487-1f3fb-200d-2642-fe0f", "haircut_man_light_skin_tone": "1f487-1f3fb-200d-2642-fe0f", "man-getting-haircut_medium_light_skin_tone": "1f487-1f3fc-200d-2642-fe0f", "haircut_man_medium_light_skin_tone": "1f487-1f3fc-200d-2642-fe0f", "man-getting-haircut_medium_skin_tone": "1f487-1f3fd-200d-2642-fe0f", "haircut_man_medium_skin_tone": "1f487-1f3fd-200d-2642-fe0f", "man-getting-haircut_medium_dark_skin_tone": "1f487-1f3fe-200d-2642-fe0f", "haircut_man_medium_dark_skin_tone": "1f487-1f3fe-200d-2642-fe0f", "man-getting-haircut_dark_skin_tone": "1f487-1f3ff-200d-2642-fe0f", "haircut_man_dark_skin_tone": "1f487-1f3ff-200d-2642-fe0f", "haircut_light_skin_tone": "1f487-1f3fb", "haircut_medium_light_skin_tone": "1f487-1f3fc", "haircut_medium_skin_tone": "1f487-1f3fd", "haircut_medium_dark_skin_tone": "1f487-1f3fe", "haircut_dark_skin_tone": "1f487-1f3ff", "muscle_light_skin_tone": "1f4aa-1f3fb", "muscle_medium_light_skin_tone": "1f4aa-1f3fc", "muscle_medium_skin_tone": "1f4aa-1f3fd", "muscle_medium_dark_skin_tone": "1f4aa-1f3fe", "muscle_dark_skin_tone": "1f4aa-1f3ff", "man_in_business_suit_levitating_light_skin_tone": "1f574-1f3fb", "business_suit_levitating_light_skin_tone": "1f574-1f3fb", "man_in_business_suit_levitating_medium_light_skin_tone": "1f574-1f3fc", "business_suit_levitating_medium_light_skin_tone": "1f574-1f3fc", "man_in_business_suit_levitating_medium_skin_tone": "1f574-1f3fd", "business_suit_levitating_medium_skin_tone": "1f574-1f3fd", "man_in_business_suit_levitating_medium_dark_skin_tone": "1f574-1f3fe", "business_suit_levitating_medium_dark_skin_tone": "1f574-1f3fe", "man_in_business_suit_levitating_dark_skin_tone": "1f574-1f3ff", "business_suit_levitating_dark_skin_tone": "1f574-1f3ff", "female-detective_light_skin_tone": "1f575-1f3fb-200d-2640-fe0f", "female_detective_light_skin_tone": "1f575-1f3fb-200d-2640-fe0f", "female-detective_medium_light_skin_tone": "1f575-1f3fc-200d-2640-fe0f", "female_detective_medium_light_skin_tone": "1f575-1f3fc-200d-2640-fe0f", "female-detective_medium_skin_tone": "1f575-1f3fd-200d-2640-fe0f", "female_detective_medium_skin_tone": "1f575-1f3fd-200d-2640-fe0f", "female-detective_medium_dark_skin_tone": "1f575-1f3fe-200d-2640-fe0f", "female_detective_medium_dark_skin_tone": "1f575-1f3fe-200d-2640-fe0f", "female-detective_dark_skin_tone": "1f575-1f3ff-200d-2640-fe0f", "female_detective_dark_skin_tone": "1f575-1f3ff-200d-2640-fe0f", "male-detective_light_skin_tone": "1f575-1f3fb-200d-2642-fe0f", "male_detective_light_skin_tone": "1f575-1f3fb-200d-2642-fe0f", "male-detective_medium_light_skin_tone": "1f575-1f3fc-200d-2642-fe0f", "male_detective_medium_light_skin_tone": "1f575-1f3fc-200d-2642-fe0f", "male-detective_medium_skin_tone": "1f575-1f3fd-200d-2642-fe0f", "male_detective_medium_skin_tone": "1f575-1f3fd-200d-2642-fe0f", "male-detective_medium_dark_skin_tone": "1f575-1f3fe-200d-2642-fe0f", "male_detective_medium_dark_skin_tone": "1f575-1f3fe-200d-2642-fe0f", "male-detective_dark_skin_tone": "1f575-1f3ff-200d-2642-fe0f", "male_detective_dark_skin_tone": "1f575-1f3ff-200d-2642-fe0f", "sleuth_or_spy_light_skin_tone": "1f575-1f3fb", "sleuth_or_spy_medium_light_skin_tone": "1f575-1f3fc", "sleuth_or_spy_medium_skin_tone": "1f575-1f3fd", "sleuth_or_spy_medium_dark_skin_tone": "1f575-1f3fe", "sleuth_or_spy_dark_skin_tone": "1f575-1f3ff", "man_dancing_light_skin_tone": "1f57a-1f3fb", "man_dancing_medium_light_skin_tone": "1f57a-1f3fc", "man_dancing_medium_skin_tone": "1f57a-1f3fd", "man_dancing_medium_dark_skin_tone": "1f57a-1f3fe", "man_dancing_dark_skin_tone": "1f57a-1f3ff", "raised_hand_with_fingers_splayed_light_skin_tone": "1f590-1f3fb", "raised_hand_with_fingers_splayed_medium_light_skin_tone": "1f590-1f3fc", "raised_hand_with_fingers_splayed_medium_skin_tone": "1f590-1f3fd", "raised_hand_with_fingers_splayed_medium_dark_skin_tone": "1f590-1f3fe", "raised_hand_with_fingers_splayed_dark_skin_tone": "1f590-1f3ff", "middle_finger_light_skin_tone": "1f595-1f3fb", "reversed_hand_with_middle_finger_extended_light_skin_tone": "1f595-1f3fb", "middle_finger_medium_light_skin_tone": "1f595-1f3fc", "reversed_hand_with_middle_finger_extended_medium_light_skin_tone": "1f595-1f3fc", "middle_finger_medium_skin_tone": "1f595-1f3fd", "reversed_hand_with_middle_finger_extended_medium_skin_tone": "1f595-1f3fd", "middle_finger_medium_dark_skin_tone": "1f595-1f3fe", "reversed_hand_with_middle_finger_extended_medium_dark_skin_tone": "1f595-1f3fe", "middle_finger_dark_skin_tone": "1f595-1f3ff", "reversed_hand_with_middle_finger_extended_dark_skin_tone": "1f595-1f3ff", "spock-hand_light_skin_tone": "1f596-1f3fb", "vulcan_salute_light_skin_tone": "1f596-1f3fb", "spock-hand_medium_light_skin_tone": "1f596-1f3fc", "vulcan_salute_medium_light_skin_tone": "1f596-1f3fc", "spock-hand_medium_skin_tone": "1f596-1f3fd", "vulcan_salute_medium_skin_tone": "1f596-1f3fd", "spock-hand_medium_dark_skin_tone": "1f596-1f3fe", "vulcan_salute_medium_dark_skin_tone": "1f596-1f3fe", "spock-hand_dark_skin_tone": "1f596-1f3ff", "vulcan_salute_dark_skin_tone": "1f596-1f3ff", "woman-gesturing-no_light_skin_tone": "1f645-1f3fb-200d-2640-fe0f", "no_good_woman_light_skin_tone": "1f645-1f3fb-200d-2640-fe0f", "woman-gesturing-no_medium_light_skin_tone": "1f645-1f3fc-200d-2640-fe0f", "no_good_woman_medium_light_skin_tone": "1f645-1f3fc-200d-2640-fe0f", "woman-gesturing-no_medium_skin_tone": "1f645-1f3fd-200d-2640-fe0f", "no_good_woman_medium_skin_tone": "1f645-1f3fd-200d-2640-fe0f", "woman-gesturing-no_medium_dark_skin_tone": "1f645-1f3fe-200d-2640-fe0f", "no_good_woman_medium_dark_skin_tone": "1f645-1f3fe-200d-2640-fe0f", "woman-gesturing-no_dark_skin_tone": "1f645-1f3ff-200d-2640-fe0f", "no_good_woman_dark_skin_tone": "1f645-1f3ff-200d-2640-fe0f", "man-gesturing-no_light_skin_tone": "1f645-1f3fb-200d-2642-fe0f", "no_good_man_light_skin_tone": "1f645-1f3fb-200d-2642-fe0f", "man-gesturing-no_medium_light_skin_tone": "1f645-1f3fc-200d-2642-fe0f", "no_good_man_medium_light_skin_tone": "1f645-1f3fc-200d-2642-fe0f", "man-gesturing-no_medium_skin_tone": "1f645-1f3fd-200d-2642-fe0f", "no_good_man_medium_skin_tone": "1f645-1f3fd-200d-2642-fe0f", "man-gesturing-no_medium_dark_skin_tone": "1f645-1f3fe-200d-2642-fe0f", "no_good_man_medium_dark_skin_tone": "1f645-1f3fe-200d-2642-fe0f", "man-gesturing-no_dark_skin_tone": "1f645-1f3ff-200d-2642-fe0f", "no_good_man_dark_skin_tone": "1f645-1f3ff-200d-2642-fe0f", "no_good_light_skin_tone": "1f645-1f3fb", "no_good_medium_light_skin_tone": "1f645-1f3fc", "no_good_medium_skin_tone": "1f645-1f3fd", "no_good_medium_dark_skin_tone": "1f645-1f3fe", "no_good_dark_skin_tone": "1f645-1f3ff", "woman-gesturing-ok_light_skin_tone": "1f646-1f3fb-200d-2640-fe0f", "woman-gesturing-ok_medium_light_skin_tone": "1f646-1f3fc-200d-2640-fe0f", "woman-gesturing-ok_medium_skin_tone": "1f646-1f3fd-200d-2640-fe0f", "woman-gesturing-ok_medium_dark_skin_tone": "1f646-1f3fe-200d-2640-fe0f", "woman-gesturing-ok_dark_skin_tone": "1f646-1f3ff-200d-2640-fe0f", "man-gesturing-ok_light_skin_tone": "1f646-1f3fb-200d-2642-fe0f", "ok_man_light_skin_tone": "1f646-1f3fb-200d-2642-fe0f", "man-gesturing-ok_medium_light_skin_tone": "1f646-1f3fc-200d-2642-fe0f", "ok_man_medium_light_skin_tone": "1f646-1f3fc-200d-2642-fe0f", "man-gesturing-ok_medium_skin_tone": "1f646-1f3fd-200d-2642-fe0f", "ok_man_medium_skin_tone": "1f646-1f3fd-200d-2642-fe0f", "man-gesturing-ok_medium_dark_skin_tone": "1f646-1f3fe-200d-2642-fe0f", "ok_man_medium_dark_skin_tone": "1f646-1f3fe-200d-2642-fe0f", "man-gesturing-ok_dark_skin_tone": "1f646-1f3ff-200d-2642-fe0f", "ok_man_dark_skin_tone": "1f646-1f3ff-200d-2642-fe0f", "ok_woman_light_skin_tone": "1f646-1f3fb", "ok_woman_medium_light_skin_tone": "1f646-1f3fc", "ok_woman_medium_skin_tone": "1f646-1f3fd", "ok_woman_medium_dark_skin_tone": "1f646-1f3fe", "ok_woman_dark_skin_tone": "1f646-1f3ff", "woman-bowing_light_skin_tone": "1f647-1f3fb-200d-2640-fe0f", "bowing_woman_light_skin_tone": "1f647-1f3fb-200d-2640-fe0f", "woman-bowing_medium_light_skin_tone": "1f647-1f3fc-200d-2640-fe0f", "bowing_woman_medium_light_skin_tone": "1f647-1f3fc-200d-2640-fe0f", "woman-bowing_medium_skin_tone": "1f647-1f3fd-200d-2640-fe0f", "bowing_woman_medium_skin_tone": "1f647-1f3fd-200d-2640-fe0f", "woman-bowing_medium_dark_skin_tone": "1f647-1f3fe-200d-2640-fe0f", "bowing_woman_medium_dark_skin_tone": "1f647-1f3fe-200d-2640-fe0f", "woman-bowing_dark_skin_tone": "1f647-1f3ff-200d-2640-fe0f", "bowing_woman_dark_skin_tone": "1f647-1f3ff-200d-2640-fe0f", "man-bowing_light_skin_tone": "1f647-1f3fb-200d-2642-fe0f", "bowing_man_light_skin_tone": "1f647-1f3fb-200d-2642-fe0f", "man-bowing_medium_light_skin_tone": "1f647-1f3fc-200d-2642-fe0f", "bowing_man_medium_light_skin_tone": "1f647-1f3fc-200d-2642-fe0f", "man-bowing_medium_skin_tone": "1f647-1f3fd-200d-2642-fe0f", "bowing_man_medium_skin_tone": "1f647-1f3fd-200d-2642-fe0f", "man-bowing_medium_dark_skin_tone": "1f647-1f3fe-200d-2642-fe0f", "bowing_man_medium_dark_skin_tone": "1f647-1f3fe-200d-2642-fe0f", "man-bowing_dark_skin_tone": "1f647-1f3ff-200d-2642-fe0f", "bowing_man_dark_skin_tone": "1f647-1f3ff-200d-2642-fe0f", "bow_light_skin_tone": "1f647-1f3fb", "bow_medium_light_skin_tone": "1f647-1f3fc", "bow_medium_skin_tone": "1f647-1f3fd", "bow_medium_dark_skin_tone": "1f647-1f3fe", "bow_dark_skin_tone": "1f647-1f3ff", "woman-raising-hand_light_skin_tone": "1f64b-1f3fb-200d-2640-fe0f", "raising_hand_woman_light_skin_tone": "1f64b-1f3fb-200d-2640-fe0f", "woman-raising-hand_medium_light_skin_tone": "1f64b-1f3fc-200d-2640-fe0f", "raising_hand_woman_medium_light_skin_tone": "1f64b-1f3fc-200d-2640-fe0f", "woman-raising-hand_medium_skin_tone": "1f64b-1f3fd-200d-2640-fe0f", "raising_hand_woman_medium_skin_tone": "1f64b-1f3fd-200d-2640-fe0f", "woman-raising-hand_medium_dark_skin_tone": "1f64b-1f3fe-200d-2640-fe0f", "raising_hand_woman_medium_dark_skin_tone": "1f64b-1f3fe-200d-2640-fe0f", "woman-raising-hand_dark_skin_tone": "1f64b-1f3ff-200d-2640-fe0f", "raising_hand_woman_dark_skin_tone": "1f64b-1f3ff-200d-2640-fe0f", "man-raising-hand_light_skin_tone": "1f64b-1f3fb-200d-2642-fe0f", "raising_hand_man_light_skin_tone": "1f64b-1f3fb-200d-2642-fe0f", "man-raising-hand_medium_light_skin_tone": "1f64b-1f3fc-200d-2642-fe0f", "raising_hand_man_medium_light_skin_tone": "1f64b-1f3fc-200d-2642-fe0f", "man-raising-hand_medium_skin_tone": "1f64b-1f3fd-200d-2642-fe0f", "raising_hand_man_medium_skin_tone": "1f64b-1f3fd-200d-2642-fe0f", "man-raising-hand_medium_dark_skin_tone": "1f64b-1f3fe-200d-2642-fe0f", "raising_hand_man_medium_dark_skin_tone": "1f64b-1f3fe-200d-2642-fe0f", "man-raising-hand_dark_skin_tone": "1f64b-1f3ff-200d-2642-fe0f", "raising_hand_man_dark_skin_tone": "1f64b-1f3ff-200d-2642-fe0f", "raising_hand_light_skin_tone": "1f64b-1f3fb", "raising_hand_medium_light_skin_tone": "1f64b-1f3fc", "raising_hand_medium_skin_tone": "1f64b-1f3fd", "raising_hand_medium_dark_skin_tone": "1f64b-1f3fe", "raising_hand_dark_skin_tone": "1f64b-1f3ff", "raised_hands_light_skin_tone": "1f64c-1f3fb", "raised_hands_medium_light_skin_tone": "1f64c-1f3fc", "raised_hands_medium_skin_tone": "1f64c-1f3fd", "raised_hands_medium_dark_skin_tone": "1f64c-1f3fe", "raised_hands_dark_skin_tone": "1f64c-1f3ff", "woman-frowning_light_skin_tone": "1f64d-1f3fb-200d-2640-fe0f", "frowning_woman_light_skin_tone": "1f64d-1f3fb-200d-2640-fe0f", "woman-frowning_medium_light_skin_tone": "1f64d-1f3fc-200d-2640-fe0f", "frowning_woman_medium_light_skin_tone": "1f64d-1f3fc-200d-2640-fe0f", "woman-frowning_medium_skin_tone": "1f64d-1f3fd-200d-2640-fe0f", "frowning_woman_medium_skin_tone": "1f64d-1f3fd-200d-2640-fe0f", "woman-frowning_medium_dark_skin_tone": "1f64d-1f3fe-200d-2640-fe0f", "frowning_woman_medium_dark_skin_tone": "1f64d-1f3fe-200d-2640-fe0f", "woman-frowning_dark_skin_tone": "1f64d-1f3ff-200d-2640-fe0f", "frowning_woman_dark_skin_tone": "1f64d-1f3ff-200d-2640-fe0f", "man-frowning_light_skin_tone": "1f64d-1f3fb-200d-2642-fe0f", "frowning_man_light_skin_tone": "1f64d-1f3fb-200d-2642-fe0f", "man-frowning_medium_light_skin_tone": "1f64d-1f3fc-200d-2642-fe0f", "frowning_man_medium_light_skin_tone": "1f64d-1f3fc-200d-2642-fe0f", "man-frowning_medium_skin_tone": "1f64d-1f3fd-200d-2642-fe0f", "frowning_man_medium_skin_tone": "1f64d-1f3fd-200d-2642-fe0f", "man-frowning_medium_dark_skin_tone": "1f64d-1f3fe-200d-2642-fe0f", "frowning_man_medium_dark_skin_tone": "1f64d-1f3fe-200d-2642-fe0f", "man-frowning_dark_skin_tone": "1f64d-1f3ff-200d-2642-fe0f", "frowning_man_dark_skin_tone": "1f64d-1f3ff-200d-2642-fe0f", "person_frowning_light_skin_tone": "1f64d-1f3fb", "person_frowning_medium_light_skin_tone": "1f64d-1f3fc", "person_frowning_medium_skin_tone": "1f64d-1f3fd", "person_frowning_medium_dark_skin_tone": "1f64d-1f3fe", "person_frowning_dark_skin_tone": "1f64d-1f3ff", "woman-pouting_light_skin_tone": "1f64e-1f3fb-200d-2640-fe0f", "pouting_woman_light_skin_tone": "1f64e-1f3fb-200d-2640-fe0f", "woman-pouting_medium_light_skin_tone": "1f64e-1f3fc-200d-2640-fe0f", "pouting_woman_medium_light_skin_tone": "1f64e-1f3fc-200d-2640-fe0f", "woman-pouting_medium_skin_tone": "1f64e-1f3fd-200d-2640-fe0f", "pouting_woman_medium_skin_tone": "1f64e-1f3fd-200d-2640-fe0f", "woman-pouting_medium_dark_skin_tone": "1f64e-1f3fe-200d-2640-fe0f", "pouting_woman_medium_dark_skin_tone": "1f64e-1f3fe-200d-2640-fe0f", "woman-pouting_dark_skin_tone": "1f64e-1f3ff-200d-2640-fe0f", "pouting_woman_dark_skin_tone": "1f64e-1f3ff-200d-2640-fe0f", "man-pouting_light_skin_tone": "1f64e-1f3fb-200d-2642-fe0f", "pouting_man_light_skin_tone": "1f64e-1f3fb-200d-2642-fe0f", "man-pouting_medium_light_skin_tone": "1f64e-1f3fc-200d-2642-fe0f", "pouting_man_medium_light_skin_tone": "1f64e-1f3fc-200d-2642-fe0f", "man-pouting_medium_skin_tone": "1f64e-1f3fd-200d-2642-fe0f", "pouting_man_medium_skin_tone": "1f64e-1f3fd-200d-2642-fe0f", "man-pouting_medium_dark_skin_tone": "1f64e-1f3fe-200d-2642-fe0f", "pouting_man_medium_dark_skin_tone": "1f64e-1f3fe-200d-2642-fe0f", "man-pouting_dark_skin_tone": "1f64e-1f3ff-200d-2642-fe0f", "pouting_man_dark_skin_tone": "1f64e-1f3ff-200d-2642-fe0f", "person_with_pouting_face_light_skin_tone": "1f64e-1f3fb", "person_with_pouting_face_medium_light_skin_tone": "1f64e-1f3fc", "person_with_pouting_face_medium_skin_tone": "1f64e-1f3fd", "person_with_pouting_face_medium_dark_skin_tone": "1f64e-1f3fe", "person_with_pouting_face_dark_skin_tone": "1f64e-1f3ff", "pray_light_skin_tone": "1f64f-1f3fb", "pray_medium_light_skin_tone": "1f64f-1f3fc", "pray_medium_skin_tone": "1f64f-1f3fd", "pray_medium_dark_skin_tone": "1f64f-1f3fe", "pray_dark_skin_tone": "1f64f-1f3ff", "woman-rowing-boat_light_skin_tone": "1f6a3-1f3fb-200d-2640-fe0f", "rowing_woman_light_skin_tone": "1f6a3-1f3fb-200d-2640-fe0f", "woman-rowing-boat_medium_light_skin_tone": "1f6a3-1f3fc-200d-2640-fe0f", "rowing_woman_medium_light_skin_tone": "1f6a3-1f3fc-200d-2640-fe0f", "woman-rowing-boat_medium_skin_tone": "1f6a3-1f3fd-200d-2640-fe0f", "rowing_woman_medium_skin_tone": "1f6a3-1f3fd-200d-2640-fe0f", "woman-rowing-boat_medium_dark_skin_tone": "1f6a3-1f3fe-200d-2640-fe0f", "rowing_woman_medium_dark_skin_tone": "1f6a3-1f3fe-200d-2640-fe0f", "woman-rowing-boat_dark_skin_tone": "1f6a3-1f3ff-200d-2640-fe0f", "rowing_woman_dark_skin_tone": "1f6a3-1f3ff-200d-2640-fe0f", "man-rowing-boat_light_skin_tone": "1f6a3-1f3fb-200d-2642-fe0f", "rowing_man_light_skin_tone": "1f6a3-1f3fb-200d-2642-fe0f", "man-rowing-boat_medium_light_skin_tone": "1f6a3-1f3fc-200d-2642-fe0f", "rowing_man_medium_light_skin_tone": "1f6a3-1f3fc-200d-2642-fe0f", "man-rowing-boat_medium_skin_tone": "1f6a3-1f3fd-200d-2642-fe0f", "rowing_man_medium_skin_tone": "1f6a3-1f3fd-200d-2642-fe0f", "man-rowing-boat_medium_dark_skin_tone": "1f6a3-1f3fe-200d-2642-fe0f", "rowing_man_medium_dark_skin_tone": "1f6a3-1f3fe-200d-2642-fe0f", "man-rowing-boat_dark_skin_tone": "1f6a3-1f3ff-200d-2642-fe0f", "rowing_man_dark_skin_tone": "1f6a3-1f3ff-200d-2642-fe0f", "rowboat_light_skin_tone": "1f6a3-1f3fb", "rowboat_medium_light_skin_tone": "1f6a3-1f3fc", "rowboat_medium_skin_tone": "1f6a3-1f3fd", "rowboat_medium_dark_skin_tone": "1f6a3-1f3fe", "rowboat_dark_skin_tone": "1f6a3-1f3ff", "woman-biking_light_skin_tone": "1f6b4-1f3fb-200d-2640-fe0f", "biking_woman_light_skin_tone": "1f6b4-1f3fb-200d-2640-fe0f", "woman-biking_medium_light_skin_tone": "1f6b4-1f3fc-200d-2640-fe0f", "biking_woman_medium_light_skin_tone": "1f6b4-1f3fc-200d-2640-fe0f", "woman-biking_medium_skin_tone": "1f6b4-1f3fd-200d-2640-fe0f", "biking_woman_medium_skin_tone": "1f6b4-1f3fd-200d-2640-fe0f", "woman-biking_medium_dark_skin_tone": "1f6b4-1f3fe-200d-2640-fe0f", "biking_woman_medium_dark_skin_tone": "1f6b4-1f3fe-200d-2640-fe0f", "woman-biking_dark_skin_tone": "1f6b4-1f3ff-200d-2640-fe0f", "biking_woman_dark_skin_tone": "1f6b4-1f3ff-200d-2640-fe0f", "man-biking_light_skin_tone": "1f6b4-1f3fb-200d-2642-fe0f", "biking_man_light_skin_tone": "1f6b4-1f3fb-200d-2642-fe0f", "man-biking_medium_light_skin_tone": "1f6b4-1f3fc-200d-2642-fe0f", "biking_man_medium_light_skin_tone": "1f6b4-1f3fc-200d-2642-fe0f", "man-biking_medium_skin_tone": "1f6b4-1f3fd-200d-2642-fe0f", "biking_man_medium_skin_tone": "1f6b4-1f3fd-200d-2642-fe0f", "man-biking_medium_dark_skin_tone": "1f6b4-1f3fe-200d-2642-fe0f", "biking_man_medium_dark_skin_tone": "1f6b4-1f3fe-200d-2642-fe0f", "man-biking_dark_skin_tone": "1f6b4-1f3ff-200d-2642-fe0f", "biking_man_dark_skin_tone": "1f6b4-1f3ff-200d-2642-fe0f", "bicyclist_light_skin_tone": "1f6b4-1f3fb", "bicyclist_medium_light_skin_tone": "1f6b4-1f3fc", "bicyclist_medium_skin_tone": "1f6b4-1f3fd", "bicyclist_medium_dark_skin_tone": "1f6b4-1f3fe", "bicyclist_dark_skin_tone": "1f6b4-1f3ff", "woman-mountain-biking_light_skin_tone": "1f6b5-1f3fb-200d-2640-fe0f", "mountain_biking_woman_light_skin_tone": "1f6b5-1f3fb-200d-2640-fe0f", "woman-mountain-biking_medium_light_skin_tone": "1f6b5-1f3fc-200d-2640-fe0f", "mountain_biking_woman_medium_light_skin_tone": "1f6b5-1f3fc-200d-2640-fe0f", "woman-mountain-biking_medium_skin_tone": "1f6b5-1f3fd-200d-2640-fe0f", "mountain_biking_woman_medium_skin_tone": "1f6b5-1f3fd-200d-2640-fe0f", "woman-mountain-biking_medium_dark_skin_tone": "1f6b5-1f3fe-200d-2640-fe0f", "mountain_biking_woman_medium_dark_skin_tone": "1f6b5-1f3fe-200d-2640-fe0f", "woman-mountain-biking_dark_skin_tone": "1f6b5-1f3ff-200d-2640-fe0f", "mountain_biking_woman_dark_skin_tone": "1f6b5-1f3ff-200d-2640-fe0f", "man-mountain-biking_light_skin_tone": "1f6b5-1f3fb-200d-2642-fe0f", "mountain_biking_man_light_skin_tone": "1f6b5-1f3fb-200d-2642-fe0f", "man-mountain-biking_medium_light_skin_tone": "1f6b5-1f3fc-200d-2642-fe0f", "mountain_biking_man_medium_light_skin_tone": "1f6b5-1f3fc-200d-2642-fe0f", "man-mountain-biking_medium_skin_tone": "1f6b5-1f3fd-200d-2642-fe0f", "mountain_biking_man_medium_skin_tone": "1f6b5-1f3fd-200d-2642-fe0f", "man-mountain-biking_medium_dark_skin_tone": "1f6b5-1f3fe-200d-2642-fe0f", "mountain_biking_man_medium_dark_skin_tone": "1f6b5-1f3fe-200d-2642-fe0f", "man-mountain-biking_dark_skin_tone": "1f6b5-1f3ff-200d-2642-fe0f", "mountain_biking_man_dark_skin_tone": "1f6b5-1f3ff-200d-2642-fe0f", "mountain_bicyclist_light_skin_tone": "1f6b5-1f3fb", "mountain_bicyclist_medium_light_skin_tone": "1f6b5-1f3fc", "mountain_bicyclist_medium_skin_tone": "1f6b5-1f3fd", "mountain_bicyclist_medium_dark_skin_tone": "1f6b5-1f3fe", "mountain_bicyclist_dark_skin_tone": "1f6b5-1f3ff", "woman-walking_light_skin_tone": "1f6b6-1f3fb-200d-2640-fe0f", "walking_woman_light_skin_tone": "1f6b6-1f3fb-200d-2640-fe0f", "woman-walking_medium_light_skin_tone": "1f6b6-1f3fc-200d-2640-fe0f", "walking_woman_medium_light_skin_tone": "1f6b6-1f3fc-200d-2640-fe0f", "woman-walking_medium_skin_tone": "1f6b6-1f3fd-200d-2640-fe0f", "walking_woman_medium_skin_tone": "1f6b6-1f3fd-200d-2640-fe0f", "woman-walking_medium_dark_skin_tone": "1f6b6-1f3fe-200d-2640-fe0f", "walking_woman_medium_dark_skin_tone": "1f6b6-1f3fe-200d-2640-fe0f", "woman-walking_dark_skin_tone": "1f6b6-1f3ff-200d-2640-fe0f", "walking_woman_dark_skin_tone": "1f6b6-1f3ff-200d-2640-fe0f", "man-walking_light_skin_tone": "1f6b6-1f3fb-200d-2642-fe0f", "walking_man_light_skin_tone": "1f6b6-1f3fb-200d-2642-fe0f", "man-walking_medium_light_skin_tone": "1f6b6-1f3fc-200d-2642-fe0f", "walking_man_medium_light_skin_tone": "1f6b6-1f3fc-200d-2642-fe0f", "man-walking_medium_skin_tone": "1f6b6-1f3fd-200d-2642-fe0f", "walking_man_medium_skin_tone": "1f6b6-1f3fd-200d-2642-fe0f", "man-walking_medium_dark_skin_tone": "1f6b6-1f3fe-200d-2642-fe0f", "walking_man_medium_dark_skin_tone": "1f6b6-1f3fe-200d-2642-fe0f", "man-walking_dark_skin_tone": "1f6b6-1f3ff-200d-2642-fe0f", "walking_man_dark_skin_tone": "1f6b6-1f3ff-200d-2642-fe0f", "walking_light_skin_tone": "1f6b6-1f3fb", "walking_medium_light_skin_tone": "1f6b6-1f3fc", "walking_medium_skin_tone": "1f6b6-1f3fd", "walking_medium_dark_skin_tone": "1f6b6-1f3fe", "walking_dark_skin_tone": "1f6b6-1f3ff", "bath_light_skin_tone": "1f6c0-1f3fb", "bath_medium_light_skin_tone": "1f6c0-1f3fc", "bath_medium_skin_tone": "1f6c0-1f3fd", "bath_medium_dark_skin_tone": "1f6c0-1f3fe", "bath_dark_skin_tone": "1f6c0-1f3ff", "sleeping_accommodation_light_skin_tone": "1f6cc-1f3fb", "sleeping_accommodation_medium_light_skin_tone": "1f6cc-1f3fc", "sleeping_accommodation_medium_skin_tone": "1f6cc-1f3fd", "sleeping_accommodation_medium_dark_skin_tone": "1f6cc-1f3fe", "sleeping_accommodation_dark_skin_tone": "1f6cc-1f3ff", "pinched_fingers_light_skin_tone": "1f90c-1f3fb", "pinched_fingers_medium_light_skin_tone": "1f90c-1f3fc", "pinched_fingers_medium_skin_tone": "1f90c-1f3fd", "pinched_fingers_medium_dark_skin_tone": "1f90c-1f3fe", "pinched_fingers_dark_skin_tone": "1f90c-1f3ff", "pinching_hand_light_skin_tone": "1f90f-1f3fb", "pinching_hand_medium_light_skin_tone": "1f90f-1f3fc", "pinching_hand_medium_skin_tone": "1f90f-1f3fd", "pinching_hand_medium_dark_skin_tone": "1f90f-1f3fe", "pinching_hand_dark_skin_tone": "1f90f-1f3ff", "the_horns_light_skin_tone": "1f918-1f3fb", "sign_of_the_horns_light_skin_tone": "1f918-1f3fb", "metal_light_skin_tone": "1f918-1f3fb", "the_horns_medium_light_skin_tone": "1f918-1f3fc", "sign_of_the_horns_medium_light_skin_tone": "1f918-1f3fc", "metal_medium_light_skin_tone": "1f918-1f3fc", "the_horns_medium_skin_tone": "1f918-1f3fd", "sign_of_the_horns_medium_skin_tone": "1f918-1f3fd", "metal_medium_skin_tone": "1f918-1f3fd", "the_horns_medium_dark_skin_tone": "1f918-1f3fe", "sign_of_the_horns_medium_dark_skin_tone": "1f918-1f3fe", "metal_medium_dark_skin_tone": "1f918-1f3fe", "the_horns_dark_skin_tone": "1f918-1f3ff", "sign_of_the_horns_dark_skin_tone": "1f918-1f3ff", "metal_dark_skin_tone": "1f918-1f3ff", "call_me_hand_light_skin_tone": "1f919-1f3fb", "call_me_hand_medium_light_skin_tone": "1f919-1f3fc", "call_me_hand_medium_skin_tone": "1f919-1f3fd", "call_me_hand_medium_dark_skin_tone": "1f919-1f3fe", "call_me_hand_dark_skin_tone": "1f919-1f3ff", "raised_back_of_hand_light_skin_tone": "1f91a-1f3fb", "raised_back_of_hand_medium_light_skin_tone": "1f91a-1f3fc", "raised_back_of_hand_medium_skin_tone": "1f91a-1f3fd", "raised_back_of_hand_medium_dark_skin_tone": "1f91a-1f3fe", "raised_back_of_hand_dark_skin_tone": "1f91a-1f3ff", "left-facing_fist_light_skin_tone": "1f91b-1f3fb", "fist_left_light_skin_tone": "1f91b-1f3fb", "left-facing_fist_medium_light_skin_tone": "1f91b-1f3fc", "fist_left_medium_light_skin_tone": "1f91b-1f3fc", "left-facing_fist_medium_skin_tone": "1f91b-1f3fd", "fist_left_medium_skin_tone": "1f91b-1f3fd", "left-facing_fist_medium_dark_skin_tone": "1f91b-1f3fe", "fist_left_medium_dark_skin_tone": "1f91b-1f3fe", "left-facing_fist_dark_skin_tone": "1f91b-1f3ff", "fist_left_dark_skin_tone": "1f91b-1f3ff", "right-facing_fist_light_skin_tone": "1f91c-1f3fb", "fist_right_light_skin_tone": "1f91c-1f3fb", "right-facing_fist_medium_light_skin_tone": "1f91c-1f3fc", "fist_right_medium_light_skin_tone": "1f91c-1f3fc", "right-facing_fist_medium_skin_tone": "1f91c-1f3fd", "fist_right_medium_skin_tone": "1f91c-1f3fd", "right-facing_fist_medium_dark_skin_tone": "1f91c-1f3fe", "fist_right_medium_dark_skin_tone": "1f91c-1f3fe", "right-facing_fist_dark_skin_tone": "1f91c-1f3ff", "fist_right_dark_skin_tone": "1f91c-1f3ff", "crossed_fingers_light_skin_tone": "1f91e-1f3fb", "hand_with_index_and_middle_fingers_crossed_light_skin_tone": "1f91e-1f3fb", "crossed_fingers_medium_light_skin_tone": "1f91e-1f3fc", "hand_with_index_and_middle_fingers_crossed_medium_light_skin_tone": "1f91e-1f3fc", "crossed_fingers_medium_skin_tone": "1f91e-1f3fd", "hand_with_index_and_middle_fingers_crossed_medium_skin_tone": "1f91e-1f3fd", "crossed_fingers_medium_dark_skin_tone": "1f91e-1f3fe", "hand_with_index_and_middle_fingers_crossed_medium_dark_skin_tone": "1f91e-1f3fe", "crossed_fingers_dark_skin_tone": "1f91e-1f3ff", "hand_with_index_and_middle_fingers_crossed_dark_skin_tone": "1f91e-1f3ff", "i_love_you_hand_sign_light_skin_tone": "1f91f-1f3fb", "i_love_you_hand_sign_medium_light_skin_tone": "1f91f-1f3fc", "i_love_you_hand_sign_medium_skin_tone": "1f91f-1f3fd", "i_love_you_hand_sign_medium_dark_skin_tone": "1f91f-1f3fe", "i_love_you_hand_sign_dark_skin_tone": "1f91f-1f3ff", "woman-facepalming_light_skin_tone": "1f926-1f3fb-200d-2640-fe0f", "woman_facepalming_light_skin_tone": "1f926-1f3fb-200d-2640-fe0f", "woman-facepalming_medium_light_skin_tone": "1f926-1f3fc-200d-2640-fe0f", "woman_facepalming_medium_light_skin_tone": "1f926-1f3fc-200d-2640-fe0f", "woman-facepalming_medium_skin_tone": "1f926-1f3fd-200d-2640-fe0f", "woman_facepalming_medium_skin_tone": "1f926-1f3fd-200d-2640-fe0f", "woman-facepalming_medium_dark_skin_tone": "1f926-1f3fe-200d-2640-fe0f", "woman_facepalming_medium_dark_skin_tone": "1f926-1f3fe-200d-2640-fe0f", "woman-facepalming_dark_skin_tone": "1f926-1f3ff-200d-2640-fe0f", "woman_facepalming_dark_skin_tone": "1f926-1f3ff-200d-2640-fe0f", "man-facepalming_light_skin_tone": "1f926-1f3fb-200d-2642-fe0f", "man_facepalming_light_skin_tone": "1f926-1f3fb-200d-2642-fe0f", "man-facepalming_medium_light_skin_tone": "1f926-1f3fc-200d-2642-fe0f", "man_facepalming_medium_light_skin_tone": "1f926-1f3fc-200d-2642-fe0f", "man-facepalming_medium_skin_tone": "1f926-1f3fd-200d-2642-fe0f", "man_facepalming_medium_skin_tone": "1f926-1f3fd-200d-2642-fe0f", "man-facepalming_medium_dark_skin_tone": "1f926-1f3fe-200d-2642-fe0f", "man_facepalming_medium_dark_skin_tone": "1f926-1f3fe-200d-2642-fe0f", "man-facepalming_dark_skin_tone": "1f926-1f3ff-200d-2642-fe0f", "man_facepalming_dark_skin_tone": "1f926-1f3ff-200d-2642-fe0f", "face_palm_light_skin_tone": "1f926-1f3fb", "face_palm_medium_light_skin_tone": "1f926-1f3fc", "face_palm_medium_skin_tone": "1f926-1f3fd", "face_palm_medium_dark_skin_tone": "1f926-1f3fe", "face_palm_dark_skin_tone": "1f926-1f3ff", "pregnant_woman_light_skin_tone": "1f930-1f3fb", "pregnant_woman_medium_light_skin_tone": "1f930-1f3fc", "pregnant_woman_medium_skin_tone": "1f930-1f3fd", "pregnant_woman_medium_dark_skin_tone": "1f930-1f3fe", "pregnant_woman_dark_skin_tone": "1f930-1f3ff", "breast-feeding_light_skin_tone": "1f931-1f3fb", "breast-feeding_medium_light_skin_tone": "1f931-1f3fc", "breast-feeding_medium_skin_tone": "1f931-1f3fd", "breast-feeding_medium_dark_skin_tone": "1f931-1f3fe", "breast-feeding_dark_skin_tone": "1f931-1f3ff", "palms_up_together_light_skin_tone": "1f932-1f3fb", "palms_up_together_medium_light_skin_tone": "1f932-1f3fc", "palms_up_together_medium_skin_tone": "1f932-1f3fd", "palms_up_together_medium_dark_skin_tone": "1f932-1f3fe", "palms_up_together_dark_skin_tone": "1f932-1f3ff", "selfie_light_skin_tone": "1f933-1f3fb", "selfie_medium_light_skin_tone": "1f933-1f3fc", "selfie_medium_skin_tone": "1f933-1f3fd", "selfie_medium_dark_skin_tone": "1f933-1f3fe", "selfie_dark_skin_tone": "1f933-1f3ff", "prince_light_skin_tone": "1f934-1f3fb", "prince_medium_light_skin_tone": "1f934-1f3fc", "prince_medium_skin_tone": "1f934-1f3fd", "prince_medium_dark_skin_tone": "1f934-1f3fe", "prince_dark_skin_tone": "1f934-1f3ff", "woman_in_tuxedo_light_skin_tone": "1f935-1f3fb-200d-2640-fe0f", "woman_in_tuxedo_medium_light_skin_tone": "1f935-1f3fc-200d-2640-fe0f", "woman_in_tuxedo_medium_skin_tone": "1f935-1f3fd-200d-2640-fe0f", "woman_in_tuxedo_medium_dark_skin_tone": "1f935-1f3fe-200d-2640-fe0f", "woman_in_tuxedo_dark_skin_tone": "1f935-1f3ff-200d-2640-fe0f", "man_in_tuxedo_light_skin_tone": "1f935-1f3fb-200d-2642-fe0f", "man_in_tuxedo_medium_light_skin_tone": "1f935-1f3fc-200d-2642-fe0f", "man_in_tuxedo_medium_skin_tone": "1f935-1f3fd-200d-2642-fe0f", "man_in_tuxedo_medium_dark_skin_tone": "1f935-1f3fe-200d-2642-fe0f", "man_in_tuxedo_dark_skin_tone": "1f935-1f3ff-200d-2642-fe0f", "person_in_tuxedo_light_skin_tone": "1f935-1f3fb", "person_in_tuxedo_medium_light_skin_tone": "1f935-1f3fc", "person_in_tuxedo_medium_skin_tone": "1f935-1f3fd", "person_in_tuxedo_medium_dark_skin_tone": "1f935-1f3fe", "person_in_tuxedo_dark_skin_tone": "1f935-1f3ff", "mrs_claus_light_skin_tone": "1f936-1f3fb", "mother_christmas_light_skin_tone": "1f936-1f3fb", "mrs_claus_medium_light_skin_tone": "1f936-1f3fc", "mother_christmas_medium_light_skin_tone": "1f936-1f3fc", "mrs_claus_medium_skin_tone": "1f936-1f3fd", "mother_christmas_medium_skin_tone": "1f936-1f3fd", "mrs_claus_medium_dark_skin_tone": "1f936-1f3fe", "mother_christmas_medium_dark_skin_tone": "1f936-1f3fe", "mrs_claus_dark_skin_tone": "1f936-1f3ff", "mother_christmas_dark_skin_tone": "1f936-1f3ff", "woman-shrugging_light_skin_tone": "1f937-1f3fb-200d-2640-fe0f", "woman_shrugging_light_skin_tone": "1f937-1f3fb-200d-2640-fe0f", "woman-shrugging_medium_light_skin_tone": "1f937-1f3fc-200d-2640-fe0f", "woman_shrugging_medium_light_skin_tone": "1f937-1f3fc-200d-2640-fe0f", "woman-shrugging_medium_skin_tone": "1f937-1f3fd-200d-2640-fe0f", "woman_shrugging_medium_skin_tone": "1f937-1f3fd-200d-2640-fe0f", "woman-shrugging_medium_dark_skin_tone": "1f937-1f3fe-200d-2640-fe0f", "woman_shrugging_medium_dark_skin_tone": "1f937-1f3fe-200d-2640-fe0f", "woman-shrugging_dark_skin_tone": "1f937-1f3ff-200d-2640-fe0f", "woman_shrugging_dark_skin_tone": "1f937-1f3ff-200d-2640-fe0f", "man-shrugging_light_skin_tone": "1f937-1f3fb-200d-2642-fe0f", "man_shrugging_light_skin_tone": "1f937-1f3fb-200d-2642-fe0f", "man-shrugging_medium_light_skin_tone": "1f937-1f3fc-200d-2642-fe0f", "man_shrugging_medium_light_skin_tone": "1f937-1f3fc-200d-2642-fe0f", "man-shrugging_medium_skin_tone": "1f937-1f3fd-200d-2642-fe0f", "man_shrugging_medium_skin_tone": "1f937-1f3fd-200d-2642-fe0f", "man-shrugging_medium_dark_skin_tone": "1f937-1f3fe-200d-2642-fe0f", "man_shrugging_medium_dark_skin_tone": "1f937-1f3fe-200d-2642-fe0f", "man-shrugging_dark_skin_tone": "1f937-1f3ff-200d-2642-fe0f", "man_shrugging_dark_skin_tone": "1f937-1f3ff-200d-2642-fe0f", "shrug_light_skin_tone": "1f937-1f3fb", "shrug_medium_light_skin_tone": "1f937-1f3fc", "shrug_medium_skin_tone": "1f937-1f3fd", "shrug_medium_dark_skin_tone": "1f937-1f3fe", "shrug_dark_skin_tone": "1f937-1f3ff", "woman-cartwheeling_light_skin_tone": "1f938-1f3fb-200d-2640-fe0f", "woman_cartwheeling_light_skin_tone": "1f938-1f3fb-200d-2640-fe0f", "woman-cartwheeling_medium_light_skin_tone": "1f938-1f3fc-200d-2640-fe0f", "woman_cartwheeling_medium_light_skin_tone": "1f938-1f3fc-200d-2640-fe0f", "woman-cartwheeling_medium_skin_tone": "1f938-1f3fd-200d-2640-fe0f", "woman_cartwheeling_medium_skin_tone": "1f938-1f3fd-200d-2640-fe0f", "woman-cartwheeling_medium_dark_skin_tone": "1f938-1f3fe-200d-2640-fe0f", "woman_cartwheeling_medium_dark_skin_tone": "1f938-1f3fe-200d-2640-fe0f", "woman-cartwheeling_dark_skin_tone": "1f938-1f3ff-200d-2640-fe0f", "woman_cartwheeling_dark_skin_tone": "1f938-1f3ff-200d-2640-fe0f", "man-cartwheeling_light_skin_tone": "1f938-1f3fb-200d-2642-fe0f", "man_cartwheeling_light_skin_tone": "1f938-1f3fb-200d-2642-fe0f", "man-cartwheeling_medium_light_skin_tone": "1f938-1f3fc-200d-2642-fe0f", "man_cartwheeling_medium_light_skin_tone": "1f938-1f3fc-200d-2642-fe0f", "man-cartwheeling_medium_skin_tone": "1f938-1f3fd-200d-2642-fe0f", "man_cartwheeling_medium_skin_tone": "1f938-1f3fd-200d-2642-fe0f", "man-cartwheeling_medium_dark_skin_tone": "1f938-1f3fe-200d-2642-fe0f", "man_cartwheeling_medium_dark_skin_tone": "1f938-1f3fe-200d-2642-fe0f", "man-cartwheeling_dark_skin_tone": "1f938-1f3ff-200d-2642-fe0f", "man_cartwheeling_dark_skin_tone": "1f938-1f3ff-200d-2642-fe0f", "person_doing_cartwheel_light_skin_tone": "1f938-1f3fb", "person_doing_cartwheel_medium_light_skin_tone": "1f938-1f3fc", "person_doing_cartwheel_medium_skin_tone": "1f938-1f3fd", "person_doing_cartwheel_medium_dark_skin_tone": "1f938-1f3fe", "person_doing_cartwheel_dark_skin_tone": "1f938-1f3ff", "woman-juggling_light_skin_tone": "1f939-1f3fb-200d-2640-fe0f", "woman_juggling_light_skin_tone": "1f939-1f3fb-200d-2640-fe0f", "woman-juggling_medium_light_skin_tone": "1f939-1f3fc-200d-2640-fe0f", "woman_juggling_medium_light_skin_tone": "1f939-1f3fc-200d-2640-fe0f", "woman-juggling_medium_skin_tone": "1f939-1f3fd-200d-2640-fe0f", "woman_juggling_medium_skin_tone": "1f939-1f3fd-200d-2640-fe0f", "woman-juggling_medium_dark_skin_tone": "1f939-1f3fe-200d-2640-fe0f", "woman_juggling_medium_dark_skin_tone": "1f939-1f3fe-200d-2640-fe0f", "woman-juggling_dark_skin_tone": "1f939-1f3ff-200d-2640-fe0f", "woman_juggling_dark_skin_tone": "1f939-1f3ff-200d-2640-fe0f", "man-juggling_light_skin_tone": "1f939-1f3fb-200d-2642-fe0f", "man_juggling_light_skin_tone": "1f939-1f3fb-200d-2642-fe0f", "man-juggling_medium_light_skin_tone": "1f939-1f3fc-200d-2642-fe0f", "man_juggling_medium_light_skin_tone": "1f939-1f3fc-200d-2642-fe0f", "man-juggling_medium_skin_tone": "1f939-1f3fd-200d-2642-fe0f", "man_juggling_medium_skin_tone": "1f939-1f3fd-200d-2642-fe0f", "man-juggling_medium_dark_skin_tone": "1f939-1f3fe-200d-2642-fe0f", "man_juggling_medium_dark_skin_tone": "1f939-1f3fe-200d-2642-fe0f", "man-juggling_dark_skin_tone": "1f939-1f3ff-200d-2642-fe0f", "man_juggling_dark_skin_tone": "1f939-1f3ff-200d-2642-fe0f", "juggling_light_skin_tone": "1f939-1f3fb", "juggling_medium_light_skin_tone": "1f939-1f3fc", "juggling_medium_skin_tone": "1f939-1f3fd", "juggling_medium_dark_skin_tone": "1f939-1f3fe", "juggling_dark_skin_tone": "1f939-1f3ff", "woman-playing-water-polo_light_skin_tone": "1f93d-1f3fb-200d-2640-fe0f", "woman_playing_water_polo_light_skin_tone": "1f93d-1f3fb-200d-2640-fe0f", "woman-playing-water-polo_medium_light_skin_tone": "1f93d-1f3fc-200d-2640-fe0f", "woman_playing_water_polo_medium_light_skin_tone": "1f93d-1f3fc-200d-2640-fe0f", "woman-playing-water-polo_medium_skin_tone": "1f93d-1f3fd-200d-2640-fe0f", "woman_playing_water_polo_medium_skin_tone": "1f93d-1f3fd-200d-2640-fe0f", "woman-playing-water-polo_medium_dark_skin_tone": "1f93d-1f3fe-200d-2640-fe0f", "woman_playing_water_polo_medium_dark_skin_tone": "1f93d-1f3fe-200d-2640-fe0f", "woman-playing-water-polo_dark_skin_tone": "1f93d-1f3ff-200d-2640-fe0f", "woman_playing_water_polo_dark_skin_tone": "1f93d-1f3ff-200d-2640-fe0f", "man-playing-water-polo_light_skin_tone": "1f93d-1f3fb-200d-2642-fe0f", "man_playing_water_polo_light_skin_tone": "1f93d-1f3fb-200d-2642-fe0f", "man-playing-water-polo_medium_light_skin_tone": "1f93d-1f3fc-200d-2642-fe0f", "man_playing_water_polo_medium_light_skin_tone": "1f93d-1f3fc-200d-2642-fe0f", "man-playing-water-polo_medium_skin_tone": "1f93d-1f3fd-200d-2642-fe0f", "man_playing_water_polo_medium_skin_tone": "1f93d-1f3fd-200d-2642-fe0f", "man-playing-water-polo_medium_dark_skin_tone": "1f93d-1f3fe-200d-2642-fe0f", "man_playing_water_polo_medium_dark_skin_tone": "1f93d-1f3fe-200d-2642-fe0f", "man-playing-water-polo_dark_skin_tone": "1f93d-1f3ff-200d-2642-fe0f", "man_playing_water_polo_dark_skin_tone": "1f93d-1f3ff-200d-2642-fe0f", "water_polo_light_skin_tone": "1f93d-1f3fb", "water_polo_medium_light_skin_tone": "1f93d-1f3fc", "water_polo_medium_skin_tone": "1f93d-1f3fd", "water_polo_medium_dark_skin_tone": "1f93d-1f3fe", "water_polo_dark_skin_tone": "1f93d-1f3ff", "woman-playing-handball_light_skin_tone": "1f93e-1f3fb-200d-2640-fe0f", "woman_playing_handball_light_skin_tone": "1f93e-1f3fb-200d-2640-fe0f", "woman-playing-handball_medium_light_skin_tone": "1f93e-1f3fc-200d-2640-fe0f", "woman_playing_handball_medium_light_skin_tone": "1f93e-1f3fc-200d-2640-fe0f", "woman-playing-handball_medium_skin_tone": "1f93e-1f3fd-200d-2640-fe0f", "woman_playing_handball_medium_skin_tone": "1f93e-1f3fd-200d-2640-fe0f", "woman-playing-handball_medium_dark_skin_tone": "1f93e-1f3fe-200d-2640-fe0f", "woman_playing_handball_medium_dark_skin_tone": "1f93e-1f3fe-200d-2640-fe0f", "woman-playing-handball_dark_skin_tone": "1f93e-1f3ff-200d-2640-fe0f", "woman_playing_handball_dark_skin_tone": "1f93e-1f3ff-200d-2640-fe0f", "man-playing-handball_light_skin_tone": "1f93e-1f3fb-200d-2642-fe0f", "man_playing_handball_light_skin_tone": "1f93e-1f3fb-200d-2642-fe0f", "man-playing-handball_medium_light_skin_tone": "1f93e-1f3fc-200d-2642-fe0f", "man_playing_handball_medium_light_skin_tone": "1f93e-1f3fc-200d-2642-fe0f", "man-playing-handball_medium_skin_tone": "1f93e-1f3fd-200d-2642-fe0f", "man_playing_handball_medium_skin_tone": "1f93e-1f3fd-200d-2642-fe0f", "man-playing-handball_medium_dark_skin_tone": "1f93e-1f3fe-200d-2642-fe0f", "man_playing_handball_medium_dark_skin_tone": "1f93e-1f3fe-200d-2642-fe0f", "man-playing-handball_dark_skin_tone": "1f93e-1f3ff-200d-2642-fe0f", "man_playing_handball_dark_skin_tone": "1f93e-1f3ff-200d-2642-fe0f", "handball_light_skin_tone": "1f93e-1f3fb", "handball_medium_light_skin_tone": "1f93e-1f3fc", "handball_medium_skin_tone": "1f93e-1f3fd", "handball_medium_dark_skin_tone": "1f93e-1f3fe", "handball_dark_skin_tone": "1f93e-1f3ff", "ninja_light_skin_tone": "1f977-1f3fb", "ninja_medium_light_skin_tone": "1f977-1f3fc", "ninja_medium_skin_tone": "1f977-1f3fd", "ninja_medium_dark_skin_tone": "1f977-1f3fe", "ninja_dark_skin_tone": "1f977-1f3ff", "leg_light_skin_tone": "1f9b5-1f3fb", "leg_medium_light_skin_tone": "1f9b5-1f3fc", "leg_medium_skin_tone": "1f9b5-1f3fd", "leg_medium_dark_skin_tone": "1f9b5-1f3fe", "leg_dark_skin_tone": "1f9b5-1f3ff", "foot_light_skin_tone": "1f9b6-1f3fb", "foot_medium_light_skin_tone": "1f9b6-1f3fc", "foot_medium_skin_tone": "1f9b6-1f3fd", "foot_medium_dark_skin_tone": "1f9b6-1f3fe", "foot_dark_skin_tone": "1f9b6-1f3ff", "female_superhero_light_skin_tone": "1f9b8-1f3fb-200d-2640-fe0f", "female_superhero_medium_light_skin_tone": "1f9b8-1f3fc-200d-2640-fe0f", "female_superhero_medium_skin_tone": "1f9b8-1f3fd-200d-2640-fe0f", "female_superhero_medium_dark_skin_tone": "1f9b8-1f3fe-200d-2640-fe0f", "female_superhero_dark_skin_tone": "1f9b8-1f3ff-200d-2640-fe0f", "male_superhero_light_skin_tone": "1f9b8-1f3fb-200d-2642-fe0f", "male_superhero_medium_light_skin_tone": "1f9b8-1f3fc-200d-2642-fe0f", "male_superhero_medium_skin_tone": "1f9b8-1f3fd-200d-2642-fe0f", "male_superhero_medium_dark_skin_tone": "1f9b8-1f3fe-200d-2642-fe0f", "male_superhero_dark_skin_tone": "1f9b8-1f3ff-200d-2642-fe0f", "superhero_light_skin_tone": "1f9b8-1f3fb", "superhero_medium_light_skin_tone": "1f9b8-1f3fc", "superhero_medium_skin_tone": "1f9b8-1f3fd", "superhero_medium_dark_skin_tone": "1f9b8-1f3fe", "superhero_dark_skin_tone": "1f9b8-1f3ff", "female_supervillain_light_skin_tone": "1f9b9-1f3fb-200d-2640-fe0f", "female_supervillain_medium_light_skin_tone": "1f9b9-1f3fc-200d-2640-fe0f", "female_supervillain_medium_skin_tone": "1f9b9-1f3fd-200d-2640-fe0f", "female_supervillain_medium_dark_skin_tone": "1f9b9-1f3fe-200d-2640-fe0f", "female_supervillain_dark_skin_tone": "1f9b9-1f3ff-200d-2640-fe0f", "male_supervillain_light_skin_tone": "1f9b9-1f3fb-200d-2642-fe0f", "male_supervillain_medium_light_skin_tone": "1f9b9-1f3fc-200d-2642-fe0f", "male_supervillain_medium_skin_tone": "1f9b9-1f3fd-200d-2642-fe0f", "male_supervillain_medium_dark_skin_tone": "1f9b9-1f3fe-200d-2642-fe0f", "male_supervillain_dark_skin_tone": "1f9b9-1f3ff-200d-2642-fe0f", "supervillain_light_skin_tone": "1f9b9-1f3fb", "supervillain_medium_light_skin_tone": "1f9b9-1f3fc", "supervillain_medium_skin_tone": "1f9b9-1f3fd", "supervillain_medium_dark_skin_tone": "1f9b9-1f3fe", "supervillain_dark_skin_tone": "1f9b9-1f3ff", "ear_with_hearing_aid_light_skin_tone": "1f9bb-1f3fb", "ear_with_hearing_aid_medium_light_skin_tone": "1f9bb-1f3fc", "ear_with_hearing_aid_medium_skin_tone": "1f9bb-1f3fd", "ear_with_hearing_aid_medium_dark_skin_tone": "1f9bb-1f3fe", "ear_with_hearing_aid_dark_skin_tone": "1f9bb-1f3ff", "woman_standing_light_skin_tone": "1f9cd-1f3fb-200d-2640-fe0f", "woman_standing_medium_light_skin_tone": "1f9cd-1f3fc-200d-2640-fe0f", "woman_standing_medium_skin_tone": "1f9cd-1f3fd-200d-2640-fe0f", "woman_standing_medium_dark_skin_tone": "1f9cd-1f3fe-200d-2640-fe0f", "woman_standing_dark_skin_tone": "1f9cd-1f3ff-200d-2640-fe0f", "man_standing_light_skin_tone": "1f9cd-1f3fb-200d-2642-fe0f", "man_standing_medium_light_skin_tone": "1f9cd-1f3fc-200d-2642-fe0f", "man_standing_medium_skin_tone": "1f9cd-1f3fd-200d-2642-fe0f", "man_standing_medium_dark_skin_tone": "1f9cd-1f3fe-200d-2642-fe0f", "man_standing_dark_skin_tone": "1f9cd-1f3ff-200d-2642-fe0f", "standing_person_light_skin_tone": "1f9cd-1f3fb", "standing_person_medium_light_skin_tone": "1f9cd-1f3fc", "standing_person_medium_skin_tone": "1f9cd-1f3fd", "standing_person_medium_dark_skin_tone": "1f9cd-1f3fe", "standing_person_dark_skin_tone": "1f9cd-1f3ff", "woman_kneeling_light_skin_tone": "1f9ce-1f3fb-200d-2640-fe0f", "woman_kneeling_medium_light_skin_tone": "1f9ce-1f3fc-200d-2640-fe0f", "woman_kneeling_medium_skin_tone": "1f9ce-1f3fd-200d-2640-fe0f", "woman_kneeling_medium_dark_skin_tone": "1f9ce-1f3fe-200d-2640-fe0f", "woman_kneeling_dark_skin_tone": "1f9ce-1f3ff-200d-2640-fe0f", "man_kneeling_light_skin_tone": "1f9ce-1f3fb-200d-2642-fe0f", "man_kneeling_medium_light_skin_tone": "1f9ce-1f3fc-200d-2642-fe0f", "man_kneeling_medium_skin_tone": "1f9ce-1f3fd-200d-2642-fe0f", "man_kneeling_medium_dark_skin_tone": "1f9ce-1f3fe-200d-2642-fe0f", "man_kneeling_dark_skin_tone": "1f9ce-1f3ff-200d-2642-fe0f", "kneeling_person_light_skin_tone": "1f9ce-1f3fb", "kneeling_person_medium_light_skin_tone": "1f9ce-1f3fc", "kneeling_person_medium_skin_tone": "1f9ce-1f3fd", "kneeling_person_medium_dark_skin_tone": "1f9ce-1f3fe", "kneeling_person_dark_skin_tone": "1f9ce-1f3ff", "deaf_woman_light_skin_tone": "1f9cf-1f3fb-200d-2640-fe0f", "deaf_woman_medium_light_skin_tone": "1f9cf-1f3fc-200d-2640-fe0f", "deaf_woman_medium_skin_tone": "1f9cf-1f3fd-200d-2640-fe0f", "deaf_woman_medium_dark_skin_tone": "1f9cf-1f3fe-200d-2640-fe0f", "deaf_woman_dark_skin_tone": "1f9cf-1f3ff-200d-2640-fe0f", "deaf_man_light_skin_tone": "1f9cf-1f3fb-200d-2642-fe0f", "deaf_man_medium_light_skin_tone": "1f9cf-1f3fc-200d-2642-fe0f", "deaf_man_medium_skin_tone": "1f9cf-1f3fd-200d-2642-fe0f", "deaf_man_medium_dark_skin_tone": "1f9cf-1f3fe-200d-2642-fe0f", "deaf_man_dark_skin_tone": "1f9cf-1f3ff-200d-2642-fe0f", "deaf_person_light_skin_tone": "1f9cf-1f3fb", "deaf_person_medium_light_skin_tone": "1f9cf-1f3fc", "deaf_person_medium_skin_tone": "1f9cf-1f3fd", "deaf_person_medium_dark_skin_tone": "1f9cf-1f3fe", "deaf_person_dark_skin_tone": "1f9cf-1f3ff", "farmer_light_skin_tone": "1f9d1-1f3fb-200d-1f33e", "farmer_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f33e", "farmer_medium_skin_tone": "1f9d1-1f3fd-200d-1f33e", "farmer_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f33e", "farmer_dark_skin_tone": "1f9d1-1f3ff-200d-1f33e", "cook_light_skin_tone": "1f9d1-1f3fb-200d-1f373", "cook_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f373", "cook_medium_skin_tone": "1f9d1-1f3fd-200d-1f373", "cook_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f373", "cook_dark_skin_tone": "1f9d1-1f3ff-200d-1f373", "person_feeding_baby_light_skin_tone": "1f9d1-1f3fb-200d-1f37c", "person_feeding_baby_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f37c", "person_feeding_baby_medium_skin_tone": "1f9d1-1f3fd-200d-1f37c", "person_feeding_baby_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f37c", "person_feeding_baby_dark_skin_tone": "1f9d1-1f3ff-200d-1f37c", "mx_claus_light_skin_tone": "1f9d1-1f3fb-200d-1f384", "mx_claus_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f384", "mx_claus_medium_skin_tone": "1f9d1-1f3fd-200d-1f384", "mx_claus_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f384", "mx_claus_dark_skin_tone": "1f9d1-1f3ff-200d-1f384", "student_light_skin_tone": "1f9d1-1f3fb-200d-1f393", "student_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f393", "student_medium_skin_tone": "1f9d1-1f3fd-200d-1f393", "student_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f393", "student_dark_skin_tone": "1f9d1-1f3ff-200d-1f393", "singer_light_skin_tone": "1f9d1-1f3fb-200d-1f3a4", "singer_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f3a4", "singer_medium_skin_tone": "1f9d1-1f3fd-200d-1f3a4", "singer_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f3a4", "singer_dark_skin_tone": "1f9d1-1f3ff-200d-1f3a4", "artist_light_skin_tone": "1f9d1-1f3fb-200d-1f3a8", "artist_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f3a8", "artist_medium_skin_tone": "1f9d1-1f3fd-200d-1f3a8", "artist_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f3a8", "artist_dark_skin_tone": "1f9d1-1f3ff-200d-1f3a8", "teacher_light_skin_tone": "1f9d1-1f3fb-200d-1f3eb", "teacher_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f3eb", "teacher_medium_skin_tone": "1f9d1-1f3fd-200d-1f3eb", "teacher_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f3eb", "teacher_dark_skin_tone": "1f9d1-1f3ff-200d-1f3eb", "factory_worker_light_skin_tone": "1f9d1-1f3fb-200d-1f3ed", "factory_worker_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f3ed", "factory_worker_medium_skin_tone": "1f9d1-1f3fd-200d-1f3ed", "factory_worker_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f3ed", "factory_worker_dark_skin_tone": "1f9d1-1f3ff-200d-1f3ed", "technologist_light_skin_tone": "1f9d1-1f3fb-200d-1f4bb", "technologist_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f4bb", "technologist_medium_skin_tone": "1f9d1-1f3fd-200d-1f4bb", "technologist_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f4bb", "technologist_dark_skin_tone": "1f9d1-1f3ff-200d-1f4bb", "office_worker_light_skin_tone": "1f9d1-1f3fb-200d-1f4bc", "office_worker_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f4bc", "office_worker_medium_skin_tone": "1f9d1-1f3fd-200d-1f4bc", "office_worker_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f4bc", "office_worker_dark_skin_tone": "1f9d1-1f3ff-200d-1f4bc", "mechanic_light_skin_tone": "1f9d1-1f3fb-200d-1f527", "mechanic_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f527", "mechanic_medium_skin_tone": "1f9d1-1f3fd-200d-1f527", "mechanic_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f527", "mechanic_dark_skin_tone": "1f9d1-1f3ff-200d-1f527", "scientist_light_skin_tone": "1f9d1-1f3fb-200d-1f52c", "scientist_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f52c", "scientist_medium_skin_tone": "1f9d1-1f3fd-200d-1f52c", "scientist_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f52c", "scientist_dark_skin_tone": "1f9d1-1f3ff-200d-1f52c", "astronaut_light_skin_tone": "1f9d1-1f3fb-200d-1f680", "astronaut_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f680", "astronaut_medium_skin_tone": "1f9d1-1f3fd-200d-1f680", "astronaut_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f680", "astronaut_dark_skin_tone": "1f9d1-1f3ff-200d-1f680", "firefighter_light_skin_tone": "1f9d1-1f3fb-200d-1f692", "firefighter_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f692", "firefighter_medium_skin_tone": "1f9d1-1f3fd-200d-1f692", "firefighter_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f692", "firefighter_dark_skin_tone": "1f9d1-1f3ff-200d-1f692", "people_holding_hands_light_skin_tone_light_skin_tone": "1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fb", "people_holding_hands_light_skin_tone_medium_light_skin_tone": "1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fc", "people_holding_hands_light_skin_tone_medium_skin_tone": "1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fd", "people_holding_hands_light_skin_tone_medium_dark_skin_tone": "1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3fe", "people_holding_hands_light_skin_tone_dark_skin_tone": "1f9d1-1f3fb-200d-1f91d-200d-1f9d1-1f3ff", "people_holding_hands_medium_light_skin_tone_light_skin_tone": "1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fb", "people_holding_hands_medium_light_skin_tone_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fc", "people_holding_hands_medium_light_skin_tone_medium_skin_tone": "1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fd", "people_holding_hands_medium_light_skin_tone_medium_dark_skin_tone": "1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3fe", "people_holding_hands_medium_light_skin_tone_dark_skin_tone": "1f9d1-1f3fc-200d-1f91d-200d-1f9d1-1f3ff", "people_holding_hands_medium_skin_tone_light_skin_tone": "1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fb", "people_holding_hands_medium_skin_tone_medium_light_skin_tone": "1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fc", "people_holding_hands_medium_skin_tone_medium_skin_tone": "1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fd", "people_holding_hands_medium_skin_tone_medium_dark_skin_tone": "1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3fe", "people_holding_hands_medium_skin_tone_dark_skin_tone": "1f9d1-1f3fd-200d-1f91d-200d-1f9d1-1f3ff", "people_holding_hands_medium_dark_skin_tone_light_skin_tone": "1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fb", "people_holding_hands_medium_dark_skin_tone_medium_light_skin_tone": "1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fc", "people_holding_hands_medium_dark_skin_tone_medium_skin_tone": "1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fd", "people_holding_hands_medium_dark_skin_tone_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3fe", "people_holding_hands_medium_dark_skin_tone_dark_skin_tone": "1f9d1-1f3fe-200d-1f91d-200d-1f9d1-1f3ff", "people_holding_hands_dark_skin_tone_light_skin_tone": "1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fb", "people_holding_hands_dark_skin_tone_medium_light_skin_tone": "1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fc", "people_holding_hands_dark_skin_tone_medium_skin_tone": "1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fd", "people_holding_hands_dark_skin_tone_medium_dark_skin_tone": "1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3fe", "people_holding_hands_dark_skin_tone_dark_skin_tone": "1f9d1-1f3ff-200d-1f91d-200d-1f9d1-1f3ff", "person_with_probing_cane_light_skin_tone": "1f9d1-1f3fb-200d-1f9af", "person_with_probing_cane_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f9af", "person_with_probing_cane_medium_skin_tone": "1f9d1-1f3fd-200d-1f9af", "person_with_probing_cane_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f9af", "person_with_probing_cane_dark_skin_tone": "1f9d1-1f3ff-200d-1f9af", "red_haired_person_light_skin_tone": "1f9d1-1f3fb-200d-1f9b0", "red_haired_person_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f9b0", "red_haired_person_medium_skin_tone": "1f9d1-1f3fd-200d-1f9b0", "red_haired_person_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f9b0", "red_haired_person_dark_skin_tone": "1f9d1-1f3ff-200d-1f9b0", "curly_haired_person_light_skin_tone": "1f9d1-1f3fb-200d-1f9b1", "curly_haired_person_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f9b1", "curly_haired_person_medium_skin_tone": "1f9d1-1f3fd-200d-1f9b1", "curly_haired_person_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f9b1", "curly_haired_person_dark_skin_tone": "1f9d1-1f3ff-200d-1f9b1", "bald_person_light_skin_tone": "1f9d1-1f3fb-200d-1f9b2", "bald_person_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f9b2", "bald_person_medium_skin_tone": "1f9d1-1f3fd-200d-1f9b2", "bald_person_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f9b2", "bald_person_dark_skin_tone": "1f9d1-1f3ff-200d-1f9b2", "white_haired_person_light_skin_tone": "1f9d1-1f3fb-200d-1f9b3", "white_haired_person_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f9b3", "white_haired_person_medium_skin_tone": "1f9d1-1f3fd-200d-1f9b3", "white_haired_person_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f9b3", "white_haired_person_dark_skin_tone": "1f9d1-1f3ff-200d-1f9b3", "person_in_motorized_wheelchair_light_skin_tone": "1f9d1-1f3fb-200d-1f9bc", "person_in_motorized_wheelchair_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f9bc", "person_in_motorized_wheelchair_medium_skin_tone": "1f9d1-1f3fd-200d-1f9bc", "person_in_motorized_wheelchair_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f9bc", "person_in_motorized_wheelchair_dark_skin_tone": "1f9d1-1f3ff-200d-1f9bc", "person_in_manual_wheelchair_light_skin_tone": "1f9d1-1f3fb-200d-1f9bd", "person_in_manual_wheelchair_medium_light_skin_tone": "1f9d1-1f3fc-200d-1f9bd", "person_in_manual_wheelchair_medium_skin_tone": "1f9d1-1f3fd-200d-1f9bd", "person_in_manual_wheelchair_medium_dark_skin_tone": "1f9d1-1f3fe-200d-1f9bd", "person_in_manual_wheelchair_dark_skin_tone": "1f9d1-1f3ff-200d-1f9bd", "health_worker_light_skin_tone": "1f9d1-1f3fb-200d-2695-fe0f", "health_worker_medium_light_skin_tone": "1f9d1-1f3fc-200d-2695-fe0f", "health_worker_medium_skin_tone": "1f9d1-1f3fd-200d-2695-fe0f", "health_worker_medium_dark_skin_tone": "1f9d1-1f3fe-200d-2695-fe0f", "health_worker_dark_skin_tone": "1f9d1-1f3ff-200d-2695-fe0f", "judge_light_skin_tone": "1f9d1-1f3fb-200d-2696-fe0f", "judge_medium_light_skin_tone": "1f9d1-1f3fc-200d-2696-fe0f", "judge_medium_skin_tone": "1f9d1-1f3fd-200d-2696-fe0f", "judge_medium_dark_skin_tone": "1f9d1-1f3fe-200d-2696-fe0f", "judge_dark_skin_tone": "1f9d1-1f3ff-200d-2696-fe0f", "pilot_light_skin_tone": "1f9d1-1f3fb-200d-2708-fe0f", "pilot_medium_light_skin_tone": "1f9d1-1f3fc-200d-2708-fe0f", "pilot_medium_skin_tone": "1f9d1-1f3fd-200d-2708-fe0f", "pilot_medium_dark_skin_tone": "1f9d1-1f3fe-200d-2708-fe0f", "pilot_dark_skin_tone": "1f9d1-1f3ff-200d-2708-fe0f", "adult_light_skin_tone": "1f9d1-1f3fb", "adult_medium_light_skin_tone": "1f9d1-1f3fc", "adult_medium_skin_tone": "1f9d1-1f3fd", "adult_medium_dark_skin_tone": "1f9d1-1f3fe", "adult_dark_skin_tone": "1f9d1-1f3ff", "child_light_skin_tone": "1f9d2-1f3fb", "child_medium_light_skin_tone": "1f9d2-1f3fc", "child_medium_skin_tone": "1f9d2-1f3fd", "child_medium_dark_skin_tone": "1f9d2-1f3fe", "child_dark_skin_tone": "1f9d2-1f3ff", "older_adult_light_skin_tone": "1f9d3-1f3fb", "older_adult_medium_light_skin_tone": "1f9d3-1f3fc", "older_adult_medium_skin_tone": "1f9d3-1f3fd", "older_adult_medium_dark_skin_tone": "1f9d3-1f3fe", "older_adult_dark_skin_tone": "1f9d3-1f3ff", "bearded_person_light_skin_tone": "1f9d4-1f3fb", "bearded_person_medium_light_skin_tone": "1f9d4-1f3fc", "bearded_person_medium_skin_tone": "1f9d4-1f3fd", "bearded_person_medium_dark_skin_tone": "1f9d4-1f3fe", "bearded_person_dark_skin_tone": "1f9d4-1f3ff", "person_with_headscarf_light_skin_tone": "1f9d5-1f3fb", "person_with_headscarf_medium_light_skin_tone": "1f9d5-1f3fc", "person_with_headscarf_medium_skin_tone": "1f9d5-1f3fd", "person_with_headscarf_medium_dark_skin_tone": "1f9d5-1f3fe", "person_with_headscarf_dark_skin_tone": "1f9d5-1f3ff", "woman_in_steamy_room_light_skin_tone": "1f9d6-1f3fb-200d-2640-fe0f", "woman_in_steamy_room_medium_light_skin_tone": "1f9d6-1f3fc-200d-2640-fe0f", "woman_in_steamy_room_medium_skin_tone": "1f9d6-1f3fd-200d-2640-fe0f", "woman_in_steamy_room_medium_dark_skin_tone": "1f9d6-1f3fe-200d-2640-fe0f", "woman_in_steamy_room_dark_skin_tone": "1f9d6-1f3ff-200d-2640-fe0f", "man_in_steamy_room_light_skin_tone": "1f9d6-1f3fb-200d-2642-fe0f", "man_in_steamy_room_medium_light_skin_tone": "1f9d6-1f3fc-200d-2642-fe0f", "man_in_steamy_room_medium_skin_tone": "1f9d6-1f3fd-200d-2642-fe0f", "man_in_steamy_room_medium_dark_skin_tone": "1f9d6-1f3fe-200d-2642-fe0f", "man_in_steamy_room_dark_skin_tone": "1f9d6-1f3ff-200d-2642-fe0f", "person_in_steamy_room_light_skin_tone": "1f9d6-1f3fb", "person_in_steamy_room_medium_light_skin_tone": "1f9d6-1f3fc", "person_in_steamy_room_medium_skin_tone": "1f9d6-1f3fd", "person_in_steamy_room_medium_dark_skin_tone": "1f9d6-1f3fe", "person_in_steamy_room_dark_skin_tone": "1f9d6-1f3ff", "woman_climbing_light_skin_tone": "1f9d7-1f3fb-200d-2640-fe0f", "woman_climbing_medium_light_skin_tone": "1f9d7-1f3fc-200d-2640-fe0f", "woman_climbing_medium_skin_tone": "1f9d7-1f3fd-200d-2640-fe0f", "woman_climbing_medium_dark_skin_tone": "1f9d7-1f3fe-200d-2640-fe0f", "woman_climbing_dark_skin_tone": "1f9d7-1f3ff-200d-2640-fe0f", "man_climbing_light_skin_tone": "1f9d7-1f3fb-200d-2642-fe0f", "man_climbing_medium_light_skin_tone": "1f9d7-1f3fc-200d-2642-fe0f", "man_climbing_medium_skin_tone": "1f9d7-1f3fd-200d-2642-fe0f", "man_climbing_medium_dark_skin_tone": "1f9d7-1f3fe-200d-2642-fe0f", "man_climbing_dark_skin_tone": "1f9d7-1f3ff-200d-2642-fe0f", "person_climbing_light_skin_tone": "1f9d7-1f3fb", "person_climbing_medium_light_skin_tone": "1f9d7-1f3fc", "person_climbing_medium_skin_tone": "1f9d7-1f3fd", "person_climbing_medium_dark_skin_tone": "1f9d7-1f3fe", "person_climbing_dark_skin_tone": "1f9d7-1f3ff", "woman_in_lotus_position_light_skin_tone": "1f9d8-1f3fb-200d-2640-fe0f", "woman_in_lotus_position_medium_light_skin_tone": "1f9d8-1f3fc-200d-2640-fe0f", "woman_in_lotus_position_medium_skin_tone": "1f9d8-1f3fd-200d-2640-fe0f", "woman_in_lotus_position_medium_dark_skin_tone": "1f9d8-1f3fe-200d-2640-fe0f", "woman_in_lotus_position_dark_skin_tone": "1f9d8-1f3ff-200d-2640-fe0f", "man_in_lotus_position_light_skin_tone": "1f9d8-1f3fb-200d-2642-fe0f", "man_in_lotus_position_medium_light_skin_tone": "1f9d8-1f3fc-200d-2642-fe0f", "man_in_lotus_position_medium_skin_tone": "1f9d8-1f3fd-200d-2642-fe0f", "man_in_lotus_position_medium_dark_skin_tone": "1f9d8-1f3fe-200d-2642-fe0f", "man_in_lotus_position_dark_skin_tone": "1f9d8-1f3ff-200d-2642-fe0f", "person_in_lotus_position_light_skin_tone": "1f9d8-1f3fb", "person_in_lotus_position_medium_light_skin_tone": "1f9d8-1f3fc", "person_in_lotus_position_medium_skin_tone": "1f9d8-1f3fd", "person_in_lotus_position_medium_dark_skin_tone": "1f9d8-1f3fe", "person_in_lotus_position_dark_skin_tone": "1f9d8-1f3ff", "female_mage_light_skin_tone": "1f9d9-1f3fb-200d-2640-fe0f", "female_mage_medium_light_skin_tone": "1f9d9-1f3fc-200d-2640-fe0f", "female_mage_medium_skin_tone": "1f9d9-1f3fd-200d-2640-fe0f", "female_mage_medium_dark_skin_tone": "1f9d9-1f3fe-200d-2640-fe0f", "female_mage_dark_skin_tone": "1f9d9-1f3ff-200d-2640-fe0f", "male_mage_light_skin_tone": "1f9d9-1f3fb-200d-2642-fe0f", "male_mage_medium_light_skin_tone": "1f9d9-1f3fc-200d-2642-fe0f", "male_mage_medium_skin_tone": "1f9d9-1f3fd-200d-2642-fe0f", "male_mage_medium_dark_skin_tone": "1f9d9-1f3fe-200d-2642-fe0f", "male_mage_dark_skin_tone": "1f9d9-1f3ff-200d-2642-fe0f", "mage_light_skin_tone": "1f9d9-1f3fb", "mage_medium_light_skin_tone": "1f9d9-1f3fc", "mage_medium_skin_tone": "1f9d9-1f3fd", "mage_medium_dark_skin_tone": "1f9d9-1f3fe", "mage_dark_skin_tone": "1f9d9-1f3ff", "female_fairy_light_skin_tone": "1f9da-1f3fb-200d-2640-fe0f", "female_fairy_medium_light_skin_tone": "1f9da-1f3fc-200d-2640-fe0f", "female_fairy_medium_skin_tone": "1f9da-1f3fd-200d-2640-fe0f", "female_fairy_medium_dark_skin_tone": "1f9da-1f3fe-200d-2640-fe0f", "female_fairy_dark_skin_tone": "1f9da-1f3ff-200d-2640-fe0f", "male_fairy_light_skin_tone": "1f9da-1f3fb-200d-2642-fe0f", "male_fairy_medium_light_skin_tone": "1f9da-1f3fc-200d-2642-fe0f", "male_fairy_medium_skin_tone": "1f9da-1f3fd-200d-2642-fe0f", "male_fairy_medium_dark_skin_tone": "1f9da-1f3fe-200d-2642-fe0f", "male_fairy_dark_skin_tone": "1f9da-1f3ff-200d-2642-fe0f", "fairy_light_skin_tone": "1f9da-1f3fb", "fairy_medium_light_skin_tone": "1f9da-1f3fc", "fairy_medium_skin_tone": "1f9da-1f3fd", "fairy_medium_dark_skin_tone": "1f9da-1f3fe", "fairy_dark_skin_tone": "1f9da-1f3ff", "female_vampire_light_skin_tone": "1f9db-1f3fb-200d-2640-fe0f", "female_vampire_medium_light_skin_tone": "1f9db-1f3fc-200d-2640-fe0f", "female_vampire_medium_skin_tone": "1f9db-1f3fd-200d-2640-fe0f", "female_vampire_medium_dark_skin_tone": "1f9db-1f3fe-200d-2640-fe0f", "female_vampire_dark_skin_tone": "1f9db-1f3ff-200d-2640-fe0f", "male_vampire_light_skin_tone": "1f9db-1f3fb-200d-2642-fe0f", "male_vampire_medium_light_skin_tone": "1f9db-1f3fc-200d-2642-fe0f", "male_vampire_medium_skin_tone": "1f9db-1f3fd-200d-2642-fe0f", "male_vampire_medium_dark_skin_tone": "1f9db-1f3fe-200d-2642-fe0f", "male_vampire_dark_skin_tone": "1f9db-1f3ff-200d-2642-fe0f", "vampire_light_skin_tone": "1f9db-1f3fb", "vampire_medium_light_skin_tone": "1f9db-1f3fc", "vampire_medium_skin_tone": "1f9db-1f3fd", "vampire_medium_dark_skin_tone": "1f9db-1f3fe", "vampire_dark_skin_tone": "1f9db-1f3ff", "mermaid_light_skin_tone": "1f9dc-1f3fb-200d-2640-fe0f", "mermaid_medium_light_skin_tone": "1f9dc-1f3fc-200d-2640-fe0f", "mermaid_medium_skin_tone": "1f9dc-1f3fd-200d-2640-fe0f", "mermaid_medium_dark_skin_tone": "1f9dc-1f3fe-200d-2640-fe0f", "mermaid_dark_skin_tone": "1f9dc-1f3ff-200d-2640-fe0f", "merman_light_skin_tone": "1f9dc-1f3fb-200d-2642-fe0f", "merman_medium_light_skin_tone": "1f9dc-1f3fc-200d-2642-fe0f", "merman_medium_skin_tone": "1f9dc-1f3fd-200d-2642-fe0f", "merman_medium_dark_skin_tone": "1f9dc-1f3fe-200d-2642-fe0f", "merman_dark_skin_tone": "1f9dc-1f3ff-200d-2642-fe0f", "merperson_light_skin_tone": "1f9dc-1f3fb", "merperson_medium_light_skin_tone": "1f9dc-1f3fc", "merperson_medium_skin_tone": "1f9dc-1f3fd", "merperson_medium_dark_skin_tone": "1f9dc-1f3fe", "merperson_dark_skin_tone": "1f9dc-1f3ff", "female_elf_light_skin_tone": "1f9dd-1f3fb-200d-2640-fe0f", "female_elf_medium_light_skin_tone": "1f9dd-1f3fc-200d-2640-fe0f", "female_elf_medium_skin_tone": "1f9dd-1f3fd-200d-2640-fe0f", "female_elf_medium_dark_skin_tone": "1f9dd-1f3fe-200d-2640-fe0f", "female_elf_dark_skin_tone": "1f9dd-1f3ff-200d-2640-fe0f", "male_elf_light_skin_tone": "1f9dd-1f3fb-200d-2642-fe0f", "male_elf_medium_light_skin_tone": "1f9dd-1f3fc-200d-2642-fe0f", "male_elf_medium_skin_tone": "1f9dd-1f3fd-200d-2642-fe0f", "male_elf_medium_dark_skin_tone": "1f9dd-1f3fe-200d-2642-fe0f", "male_elf_dark_skin_tone": "1f9dd-1f3ff-200d-2642-fe0f", "elf_light_skin_tone": "1f9dd-1f3fb", "elf_medium_light_skin_tone": "1f9dd-1f3fc", "elf_medium_skin_tone": "1f9dd-1f3fd", "elf_medium_dark_skin_tone": "1f9dd-1f3fe", "elf_dark_skin_tone": "1f9dd-1f3ff", "point_up_light_skin_tone": "261d-1f3fb", "point_up_medium_light_skin_tone": "261d-1f3fc", "point_up_medium_skin_tone": "261d-1f3fd", "point_up_medium_dark_skin_tone": "261d-1f3fe", "point_up_dark_skin_tone": "261d-1f3ff", "woman-bouncing-ball_light_skin_tone": "26f9-1f3fb-200d-2640-fe0f", "basketball_woman_light_skin_tone": "26f9-1f3fb-200d-2640-fe0f", "woman-bouncing-ball_medium_light_skin_tone": "26f9-1f3fc-200d-2640-fe0f", "basketball_woman_medium_light_skin_tone": "26f9-1f3fc-200d-2640-fe0f", "woman-bouncing-ball_medium_skin_tone": "26f9-1f3fd-200d-2640-fe0f", "basketball_woman_medium_skin_tone": "26f9-1f3fd-200d-2640-fe0f", "woman-bouncing-ball_medium_dark_skin_tone": "26f9-1f3fe-200d-2640-fe0f", "basketball_woman_medium_dark_skin_tone": "26f9-1f3fe-200d-2640-fe0f", "woman-bouncing-ball_dark_skin_tone": "26f9-1f3ff-200d-2640-fe0f", "basketball_woman_dark_skin_tone": "26f9-1f3ff-200d-2640-fe0f", "man-bouncing-ball_light_skin_tone": "26f9-1f3fb-200d-2642-fe0f", "basketball_man_light_skin_tone": "26f9-1f3fb-200d-2642-fe0f", "man-bouncing-ball_medium_light_skin_tone": "26f9-1f3fc-200d-2642-fe0f", "basketball_man_medium_light_skin_tone": "26f9-1f3fc-200d-2642-fe0f", "man-bouncing-ball_medium_skin_tone": "26f9-1f3fd-200d-2642-fe0f", "basketball_man_medium_skin_tone": "26f9-1f3fd-200d-2642-fe0f", "man-bouncing-ball_medium_dark_skin_tone": "26f9-1f3fe-200d-2642-fe0f", "basketball_man_medium_dark_skin_tone": "26f9-1f3fe-200d-2642-fe0f", "man-bouncing-ball_dark_skin_tone": "26f9-1f3ff-200d-2642-fe0f", "basketball_man_dark_skin_tone": "26f9-1f3ff-200d-2642-fe0f", "person_with_ball_light_skin_tone": "26f9-1f3fb", "person_with_ball_medium_light_skin_tone": "26f9-1f3fc", "person_with_ball_medium_skin_tone": "26f9-1f3fd", "person_with_ball_medium_dark_skin_tone": "26f9-1f3fe", "person_with_ball_dark_skin_tone": "26f9-1f3ff", "fist_light_skin_tone": "270a-1f3fb", "fist_raised_light_skin_tone": "270a-1f3fb", "fist_medium_light_skin_tone": "270a-1f3fc", "fist_raised_medium_light_skin_tone": "270a-1f3fc", "fist_medium_skin_tone": "270a-1f3fd", "fist_raised_medium_skin_tone": "270a-1f3fd", "fist_medium_dark_skin_tone": "270a-1f3fe", "fist_raised_medium_dark_skin_tone": "270a-1f3fe", "fist_dark_skin_tone": "270a-1f3ff", "fist_raised_dark_skin_tone": "270a-1f3ff", "hand_light_skin_tone": "270b-1f3fb", "raised_hand_light_skin_tone": "270b-1f3fb", "hand_medium_light_skin_tone": "270b-1f3fc", "raised_hand_medium_light_skin_tone": "270b-1f3fc", "hand_medium_skin_tone": "270b-1f3fd", "raised_hand_medium_skin_tone": "270b-1f3fd", "hand_medium_dark_skin_tone": "270b-1f3fe", "raised_hand_medium_dark_skin_tone": "270b-1f3fe", "hand_dark_skin_tone": "270b-1f3ff", "raised_hand_dark_skin_tone": "270b-1f3ff", "v_light_skin_tone": "270c-1f3fb", "v_medium_light_skin_tone": "270c-1f3fc", "v_medium_skin_tone": "270c-1f3fd", "v_medium_dark_skin_tone": "270c-1f3fe", "v_dark_skin_tone": "270c-1f3ff", "writing_hand_light_skin_tone": "270d-1f3fb", "writing_hand_medium_light_skin_tone": "270d-1f3fc", "writing_hand_medium_skin_tone": "270d-1f3fd", "writing_hand_medium_dark_skin_tone": "270d-1f3fe", "writing_hand_dark_skin_tone": "270d-1f3ff", "mattermost": "mattermost"}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/feature_flags.go b/vendor/github.com/mattermost/mattermost-server/v5/model/feature_flags.go
index 316c7ffb..7d3d6680 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/feature_flags.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/feature_flags.go
@@ -3,16 +3,92 @@
package model
+import (
+ "reflect"
+ "strconv"
+)
+
type FeatureFlags struct {
// Exists only for unit and manual testing.
// When set to a value, will be returned by the ping endpoint.
TestFeature string
+ // Exists only for testing bool functionality. Boolean feature flags interpret "on" or "true" as true and
+ // all other values as false.
+ TestBoolFeature bool
// Toggle on and off scheduled jobs for cloud user limit emails see MM-29999
CloudDelinquentEmailJobsEnabled bool
+
+ // Toggle on and off support for Collapsed Threads
+ CollapsedThreads bool
+
+ // Enable the remote cluster service for shared channels.
+ EnableRemoteClusterService bool
+
+ // AppsEnabled toggle the Apps framework functionalities both in server and client side
+ AppsEnabled bool
+
+ // Feature flags to control plugin versions
+ PluginIncidentManagement string `plugin_id:"com.mattermost.plugin-incident-management"`
+ PluginApps string `plugin_id:"com.mattermost.apps"`
+ PluginFocalboard string `plugin_id:"focalboard"`
+
+ // Enable timed dnd support for user status
+ TimedDND bool
}
func (f *FeatureFlags) SetDefaults() {
f.TestFeature = "off"
+ f.TestBoolFeature = false
f.CloudDelinquentEmailJobsEnabled = false
+ f.CollapsedThreads = true
+ f.EnableRemoteClusterService = false
+ f.AppsEnabled = false
+ f.PluginIncidentManagement = "1.16.1"
+ f.PluginApps = ""
+ f.PluginFocalboard = ""
+ f.TimedDND = false
+}
+
+func (f *FeatureFlags) Plugins() map[string]string {
+ rFFVal := reflect.ValueOf(f).Elem()
+ rFFType := reflect.TypeOf(f).Elem()
+
+ pluginVersions := make(map[string]string)
+ for i := 0; i < rFFVal.NumField(); i++ {
+ rFieldVal := rFFVal.Field(i)
+ rFieldType := rFFType.Field(i)
+
+ pluginId, hasPluginId := rFieldType.Tag.Lookup("plugin_id")
+ if !hasPluginId {
+ continue
+ }
+
+ pluginVersions[pluginId] = rFieldVal.String()
+ }
+
+ return pluginVersions
+}
+
+// ToMap returns the feature flags as a map[string]string
+// Supports boolean and string feature flags.
+func (f *FeatureFlags) ToMap() map[string]string {
+ refStructVal := reflect.ValueOf(*f)
+ refStructType := reflect.TypeOf(*f)
+ ret := make(map[string]string)
+ for i := 0; i < refStructVal.NumField(); i++ {
+ refFieldVal := refStructVal.Field(i)
+ if !refFieldVal.IsValid() {
+ continue
+ }
+ refFieldType := refStructType.Field(i)
+ switch refFieldType.Type.Kind() {
+ case reflect.Bool:
+ ret[refFieldType.Name] = strconv.FormatBool(refFieldVal.Bool())
+ default:
+ ret[refFieldType.Name] = refFieldVal.String()
+ }
+ }
+
+ return ret
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/file.go b/vendor/github.com/mattermost/mattermost-server/v5/model/file.go
index 9f76bac1..d2cb8f34 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/file.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/file.go
@@ -12,11 +12,6 @@ const (
MaxImageSize = int64(6048 * 4032) // 24 megapixels, roughly 36MB as a raw image
)
-var (
- IMAGE_EXTENSIONS = [7]string{".jpg", ".jpeg", ".gif", ".bmp", ".png", ".tiff", "tif"}
- IMAGE_MIME_TYPES = map[string]string{".jpg": "image/jpeg", ".jpeg": "image/jpeg", ".gif": "image/gif", ".bmp": "image/bmp", ".png": "image/png", ".tiff": "image/tiff", ".tif": "image/tif"}
-)
-
type FileUploadResponse struct {
FileInfos []*FileInfo `json:"file_infos"`
ClientIds []string `json:"client_ids"`
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/file_info.go b/vendor/github.com/mattermost/mattermost-server/v5/model/file_info.go
index c622b8f2..2bad9023 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/file_info.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/file_info.go
@@ -4,19 +4,14 @@
package model
import (
- "bytes"
"encoding/json"
"image"
"image/gif"
- "image/jpeg"
"io"
"mime"
"net/http"
"path/filepath"
"strings"
-
- "github.com/disintegration/imaging"
- "github.com/mattermost/mattermost-server/v5/mlog"
)
const (
@@ -44,6 +39,7 @@ type FileInfo struct {
Id string `json:"id"`
CreatorId string `json:"user_id"`
PostId string `json:"post_id,omitempty"`
+ ChannelId string `db:"-" json:"channel_id"`
CreateAt int64 `json:"create_at"`
UpdateAt int64 `json:"update_at"`
DeleteAt int64 `json:"delete_at"`
@@ -59,6 +55,7 @@ type FileInfo struct {
HasPreviewImage bool `json:"has_preview_image,omitempty"`
MiniPreview *[]byte `json:"mini_preview"` // declared as *[]byte to avoid postgres/mysql differences in deserialization
Content string `json:"-"`
+ RemoteId *string `json:"remote_id"`
}
func (fi *FileInfo) ToJson() string {
@@ -72,9 +69,8 @@ func FileInfoFromJson(data io.Reader) *FileInfo {
var fi FileInfo
if err := decoder.Decode(&fi); err != nil {
return nil
- } else {
- return &fi
}
+ return &fi
}
func FileInfosToJson(infos []*FileInfo) string {
@@ -88,9 +84,8 @@ func FileInfosFromJson(data io.Reader) []*FileInfo {
var infos []*FileInfo
if err := decoder.Decode(&infos); err != nil {
return nil
- } else {
- return infos
}
+ return infos
}
func (fi *FileInfo) PreSave() {
@@ -105,6 +100,10 @@ func (fi *FileInfo) PreSave() {
if fi.UpdateAt < fi.CreateAt {
fi.UpdateAt = fi.CreateAt
}
+
+ if fi.RemoteId == nil {
+ fi.RemoteId = NewString("")
+ }
}
func (fi *FileInfo) IsValid() *AppError {
@@ -116,7 +115,7 @@ func (fi *FileInfo) IsValid() *AppError {
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.user_id.app_error", nil, "id="+fi.Id, http.StatusBadRequest)
}
- if len(fi.PostId) != 0 && !IsValidId(fi.PostId) {
+ if fi.PostId != "" && !IsValidId(fi.PostId) {
return NewAppError("FileInfo.IsValid", "model.file_info.is_valid.post_id.app_error", nil, "id="+fi.Id, http.StatusBadRequest)
}
@@ -157,19 +156,6 @@ func NewInfo(name string) *FileInfo {
return info
}
-func GenerateMiniPreviewImage(img image.Image) *[]byte {
- preview := imaging.Resize(img, 16, 16, imaging.Lanczos)
-
- buf := new(bytes.Buffer)
-
- if err := jpeg.Encode(buf, preview, &jpeg.Options{Quality: 90}); err != nil {
- mlog.Error("Unable to encode image as mini preview jpg", mlog.Err(err))
- return nil
- }
- data := buf.Bytes()
- return &data
-}
-
func GetInfoForBytes(name string, data io.ReadSeeker, size int) (*FileInfo, *AppError) {
info := &FileInfo{
Name: name,
@@ -196,13 +182,13 @@ func GetInfoForBytes(name string, data io.ReadSeeker, size int) (*FileInfo, *App
if info.MimeType == "image/gif" {
// Just show the gif itself instead of a preview image for animated gifs
data.Seek(0, io.SeekStart)
- if gifConfig, err := gif.DecodeAll(data); err != nil {
+ gifConfig, err := gif.DecodeAll(data)
+ if err != nil {
// Still return the rest of the info even though it doesn't appear to be an actual gif
info.HasPreviewImage = true
return info, NewAppError("GetInfoForBytes", "model.file_info.get.gif.app_error", nil, err.Error(), http.StatusBadRequest)
- } else {
- info.HasPreviewImage = len(gifConfig.Image) == 1
}
+ info.HasPreviewImage = len(gifConfig.Image) == 1
} else {
info.HasPreviewImage = true
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/file_info_list.go b/vendor/github.com/mattermost/mattermost-server/v5/model/file_info_list.go
new file mode 100644
index 00000000..cd9694f5
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/file_info_list.go
@@ -0,0 +1,128 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "io"
+ "sort"
+)
+
+type FileInfoList struct {
+ Order []string `json:"order"`
+ FileInfos map[string]*FileInfo `json:"file_infos"`
+ NextFileInfoId string `json:"next_file_info_id"`
+ PrevFileInfoId string `json:"prev_file_info_id"`
+}
+
+func NewFileInfoList() *FileInfoList {
+ return &FileInfoList{
+ Order: make([]string, 0),
+ FileInfos: make(map[string]*FileInfo),
+ NextFileInfoId: "",
+ PrevFileInfoId: "",
+ }
+}
+
+func (o *FileInfoList) ToSlice() []*FileInfo {
+ var fileInfos []*FileInfo
+ for _, id := range o.Order {
+ fileInfos = append(fileInfos, o.FileInfos[id])
+ }
+ return fileInfos
+}
+
+func (o *FileInfoList) ToJson() string {
+ b, err := json.Marshal(o)
+ if err != nil {
+ return ""
+ } else {
+ return string(b)
+ }
+}
+
+func (o *FileInfoList) MakeNonNil() {
+ if o.Order == nil {
+ o.Order = make([]string, 0)
+ }
+
+ if o.FileInfos == nil {
+ o.FileInfos = make(map[string]*FileInfo)
+ }
+}
+
+func (o *FileInfoList) AddOrder(id string) {
+ if o.Order == nil {
+ o.Order = make([]string, 0, 128)
+ }
+
+ o.Order = append(o.Order, id)
+}
+
+func (o *FileInfoList) AddFileInfo(fileInfo *FileInfo) {
+ if o.FileInfos == nil {
+ o.FileInfos = make(map[string]*FileInfo)
+ }
+
+ o.FileInfos[fileInfo.Id] = fileInfo
+}
+
+func (o *FileInfoList) UniqueOrder() {
+ keys := make(map[string]bool)
+ order := []string{}
+ for _, fileInfoId := range o.Order {
+ if _, value := keys[fileInfoId]; !value {
+ keys[fileInfoId] = true
+ order = append(order, fileInfoId)
+ }
+ }
+
+ o.Order = order
+}
+
+func (o *FileInfoList) Extend(other *FileInfoList) {
+ for fileInfoId := range other.FileInfos {
+ o.AddFileInfo(other.FileInfos[fileInfoId])
+ }
+
+ for _, fileInfoId := range other.Order {
+ o.AddOrder(fileInfoId)
+ }
+
+ o.UniqueOrder()
+}
+
+func (o *FileInfoList) SortByCreateAt() {
+ sort.Slice(o.Order, func(i, j int) bool {
+ return o.FileInfos[o.Order[i]].CreateAt > o.FileInfos[o.Order[j]].CreateAt
+ })
+}
+
+func (o *FileInfoList) Etag() string {
+ id := "0"
+ var t int64 = 0
+
+ for _, v := range o.FileInfos {
+ if v.UpdateAt > t {
+ t = v.UpdateAt
+ id = v.Id
+ } else if v.UpdateAt == t && v.Id > id {
+ t = v.UpdateAt
+ id = v.Id
+ }
+ }
+
+ orderId := ""
+ if len(o.Order) > 0 {
+ orderId = o.Order[0]
+ }
+
+ return Etag(orderId, id, t)
+}
+
+func FileInfoListFromJson(data io.Reader) *FileInfoList {
+ var o *FileInfoList
+ json.NewDecoder(data).Decode(&o)
+ return o
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/file_info_search_results.go b/vendor/github.com/mattermost/mattermost-server/v5/model/file_info_search_results.go
new file mode 100644
index 00000000..90f2922b
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/file_info_search_results.go
@@ -0,0 +1,37 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "io"
+)
+
+type FileInfoSearchMatches map[string][]string
+
+type FileInfoSearchResults struct {
+ *FileInfoList
+ Matches FileInfoSearchMatches `json:"matches"`
+}
+
+func MakeFileInfoSearchResults(fileInfos *FileInfoList, matches FileInfoSearchMatches) *FileInfoSearchResults {
+ return &FileInfoSearchResults{
+ fileInfos,
+ matches,
+ }
+}
+
+func (o *FileInfoSearchResults) ToJson() string {
+ b, err := json.Marshal(o)
+ if err != nil {
+ return ""
+ }
+ return string(b)
+}
+
+func FileInfoSearchResultsFromJson(data io.Reader) *FileInfoSearchResults {
+ var o *FileInfoSearchResults
+ json.NewDecoder(data).Decode(&o)
+ return o
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/group.go b/vendor/github.com/mattermost/mattermost-server/v5/model/group.go
index 49783c83..c70b7aa1 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/group.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/group.go
@@ -139,7 +139,7 @@ func (group *Group) IsValidForCreate() *AppError {
return NewAppError("Group.IsValidForCreate", "model.group.source.app_error", nil, "", http.StatusBadRequest)
}
- if len(group.RemoteId) > GroupRemoteIDMaxLength || (len(group.RemoteId) == 0 && group.requiresRemoteId()) {
+ if len(group.RemoteId) > GroupRemoteIDMaxLength || (group.RemoteId == "" && group.requiresRemoteId()) {
return NewAppError("Group.IsValidForCreate", "model.group.remote_id.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/group_syncable.go b/vendor/github.com/mattermost/mattermost-server/v5/model/group_syncable.go
index 6a4d4023..eb3bdf09 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/group_syncable.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/group_syncable.go
@@ -60,14 +60,14 @@ func (syncable *GroupSyncable) UnmarshalJSON(b []byte) error {
if err != nil {
return err
}
+ var channelId string
+ var teamId string
for key, value := range kvp {
switch key {
case "team_id":
- syncable.SyncableId = value.(string)
- syncable.Type = GroupSyncableTypeTeam
+ teamId = value.(string)
case "channel_id":
- syncable.SyncableId = value.(string)
- syncable.Type = GroupSyncableTypeChannel
+ channelId = value.(string)
case "group_id":
syncable.GroupId = value.(string)
case "auto_add":
@@ -75,30 +75,40 @@ func (syncable *GroupSyncable) UnmarshalJSON(b []byte) error {
default:
}
}
+ if channelId != "" {
+ syncable.TeamID = teamId
+ syncable.SyncableId = channelId
+ syncable.Type = GroupSyncableTypeChannel
+ } else {
+ syncable.SyncableId = teamId
+ syncable.Type = GroupSyncableTypeTeam
+ }
return nil
}
func (syncable *GroupSyncable) MarshalJSON() ([]byte, error) {
type Alias GroupSyncable
-
switch syncable.Type {
case GroupSyncableTypeTeam:
return json.Marshal(&struct {
- TeamID string `json:"team_id"`
- TeamDisplayName string `json:"team_display_name,omitempty"`
- TeamType string `json:"team_type,omitempty"`
+ TeamID string `json:"team_id"`
+ TeamDisplayName string `json:"team_display_name,omitempty"`
+ TeamType string `json:"team_type,omitempty"`
+ Type GroupSyncableType `json:"type,omitempty"`
*Alias
}{
TeamDisplayName: syncable.TeamDisplayName,
TeamType: syncable.TeamType,
TeamID: syncable.SyncableId,
+ Type: syncable.Type,
Alias: (*Alias)(syncable),
})
case GroupSyncableTypeChannel:
return json.Marshal(&struct {
- ChannelID string `json:"channel_id"`
- ChannelDisplayName string `json:"channel_display_name,omitempty"`
- ChannelType string `json:"channel_type,omitempty"`
+ ChannelID string `json:"channel_id"`
+ ChannelDisplayName string `json:"channel_display_name,omitempty"`
+ ChannelType string `json:"channel_type,omitempty"`
+ Type GroupSyncableType `json:"type,omitempty"`
TeamID string `json:"team_id,omitempty"`
TeamDisplayName string `json:"team_display_name,omitempty"`
@@ -109,6 +119,7 @@ func (syncable *GroupSyncable) MarshalJSON() ([]byte, error) {
ChannelID: syncable.SyncableId,
ChannelDisplayName: syncable.ChannelDisplayName,
ChannelType: syncable.ChannelType,
+ Type: syncable.Type,
TeamID: syncable.TeamID,
TeamDisplayName: syncable.TeamDisplayName,
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/guest_invite.go b/vendor/github.com/mattermost/mattermost-server/v5/model/guest_invite.go
index 3cdd4893..ac803a5d 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/guest_invite.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/guest_invite.go
@@ -23,7 +23,7 @@ func (i *GuestsInvite) IsValid() *AppError {
}
for _, email := range i.Emails {
- if len(email) > USER_EMAIL_MAX_LENGTH || len(email) == 0 || !IsValidEmail(email) {
+ if len(email) > USER_EMAIL_MAX_LENGTH || email == "" || !IsValidEmail(email) {
return NewAppError("GuestsInvite.IsValid", "model.guest.is_valid.email.app_error", nil, "email="+email, http.StatusBadRequest)
}
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/incoming_webhook.go b/vendor/github.com/mattermost/mattermost-server/v5/model/incoming_webhook.go
index 78f1e4e8..f8fffe20 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/incoming_webhook.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/incoming_webhook.go
@@ -182,9 +182,8 @@ func decodeIncomingWebhookRequest(by []byte) (*IncomingWebhookRequest, error) {
err := decoder.Decode(&o)
if err == nil {
return &o, nil
- } else {
- return nil, err
}
+ return nil, err
}
func IncomingWebhookRequestFromJson(data io.Reader) (*IncomingWebhookRequest, *AppError) {
@@ -211,7 +210,6 @@ func (o *IncomingWebhookRequest) ToJson() string {
b, err := json.Marshal(o)
if err != nil {
return ""
- } else {
- return string(b)
}
+ return string(b)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/initial_load.go b/vendor/github.com/mattermost/mattermost-server/v5/model/initial_load.go
index 9368f371..c533faa5 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/initial_load.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/initial_load.go
@@ -18,13 +18,13 @@ type InitialLoad struct {
NoAccounts bool `json:"no_accounts"`
}
-func (me *InitialLoad) ToJson() string {
- b, _ := json.Marshal(me)
+func (il *InitialLoad) ToJson() string {
+ b, _ := json.Marshal(il)
return string(b)
}
func InitialLoadFromJson(data io.Reader) *InitialLoad {
- var o *InitialLoad
- json.NewDecoder(data).Decode(&o)
- return o
+ var il *InitialLoad
+ json.NewDecoder(data).Decode(&il)
+ return il
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go b/vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go
index a572c9de..7124a7e3 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/integration_action.go
@@ -394,7 +394,7 @@ func (o *Post) StripActionIntegrations() {
func (o *Post) GetAction(id string) *PostAction {
for _, attachment := range o.Attachments() {
for _, action := range attachment.Actions {
- if action.Id == id {
+ if action != nil && action.Id == id {
return action
}
}
@@ -409,7 +409,7 @@ func (o *Post) GenerateActionIds() {
if attachments, ok := o.GetProp("attachments").([]*SlackAttachment); ok {
for _, attachment := range attachments {
for _, action := range attachment.Actions {
- if action.Id == "" {
+ if action != nil && action.Id == "" {
action.Id = NewId()
}
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/job.go b/vendor/github.com/mattermost/mattermost-server/v5/model/job.go
index 072bfb2b..78d5a4ff 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/job.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/job.go
@@ -22,7 +22,12 @@ const (
JOB_TYPE_EXPIRY_NOTIFY = "expiry_notify"
JOB_TYPE_PRODUCT_NOTICES = "product_notices"
JOB_TYPE_ACTIVE_USERS = "active_users"
+ JOB_TYPE_IMPORT_PROCESS = "import_process"
+ JOB_TYPE_IMPORT_DELETE = "import_delete"
+ JOB_TYPE_EXPORT_PROCESS = "export_process"
+ JOB_TYPE_EXPORT_DELETE = "export_delete"
JOB_TYPE_CLOUD = "cloud"
+ JOB_TYPE_RESEND_INVITATION_EMAIL = "resend_invitation_email"
JOB_STATUS_PENDING = "pending"
JOB_STATUS_IN_PROGRESS = "in_progress"
@@ -33,6 +38,25 @@ const (
JOB_STATUS_WARNING = "warning"
)
+var ALL_JOB_TYPES = [...]string{
+ JOB_TYPE_DATA_RETENTION,
+ JOB_TYPE_MESSAGE_EXPORT,
+ JOB_TYPE_ELASTICSEARCH_POST_INDEXING,
+ JOB_TYPE_ELASTICSEARCH_POST_AGGREGATION,
+ JOB_TYPE_BLEVE_POST_INDEXING,
+ JOB_TYPE_LDAP_SYNC,
+ JOB_TYPE_MIGRATIONS,
+ JOB_TYPE_PLUGINS,
+ JOB_TYPE_EXPIRY_NOTIFY,
+ JOB_TYPE_PRODUCT_NOTICES,
+ JOB_TYPE_ACTIVE_USERS,
+ JOB_TYPE_IMPORT_PROCESS,
+ JOB_TYPE_IMPORT_DELETE,
+ JOB_TYPE_EXPORT_PROCESS,
+ JOB_TYPE_EXPORT_DELETE,
+ JOB_TYPE_CLOUD,
+}
+
type Job struct {
Id string `json:"id"`
Type string `json:"type"`
@@ -66,7 +90,12 @@ func (j *Job) IsValid() *AppError {
case JOB_TYPE_PRODUCT_NOTICES:
case JOB_TYPE_EXPIRY_NOTIFY:
case JOB_TYPE_ACTIVE_USERS:
+ case JOB_TYPE_IMPORT_PROCESS:
+ case JOB_TYPE_IMPORT_DELETE:
+ case JOB_TYPE_EXPORT_PROCESS:
+ case JOB_TYPE_EXPORT_DELETE:
case JOB_TYPE_CLOUD:
+ case JOB_TYPE_RESEND_INVITATION_EMAIL:
default:
return NewAppError("Job.IsValid", "model.job.is_valid.type.app_error", nil, "id="+j.Id, http.StatusBadRequest)
}
@@ -94,9 +123,8 @@ func JobFromJson(data io.Reader) *Job {
var job Job
if err := json.NewDecoder(data).Decode(&job); err == nil {
return &job
- } else {
- return nil
}
+ return nil
}
func JobsToJson(jobs []*Job) string {
@@ -108,9 +136,8 @@ func JobsFromJson(data io.Reader) []*Job {
var jobs []*Job
if err := json.NewDecoder(data).Decode(&jobs); err == nil {
return jobs
- } else {
- return nil
}
+ return nil
}
func (j *Job) DataToJson() string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/license.go b/vendor/github.com/mattermost/mattermost-server/v5/model/license.go
index 3de4aba8..ab9e481a 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/license.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/license.go
@@ -5,8 +5,10 @@ package model
import (
"encoding/json"
+ "fmt"
"io"
"net/http"
+ "time"
)
const (
@@ -16,6 +18,22 @@ const (
LICENSE_RENEWAL_LINK = "https://mattermost.com/renew/"
)
+const (
+ SIXTY_DAYS = 60
+ FIFTY_EIGHT = 58
+ LICENSE_UP_FOR_RENEWAL_EMAIL_SENT = "LicenseUpForRenewalEmailSent"
+)
+
+var (
+ trialDuration = 30*(time.Hour*24) + (time.Hour * 8) // 720 hours (30 days) + 8 hours is trial license duration
+ adminTrialDuration = 30*(time.Hour*24) + (time.Hour * 23) + (time.Minute * 59) + (time.Second * 59) // 720 hours (30 days) + 23 hours, 59 mins and 59 seconds
+
+ // a sanctioned trial's duration is either more than the upper bound,
+ // or less than the lower bound
+ sanctionedTrialDurationLowerBound = 31*(time.Hour*24) + (time.Hour * 23) + (time.Minute * 59) + (time.Second * 59) // 744 hours (31 days) + 23 hours, 59 mins and 59 seconds
+ sanctionedTrialDurationUpperBound = 29*(time.Hour*24) + (time.Hour * 23) + (time.Minute * 59) + (time.Second * 59) // 696 hours (29 days) + 23 hours, 59 mins and 59 seconds
+)
+
type LicenseRecord struct {
Id string `json:"id"`
CreateAt int64 `json:"create_at"`
@@ -31,6 +49,7 @@ type License struct {
Features *Features `json:"features"`
SkuName string `json:"sku_name"`
SkuShortName string `json:"sku_short_name"`
+ IsTrial bool `json:"is_trial"`
}
type Customer struct {
@@ -63,6 +82,7 @@ type Features struct {
MFA *bool `json:"mfa"`
GoogleOAuth *bool `json:"google_oauth"`
Office365OAuth *bool `json:"office365_oauth"`
+ OpenId *bool `json:"openid"`
Compliance *bool `json:"compliance"`
Cluster *bool `json:"cluster"`
Metrics *bool `json:"metrics"`
@@ -83,6 +103,8 @@ type Features struct {
EnterprisePlugins *bool `json:"enterprise_plugins"`
AdvancedLogging *bool `json:"advanced_logging"`
Cloud *bool `json:"cloud"`
+ SharedChannels *bool `json:"shared_channels"`
+ RemoteClusterService *bool `json:"remote_cluster_service"`
// after we enabled more features we'll need to control them with this
FutureFeatures *bool `json:"future_features"`
@@ -95,6 +117,7 @@ func (f *Features) ToMap() map[string]interface{} {
"mfa": *f.MFA,
"google": *f.GoogleOAuth,
"office365": *f.Office365OAuth,
+ "openid": *f.OpenId,
"compliance": *f.Compliance,
"cluster": *f.Cluster,
"metrics": *f.Metrics,
@@ -112,6 +135,8 @@ func (f *Features) ToMap() map[string]interface{} {
"enterprise_plugins": *f.EnterprisePlugins,
"advanced_logging": *f.AdvancedLogging,
"cloud": *f.Cloud,
+ "shared_channels": *f.SharedChannels,
+ "remote_cluster_service": *f.RemoteClusterService,
"future": *f.FutureFeatures,
}
}
@@ -145,6 +170,10 @@ func (f *Features) SetDefaults() {
f.Office365OAuth = NewBool(*f.FutureFeatures)
}
+ if f.OpenId == nil {
+ f.OpenId = NewBool(*f.FutureFeatures)
+ }
+
if f.Compliance == nil {
f.Compliance = NewBool(*f.FutureFeatures)
}
@@ -224,6 +253,14 @@ func (f *Features) SetDefaults() {
if f.Cloud == nil {
f.Cloud = NewBool(false)
}
+
+ if f.SharedChannels == nil {
+ f.SharedChannels = NewBool(*f.FutureFeatures)
+ }
+
+ if f.RemoteClusterService == nil {
+ f.RemoteClusterService = NewBool(*f.FutureFeatures)
+ }
}
func (l *License) IsExpired() bool {
@@ -235,6 +272,18 @@ func (l *License) IsPastGracePeriod() bool {
return timeDiff > LICENSE_GRACE_PERIOD
}
+func (l *License) IsWithinExpirationPeriod() bool {
+ days := l.DaysToExpiration()
+ return days <= SIXTY_DAYS && days >= FIFTY_EIGHT
+}
+
+func (l *License) DaysToExpiration() int {
+ dif := l.ExpiresAt - GetMillis()
+ d, _ := time.ParseDuration(fmt.Sprint(dif) + "ms")
+ days := d.Hours() / 24
+ return int(days)
+}
+
func (l *License) IsStarted() bool {
return l.StartsAt < GetMillis()
}
@@ -244,6 +293,17 @@ func (l *License) ToJson() string {
return string(b)
}
+func (l *License) IsTrialLicense() bool {
+ return l.IsTrial || (l.ExpiresAt-l.StartsAt) == trialDuration.Milliseconds() || (l.ExpiresAt-l.StartsAt) == adminTrialDuration.Milliseconds()
+}
+
+func (l *License) IsSanctionedTrial() bool {
+ duration := l.ExpiresAt - l.StartsAt
+
+ return l.IsTrialLicense() &&
+ (duration >= sanctionedTrialDurationLowerBound.Milliseconds() || duration <= sanctionedTrialDurationUpperBound.Milliseconds())
+}
+
// NewTestLicense returns a license that expires in the future and has the given features.
func NewTestLicense(features ...string) *License {
ret := &License{
@@ -278,7 +338,7 @@ func (lr *LicenseRecord) IsValid() *AppError {
return NewAppError("LicenseRecord.IsValid", "model.license_record.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
}
- if len(lr.Bytes) == 0 || len(lr.Bytes) > 10000 {
+ if lr.Bytes == "" || len(lr.Bytes) > 10000 {
return NewAppError("LicenseRecord.IsValid", "model.license_record.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/manifest.go b/vendor/github.com/mattermost/mattermost-server/v5/model/manifest.go
index 7c09830a..3fba0890 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/manifest.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/manifest.go
@@ -147,7 +147,7 @@ type Manifest struct {
Id string `json:"id" yaml:"id"`
// The name to be displayed for the plugin.
- Name string `json:"name,omitempty" yaml:"name,omitempty"`
+ Name string `json:"name" yaml:"name"`
// A description of what your plugin is and does.
Description string `json:"description,omitempty" yaml:"description,omitempty"`
@@ -196,9 +196,21 @@ type Manifest struct {
}
type ManifestServer struct {
- // Executables are the paths to your executable binaries, specifying multiple entry points
- // for different platforms when bundled together in a single plugin.
- Executables *ManifestExecutables `json:"executables,omitempty" yaml:"executables,omitempty"`
+ // AllExecutables are the paths to your executable binaries, specifying multiple entry
+ // points for different platforms when bundled together in a single plugin.
+ AllExecutables map[string]string `json:"executables,omitempty" yaml:"executables,omitempty"`
+
+ // Executables is a legacy field populated with a subset of supported platform executables.
+ // When unmarshalling, Executables is authoritative for the platform executable paths it
+ // contains, overriding any values in AllExecutables. When marshalling, AllExecutables
+ // is authoritative.
+ //
+ // Code duplication is avoided when (un)marshalling by leveraging type aliases in the
+ // various (Un)Marshal(JSON|YAML) methods, since aliases don't inherit the aliased type's
+ // methods.
+ //
+ // In v6.0, we should remove this field and rename AllExecutables back to Executables.
+ Executables *ManifestExecutables `json:"-" yaml:"-"`
// Executable is the path to your executable binary. This should be relative to the root
// of your bundle and the location of the manifest file.
@@ -210,6 +222,79 @@ type ManifestServer struct {
Executable string `json:"executable" yaml:"executable"`
}
+func (ms *ManifestServer) MarshalJSON() ([]byte, error) {
+ type auxManifestServer ManifestServer
+
+ // Populate AllExecutables from Executables, if it exists.
+ if ms.Executables != nil {
+ if ms.AllExecutables == nil {
+ ms.AllExecutables = make(map[string]string)
+ }
+
+ ms.AllExecutables["linux-amd64"] = ms.Executables.LinuxAmd64
+ ms.AllExecutables["darwin-amd64"] = ms.Executables.DarwinAmd64
+ ms.AllExecutables["windows-amd64"] = ms.Executables.WindowsAmd64
+ }
+
+ return json.Marshal((*auxManifestServer)(ms))
+}
+
+func (ms *ManifestServer) UnmarshalJSON(data []byte) error {
+ type auxManifestServer ManifestServer
+
+ aux := (*auxManifestServer)(ms)
+ if err := json.Unmarshal(data, aux); err != nil {
+ return err
+ }
+
+ if len(aux.AllExecutables) > 0 {
+ ms.Executables = &ManifestExecutables{
+ LinuxAmd64: aux.AllExecutables["linux-amd64"],
+ DarwinAmd64: aux.AllExecutables["darwin-amd64"],
+ WindowsAmd64: aux.AllExecutables["windows-amd64"],
+ }
+ }
+
+ return nil
+}
+
+func (ms *ManifestServer) MarshalYAML() ([]byte, error) {
+ type auxManifestServer ManifestServer
+
+ // Populate AllExecutables from Executables, if it exists.
+ if ms.Executables != nil {
+ if ms.AllExecutables == nil {
+ ms.AllExecutables = make(map[string]string)
+ }
+
+ ms.AllExecutables["linux-amd64"] = ms.Executables.LinuxAmd64
+ ms.AllExecutables["darwin-amd64"] = ms.Executables.DarwinAmd64
+ ms.AllExecutables["windows-amd64"] = ms.Executables.WindowsAmd64
+ }
+
+ return yaml.Marshal((*auxManifestServer)(ms))
+}
+
+func (ms *ManifestServer) UnmarshalYAML(unmarshal func(interface{}) error) error {
+ type auxManifestServer ManifestServer
+
+ aux := (*auxManifestServer)(ms)
+ if err := unmarshal(&aux); err != nil {
+ return err
+ }
+
+ if len(aux.AllExecutables) > 0 {
+ ms.Executables = &ManifestExecutables{
+ LinuxAmd64: aux.AllExecutables["linux-amd64"],
+ DarwinAmd64: aux.AllExecutables["darwin-amd64"],
+ WindowsAmd64: aux.AllExecutables["windows-amd64"],
+ }
+ }
+
+ return nil
+}
+
+// ManifestExecutables is a legacy structure capturing a subet of the known platform executables.
type ManifestExecutables struct {
// LinuxAmd64 is the path to your executable binary for the corresponding platform
LinuxAmd64 string `json:"linux-amd64,omitempty" yaml:"linux-amd64,omitempty"`
@@ -287,14 +372,9 @@ func (m *Manifest) GetExecutableForRuntime(goOs, goArch string) string {
}
var executable string
- if server.Executables != nil {
- if goOs == "linux" && goArch == "amd64" {
- executable = server.Executables.LinuxAmd64
- } else if goOs == "darwin" && goArch == "amd64" {
- executable = server.Executables.DarwinAmd64
- } else if goOs == "windows" && goArch == "amd64" {
- executable = server.Executables.WindowsAmd64
- }
+ if len(server.AllExecutables) > 0 {
+ osArch := fmt.Sprintf("%s-%s", goOs, goArch)
+ executable = server.AllExecutables[osArch]
}
if executable == "" {
@@ -329,6 +409,10 @@ func (m *Manifest) IsValid() error {
return errors.New("invalid plugin ID")
}
+ if strings.TrimSpace(m.Name) == "" {
+ return errors.New("a plugin name is needed")
+ }
+
if m.HomepageURL != "" && !IsValidHttpUrl(m.HomepageURL) {
return errors.New("invalid HomepageURL")
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/marketplace_plugin.go b/vendor/github.com/mattermost/mattermost-server/v5/model/marketplace_plugin.go
index cccfb7f6..cad93dfb 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/marketplace_plugin.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/marketplace_plugin.go
@@ -20,8 +20,12 @@ type BaseMarketplacePlugin struct {
IconData string `json:"icon_data"`
DownloadURL string `json:"download_url"`
ReleaseNotesURL string `json:"release_notes_url"`
- Labels []MarketplaceLabel `json:"labels"`
- Signature string `json:"signature"` // Signature represents a signature of a plugin saved in base64 encoding.
+ Labels []MarketplaceLabel `json:"labels,omitempty"`
+ Hosting string `json:"hosting"` // Indicated if the plugin is limited to a certain hosting type
+ AuthorType string `json:"author_type"` // The maintainer of the plugin
+ ReleaseStage string `json:"release_stage"` // The stage in the software release cycle that the plugin is in
+ Enterprise bool `json:"enterprise"` // Indicated if the plugin is an enterprise plugin
+ Signature string `json:"signature"` // Signature represents a signature of a plugin saved in base64 encoding.
Manifest *Manifest `json:"manifest"`
}
@@ -83,6 +87,8 @@ type MarketplacePluginFilter struct {
Cloud bool
LocalOnly bool
Platform string
+ PluginId string
+ ReturnAllVersions bool
}
// ApplyToURL modifies the given url to include query string parameters for the request.
@@ -99,6 +105,8 @@ func (filter *MarketplacePluginFilter) ApplyToURL(u *url.URL) {
q.Add("cloud", strconv.FormatBool(filter.Cloud))
q.Add("local_only", strconv.FormatBool(filter.LocalOnly))
q.Add("platform", filter.Platform)
+ q.Add("plugin_id", filter.PluginId)
+ q.Add("return_all_versions", strconv.FormatBool(filter.ReturnAllVersions))
u.RawQuery = q.Encode()
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/message_export.go b/vendor/github.com/mattermost/mattermost-server/v5/model/message_export.go
index 88108e2e..f94d861f 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/message_export.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/message_export.go
@@ -29,3 +29,8 @@ type MessageExport struct {
PostOriginalId *string
PostFileIds StringArray
}
+
+type MessageExportCursor struct {
+ LastPostUpdateAt int64
+ LastPostId string
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/mfa_secret.go b/vendor/github.com/mattermost/mattermost-server/v5/model/mfa_secret.go
index 979ff342..b2293566 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/mfa_secret.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/mfa_secret.go
@@ -13,13 +13,13 @@ type MfaSecret struct {
QRCode string `json:"qr_code"`
}
-func (me *MfaSecret) ToJson() string {
- b, _ := json.Marshal(me)
+func (mfa *MfaSecret) ToJson() string {
+ b, _ := json.Marshal(mfa)
return string(b)
}
func MfaSecretFromJson(data io.Reader) *MfaSecret {
- var me *MfaSecret
- json.NewDecoder(data).Decode(&me)
- return me
+ var mfa *MfaSecret
+ json.NewDecoder(data).Decode(&mfa)
+ return mfa
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/migration.go b/vendor/github.com/mattermost/mattermost-server/v5/model/migration.go
index f552d168..019ca7b5 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/migration.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/migration.go
@@ -22,5 +22,17 @@ const (
MIGRATION_KEY_SIDEBAR_CATEGORIES_PHASE_2 = "migration_sidebar_categories_phase_2"
MIGRATION_KEY_ADD_CONVERT_CHANNEL_PERMISSIONS = "add_convert_channel_permissions"
MIGRATION_KEY_ADD_SYSTEM_ROLES_PERMISSIONS = "add_system_roles_permissions"
+ MIGRATION_KEY_ADD_BILLING_PERMISSIONS = "add_billing_permissions"
MIGRATION_KEY_ADD_MANAGE_SHARED_CHANNEL_PERMISSIONS = "manage_shared_channel_permissions"
+ MIGRATION_KEY_ADD_MANAGE_SECURE_CONNECTIONS_PERMISSIONS = "manage_secure_connections_permissions"
+ MIGRATION_KEY_ADD_DOWNLOAD_COMPLIANCE_EXPORT_RESULTS = "download_compliance_export_results"
+ MIGRATION_KEY_ADD_COMPLIANCE_SUBSECTION_PERMISSIONS = "compliance_subsection_permissions"
+ MIGRATION_KEY_ADD_EXPERIMENTAL_SUBSECTION_PERMISSIONS = "experimental_subsection_permissions"
+ MIGRATION_KEY_ADD_AUTHENTICATION_SUBSECTION_PERMISSIONS = "authentication_subsection_permissions"
+ MIGRATION_KEY_ADD_SITE_SUBSECTION_PERMISSIONS = "site_subsection_permissions"
+ MIGRATION_KEY_ADD_ENVIRONMENT_SUBSECTION_PERMISSIONS = "environment_subsection_permissions"
+ MIGRATION_KEY_ADD_REPORTING_SUBSECTION_PERMISSIONS = "reporting_subsection_permissions"
+ MIGRATION_KEY_ADD_TEST_EMAIL_ANCILLARY_PERMISSION = "test_email_ancillary_permission"
+ MIGRATION_KEY_ADD_ABOUT_SUBSECTION_PERMISSIONS = "about_subsection_permissions"
+ MIGRATION_KEY_ADD_INTEGRATIONS_SUBSECTION_PERMISSIONS = "integrations_subsection_permissions"
)
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/oauth.go b/vendor/github.com/mattermost/mattermost-server/v5/model/oauth.go
index 4a345a6e..07198116 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/oauth.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/oauth.go
@@ -53,11 +53,11 @@ func (a *OAuthApp) IsValid() *AppError {
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.creator_id.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
}
- if len(a.ClientSecret) == 0 || len(a.ClientSecret) > 128 {
+ if a.ClientSecret == "" || len(a.ClientSecret) > 128 {
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.client_secret.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
}
- if len(a.Name) == 0 || len(a.Name) > 64 {
+ if a.Name == "" || len(a.Name) > 64 {
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.name.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
}
@@ -71,7 +71,7 @@ func (a *OAuthApp) IsValid() *AppError {
}
}
- if len(a.Homepage) == 0 || len(a.Homepage) > 256 || !IsValidHttpUrl(a.Homepage) {
+ if a.Homepage == "" || len(a.Homepage) > 256 || !IsValidHttpUrl(a.Homepage) {
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.homepage.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
}
@@ -79,7 +79,7 @@ func (a *OAuthApp) IsValid() *AppError {
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.description.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
}
- if len(a.IconURL) > 0 {
+ if a.IconURL != "" {
if len(a.IconURL) > 512 || !IsValidHttpUrl(a.IconURL) {
return NewAppError("OAuthApp.IsValid", "model.oauth.is_valid.icon_url.app_error", nil, "app_id="+a.Id, http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/outgoing_webhook.go b/vendor/github.com/mattermost/mattermost-server/v5/model/outgoing_webhook.go
index d6cb2138..0d7a88fb 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/outgoing_webhook.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/outgoing_webhook.go
@@ -140,7 +140,7 @@ func (o *OutgoingWebhook) IsValid() *AppError {
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.user_id.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.ChannelId) != 0 && !IsValidId(o.ChannelId) {
+ if o.ChannelId != "" && !IsValidId(o.ChannelId) {
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
}
@@ -154,7 +154,7 @@ func (o *OutgoingWebhook) IsValid() *AppError {
if len(o.TriggerWords) != 0 {
for _, triggerWord := range o.TriggerWords {
- if len(triggerWord) == 0 {
+ if triggerWord == "" {
return NewAppError("OutgoingWebhook.IsValid", "model.outgoing_hook.is_valid.trigger_words.app_error", nil, "", http.StatusBadRequest)
}
}
@@ -215,7 +215,7 @@ func (o *OutgoingWebhook) PreUpdate() {
}
func (o *OutgoingWebhook) TriggerWordExactMatch(word string) bool {
- if len(word) == 0 {
+ if word == "" {
return false
}
@@ -229,7 +229,7 @@ func (o *OutgoingWebhook) TriggerWordExactMatch(word string) bool {
}
func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool {
- if len(word) == 0 {
+ if word == "" {
return false
}
@@ -243,7 +243,7 @@ func (o *OutgoingWebhook) TriggerWordStartsWith(word string) bool {
}
func (o *OutgoingWebhook) GetTriggerWord(word string, isExactMatch bool) (triggerWord string) {
- if len(word) == 0 {
+ if word == "" {
return
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/permission.go b/vendor/github.com/mattermost/mattermost-server/v5/model/permission.go
index d982962f..bc4de236 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/permission.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/permission.go
@@ -100,13 +100,69 @@ var PERMISSION_USE_GROUP_MENTIONS *Permission
var PERMISSION_READ_OTHER_USERS_TEAMS *Permission
var PERMISSION_EDIT_BRAND *Permission
var PERMISSION_MANAGE_SHARED_CHANNELS *Permission
+var PERMISSION_MANAGE_SECURE_CONNECTIONS *Permission
+var PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT *Permission
+var PERMISSION_CREATE_DATA_RETENTION_JOB *Permission
+var PERMISSION_READ_DATA_RETENTION_JOB *Permission
+var PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB *Permission
+var PERMISSION_READ_COMPLIANCE_EXPORT_JOB *Permission
+var PERMISSION_READ_AUDITS *Permission
+var PERMISSION_TEST_ELASTICSEARCH *Permission
+var PERMISSION_TEST_SITE_URL *Permission
+var PERMISSION_TEST_S3 *Permission
+var PERMISSION_RELOAD_CONFIG *Permission
+var PERMISSION_INVALIDATE_CACHES *Permission
+var PERMISSION_RECYCLE_DATABASE_CONNECTIONS *Permission
+var PERMISSION_PURGE_ELASTICSEARCH_INDEXES *Permission
+var PERMISSION_TEST_EMAIL *Permission
+var PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB *Permission
+var PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB *Permission
+var PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB *Permission
+var PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB *Permission
+var PERMISSION_PURGE_BLEVE_INDEXES *Permission
+var PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB *Permission
+var PERMISSION_CREATE_LDAP_SYNC_JOB *Permission
+var PERMISSION_READ_LDAP_SYNC_JOB *Permission
+var PERMISSION_TEST_LDAP *Permission
+var PERMISSION_INVALIDATE_EMAIL_INVITE *Permission
+var PERMISSION_GET_SAML_METADATA_FROM_IDP *Permission
+var PERMISSION_ADD_SAML_PUBLIC_CERT *Permission
+var PERMISSION_ADD_SAML_PRIVATE_CERT *Permission
+var PERMISSION_ADD_SAML_IDP_CERT *Permission
+var PERMISSION_REMOVE_SAML_PUBLIC_CERT *Permission
+var PERMISSION_REMOVE_SAML_PRIVATE_CERT *Permission
+var PERMISSION_REMOVE_SAML_IDP_CERT *Permission
+var PERMISSION_GET_SAML_CERT_STATUS *Permission
+var PERMISSION_ADD_LDAP_PUBLIC_CERT *Permission
+var PERMISSION_ADD_LDAP_PRIVATE_CERT *Permission
+var PERMISSION_REMOVE_LDAP_PUBLIC_CERT *Permission
+var PERMISSION_REMOVE_LDAP_PRIVATE_CERT *Permission
+var PERMISSION_GET_LOGS *Permission
+var PERMISSION_GET_ANALYTICS *Permission
+var PERMISSION_READ_LICENSE_INFORMATION *Permission
+var PERMISSION_MANAGE_LICENSE_INFORMATION *Permission
var PERMISSION_SYSCONSOLE_READ_ABOUT *Permission
var PERMISSION_SYSCONSOLE_WRITE_ABOUT *Permission
+var PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE *Permission
+
+var PERMISSION_SYSCONSOLE_READ_BILLING *Permission
+var PERMISSION_SYSCONSOLE_WRITE_BILLING *Permission
+
var PERMISSION_SYSCONSOLE_READ_REPORTING *Permission
var PERMISSION_SYSCONSOLE_WRITE_REPORTING *Permission
+var PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_REPORTING_SITE_STATISTICS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_REPORTING_TEAM_STATISTICS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_REPORTING_SERVER_LOGS *Permission
+
var PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS *Permission
var PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS *Permission
@@ -125,27 +181,156 @@ var PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS *Permission
var PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES *Permission
var PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES *Permission
+// DEPRECATED
var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT *Permission
+
+// DEPRECATED
var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT *Permission
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING *Permission
+
+var PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER *Permission
+var PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER *Permission
+
var PERMISSION_SYSCONSOLE_READ_SITE *Permission
var PERMISSION_SYSCONSOLE_WRITE_SITE *Permission
+var PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_EMOJI *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_POSTS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_SITE_NOTICES *Permission
+var PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES *Permission
+
var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION *Permission
var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION *Permission
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SIGNUP *Permission
+
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL *Permission
+
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_PASSWORD *Permission
+
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_MFA *Permission
+
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP *Permission
+
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML *Permission
+
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_OPENID *Permission
+
+var PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_GUEST_ACCESS *Permission
+
var PERMISSION_SYSCONSOLE_READ_PLUGINS *Permission
var PERMISSION_SYSCONSOLE_WRITE_PLUGINS *Permission
var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS *Permission
var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS *Permission
+var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT *Permission
+var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT *Permission
+
+var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF *Permission
+var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF *Permission
+
+var PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS *Permission
+
var PERMISSION_SYSCONSOLE_READ_COMPLIANCE *Permission
var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE *Permission
+var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY *Permission
+var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY *Permission
+
+var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT *Permission
+var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT *Permission
+
+var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING *Permission
+var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_MONITORING *Permission
+
+var PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE *Permission
+var PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE *Permission
+
var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL *Permission
var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL *Permission
+var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES *Permission
+var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURES *Permission
+
+var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS *Permission
+var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURE_FLAGS *Permission
+
+var PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE *Permission
+var PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE *Permission
+
// General permission that encompasses all system admin functions
// in the future this could be broken up to allow access to some
// admin functions but not others
@@ -526,6 +711,277 @@ func initializePermissions() {
"authentication.permissions.manage_shared_channels.description",
PermissionScopeSystem,
}
+ PERMISSION_MANAGE_SECURE_CONNECTIONS = &Permission{
+ "manage_secure_connections",
+ "authentication.permissions.manage_secure_connections.name",
+ "authentication.permissions.manage_secure_connections.description",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_CREATE_DATA_RETENTION_JOB = &Permission{
+ "create_data_retention_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_READ_DATA_RETENTION_JOB = &Permission{
+ "read_data_retention_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB = &Permission{
+ "create_compliance_export_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_READ_COMPLIANCE_EXPORT_JOB = &Permission{
+ "read_compliance_export_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_READ_AUDITS = &Permission{
+ "read_audits",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_PURGE_BLEVE_INDEXES = &Permission{
+ "purge_bleve_indexes",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB = &Permission{
+ "create_post_bleve_indexes_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_CREATE_LDAP_SYNC_JOB = &Permission{
+ "create_ldap_sync_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_READ_LDAP_SYNC_JOB = &Permission{
+ "read_ldap_sync_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_TEST_LDAP = &Permission{
+ "test_ldap",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_INVALIDATE_EMAIL_INVITE = &Permission{
+ "invalidate_email_invite",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_GET_SAML_METADATA_FROM_IDP = &Permission{
+ "get_saml_metadata_from_idp",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_ADD_SAML_PUBLIC_CERT = &Permission{
+ "add_saml_public_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_ADD_SAML_PRIVATE_CERT = &Permission{
+ "add_saml_private_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_ADD_SAML_IDP_CERT = &Permission{
+ "add_saml_idp_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_REMOVE_SAML_PUBLIC_CERT = &Permission{
+ "remove_saml_public_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_REMOVE_SAML_PRIVATE_CERT = &Permission{
+ "remove_saml_private_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_REMOVE_SAML_IDP_CERT = &Permission{
+ "remove_saml_idp_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_GET_SAML_CERT_STATUS = &Permission{
+ "get_saml_cert_status",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_ADD_LDAP_PUBLIC_CERT = &Permission{
+ "add_ldap_public_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_ADD_LDAP_PRIVATE_CERT = &Permission{
+ "add_ldap_private_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_REMOVE_LDAP_PUBLIC_CERT = &Permission{
+ "remove_ldap_public_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_REMOVE_LDAP_PRIVATE_CERT = &Permission{
+ "remove_ldap_private_cert",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_GET_LOGS = &Permission{
+ "get_logs",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_READ_LICENSE_INFORMATION = &Permission{
+ "read_license_information",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_GET_ANALYTICS = &Permission{
+ "get_analytics",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_MANAGE_LICENSE_INFORMATION = &Permission{
+ "manage_license_information",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT = &Permission{
+ "download_compliance_export_result",
+ "authentication.permissions.download_compliance_export_result.name",
+ "authentication.permissions.download_compliance_export_result.description",
+ PermissionScopeSystem,
+ }
+
+ PERMISSION_TEST_SITE_URL = &Permission{
+ "test_site_url",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_TEST_ELASTICSEARCH = &Permission{
+ "test_elasticsearch",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_TEST_S3 = &Permission{
+ "test_s3",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_RELOAD_CONFIG = &Permission{
+ "reload_config",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_INVALIDATE_CACHES = &Permission{
+ "invalidate_caches",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_RECYCLE_DATABASE_CONNECTIONS = &Permission{
+ "recycle_database_connections",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_PURGE_ELASTICSEARCH_INDEXES = &Permission{
+ "purge_elasticsearch_indexes",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_TEST_EMAIL = &Permission{
+ "test_email",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB = &Permission{
+ "create_elasticsearch_post_indexing_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB = &Permission{
+ "create_elasticsearch_post_aggregation_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB = &Permission{
+ "read_elasticsearch_post_indexing_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB = &Permission{
+ "read_elasticsearch_post_aggregation_job",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
PERMISSION_REMOVE_USER_FROM_TEAM = &Permission{
"remove_user_from_team",
"authentication.permissions.remove_user_from_team.name",
@@ -676,30 +1132,94 @@ func initializePermissions() {
"authentication.permissions.edit_brand.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_READ_ABOUT = &Permission{
"sysconsole_read_about",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_WRITE_ABOUT = &Permission{
"sysconsole_write_about",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE = &Permission{
+ "sysconsole_read_about_edition_and_license",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE = &Permission{
+ "sysconsole_write_about_edition_and_license",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_BILLING = &Permission{
+ "sysconsole_read_billing",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_BILLING = &Permission{
+ "sysconsole_write_billing",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ // DEPRECATED
PERMISSION_SYSCONSOLE_READ_REPORTING = &Permission{
"sysconsole_read_reporting",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_WRITE_REPORTING = &Permission{
"sysconsole_write_reporting",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS = &Permission{
+ "sysconsole_read_reporting_site_statistics",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_REPORTING_SITE_STATISTICS = &Permission{
+ "sysconsole_write_reporting_site_statistics",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS = &Permission{
+ "sysconsole_read_reporting_team_statistics",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_REPORTING_TEAM_STATISTICS = &Permission{
+ "sysconsole_write_reporting_team_statistics",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS = &Permission{
+ "sysconsole_read_reporting_server_logs",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_REPORTING_SERVER_LOGS = &Permission{
+ "sysconsole_write_reporting_server_logs",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS = &Permission{
"sysconsole_read_user_management_users",
"authentication.permissions.use_group_mentions.name",
@@ -772,42 +1292,422 @@ func initializePermissions() {
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_READ_ENVIRONMENT = &Permission{
"sysconsole_read_environment",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT = &Permission{
"sysconsole_write_environment",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER = &Permission{
+ "sysconsole_read_environment_web_server",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER = &Permission{
+ "sysconsole_write_environment_web_server",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE = &Permission{
+ "sysconsole_read_environment_database",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE = &Permission{
+ "sysconsole_write_environment_database",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH = &Permission{
+ "sysconsole_read_environment_elasticsearch",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH = &Permission{
+ "sysconsole_write_environment_elasticsearch",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE = &Permission{
+ "sysconsole_read_environment_file_storage",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE = &Permission{
+ "sysconsole_write_environment_file_storage",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY = &Permission{
+ "sysconsole_read_environment_image_proxy",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY = &Permission{
+ "sysconsole_write_environment_image_proxy",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP = &Permission{
+ "sysconsole_read_environment_smtp",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP = &Permission{
+ "sysconsole_write_environment_smtp",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER = &Permission{
+ "sysconsole_read_environment_push_notification_server",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER = &Permission{
+ "sysconsole_write_environment_push_notification_server",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY = &Permission{
+ "sysconsole_read_environment_high_availability",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY = &Permission{
+ "sysconsole_write_environment_high_availability",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING = &Permission{
+ "sysconsole_read_environment_rate_limiting",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING = &Permission{
+ "sysconsole_write_environment_rate_limiting",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING = &Permission{
+ "sysconsole_read_environment_logging",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING = &Permission{
+ "sysconsole_write_environment_logging",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS = &Permission{
+ "sysconsole_read_environment_session_lengths",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS = &Permission{
+ "sysconsole_write_environment_session_lengths",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING = &Permission{
+ "sysconsole_read_environment_performance_monitoring",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING = &Permission{
+ "sysconsole_write_environment_performance_monitoring",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER = &Permission{
+ "sysconsole_read_environment_developer",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER = &Permission{
+ "sysconsole_write_environment_developer",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ // DEPRECATED
PERMISSION_SYSCONSOLE_READ_SITE = &Permission{
"sysconsole_read_site",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_WRITE_SITE = &Permission{
"sysconsole_write_site",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+
+ PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION = &Permission{
+ "sysconsole_read_site_customization",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION = &Permission{
+ "sysconsole_write_site_customization",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION = &Permission{
+ "sysconsole_read_site_localization",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION = &Permission{
+ "sysconsole_write_site_localization",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS = &Permission{
+ "sysconsole_read_site_users_and_teams",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS = &Permission{
+ "sysconsole_write_site_users_and_teams",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS = &Permission{
+ "sysconsole_read_site_notifications",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS = &Permission{
+ "sysconsole_write_site_notifications",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER = &Permission{
+ "sysconsole_read_site_announcement_banner",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER = &Permission{
+ "sysconsole_write_site_announcement_banner",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_EMOJI = &Permission{
+ "sysconsole_read_site_emoji",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI = &Permission{
+ "sysconsole_write_site_emoji",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_POSTS = &Permission{
+ "sysconsole_read_site_posts",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS = &Permission{
+ "sysconsole_write_site_posts",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS = &Permission{
+ "sysconsole_read_site_file_sharing_and_downloads",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS = &Permission{
+ "sysconsole_write_site_file_sharing_and_downloads",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS = &Permission{
+ "sysconsole_read_site_public_links",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS = &Permission{
+ "sysconsole_write_site_public_links",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTICES = &Permission{
+ "sysconsole_read_site_notices",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES = &Permission{
+ "sysconsole_write_site_notices",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+
+ // Deprecated
PERMISSION_SYSCONSOLE_READ_AUTHENTICATION = &Permission{
"sysconsole_read_authentication",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // Deprecated
PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION = &Permission{
"sysconsole_write_authentication",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP = &Permission{
+ "sysconsole_read_authentication_signup",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SIGNUP = &Permission{
+ "sysconsole_write_authentication_signup",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL = &Permission{
+ "sysconsole_read_authentication_email",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL = &Permission{
+ "sysconsole_write_authentication_email",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD = &Permission{
+ "sysconsole_read_authentication_password",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_PASSWORD = &Permission{
+ "sysconsole_write_authentication_password",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA = &Permission{
+ "sysconsole_read_authentication_mfa",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_MFA = &Permission{
+ "sysconsole_write_authentication_mfa",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP = &Permission{
+ "sysconsole_read_authentication_ldap",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP = &Permission{
+ "sysconsole_write_authentication_ldap",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML = &Permission{
+ "sysconsole_read_authentication_saml",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML = &Permission{
+ "sysconsole_write_authentication_saml",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID = &Permission{
+ "sysconsole_read_authentication_openid",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_OPENID = &Permission{
+ "sysconsole_write_authentication_openid",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS = &Permission{
+ "sysconsole_read_authentication_guest_access",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_GUEST_ACCESS = &Permission{
+ "sysconsole_write_authentication_guest_access",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
PERMISSION_SYSCONSOLE_READ_PLUGINS = &Permission{
"sysconsole_read_plugins",
"authentication.permissions.use_group_mentions.name",
@@ -820,89 +1720,293 @@ func initializePermissions() {
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_READ_INTEGRATIONS = &Permission{
"sysconsole_read_integrations",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS = &Permission{
"sysconsole_write_integrations",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT = &Permission{
+ "sysconsole_read_integrations_integration_management",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT = &Permission{
+ "sysconsole_write_integrations_integration_management",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS = &Permission{
+ "sysconsole_read_integrations_bot_accounts",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS = &Permission{
+ "sysconsole_write_integrations_bot_accounts",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF = &Permission{
+ "sysconsole_read_integrations_gif",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF = &Permission{
+ "sysconsole_write_integrations_gif",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS = &Permission{
+ "sysconsole_read_integrations_cors",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS = &Permission{
+ "sysconsole_write_integrations_cors",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ // DEPRECATED
PERMISSION_SYSCONSOLE_READ_COMPLIANCE = &Permission{
"sysconsole_read_compliance",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE = &Permission{
"sysconsole_write_compliance",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
- PERMISSION_SYSCONSOLE_READ_PLUGINS = &Permission{
- "sysconsole_read_plugins",
- "authentication.permissions.use_group_mentions.name",
- "authentication.permissions.use_group_mentions.description",
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY = &Permission{
+ "sysconsole_read_compliance_data_retention_policy",
+ "",
+ "",
PermissionScopeSystem,
}
- PERMISSION_SYSCONSOLE_WRITE_PLUGINS = &Permission{
- "sysconsole_write_plugins",
- "authentication.permissions.use_group_mentions.name",
- "authentication.permissions.use_group_mentions.description",
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY = &Permission{
+ "sysconsole_write_compliance_data_retention_policy",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT = &Permission{
+ "sysconsole_read_compliance_compliance_export",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT = &Permission{
+ "sysconsole_write_compliance_compliance_export",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING = &Permission{
+ "sysconsole_read_compliance_compliance_monitoring",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_MONITORING = &Permission{
+ "sysconsole_write_compliance_compliance_monitoring",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE = &Permission{
+ "sysconsole_read_compliance_custom_terms_of_service",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE = &Permission{
+ "sysconsole_write_compliance_custom_terms_of_service",
+ "",
+ "",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL = &Permission{
"sysconsole_read_experimental",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ // DEPRECATED
PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL = &Permission{
"sysconsole_write_experimental",
"authentication.permissions.use_group_mentions.name",
"authentication.permissions.use_group_mentions.description",
PermissionScopeSystem,
}
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES = &Permission{
+ "sysconsole_read_experimental_features",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURES = &Permission{
+ "sysconsole_write_experimental_features",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS = &Permission{
+ "sysconsole_read_experimental_feature_flags",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURE_FLAGS = &Permission{
+ "sysconsole_write_experimental_feature_flags",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE = &Permission{
+ "sysconsole_read_experimental_bleve",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE = &Permission{
+ "sysconsole_write_experimental_bleve",
+ "",
+ "",
+ PermissionScopeSystem,
+ }
SysconsoleReadPermissions = []*Permission{
- PERMISSION_SYSCONSOLE_READ_ABOUT,
- PERMISSION_SYSCONSOLE_READ_REPORTING,
+ PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE,
+ PERMISSION_SYSCONSOLE_READ_BILLING,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES,
- PERMISSION_SYSCONSOLE_READ_ENVIRONMENT,
- PERMISSION_SYSCONSOLE_READ_SITE,
- PERMISSION_SYSCONSOLE_READ_AUTHENTICATION,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER,
+ PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION,
+ PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION,
+ PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS,
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS,
+ PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER,
+ PERMISSION_SYSCONSOLE_READ_SITE_EMOJI,
+ PERMISSION_SYSCONSOLE_READ_SITE_POSTS,
+ PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS,
+ PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS,
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTICES,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS,
PERMISSION_SYSCONSOLE_READ_PLUGINS,
- PERMISSION_SYSCONSOLE_READ_INTEGRATIONS,
- PERMISSION_SYSCONSOLE_READ_COMPLIANCE,
- PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE,
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES,
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS,
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE,
}
SysconsoleWritePermissions = []*Permission{
- PERMISSION_SYSCONSOLE_WRITE_ABOUT,
- PERMISSION_SYSCONSOLE_WRITE_REPORTING,
+ PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE,
+ PERMISSION_SYSCONSOLE_WRITE_BILLING,
+ PERMISSION_SYSCONSOLE_WRITE_REPORTING_SITE_STATISTICS,
+ PERMISSION_SYSCONSOLE_WRITE_REPORTING_TEAM_STATISTICS,
+ PERMISSION_SYSCONSOLE_WRITE_REPORTING_SERVER_LOGS,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES,
- PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT,
- PERMISSION_SYSCONSOLE_WRITE_SITE,
- PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SIGNUP,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_PASSWORD,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_MFA,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_OPENID,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_GUEST_ACCESS,
PERMISSION_SYSCONSOLE_WRITE_PLUGINS,
- PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS,
- PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE,
- PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS,
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY,
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT,
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_MONITORING,
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE,
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURES,
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_FEATURE_FLAGS,
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE,
}
SystemScopedPermissionsMinusSysconsole := []*Permission{
@@ -937,6 +2041,47 @@ func initializePermissions() {
PERMISSION_DEMOTE_TO_GUEST,
PERMISSION_EDIT_BRAND,
PERMISSION_MANAGE_SHARED_CHANNELS,
+ PERMISSION_MANAGE_SECURE_CONNECTIONS,
+ PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT,
+ PERMISSION_CREATE_DATA_RETENTION_JOB,
+ PERMISSION_READ_DATA_RETENTION_JOB,
+ PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB,
+ PERMISSION_READ_COMPLIANCE_EXPORT_JOB,
+ PERMISSION_READ_AUDITS,
+ PERMISSION_TEST_SITE_URL,
+ PERMISSION_TEST_ELASTICSEARCH,
+ PERMISSION_TEST_S3,
+ PERMISSION_RELOAD_CONFIG,
+ PERMISSION_INVALIDATE_CACHES,
+ PERMISSION_RECYCLE_DATABASE_CONNECTIONS,
+ PERMISSION_PURGE_ELASTICSEARCH_INDEXES,
+ PERMISSION_TEST_EMAIL,
+ PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB,
+ PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB,
+ PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB,
+ PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB,
+ PERMISSION_PURGE_BLEVE_INDEXES,
+ PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB,
+ PERMISSION_CREATE_LDAP_SYNC_JOB,
+ PERMISSION_READ_LDAP_SYNC_JOB,
+ PERMISSION_TEST_LDAP,
+ PERMISSION_INVALIDATE_EMAIL_INVITE,
+ PERMISSION_GET_SAML_METADATA_FROM_IDP,
+ PERMISSION_ADD_SAML_PUBLIC_CERT,
+ PERMISSION_ADD_SAML_PRIVATE_CERT,
+ PERMISSION_ADD_SAML_IDP_CERT,
+ PERMISSION_REMOVE_SAML_PUBLIC_CERT,
+ PERMISSION_REMOVE_SAML_PRIVATE_CERT,
+ PERMISSION_REMOVE_SAML_IDP_CERT,
+ PERMISSION_GET_SAML_CERT_STATUS,
+ PERMISSION_ADD_LDAP_PUBLIC_CERT,
+ PERMISSION_ADD_LDAP_PRIVATE_CERT,
+ PERMISSION_REMOVE_LDAP_PUBLIC_CERT,
+ PERMISSION_REMOVE_LDAP_PRIVATE_CERT,
+ PERMISSION_GET_ANALYTICS,
+ PERMISSION_GET_LOGS,
+ PERMISSION_READ_LICENSE_INFORMATION,
+ PERMISSION_MANAGE_LICENSE_INFORMATION,
}
TeamScopedPermissions := []*Permission{
@@ -1000,6 +2145,22 @@ func initializePermissions() {
PERMISSION_MANAGE_OTHERS_WEBHOOKS,
PERMISSION_MANAGE_EMOJIS,
PERMISSION_MANAGE_OTHERS_EMOJIS,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION,
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION,
+ PERMISSION_SYSCONSOLE_READ_SITE,
+ PERMISSION_SYSCONSOLE_WRITE_SITE,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT,
+ PERMISSION_SYSCONSOLE_READ_REPORTING,
+ PERMISSION_SYSCONSOLE_WRITE_REPORTING,
+ PERMISSION_SYSCONSOLE_READ_ABOUT,
+ PERMISSION_SYSCONSOLE_WRITE_ABOUT,
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL,
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE,
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE,
}
AllPermissions = []*Permission{}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/plugin_cluster_event.go b/vendor/github.com/mattermost/mattermost-server/v5/model/plugin_cluster_event.go
new file mode 100644
index 00000000..ba5c8052
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/plugin_cluster_event.go
@@ -0,0 +1,28 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+const (
+ PluginClusterEventSendTypeReliable = CLUSTER_SEND_RELIABLE
+ PluginClusterEventSendTypeBestEffort = CLUSTER_SEND_BEST_EFFORT
+)
+
+// PluginClusterEvent is used to allow intra-cluster plugin communication.
+type PluginClusterEvent struct {
+ // Id is the unique identifier for the event.
+ Id string
+ // Data is the event payload.
+ Data []byte
+}
+
+// PluginClusterEventSendOptions defines some properties that apply when sending
+// plugin events across a cluster.
+type PluginClusterEventSendOptions struct {
+ // SendType defines the type of communication channel used to send the event.
+ SendType string
+ // TargetId identifies the cluster node to which the event should be sent.
+ // It should match the cluster id of the receiving instance.
+ // If empty, the event gets broadcasted to all other nodes.
+ TargetId string
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/plugin_key_value.go b/vendor/github.com/mattermost/mattermost-server/v5/model/plugin_key_value.go
index cd5406ea..73ef2d23 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/plugin_key_value.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/plugin_key_value.go
@@ -21,11 +21,11 @@ type PluginKeyValue struct {
}
func (kv *PluginKeyValue) IsValid() *AppError {
- if len(kv.PluginId) == 0 || utf8.RuneCountInString(kv.PluginId) > KEY_VALUE_PLUGIN_ID_MAX_RUNES {
+ if kv.PluginId == "" || utf8.RuneCountInString(kv.PluginId) > KEY_VALUE_PLUGIN_ID_MAX_RUNES {
return NewAppError("PluginKeyValue.IsValid", "model.plugin_key_value.is_valid.plugin_id.app_error", map[string]interface{}{"Max": KEY_VALUE_KEY_MAX_RUNES, "Min": 0}, "key="+kv.Key, http.StatusBadRequest)
}
- if len(kv.Key) == 0 || utf8.RuneCountInString(kv.Key) > KEY_VALUE_KEY_MAX_RUNES {
+ if kv.Key == "" || utf8.RuneCountInString(kv.Key) > KEY_VALUE_KEY_MAX_RUNES {
return NewAppError("PluginKeyValue.IsValid", "model.plugin_key_value.is_valid.key.app_error", map[string]interface{}{"Max": KEY_VALUE_KEY_MAX_RUNES, "Min": 0}, "key="+kv.Key, http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/post.go b/vendor/github.com/mattermost/mattermost-server/v5/model/post.go
index 6e29ba3e..b7dff5bc 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/post.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/post.go
@@ -14,7 +14,7 @@ import (
"sync"
"unicode/utf8"
- "github.com/mattermost/mattermost-server/v5/utils/markdown"
+ "github.com/mattermost/mattermost-server/v5/shared/markdown"
)
const (
@@ -45,7 +45,7 @@ const (
POST_EPHEMERAL = "system_ephemeral"
POST_CHANGE_CHANNEL_PRIVACY = "system_change_chan_privacy"
POST_ADD_BOT_TEAMS_CHANNELS = "add_bot_teams_channels"
- POST_FILEIDS_MAX_RUNES = 150
+ POST_FILEIDS_MAX_RUNES = 300
POST_FILENAMES_MAX_RUNES = 4000
POST_HASHTAGS_MAX_RUNES = 1000
POST_MESSAGE_MAX_RUNES_V1 = 4000
@@ -96,10 +96,14 @@ type Post struct {
FileIds StringArray `json:"file_ids,omitempty"`
PendingPostId string `json:"pending_post_id" db:"-"`
HasReactions bool `json:"has_reactions,omitempty"`
+ RemoteId *string `json:"remote_id,omitempty"`
// Transient data populated before sending a post to the client
- ReplyCount int64 `json:"reply_count" db:"-"`
- Metadata *PostMetadata `json:"metadata,omitempty" db:"-"`
+ ReplyCount int64 `json:"reply_count" db:"-"`
+ LastReplyAt int64 `json:"last_reply_at" db:"-"`
+ Participants []*User `json:"participants" db:"-"`
+ IsFollowing *bool `json:"is_following,omitempty" db:"-"` // for root posts in collapsed thread mode indicates if the current user is following this thread
+ Metadata *PostMetadata `json:"metadata,omitempty" db:"-"`
}
type PostEphemeral struct {
@@ -163,6 +167,12 @@ type PostForIndexing struct {
ParentCreateAt *int64 `json:"parent_create_at"`
}
+type FileForIndexing struct {
+ FileInfo
+ ChannelId string `json:"channel_id"`
+ Content string `json:"content"`
+}
+
// ShallowCopy is an utility function to shallow copy a Post to the given
// destination without touching the internal RWMutex.
func (o *Post) ShallowCopy(dst *Post) error {
@@ -194,7 +204,13 @@ func (o *Post) ShallowCopy(dst *Post) error {
dst.PendingPostId = o.PendingPostId
dst.HasReactions = o.HasReactions
dst.ReplyCount = o.ReplyCount
+ dst.Participants = o.Participants
+ dst.LastReplyAt = o.LastReplyAt
dst.Metadata = o.Metadata
+ if o.IsFollowing != nil {
+ dst.IsFollowing = NewBool(*o.IsFollowing)
+ }
+ dst.RemoteId = o.RemoteId
return nil
}
@@ -218,17 +234,35 @@ func (o *Post) ToUnsanitizedJson() string {
}
type GetPostsSinceOptions struct {
- ChannelId string
- Time int64
- SkipFetchThreads bool
+ UserId string
+ ChannelId string
+ Time int64
+ SkipFetchThreads bool
+ CollapsedThreads bool
+ CollapsedThreadsExtended bool
+ SortAscending bool
+}
+
+type GetPostsSinceForSyncCursor struct {
+ LastPostUpdateAt int64
+ LastPostId string
+}
+
+type GetPostsSinceForSyncOptions struct {
+ ChannelId string
+ ExcludeRemoteId string
+ IncludeDeleted bool
}
type GetPostsOptions struct {
- ChannelId string
- PostId string
- Page int
- PerPage int
- SkipFetchThreads bool
+ UserId string
+ ChannelId string
+ PostId string
+ Page int
+ PerPage int
+ SkipFetchThreads bool
+ CollapsedThreads bool
+ CollapsedThreadsExtended bool
}
func PostFromJson(data io.Reader) *Post {
@@ -262,19 +296,19 @@ func (o *Post) IsValid(maxPostSize int) *AppError {
return NewAppError("Post.IsValid", "model.post.is_valid.channel_id.app_error", nil, "", http.StatusBadRequest)
}
- if !(IsValidId(o.RootId) || len(o.RootId) == 0) {
+ if !(IsValidId(o.RootId) || o.RootId == "") {
return NewAppError("Post.IsValid", "model.post.is_valid.root_id.app_error", nil, "", http.StatusBadRequest)
}
- if !(IsValidId(o.ParentId) || len(o.ParentId) == 0) {
+ if !(IsValidId(o.ParentId) || o.ParentId == "") {
return NewAppError("Post.IsValid", "model.post.is_valid.parent_id.app_error", nil, "", http.StatusBadRequest)
}
- if len(o.ParentId) == 26 && len(o.RootId) == 0 {
+ if len(o.ParentId) == 26 && o.RootId == "" {
return NewAppError("Post.IsValid", "model.post.is_valid.root_parent.app_error", nil, "", http.StatusBadRequest)
}
- if !(len(o.OriginalId) == 26 || len(o.OriginalId) == 0) {
+ if !(len(o.OriginalId) == 26 || o.OriginalId == "") {
return NewAppError("Post.IsValid", "model.post.is_valid.original_id.app_error", nil, "", http.StatusBadRequest)
}
@@ -337,6 +371,9 @@ func (o *Post) IsValid(maxPostSize int) *AppError {
}
func (o *Post) SanitizeProps() {
+ if o == nil {
+ return
+ }
membersToSanitize := []string{
PROPS_ADD_CHANNEL_MEMBER,
}
@@ -346,6 +383,9 @@ func (o *Post) SanitizeProps() {
o.DelProp(member)
}
}
+ for _, p := range o.Participants {
+ p.Sanitize(map[string]bool{})
+ }
}
func (o *Post) PreSave() {
@@ -432,6 +472,19 @@ func (o *Post) IsSystemMessage() bool {
return len(o.Type) >= len(POST_SYSTEM_MESSAGE_PREFIX) && o.Type[:len(POST_SYSTEM_MESSAGE_PREFIX)] == POST_SYSTEM_MESSAGE_PREFIX
}
+// IsRemote returns true if the post originated on a remote cluster.
+func (o *Post) IsRemote() bool {
+ return o.RemoteId != nil && *o.RemoteId != ""
+}
+
+// GetRemoteID safely returns the remoteID or empty string if not remote.
+func (o *Post) GetRemoteID() string {
+ if o.RemoteId != nil {
+ return *o.RemoteId
+ }
+ return ""
+}
+
func (o *Post) IsJoinLeaveMessage() bool {
return o.Type == POST_JOIN_LEAVE ||
o.Type == POST_ADD_REMOVE ||
@@ -552,6 +605,25 @@ func (o *Post) Attachments() []*SlackAttachment {
if enc, err := json.Marshal(attachment); err == nil {
var decoded SlackAttachment
if json.Unmarshal(enc, &decoded) == nil {
+ // Ignoring nil actions
+ i := 0
+ for _, action := range decoded.Actions {
+ if action != nil {
+ decoded.Actions[i] = action
+ i++
+ }
+ }
+ decoded.Actions = decoded.Actions[:i]
+
+ // Ignoring nil fields
+ i = 0
+ for _, field := range decoded.Fields {
+ if field != nil {
+ decoded.Fields[i] = field
+ i++
+ }
+ }
+ decoded.Fields = decoded.Fields[:i]
ret = append(ret, &decoded)
}
}
@@ -665,3 +737,15 @@ func RewriteImageURLs(message string, f func(string) string) string {
return string(result)
}
+
+func (o *Post) IsFromOAuthBot() bool {
+ props := o.GetProps()
+ return props["from_webhook"] == "true" && props["override_username"] != ""
+}
+
+func (o *Post) ToNilIfInvalid() *Post {
+ if o.Id == "" {
+ return nil
+ }
+ return o
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/post_list.go b/vendor/github.com/mattermost/mattermost-server/v5/model/post_list.go
index d00b68b5..ba84f749 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/post_list.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/post_list.go
@@ -27,6 +27,11 @@ func NewPostList() *PostList {
func (o *PostList) ToSlice() []*Post {
var posts []*Post
+
+ if l := len(o.Posts); l > 0 {
+ posts = make([]*Post, 0, l)
+ }
+
for _, id := range o.Order {
posts = append(posts, o.Posts[id])
}
@@ -58,9 +63,8 @@ func (o *PostList) ToJson() string {
b, err := json.Marshal(&copy)
if err != nil {
return ""
- } else {
- return string(b)
}
+ return string(b)
}
func (o *PostList) MakeNonNil() {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/post_search_results.go b/vendor/github.com/mattermost/mattermost-server/v5/model/post_search_results.go
index 74ef4b52..fc9ba083 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/post_search_results.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/post_search_results.go
@@ -28,9 +28,8 @@ func (o *PostSearchResults) ToJson() string {
b, err := json.Marshal(&copy)
if err != nil {
return ""
- } else {
- return string(b)
}
+ return string(b)
}
func PostSearchResultsFromJson(data io.Reader) *PostSearchResults {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/preference.go b/vendor/github.com/mattermost/mattermost-server/v5/model/preference.go
index e752bb54..ee0d21aa 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/preference.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/preference.go
@@ -21,12 +21,14 @@ const (
PREFERENCE_CATEGORY_FAVORITE_CHANNEL = "favorite_channel"
PREFERENCE_CATEGORY_SIDEBAR_SETTINGS = "sidebar_settings"
- PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings"
- PREFERENCE_NAME_CHANNEL_DISPLAY_MODE = "channel_display_mode"
- PREFERENCE_NAME_COLLAPSE_SETTING = "collapse_previews"
- PREFERENCE_NAME_MESSAGE_DISPLAY = "message_display"
- PREFERENCE_NAME_NAME_FORMAT = "name_format"
- PREFERENCE_NAME_USE_MILITARY_TIME = "use_military_time"
+ PREFERENCE_CATEGORY_DISPLAY_SETTINGS = "display_settings"
+ PREFERENCE_NAME_COLLAPSED_THREADS_ENABLED = "collapsed_reply_threads"
+ PREFERENCE_NAME_CHANNEL_DISPLAY_MODE = "channel_display_mode"
+ PREFERENCE_NAME_COLLAPSE_SETTING = "collapse_previews"
+ PREFERENCE_NAME_MESSAGE_DISPLAY = "message_display"
+ PREFERENCE_NAME_NAME_FORMAT = "name_format"
+ PREFERENCE_NAME_USE_MILITARY_TIME = "use_military_time"
+ PREFERENCE_RECOMMENDED_NEXT_STEPS = "recommended_next_steps"
PREFERENCE_CATEGORY_THEME = "theme"
// the name for theme props is the team id
@@ -38,6 +40,12 @@ const (
PREFERENCE_NAME_LAST_CHANNEL = "channel"
PREFERENCE_NAME_LAST_TEAM = "team"
+ PREFERENCE_CATEGORY_CUSTOM_STATUS = "custom_status"
+ PREFERENCE_NAME_RECENT_CUSTOM_STATUSES = "recent_custom_statuses"
+ PREFERENCE_NAME_CUSTOM_STATUS_TUTORIAL_STATE = "custom_status_tutorial_state"
+
+ PREFERENCE_CUSTOM_STATUS_MODAL_VIEWED = "custom_status_modal_viewed"
+
PREFERENCE_CATEGORY_NOTIFICATIONS = "notifications"
PREFERENCE_NAME_EMAIL_INTERVAL = "email_interval"
@@ -73,7 +81,7 @@ func (o *Preference) IsValid() *AppError {
return NewAppError("Preference.IsValid", "model.preference.is_valid.id.app_error", nil, "user_id="+o.UserId, http.StatusBadRequest)
}
- if len(o.Category) == 0 || len(o.Category) > 32 {
+ if o.Category == "" || len(o.Category) > 32 {
return NewAppError("Preference.IsValid", "model.preference.is_valid.category.app_error", nil, "category="+o.Category, http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/preferences.go b/vendor/github.com/mattermost/mattermost-server/v5/model/preferences.go
index 6ed845b6..c2d24865 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/preferences.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/preferences.go
@@ -19,9 +19,8 @@ func PreferencesFromJson(data io.Reader) (Preferences, error) {
decoder := json.NewDecoder(data)
var o Preferences
err := decoder.Decode(&o)
- if err == nil {
- return o, nil
- } else {
+ if err != nil {
return nil, err
}
+ return o, nil
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/product_notices.go b/vendor/github.com/mattermost/mattermost-server/v5/model/product_notices.go
index 6aa88fc7..455ae475 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/product_notices.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/product_notices.go
@@ -5,8 +5,9 @@ package model
import (
"encoding/json"
- "github.com/pkg/errors"
"io"
+
+ "github.com/pkg/errors"
)
type ProductNotices []ProductNotice
@@ -39,18 +40,19 @@ func (n *ProductNotice) TeamAdminOnly() bool {
}
type Conditions struct {
- Audience *NoticeAudience `json:"audience,omitempty"`
- ClientType *NoticeClientType `json:"clientType,omitempty"` // Only show the notice on specific clients. Defaults to 'all'
- DesktopVersion []string `json:"desktopVersion,omitempty"` // What desktop client versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
- DisplayDate *string `json:"displayDate,omitempty"` // When to display the notice.; Examples:; "2020-03-01T00:00:00Z" - show on specified date; ">= 2020-03-01T00:00:00Z" - show after specified date; "< 2020-03-01T00:00:00Z" - show before the specified date; "> 2020-03-01T00:00:00Z <= 2020-04-01T00:00:00Z" - show only between the specified dates
- InstanceType *NoticeInstanceType `json:"instanceType,omitempty"`
- MobileVersion []string `json:"mobileVersion,omitempty"` // What mobile client versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
- NumberOfPosts *int64 `json:"numberOfPosts,omitempty"` // Only show the notice when server has more than specified number of posts
- NumberOfUsers *int64 `json:"numberOfUsers,omitempty"` // Only show the notice when server has more than specified number of users
- ServerConfig map[string]interface{} `json:"serverConfig,omitempty"` // Map of mattermost server config paths and their values. Notice will be displayed only if; the values match the target server config; Example: serverConfig: { "PluginSettings.Enable": true, "GuestAccountsSettings.Enable":; false }
- ServerVersion []string `json:"serverVersion,omitempty"` // What server versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
- Sku *NoticeSKU `json:"sku,omitempty"`
- UserConfig map[string]interface{} `json:"userConfig,omitempty"` // Map of user's settings and their values. Notice will be displayed only if the values; match the viewing users' config; Example: userConfig: { "new_sidebar.disabled": true }
+ Audience *NoticeAudience `json:"audience,omitempty"`
+ ClientType *NoticeClientType `json:"clientType,omitempty"` // Only show the notice on specific clients. Defaults to 'all'
+ DesktopVersion []string `json:"desktopVersion,omitempty"` // What desktop client versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
+ DisplayDate *string `json:"displayDate,omitempty"` // When to display the notice.; Examples:; "2020-03-01T00:00:00Z" - show on specified date; ">= 2020-03-01T00:00:00Z" - show after specified date; "< 2020-03-01T00:00:00Z" - show before the specified date; "> 2020-03-01T00:00:00Z <= 2020-04-01T00:00:00Z" - show only between the specified dates
+ InstanceType *NoticeInstanceType `json:"instanceType,omitempty"`
+ MobileVersion []string `json:"mobileVersion,omitempty"` // What mobile client versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
+ NumberOfPosts *int64 `json:"numberOfPosts,omitempty"` // Only show the notice when server has more than specified number of posts
+ NumberOfUsers *int64 `json:"numberOfUsers,omitempty"` // Only show the notice when server has more than specified number of users
+ ServerConfig map[string]interface{} `json:"serverConfig,omitempty"` // Map of mattermost server config paths and their values. Notice will be displayed only if; the values match the target server config; Example: serverConfig: { "PluginSettings.Enable": true, "GuestAccountsSettings.Enable":; false }
+ ServerVersion []string `json:"serverVersion,omitempty"` // What server versions does this notice apply to.; Format: semver ranges (https://devhints.io/semver); Example: [">=1.2.3 < ~2.4.x"]; Example: ["<v5.19", "v5.20-v5.22"]
+ Sku *NoticeSKU `json:"sku,omitempty"`
+ UserConfig map[string]interface{} `json:"userConfig,omitempty"` // Map of user's settings and their values. Notice will be displayed only if the values; match the viewing users' config; Example: userConfig: { "new_sidebar.disabled": true }
+ DeprecatingDependency *ExternalDependency `json:"deprecating_dependency,omitempty"` // External dependency which is going to be deprecated
}
type NoticeMessageInternal struct {
@@ -211,3 +213,8 @@ type ProductNoticeViewState struct {
Viewed int32
Timestamp int64
}
+
+type ExternalDependency struct {
+ Name string `json:"name"`
+ MinimumVersion string `json:"minimum_version"`
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/push_notification.go b/vendor/github.com/mattermost/mattermost-server/v5/model/push_notification.go
index 80945905..2a0dc658 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/push_notification.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/push_notification.go
@@ -70,23 +70,23 @@ type PushNotification struct {
IsIdLoaded bool `json:"is_id_loaded"`
}
-func (me *PushNotification) ToJson() string {
- b, _ := json.Marshal(me)
+func (pn *PushNotification) ToJson() string {
+ b, _ := json.Marshal(pn)
return string(b)
}
-func (me *PushNotification) DeepCopy() *PushNotification {
- copy := *me
+func (pn *PushNotification) DeepCopy() *PushNotification {
+ copy := *pn
return &copy
}
-func (me *PushNotification) SetDeviceIdAndPlatform(deviceId string) {
+func (pn *PushNotification) SetDeviceIdAndPlatform(deviceId string) {
index := strings.Index(deviceId, ":")
if index > -1 {
- me.Platform = deviceId[:index]
- me.DeviceId = deviceId[index+1:]
+ pn.Platform = deviceId[:index]
+ pn.DeviceId = deviceId[index+1:]
}
}
@@ -94,11 +94,11 @@ func PushNotificationFromJson(data io.Reader) (*PushNotification, error) {
if data == nil {
return nil, errors.New("push notification data can't be nil")
}
- var me *PushNotification
- if err := json.NewDecoder(data).Decode(&me); err != nil {
+ var pn *PushNotification
+ if err := json.NewDecoder(data).Decode(&pn); err != nil {
return nil, err
}
- return me, nil
+ return pn, nil
}
func PushNotificationAckFromJson(data io.Reader) (*PushNotificationAck, error) {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/push_response.go b/vendor/github.com/mattermost/mattermost-server/v5/model/push_response.go
index e6e8059b..227a089b 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/push_response.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/push_response.go
@@ -37,8 +37,8 @@ func NewErrorPushResponse(message string) PushResponse {
return m
}
-func (me *PushResponse) ToJson() string {
- b, _ := json.Marshal(me)
+func (pr *PushResponse) ToJson() string {
+ b, _ := json.Marshal(pr)
return string(b)
}
@@ -48,7 +48,6 @@ func PushResponseFromJson(data io.Reader) PushResponse {
var objmap PushResponse
if err := decoder.Decode(&objmap); err != nil {
return make(map[string]string)
- } else {
- return objmap
}
+ return objmap
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/reaction.go b/vendor/github.com/mattermost/mattermost-server/v5/model/reaction.go
index 50879c67..6d0ea68d 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/reaction.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/reaction.go
@@ -11,10 +11,13 @@ import (
)
type Reaction struct {
- UserId string `json:"user_id"`
- PostId string `json:"post_id"`
- EmojiName string `json:"emoji_name"`
- CreateAt int64 `json:"create_at"`
+ UserId string `json:"user_id"`
+ PostId string `json:"post_id"`
+ EmojiName string `json:"emoji_name"`
+ CreateAt int64 `json:"create_at"`
+ UpdateAt int64 `json:"update_at"`
+ DeleteAt int64 `json:"delete_at"`
+ RemoteId *string `json:"remote_id"`
}
func (o *Reaction) ToJson() string {
@@ -27,9 +30,8 @@ func ReactionFromJson(data io.Reader) *Reaction {
if err := json.NewDecoder(data).Decode(&o); err != nil {
return nil
- } else {
- return &o
}
+ return &o
}
func ReactionsToJson(o []*Reaction) string {
@@ -48,9 +50,8 @@ func MapPostIdToReactionsFromJson(data io.Reader) map[string][]*Reaction {
var objmap map[string][]*Reaction
if err := decoder.Decode(&objmap); err != nil {
return make(map[string][]*Reaction)
- } else {
- return objmap
}
+ return objmap
}
func ReactionsFromJson(data io.Reader) []*Reaction {
@@ -58,9 +59,8 @@ func ReactionsFromJson(data io.Reader) []*Reaction {
if err := json.NewDecoder(data).Decode(&o); err != nil {
return nil
- } else {
- return o
}
+ return o
}
func (o *Reaction) IsValid() *AppError {
@@ -74,7 +74,7 @@ func (o *Reaction) IsValid() *AppError {
validName := regexp.MustCompile(`^[a-zA-Z0-9\-\+_]+$`)
- if len(o.EmojiName) == 0 || len(o.EmojiName) > EMOJI_NAME_MAX_LENGTH || !validName.MatchString(o.EmojiName) {
+ if o.EmojiName == "" || len(o.EmojiName) > EMOJI_NAME_MAX_LENGTH || !validName.MatchString(o.EmojiName) {
return NewAppError("Reaction.IsValid", "model.reaction.is_valid.emoji_name.app_error", nil, "emoji_name="+o.EmojiName, http.StatusBadRequest)
}
@@ -82,6 +82,10 @@ func (o *Reaction) IsValid() *AppError {
return NewAppError("Reaction.IsValid", "model.reaction.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
}
+ if o.UpdateAt == 0 {
+ return NewAppError("Reaction.IsValid", "model.reaction.is_valid.update_at.app_error", nil, "", http.StatusBadRequest)
+ }
+
return nil
}
@@ -89,4 +93,18 @@ func (o *Reaction) PreSave() {
if o.CreateAt == 0 {
o.CreateAt = GetMillis()
}
+ o.UpdateAt = GetMillis()
+ o.DeleteAt = 0
+
+ if o.RemoteId == nil {
+ o.RemoteId = NewString("")
+ }
+}
+
+func (o *Reaction) PreUpdate() {
+ o.UpdateAt = GetMillis()
+
+ if o.RemoteId == nil {
+ o.RemoteId = NewString("")
+ }
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/remote_cluster.go b/vendor/github.com/mattermost/mattermost-server/v5/model/remote_cluster.go
new file mode 100644
index 00000000..2ec0cc9b
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/remote_cluster.go
@@ -0,0 +1,355 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+import (
+ "crypto/aes"
+ "crypto/cipher"
+ "crypto/rand"
+ "encoding/json"
+ "errors"
+ "io"
+ "net/http"
+ "regexp"
+ "strings"
+
+ "golang.org/x/crypto/scrypt"
+)
+
+const (
+ RemoteOfflineAfterMillis = 1000 * 60 * 5 // 5 minutes
+ RemoteNameMinLength = 1
+ RemoteNameMaxLength = 64
+)
+
+var (
+ validRemoteNameChars = regexp.MustCompile(`^[a-zA-Z0-9\.\-\_]+$`)
+)
+
+type RemoteCluster struct {
+ RemoteId string `json:"remote_id"`
+ RemoteTeamId string `json:"remote_team_id"`
+ Name string `json:"name"`
+ DisplayName string `json:"display_name"`
+ SiteURL string `json:"site_url"`
+ CreateAt int64 `json:"create_at"`
+ LastPingAt int64 `json:"last_ping_at"`
+ Token string `json:"token"`
+ RemoteToken string `json:"remote_token"`
+ Topics string `json:"topics"`
+ CreatorId string `json:"creator_id"`
+}
+
+func (rc *RemoteCluster) PreSave() {
+ if rc.RemoteId == "" {
+ rc.RemoteId = NewId()
+ }
+
+ if rc.DisplayName == "" {
+ rc.DisplayName = rc.Name
+ }
+
+ rc.Name = SanitizeUnicode(rc.Name)
+ rc.DisplayName = SanitizeUnicode(rc.DisplayName)
+ rc.Name = NormalizeRemoteName(rc.Name)
+
+ if rc.Token == "" {
+ rc.Token = NewId()
+ }
+
+ if rc.CreateAt == 0 {
+ rc.CreateAt = GetMillis()
+ }
+ rc.fixTopics()
+}
+
+func (rc *RemoteCluster) IsValid() *AppError {
+ if !IsValidId(rc.RemoteId) {
+ return NewAppError("RemoteCluster.IsValid", "model.cluster.is_valid.id.app_error", nil, "id="+rc.RemoteId, http.StatusBadRequest)
+ }
+
+ if !IsValidRemoteName(rc.Name) {
+ return NewAppError("RemoteCluster.IsValid", "model.cluster.is_valid.name.app_error", nil, "name="+rc.Name, http.StatusBadRequest)
+ }
+
+ if rc.CreateAt == 0 {
+ return NewAppError("RemoteCluster.IsValid", "model.cluster.is_valid.create_at.app_error", nil, "create_at=0", http.StatusBadRequest)
+ }
+
+ if !IsValidId(rc.CreatorId) {
+ return NewAppError("RemoteCluster.IsValid", "model.cluster.is_valid.id.app_error", nil, "creator_id="+rc.CreatorId, http.StatusBadRequest)
+ }
+ return nil
+}
+
+func IsValidRemoteName(s string) bool {
+ if len(s) < RemoteNameMinLength || len(s) > RemoteNameMaxLength {
+ return false
+ }
+ return validRemoteNameChars.MatchString(s)
+}
+
+func (rc *RemoteCluster) PreUpdate() {
+ if rc.DisplayName == "" {
+ rc.DisplayName = rc.Name
+ }
+
+ rc.Name = SanitizeUnicode(rc.Name)
+ rc.DisplayName = SanitizeUnicode(rc.DisplayName)
+ rc.Name = NormalizeRemoteName(rc.Name)
+ rc.fixTopics()
+}
+
+func (rc *RemoteCluster) IsOnline() bool {
+ return rc.LastPingAt > GetMillis()-RemoteOfflineAfterMillis
+}
+
+// fixTopics ensures all topics are separated by one, and only one, space.
+func (rc *RemoteCluster) fixTopics() {
+ trimmed := strings.TrimSpace(rc.Topics)
+ if trimmed == "" || trimmed == "*" {
+ rc.Topics = trimmed
+ return
+ }
+
+ var sb strings.Builder
+ sb.WriteString(" ")
+
+ ss := strings.Split(rc.Topics, " ")
+ for _, c := range ss {
+ cc := strings.TrimSpace(c)
+ if cc != "" {
+ sb.WriteString(cc)
+ sb.WriteString(" ")
+ }
+ }
+ rc.Topics = sb.String()
+}
+
+func (rc *RemoteCluster) ToJSON() (string, error) {
+ b, err := json.Marshal(rc)
+ if err != nil {
+ return "", err
+ }
+ return string(b), nil
+}
+
+func (rc *RemoteCluster) ToRemoteClusterInfo() RemoteClusterInfo {
+ return RemoteClusterInfo{
+ Name: rc.Name,
+ DisplayName: rc.DisplayName,
+ CreateAt: rc.CreateAt,
+ LastPingAt: rc.LastPingAt,
+ }
+}
+
+func NormalizeRemoteName(name string) string {
+ return strings.ToLower(name)
+}
+
+func RemoteClusterFromJSON(data io.Reader) (*RemoteCluster, *AppError) {
+ var rc RemoteCluster
+ err := json.NewDecoder(data).Decode(&rc)
+ if err != nil {
+ return nil, NewAppError("RemoteClusterFromJSON", "model.utils.decode_json.app_error", nil, err.Error(), http.StatusBadRequest)
+ }
+ return &rc, nil
+}
+
+// RemoteClusterInfo provides a subset of RemoteCluster fields suitable for sending to clients.
+type RemoteClusterInfo struct {
+ Name string `json:"name"`
+ DisplayName string `json:"display_name"`
+ CreateAt int64 `json:"create_at"`
+ LastPingAt int64 `json:"last_ping_at"`
+}
+
+// RemoteClusterFrame wraps a `RemoteClusterMsg` with credentials specific to a remote cluster.
+type RemoteClusterFrame struct {
+ RemoteId string `json:"remote_id"`
+ Msg RemoteClusterMsg `json:"msg"`
+}
+
+func (f *RemoteClusterFrame) IsValid() *AppError {
+ if !IsValidId(f.RemoteId) {
+ return NewAppError("RemoteClusterFrame.IsValid", "api.remote_cluster.invalid_id.app_error", nil, "RemoteId="+f.RemoteId, http.StatusBadRequest)
+ }
+
+ if err := f.Msg.IsValid(); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func RemoteClusterFrameFromJSON(data io.Reader) (*RemoteClusterFrame, *AppError) {
+ var frame RemoteClusterFrame
+ err := json.NewDecoder(data).Decode(&frame)
+ if err != nil {
+ return nil, NewAppError("RemoteClusterFrameFromJSON", "model.utils.decode_json.app_error", nil, err.Error(), http.StatusBadRequest)
+ }
+ return &frame, nil
+}
+
+// RemoteClusterMsg represents a message that is sent and received between clusters.
+// These are processed and routed via the RemoteClusters service.
+type RemoteClusterMsg struct {
+ Id string `json:"id"`
+ Topic string `json:"topic"`
+ CreateAt int64 `json:"create_at"`
+ Payload json.RawMessage `json:"payload"`
+}
+
+func NewRemoteClusterMsg(topic string, payload json.RawMessage) RemoteClusterMsg {
+ return RemoteClusterMsg{
+ Id: NewId(),
+ Topic: topic,
+ CreateAt: GetMillis(),
+ Payload: payload,
+ }
+}
+
+func (m RemoteClusterMsg) IsValid() *AppError {
+ if !IsValidId(m.Id) {
+ return NewAppError("RemoteClusterMsg.IsValid", "api.remote_cluster.invalid_id.app_error", nil, "Id="+m.Id, http.StatusBadRequest)
+ }
+
+ if m.Topic == "" {
+ return NewAppError("RemoteClusterMsg.IsValid", "api.remote_cluster.invalid_topic.app_error", nil, "Topic empty", http.StatusBadRequest)
+ }
+
+ if len(m.Payload) == 0 {
+ return NewAppError("RemoteClusterMsg.IsValid", "api.context.invalid_body_param.app_error", map[string]interface{}{"Name": "PayLoad"}, "", http.StatusBadRequest)
+ }
+
+ return nil
+}
+
+func RemoteClusterMsgFromJSON(data io.Reader) (RemoteClusterMsg, *AppError) {
+ var msg RemoteClusterMsg
+ err := json.NewDecoder(data).Decode(&msg)
+ if err != nil {
+ return RemoteClusterMsg{}, NewAppError("RemoteClusterMsgFromJSON", "model.utils.decode_json.app_error", nil, err.Error(), http.StatusBadRequest)
+ }
+ return msg, nil
+}
+
+// RemoteClusterPing represents a ping that is sent and received between clusters
+// to indicate a connection is alive. This is the payload for a `RemoteClusterMsg`.
+type RemoteClusterPing struct {
+ SentAt int64 `json:"sent_at"`
+ RecvAt int64 `json:"recv_at"`
+}
+
+func RemoteClusterPingFromRawJSON(raw json.RawMessage) (RemoteClusterPing, *AppError) {
+ var ping RemoteClusterPing
+ err := json.Unmarshal(raw, &ping)
+ if err != nil {
+ return RemoteClusterPing{}, NewAppError("RemoteClusterPingFromRawJSON", "model.utils.decode_json.app_error", nil, err.Error(), http.StatusBadRequest)
+ }
+ return ping, nil
+}
+
+// RemoteClusterInvite represents an invitation to establish a simple trust with a remote cluster.
+type RemoteClusterInvite struct {
+ RemoteId string `json:"remote_id"`
+ RemoteTeamId string `json:"remote_team_id"`
+ SiteURL string `json:"site_url"`
+ Token string `json:"token"`
+}
+
+func RemoteClusterInviteFromRawJSON(raw json.RawMessage) (*RemoteClusterInvite, *AppError) {
+ var invite RemoteClusterInvite
+ err := json.Unmarshal(raw, &invite)
+ if err != nil {
+ return nil, NewAppError("RemoteClusterInviteFromRawJSON", "model.utils.decode_json.app_error", nil, err.Error(), http.StatusBadRequest)
+ }
+ return &invite, nil
+}
+
+func (rci *RemoteClusterInvite) Encrypt(password string) ([]byte, error) {
+ raw, err := json.Marshal(&rci)
+ if err != nil {
+ return nil, err
+ }
+
+ // create random salt to be prepended to the blob.
+ salt := make([]byte, 16)
+ if _, err = io.ReadFull(rand.Reader, salt); err != nil {
+ return nil, err
+ }
+
+ key, err := scrypt.Key([]byte(password), salt, 32768, 8, 1, 32)
+ if err != nil {
+ return nil, err
+ }
+
+ block, err := aes.NewCipher(key[:])
+ if err != nil {
+ return nil, err
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return nil, err
+ }
+
+ // create random nonce
+ nonce := make([]byte, gcm.NonceSize())
+ if _, err = io.ReadFull(rand.Reader, nonce); err != nil {
+ return nil, err
+ }
+
+ // prefix the nonce to the cyphertext so we don't need to keep track of it.
+ sealed := gcm.Seal(nonce, nonce, raw, nil)
+
+ return append(salt, sealed...), nil
+}
+
+func (rci *RemoteClusterInvite) Decrypt(encrypted []byte, password string) error {
+ if len(encrypted) <= 16 {
+ return errors.New("invalid length")
+ }
+
+ // first 16 bytes is the salt that was used to derive a key
+ salt := encrypted[:16]
+ encrypted = encrypted[16:]
+
+ key, err := scrypt.Key([]byte(password), salt, 32768, 8, 1, 32)
+ if err != nil {
+ return err
+ }
+
+ block, err := aes.NewCipher(key[:])
+ if err != nil {
+ return err
+ }
+
+ gcm, err := cipher.NewGCM(block)
+ if err != nil {
+ return err
+ }
+
+ // nonce was prefixed to the cyphertext when encrypting so we need to extract it.
+ nonceSize := gcm.NonceSize()
+ nonce, cyphertext := encrypted[:nonceSize], encrypted[nonceSize:]
+
+ plain, err := gcm.Open(nil, nonce, cyphertext, nil)
+ if err != nil {
+ return err
+ }
+
+ // try to unmarshall the decrypted JSON to this invite struct.
+ return json.Unmarshal(plain, &rci)
+}
+
+// RemoteClusterQueryFilter provides filter criteria for RemoteClusterStore.GetAll
+type RemoteClusterQueryFilter struct {
+ ExcludeOffline bool
+ InChannel string
+ NotInChannel string
+ Topic string
+ CreatorId string
+ OnlyConfirmed bool
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/role.go b/vendor/github.com/mattermost/mattermost-server/v5/model/role.go
index 271e295b..fc1606ce 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/role.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/role.go
@@ -47,6 +47,12 @@ func init() {
// When updating the values here, the values in mattermost-redux must also be updated.
SysconsoleAncillaryPermissions = map[string][]*Permission{
+ PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id: {
+ PERMISSION_READ_LICENSE_INFORMATION,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_ABOUT_EDITION_AND_LICENSE.Id: {
+ PERMISSION_MANAGE_LICENSE_INFORMATION,
+ },
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id: {
PERMISSION_READ_PUBLIC_CHANNEL,
PERMISSION_READ_CHANNEL,
@@ -55,19 +61,44 @@ func init() {
},
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id: {
PERMISSION_READ_OTHER_USERS_TEAMS,
+ PERMISSION_GET_ANALYTICS,
},
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id: {
PERMISSION_LIST_PRIVATE_TEAMS,
PERMISSION_LIST_PUBLIC_TEAMS,
PERMISSION_VIEW_TEAM,
},
- PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id: {
- PERMISSION_READ_JOBS,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id: {
+ PERMISSION_READ_ELASTICSEARCH_POST_INDEXING_JOB,
+ PERMISSION_READ_ELASTICSEARCH_POST_AGGREGATION_JOB,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER.Id: {
+ PERMISSION_TEST_SITE_URL,
+ PERMISSION_RELOAD_CONFIG,
+ PERMISSION_INVALIDATE_CACHES,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE.Id: {
+ PERMISSION_RECYCLE_DATABASE_CONNECTIONS,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH.Id: {
+ PERMISSION_TEST_ELASTICSEARCH,
+ PERMISSION_CREATE_ELASTICSEARCH_POST_INDEXING_JOB,
+ PERMISSION_CREATE_ELASTICSEARCH_POST_AGGREGATION_JOB,
+ PERMISSION_PURGE_ELASTICSEARCH_INDEXES,
},
- PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id: {
- PERMISSION_READ_JOBS,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE.Id: {
+ PERMISSION_TEST_S3,
},
- PERMISSION_SYSCONSOLE_READ_REPORTING.Id: {
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP.Id: {
+ PERMISSION_TEST_EMAIL,
+ },
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.Id: {
+ PERMISSION_GET_LOGS,
+ },
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id: {
+ PERMISSION_GET_ANALYTICS,
+ },
+ PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS.Id: {
PERMISSION_VIEW_TEAM,
},
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_USERS.Id: {
@@ -102,12 +133,54 @@ func init() {
PERMISSION_CONVERT_PUBLIC_CHANNEL_TO_PRIVATE,
PERMISSION_CONVERT_PRIVATE_CHANNEL_TO_PUBLIC,
},
- PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id: {
- PERMISSION_MANAGE_JOBS,
- },
- PERMISSION_SYSCONSOLE_WRITE_SITE.Id: {
+ PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION.Id: {
PERMISSION_EDIT_BRAND,
},
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_DATA_RETENTION_POLICY.Id: {
+ PERMISSION_CREATE_DATA_RETENTION_JOB,
+ },
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY.Id: {
+ PERMISSION_READ_DATA_RETENTION_JOB,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_COMPLIANCE_COMPLIANCE_EXPORT.Id: {
+ PERMISSION_CREATE_COMPLIANCE_EXPORT_JOB,
+ PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT,
+ },
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT.Id: {
+ PERMISSION_READ_COMPLIANCE_EXPORT_JOB,
+ PERMISSION_DOWNLOAD_COMPLIANCE_EXPORT_RESULT,
+ },
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE.Id: {
+ PERMISSION_READ_AUDITS,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_EXPERIMENTAL_BLEVE.Id: {
+ PERMISSION_CREATE_POST_BLEVE_INDEXES_JOB,
+ PERMISSION_PURGE_BLEVE_INDEXES,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_LDAP.Id: {
+ PERMISSION_CREATE_LDAP_SYNC_JOB,
+ PERMISSION_ADD_LDAP_PUBLIC_CERT,
+ PERMISSION_REMOVE_LDAP_PUBLIC_CERT,
+ PERMISSION_ADD_LDAP_PRIVATE_CERT,
+ PERMISSION_REMOVE_LDAP_PRIVATE_CERT,
+ },
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id: {
+ PERMISSION_TEST_LDAP,
+ PERMISSION_READ_LDAP_SYNC_JOB,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_EMAIL.Id: {
+ PERMISSION_INVALIDATE_EMAIL_INVITE,
+ },
+ PERMISSION_SYSCONSOLE_WRITE_AUTHENTICATION_SAML.Id: {
+ PERMISSION_GET_SAML_METADATA_FROM_IDP,
+ PERMISSION_ADD_SAML_PUBLIC_CERT,
+ PERMISSION_ADD_SAML_PRIVATE_CERT,
+ PERMISSION_ADD_SAML_IDP_CERT,
+ PERMISSION_REMOVE_SAML_PUBLIC_CERT,
+ PERMISSION_REMOVE_SAML_PRIVATE_CERT,
+ PERMISSION_REMOVE_SAML_IDP_CERT,
+ PERMISSION_GET_SAML_CERT_STATUS,
+ },
}
SystemUserManagerDefaultPermissions = []string{
@@ -118,29 +191,76 @@ func init() {
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_GROUPS.Id,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id,
- PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS.Id,
}
SystemReadOnlyAdminDefaultPermissions = []string{
- PERMISSION_SYSCONSOLE_READ_ABOUT.Id,
- PERMISSION_SYSCONSOLE_READ_REPORTING.Id,
+ PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS.Id,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_PERMISSIONS.Id,
- PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id,
- PERMISSION_SYSCONSOLE_READ_SITE.Id,
- PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_EMOJI.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_POSTS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTICES.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS.Id,
PERMISSION_SYSCONSOLE_READ_PLUGINS.Id,
- PERMISSION_SYSCONSOLE_READ_COMPLIANCE.Id,
- PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id,
- PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS.Id,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_DATA_RETENTION_POLICY.Id,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_EXPORT.Id,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_COMPLIANCE_MONITORING.Id,
+ PERMISSION_SYSCONSOLE_READ_COMPLIANCE_CUSTOM_TERMS_OF_SERVICE.Id,
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURES.Id,
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_FEATURE_FLAGS.Id,
+ PERMISSION_SYSCONSOLE_READ_EXPERIMENTAL_BLEVE.Id,
}
SystemManagerDefaultPermissions = []string{
- PERMISSION_SYSCONSOLE_READ_ABOUT.Id,
- PERMISSION_SYSCONSOLE_READ_REPORTING.Id,
+ PERMISSION_SYSCONSOLE_READ_ABOUT_EDITION_AND_LICENSE.Id,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS.Id,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_TEAM_STATISTICS.Id,
+ PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_GROUPS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_TEAMS.Id,
PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_CHANNELS.Id,
@@ -149,20 +269,75 @@ func init() {
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_TEAMS.Id,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_CHANNELS.Id,
PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS.Id,
- PERMISSION_SYSCONSOLE_READ_ENVIRONMENT.Id,
- PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT.Id,
- PERMISSION_SYSCONSOLE_READ_SITE.Id,
- PERMISSION_SYSCONSOLE_WRITE_SITE.Id,
- PERMISSION_SYSCONSOLE_READ_AUTHENTICATION.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_WEB_SERVER.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DATABASE.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_ELASTICSEARCH.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_FILE_STORAGE.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_IMAGE_PROXY.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SMTP.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_HIGH_AVAILABILITY.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_RATE_LIMITING.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_LOGGING.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_SESSION_LENGTHS.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_PERFORMANCE_MONITORING.Id,
+ PERMISSION_SYSCONSOLE_READ_ENVIRONMENT_DEVELOPER.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_WEB_SERVER.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DATABASE.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_ELASTICSEARCH.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_FILE_STORAGE.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_IMAGE_PROXY.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SMTP.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PUSH_NOTIFICATION_SERVER.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_HIGH_AVAILABILITY.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_RATE_LIMITING.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_LOGGING.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_SESSION_LENGTHS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_PERFORMANCE_MONITORING.Id,
+ PERMISSION_SYSCONSOLE_WRITE_ENVIRONMENT_DEVELOPER.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_CUSTOMIZATION.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_CUSTOMIZATION.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_LOCALIZATION.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_LOCALIZATION.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_USERS_AND_TEAMS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_USERS_AND_TEAMS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTIFICATIONS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_NOTIFICATIONS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_ANNOUNCEMENT_BANNER.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_ANNOUNCEMENT_BANNER.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_EMOJI.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_EMOJI.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_POSTS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_POSTS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_FILE_SHARING_AND_DOWNLOADS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_FILE_SHARING_AND_DOWNLOADS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_PUBLIC_LINKS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_PUBLIC_LINKS.Id,
+ PERMISSION_SYSCONSOLE_READ_SITE_NOTICES.Id,
+ PERMISSION_SYSCONSOLE_WRITE_SITE_NOTICES.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SIGNUP.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_EMAIL.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_PASSWORD.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_MFA.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_LDAP.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_SAML.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_OPENID.Id,
+ PERMISSION_SYSCONSOLE_READ_AUTHENTICATION_GUEST_ACCESS.Id,
PERMISSION_SYSCONSOLE_READ_PLUGINS.Id,
- PERMISSION_SYSCONSOLE_READ_INTEGRATIONS.Id,
- PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_BOT_ACCOUNTS.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_GIF.Id,
+ PERMISSION_SYSCONSOLE_READ_INTEGRATIONS_CORS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_INTEGRATION_MANAGEMENT.Id,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_BOT_ACCOUNTS.Id,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_GIF.Id,
+ PERMISSION_SYSCONSOLE_WRITE_INTEGRATIONS_CORS.Id,
}
// Add the ancillary permissions to each system role
- SystemUserManagerDefaultPermissions = addAncillaryPermissions(SystemUserManagerDefaultPermissions)
- SystemReadOnlyAdminDefaultPermissions = addAncillaryPermissions(SystemReadOnlyAdminDefaultPermissions)
- SystemManagerDefaultPermissions = addAncillaryPermissions(SystemManagerDefaultPermissions)
+ SystemUserManagerDefaultPermissions = AddAncillaryPermissions(SystemUserManagerDefaultPermissions)
+ SystemReadOnlyAdminDefaultPermissions = AddAncillaryPermissions(SystemReadOnlyAdminDefaultPermissions)
+ SystemManagerDefaultPermissions = AddAncillaryPermissions(SystemManagerDefaultPermissions)
}
type RoleType string
@@ -278,7 +453,7 @@ func (r *Role) MergeChannelHigherScopedPermissions(higherScopedPermissions *Role
_, presentOnHigherScope := higherScopedPermissionsMap[cp.Id]
- // For the channel admin role always look to the higher scope to determine if the role has ther permission.
+ // For the channel admin role always look to the higher scope to determine if the role has their permission.
// The channel admin is a special case because they're not part of the UI to be "channel moderated", only
// channel members and channel guests are.
if higherScopedPermissions.RoleID == CHANNEL_ADMIN_ROLE_ID && presentOnHigherScope {
@@ -475,7 +650,7 @@ func (r *Role) IsValidWithoutId() bool {
return false
}
- if len(r.DisplayName) == 0 || len(r.DisplayName) > ROLE_DISPLAY_NAME_MAX_LENGTH {
+ if r.DisplayName == "" || len(r.DisplayName) > ROLE_DISPLAY_NAME_MAX_LENGTH {
return false
}
@@ -519,7 +694,7 @@ func CleanRoleNames(roleNames []string) ([]string, bool) {
}
func IsValidRoleName(roleName string) bool {
- if len(roleName) <= 0 || len(roleName) > ROLE_NAME_MAX_LENGTH {
+ if roleName == "" || len(roleName) > ROLE_NAME_MAX_LENGTH {
return false
}
@@ -765,7 +940,7 @@ func MakeDefaultRoles() map[string]*Role {
return roles
}
-func addAncillaryPermissions(permissions []string) []string {
+func AddAncillaryPermissions(permissions []string) []string {
for _, permission := range permissions {
if ancillaryPermissions, ok := SysconsoleAncillaryPermissions[permission]; ok {
for _, ancillaryPermission := range ancillaryPermissions {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/scheduled_task.go b/vendor/github.com/mattermost/mattermost-server/v5/model/scheduled_task.go
index 657cc749..cf20db63 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/scheduled_task.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/scheduled_task.go
@@ -11,42 +11,65 @@ import (
type TaskFunc func()
type ScheduledTask struct {
- Name string `json:"name"`
- Interval time.Duration `json:"interval"`
- Recurring bool `json:"recurring"`
- function func()
- cancel chan struct{}
- cancelled chan struct{}
+ Name string `json:"name"`
+ Interval time.Duration `json:"interval"`
+ Recurring bool `json:"recurring"`
+ function func()
+ cancel chan struct{}
+ cancelled chan struct{}
+ fromNextIntervalTime bool
}
func CreateTask(name string, function TaskFunc, timeToExecution time.Duration) *ScheduledTask {
- return createTask(name, function, timeToExecution, false)
+ return createTask(name, function, timeToExecution, false, false)
}
func CreateRecurringTask(name string, function TaskFunc, interval time.Duration) *ScheduledTask {
- return createTask(name, function, interval, true)
+ return createTask(name, function, interval, true, false)
}
-func createTask(name string, function TaskFunc, interval time.Duration, recurring bool) *ScheduledTask {
+func CreateRecurringTaskFromNextIntervalTime(name string, function TaskFunc, interval time.Duration) *ScheduledTask {
+ return createTask(name, function, interval, true, true)
+}
+
+func createTask(name string, function TaskFunc, interval time.Duration, recurring bool, fromNextIntervalTime bool) *ScheduledTask {
task := &ScheduledTask{
- Name: name,
- Interval: interval,
- Recurring: recurring,
- function: function,
- cancel: make(chan struct{}),
- cancelled: make(chan struct{}),
+ Name: name,
+ Interval: interval,
+ Recurring: recurring,
+ function: function,
+ cancel: make(chan struct{}),
+ cancelled: make(chan struct{}),
+ fromNextIntervalTime: fromNextIntervalTime,
}
go func() {
defer close(task.cancelled)
- ticker := time.NewTicker(interval)
+ var firstTick <-chan time.Time
+ var ticker *time.Ticker
+
+ if task.fromNextIntervalTime {
+ currTime := time.Now()
+ first := currTime.Truncate(interval)
+ if first.Before(currTime) {
+ first = first.Add(interval)
+ }
+ firstTick = time.After(time.Until(first))
+ ticker = &time.Ticker{C: nil}
+ } else {
+ firstTick = nil
+ ticker = time.NewTicker(interval)
+ }
defer func() {
ticker.Stop()
}()
for {
select {
+ case <-firstTick:
+ ticker = time.NewTicker(interval)
+ function()
case <-ticker.C:
function()
case <-task.cancel:
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/scheme.go b/vendor/github.com/mattermost/mattermost-server/v5/model/scheme.go
index 630f14a6..b5bbf34a 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/scheme.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/scheme.go
@@ -101,9 +101,8 @@ func SchemesFromJson(data io.Reader) []*Scheme {
var schemes []*Scheme
if err := json.NewDecoder(data).Decode(&schemes); err == nil {
return schemes
- } else {
- return nil
}
+ return nil
}
func (scheme *Scheme) IsValid() bool {
@@ -115,7 +114,7 @@ func (scheme *Scheme) IsValid() bool {
}
func (scheme *Scheme) IsValidForCreate() bool {
- if len(scheme.DisplayName) == 0 || len(scheme.DisplayName) > SCHEME_DISPLAY_NAME_MAX_LENGTH {
+ if scheme.DisplayName == "" || len(scheme.DisplayName) > SCHEME_DISPLAY_NAME_MAX_LENGTH {
return false
}
@@ -160,15 +159,15 @@ func (scheme *Scheme) IsValidForCreate() bool {
}
if scheme.Scope == SCHEME_SCOPE_CHANNEL {
- if len(scheme.DefaultTeamAdminRole) != 0 {
+ if scheme.DefaultTeamAdminRole != "" {
return false
}
- if len(scheme.DefaultTeamUserRole) != 0 {
+ if scheme.DefaultTeamUserRole != "" {
return false
}
- if len(scheme.DefaultTeamGuestRole) != 0 {
+ if scheme.DefaultTeamGuestRole != "" {
return false
}
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/search_params.go b/vendor/github.com/mattermost/mattermost-server/v5/model/search_params.go
index d34c8865..41a2db2a 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/search_params.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/search_params.go
@@ -25,6 +25,8 @@ type SearchParams struct {
ExcludedAfterDate string
BeforeDate string
ExcludedBeforeDate string
+ Extensions []string
+ ExcludedExtensions []string
OnDate string
ExcludedDate string
OrTerms bool
@@ -106,7 +108,7 @@ func (p *SearchParams) GetExcludedDateMillis() (int64, int64) {
return GetStartOfDayMillis(date, p.TimeZoneOffset), GetEndOfDayMillis(date, p.TimeZoneOffset)
}
-var searchFlags = [...]string{"from", "channel", "in", "before", "after", "on"}
+var searchFlags = [...]string{"from", "channel", "in", "before", "after", "on", "ext"}
type flag struct {
name string
@@ -214,7 +216,7 @@ func parseSearchFlags(input []string) ([]searchWord, []flag) {
// and remove extra pound #s
word = hashtagStart.ReplaceAllString(word, "#")
- if len(word) != 0 {
+ if word != "" {
words = append(words, searchWord{
word,
exclude,
@@ -265,6 +267,8 @@ func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
excludedBeforeDate := ""
onDate := ""
excludedDate := ""
+ excludedExtensions := []string{}
+ extensions := []string{}
for _, flag := range flags {
if flag.name == "in" || flag.name == "channel" {
@@ -297,12 +301,18 @@ func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
} else {
onDate = flag.value
}
+ } else if flag.name == "ext" {
+ if flag.exclude {
+ excludedExtensions = append(excludedExtensions, flag.value)
+ } else {
+ extensions = append(extensions, flag.value)
+ }
}
}
paramsList := []*SearchParams{}
- if len(plainTerms) > 0 || len(excludedPlainTerms) > 0 {
+ if plainTerms != "" || excludedPlainTerms != "" {
paramsList = append(paramsList, &SearchParams{
Terms: plainTerms,
ExcludedTerms: excludedPlainTerms,
@@ -315,13 +325,15 @@ func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
ExcludedAfterDate: excludedAfterDate,
BeforeDate: beforeDate,
ExcludedBeforeDate: excludedBeforeDate,
+ Extensions: extensions,
+ ExcludedExtensions: excludedExtensions,
OnDate: onDate,
ExcludedDate: excludedDate,
TimeZoneOffset: timeZoneOffset,
})
}
- if len(hashtagTerms) > 0 || len(excludedHashtagTerms) > 0 {
+ if hashtagTerms != "" || excludedHashtagTerms != "" {
paramsList = append(paramsList, &SearchParams{
Terms: hashtagTerms,
ExcludedTerms: excludedHashtagTerms,
@@ -334,6 +346,8 @@ func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
ExcludedAfterDate: excludedAfterDate,
BeforeDate: beforeDate,
ExcludedBeforeDate: excludedBeforeDate,
+ Extensions: extensions,
+ ExcludedExtensions: excludedExtensions,
OnDate: onDate,
ExcludedDate: excludedDate,
TimeZoneOffset: timeZoneOffset,
@@ -341,13 +355,14 @@ func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
}
// special case for when no terms are specified but we still have a filter
- if len(plainTerms) == 0 && len(hashtagTerms) == 0 &&
- len(excludedPlainTerms) == 0 && len(excludedHashtagTerms) == 0 &&
+ if plainTerms == "" && hashtagTerms == "" &&
+ excludedPlainTerms == "" && excludedHashtagTerms == "" &&
(len(inChannels) != 0 || len(fromUsers) != 0 ||
len(excludedChannels) != 0 || len(excludedUsers) != 0 ||
- len(afterDate) != 0 || len(excludedAfterDate) != 0 ||
- len(beforeDate) != 0 || len(excludedBeforeDate) != 0 ||
- len(onDate) != 0 || len(excludedDate) != 0) {
+ len(extensions) != 0 || len(excludedExtensions) != 0 ||
+ afterDate != "" || excludedAfterDate != "" ||
+ beforeDate != "" || excludedBeforeDate != "" ||
+ onDate != "" || excludedDate != "") {
paramsList = append(paramsList, &SearchParams{
Terms: "",
ExcludedTerms: "",
@@ -360,6 +375,8 @@ func ParseSearchParams(text string, timeZoneOffset int) []*SearchParams {
ExcludedAfterDate: excludedAfterDate,
BeforeDate: beforeDate,
ExcludedBeforeDate: excludedBeforeDate,
+ Extensions: extensions,
+ ExcludedExtensions: excludedExtensions,
OnDate: onDate,
ExcludedDate: excludedDate,
TimeZoneOffset: timeZoneOffset,
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/security_bulletin.go b/vendor/github.com/mattermost/mattermost-server/v5/model/security_bulletin.go
index ae66cf30..66a65812 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/security_bulletin.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/security_bulletin.go
@@ -15,8 +15,8 @@ type SecurityBulletin struct {
type SecurityBulletins []SecurityBulletin
-func (me *SecurityBulletin) ToJson() string {
- b, _ := json.Marshal(me)
+func (sb *SecurityBulletin) ToJson() string {
+ b, _ := json.Marshal(sb)
return string(b)
}
@@ -26,12 +26,12 @@ func SecurityBulletinFromJson(data io.Reader) *SecurityBulletin {
return o
}
-func (me SecurityBulletins) ToJson() string {
- if b, err := json.Marshal(me); err != nil {
+func (sb SecurityBulletins) ToJson() string {
+ b, err := json.Marshal(sb)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func SecurityBulletinsFromJson(data io.Reader) SecurityBulletins {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/serialized_gen.go b/vendor/github.com/mattermost/mattermost-server/v5/model/serialized_gen.go
deleted file mode 100644
index 1f16f1cb..00000000
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/serialized_gen.go
+++ /dev/null
@@ -1,1779 +0,0 @@
-// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
-// See LICENSE.txt for license information.
-
-package model
-
-// Code generated by github.com/tinylib/msgp DO NOT EDIT.
-
-import (
- "github.com/tinylib/msgp/msgp"
-)
-
-// DecodeMsg implements msgp.Decodable
-func (z *Session) DecodeMsg(dc *msgp.Reader) (err error) {
- var zb0001 uint32
- zb0001, err = dc.ReadArrayHeader()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if zb0001 != 13 {
- err = msgp.ArrayError{Wanted: 13, Got: zb0001}
- return
- }
- z.Id, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Id")
- return
- }
- z.Token, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Token")
- return
- }
- z.CreateAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "CreateAt")
- return
- }
- z.ExpiresAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "ExpiresAt")
- return
- }
- z.LastActivityAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "LastActivityAt")
- return
- }
- z.UserId, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "UserId")
- return
- }
- z.DeviceId, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "DeviceId")
- return
- }
- z.Roles, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- z.IsOAuth, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "IsOAuth")
- return
- }
- z.ExpiredNotify, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "ExpiredNotify")
- return
- }
- var zb0002 uint32
- zb0002, err = dc.ReadMapHeader()
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- if z.Props == nil {
- z.Props = make(StringMap, zb0002)
- } else if len(z.Props) > 0 {
- for key := range z.Props {
- delete(z.Props, key)
- }
- }
- for zb0002 > 0 {
- zb0002--
- var za0001 string
- var za0002 string
- za0001, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- za0002, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Props", za0001)
- return
- }
- z.Props[za0001] = za0002
- }
- var zb0003 uint32
- zb0003, err = dc.ReadArrayHeader()
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers")
- return
- }
- if cap(z.TeamMembers) >= int(zb0003) {
- z.TeamMembers = (z.TeamMembers)[:zb0003]
- } else {
- z.TeamMembers = make([]*TeamMember, zb0003)
- }
- for za0003 := range z.TeamMembers {
- if dc.IsNil() {
- err = dc.ReadNil()
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers", za0003)
- return
- }
- z.TeamMembers[za0003] = nil
- } else {
- if z.TeamMembers[za0003] == nil {
- z.TeamMembers[za0003] = new(TeamMember)
- }
- err = z.TeamMembers[za0003].DecodeMsg(dc)
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers", za0003)
- return
- }
- }
- }
- z.Local, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "Local")
- return
- }
- return
-}
-
-// EncodeMsg implements msgp.Encodable
-func (z *Session) EncodeMsg(en *msgp.Writer) (err error) {
- // array header, size 13
- err = en.Append(0x9d)
- if err != nil {
- return
- }
- err = en.WriteString(z.Id)
- if err != nil {
- err = msgp.WrapError(err, "Id")
- return
- }
- err = en.WriteString(z.Token)
- if err != nil {
- err = msgp.WrapError(err, "Token")
- return
- }
- err = en.WriteInt64(z.CreateAt)
- if err != nil {
- err = msgp.WrapError(err, "CreateAt")
- return
- }
- err = en.WriteInt64(z.ExpiresAt)
- if err != nil {
- err = msgp.WrapError(err, "ExpiresAt")
- return
- }
- err = en.WriteInt64(z.LastActivityAt)
- if err != nil {
- err = msgp.WrapError(err, "LastActivityAt")
- return
- }
- err = en.WriteString(z.UserId)
- if err != nil {
- err = msgp.WrapError(err, "UserId")
- return
- }
- err = en.WriteString(z.DeviceId)
- if err != nil {
- err = msgp.WrapError(err, "DeviceId")
- return
- }
- err = en.WriteString(z.Roles)
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- err = en.WriteBool(z.IsOAuth)
- if err != nil {
- err = msgp.WrapError(err, "IsOAuth")
- return
- }
- err = en.WriteBool(z.ExpiredNotify)
- if err != nil {
- err = msgp.WrapError(err, "ExpiredNotify")
- return
- }
- err = en.WriteMapHeader(uint32(len(z.Props)))
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- for za0001, za0002 := range z.Props {
- err = en.WriteString(za0001)
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- err = en.WriteString(za0002)
- if err != nil {
- err = msgp.WrapError(err, "Props", za0001)
- return
- }
- }
- err = en.WriteArrayHeader(uint32(len(z.TeamMembers)))
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers")
- return
- }
- for za0003 := range z.TeamMembers {
- if z.TeamMembers[za0003] == nil {
- err = en.WriteNil()
- if err != nil {
- return
- }
- } else {
- err = z.TeamMembers[za0003].EncodeMsg(en)
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers", za0003)
- return
- }
- }
- }
- err = en.WriteBool(z.Local)
- if err != nil {
- err = msgp.WrapError(err, "Local")
- return
- }
- return
-}
-
-// MarshalMsg implements msgp.Marshaler
-func (z *Session) MarshalMsg(b []byte) (o []byte, err error) {
- o = msgp.Require(b, z.Msgsize())
- // array header, size 13
- o = append(o, 0x9d)
- o = msgp.AppendString(o, z.Id)
- o = msgp.AppendString(o, z.Token)
- o = msgp.AppendInt64(o, z.CreateAt)
- o = msgp.AppendInt64(o, z.ExpiresAt)
- o = msgp.AppendInt64(o, z.LastActivityAt)
- o = msgp.AppendString(o, z.UserId)
- o = msgp.AppendString(o, z.DeviceId)
- o = msgp.AppendString(o, z.Roles)
- o = msgp.AppendBool(o, z.IsOAuth)
- o = msgp.AppendBool(o, z.ExpiredNotify)
- o = msgp.AppendMapHeader(o, uint32(len(z.Props)))
- for za0001, za0002 := range z.Props {
- o = msgp.AppendString(o, za0001)
- o = msgp.AppendString(o, za0002)
- }
- o = msgp.AppendArrayHeader(o, uint32(len(z.TeamMembers)))
- for za0003 := range z.TeamMembers {
- if z.TeamMembers[za0003] == nil {
- o = msgp.AppendNil(o)
- } else {
- o, err = z.TeamMembers[za0003].MarshalMsg(o)
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers", za0003)
- return
- }
- }
- }
- o = msgp.AppendBool(o, z.Local)
- return
-}
-
-// UnmarshalMsg implements msgp.Unmarshaler
-func (z *Session) UnmarshalMsg(bts []byte) (o []byte, err error) {
- var zb0001 uint32
- zb0001, bts, err = msgp.ReadArrayHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if zb0001 != 13 {
- err = msgp.ArrayError{Wanted: 13, Got: zb0001}
- return
- }
- z.Id, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Id")
- return
- }
- z.Token, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Token")
- return
- }
- z.CreateAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "CreateAt")
- return
- }
- z.ExpiresAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "ExpiresAt")
- return
- }
- z.LastActivityAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "LastActivityAt")
- return
- }
- z.UserId, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "UserId")
- return
- }
- z.DeviceId, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "DeviceId")
- return
- }
- z.Roles, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- z.IsOAuth, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "IsOAuth")
- return
- }
- z.ExpiredNotify, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "ExpiredNotify")
- return
- }
- var zb0002 uint32
- zb0002, bts, err = msgp.ReadMapHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- if z.Props == nil {
- z.Props = make(StringMap, zb0002)
- } else if len(z.Props) > 0 {
- for key := range z.Props {
- delete(z.Props, key)
- }
- }
- for zb0002 > 0 {
- var za0001 string
- var za0002 string
- zb0002--
- za0001, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- za0002, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Props", za0001)
- return
- }
- z.Props[za0001] = za0002
- }
- var zb0003 uint32
- zb0003, bts, err = msgp.ReadArrayHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers")
- return
- }
- if cap(z.TeamMembers) >= int(zb0003) {
- z.TeamMembers = (z.TeamMembers)[:zb0003]
- } else {
- z.TeamMembers = make([]*TeamMember, zb0003)
- }
- for za0003 := range z.TeamMembers {
- if msgp.IsNil(bts) {
- bts, err = msgp.ReadNilBytes(bts)
- if err != nil {
- return
- }
- z.TeamMembers[za0003] = nil
- } else {
- if z.TeamMembers[za0003] == nil {
- z.TeamMembers[za0003] = new(TeamMember)
- }
- bts, err = z.TeamMembers[za0003].UnmarshalMsg(bts)
- if err != nil {
- err = msgp.WrapError(err, "TeamMembers", za0003)
- return
- }
- }
- }
- z.Local, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Local")
- return
- }
- o = bts
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *Session) Msgsize() (s int) {
- s = 1 + msgp.StringPrefixSize + len(z.Id) + msgp.StringPrefixSize + len(z.Token) + msgp.Int64Size + msgp.Int64Size + msgp.Int64Size + msgp.StringPrefixSize + len(z.UserId) + msgp.StringPrefixSize + len(z.DeviceId) + msgp.StringPrefixSize + len(z.Roles) + msgp.BoolSize + msgp.BoolSize + msgp.MapHeaderSize
- if z.Props != nil {
- for za0001, za0002 := range z.Props {
- _ = za0002
- s += msgp.StringPrefixSize + len(za0001) + msgp.StringPrefixSize + len(za0002)
- }
- }
- s += msgp.ArrayHeaderSize
- for za0003 := range z.TeamMembers {
- if z.TeamMembers[za0003] == nil {
- s += msgp.NilSize
- } else {
- s += z.TeamMembers[za0003].Msgsize()
- }
- }
- s += msgp.BoolSize
- return
-}
-
-// DecodeMsg implements msgp.Decodable
-func (z *StringMap) DecodeMsg(dc *msgp.Reader) (err error) {
- var zb0003 uint32
- zb0003, err = dc.ReadMapHeader()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if (*z) == nil {
- (*z) = make(StringMap, zb0003)
- } else if len((*z)) > 0 {
- for key := range *z {
- delete((*z), key)
- }
- }
- for zb0003 > 0 {
- zb0003--
- var zb0001 string
- var zb0002 string
- zb0001, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- zb0002, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, zb0001)
- return
- }
- (*z)[zb0001] = zb0002
- }
- return
-}
-
-// EncodeMsg implements msgp.Encodable
-func (z StringMap) EncodeMsg(en *msgp.Writer) (err error) {
- err = en.WriteMapHeader(uint32(len(z)))
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- for zb0004, zb0005 := range z {
- err = en.WriteString(zb0004)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- err = en.WriteString(zb0005)
- if err != nil {
- err = msgp.WrapError(err, zb0004)
- return
- }
- }
- return
-}
-
-// MarshalMsg implements msgp.Marshaler
-func (z StringMap) MarshalMsg(b []byte) (o []byte, err error) {
- o = msgp.Require(b, z.Msgsize())
- o = msgp.AppendMapHeader(o, uint32(len(z)))
- for zb0004, zb0005 := range z {
- o = msgp.AppendString(o, zb0004)
- o = msgp.AppendString(o, zb0005)
- }
- return
-}
-
-// UnmarshalMsg implements msgp.Unmarshaler
-func (z *StringMap) UnmarshalMsg(bts []byte) (o []byte, err error) {
- var zb0003 uint32
- zb0003, bts, err = msgp.ReadMapHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if (*z) == nil {
- (*z) = make(StringMap, zb0003)
- } else if len((*z)) > 0 {
- for key := range *z {
- delete((*z), key)
- }
- }
- for zb0003 > 0 {
- var zb0001 string
- var zb0002 string
- zb0003--
- zb0001, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- zb0002, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, zb0001)
- return
- }
- (*z)[zb0001] = zb0002
- }
- o = bts
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z StringMap) Msgsize() (s int) {
- s = msgp.MapHeaderSize
- if z != nil {
- for zb0004, zb0005 := range z {
- _ = zb0005
- s += msgp.StringPrefixSize + len(zb0004) + msgp.StringPrefixSize + len(zb0005)
- }
- }
- return
-}
-
-// DecodeMsg implements msgp.Decodable
-func (z *TeamMember) DecodeMsg(dc *msgp.Reader) (err error) {
- var field []byte
- _ = field
- var zb0001 uint32
- zb0001, err = dc.ReadMapHeader()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- for zb0001 > 0 {
- zb0001--
- field, err = dc.ReadMapKeyPtr()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- switch msgp.UnsafeString(field) {
- case "TeamId":
- z.TeamId, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "TeamId")
- return
- }
- case "UserId":
- z.UserId, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "UserId")
- return
- }
- case "Roles":
- z.Roles, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- case "DeleteAt":
- z.DeleteAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "DeleteAt")
- return
- }
- case "SchemeGuest":
- z.SchemeGuest, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "SchemeGuest")
- return
- }
- case "SchemeUser":
- z.SchemeUser, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "SchemeUser")
- return
- }
- case "SchemeAdmin":
- z.SchemeAdmin, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "SchemeAdmin")
- return
- }
- case "ExplicitRoles":
- z.ExplicitRoles, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "ExplicitRoles")
- return
- }
- default:
- err = dc.Skip()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- }
- }
- return
-}
-
-// EncodeMsg implements msgp.Encodable
-func (z *TeamMember) EncodeMsg(en *msgp.Writer) (err error) {
- // map header, size 8
- // write "TeamId"
- err = en.Append(0x88, 0xa6, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64)
- if err != nil {
- return
- }
- err = en.WriteString(z.TeamId)
- if err != nil {
- err = msgp.WrapError(err, "TeamId")
- return
- }
- // write "UserId"
- err = en.Append(0xa6, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64)
- if err != nil {
- return
- }
- err = en.WriteString(z.UserId)
- if err != nil {
- err = msgp.WrapError(err, "UserId")
- return
- }
- // write "Roles"
- err = en.Append(0xa5, 0x52, 0x6f, 0x6c, 0x65, 0x73)
- if err != nil {
- return
- }
- err = en.WriteString(z.Roles)
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- // write "DeleteAt"
- err = en.Append(0xa8, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74)
- if err != nil {
- return
- }
- err = en.WriteInt64(z.DeleteAt)
- if err != nil {
- err = msgp.WrapError(err, "DeleteAt")
- return
- }
- // write "SchemeGuest"
- err = en.Append(0xab, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x47, 0x75, 0x65, 0x73, 0x74)
- if err != nil {
- return
- }
- err = en.WriteBool(z.SchemeGuest)
- if err != nil {
- err = msgp.WrapError(err, "SchemeGuest")
- return
- }
- // write "SchemeUser"
- err = en.Append(0xaa, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x55, 0x73, 0x65, 0x72)
- if err != nil {
- return
- }
- err = en.WriteBool(z.SchemeUser)
- if err != nil {
- err = msgp.WrapError(err, "SchemeUser")
- return
- }
- // write "SchemeAdmin"
- err = en.Append(0xab, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e)
- if err != nil {
- return
- }
- err = en.WriteBool(z.SchemeAdmin)
- if err != nil {
- err = msgp.WrapError(err, "SchemeAdmin")
- return
- }
- // write "ExplicitRoles"
- err = en.Append(0xad, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73)
- if err != nil {
- return
- }
- err = en.WriteString(z.ExplicitRoles)
- if err != nil {
- err = msgp.WrapError(err, "ExplicitRoles")
- return
- }
- return
-}
-
-// MarshalMsg implements msgp.Marshaler
-func (z *TeamMember) MarshalMsg(b []byte) (o []byte, err error) {
- o = msgp.Require(b, z.Msgsize())
- // map header, size 8
- // string "TeamId"
- o = append(o, 0x88, 0xa6, 0x54, 0x65, 0x61, 0x6d, 0x49, 0x64)
- o = msgp.AppendString(o, z.TeamId)
- // string "UserId"
- o = append(o, 0xa6, 0x55, 0x73, 0x65, 0x72, 0x49, 0x64)
- o = msgp.AppendString(o, z.UserId)
- // string "Roles"
- o = append(o, 0xa5, 0x52, 0x6f, 0x6c, 0x65, 0x73)
- o = msgp.AppendString(o, z.Roles)
- // string "DeleteAt"
- o = append(o, 0xa8, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x41, 0x74)
- o = msgp.AppendInt64(o, z.DeleteAt)
- // string "SchemeGuest"
- o = append(o, 0xab, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x47, 0x75, 0x65, 0x73, 0x74)
- o = msgp.AppendBool(o, z.SchemeGuest)
- // string "SchemeUser"
- o = append(o, 0xaa, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x55, 0x73, 0x65, 0x72)
- o = msgp.AppendBool(o, z.SchemeUser)
- // string "SchemeAdmin"
- o = append(o, 0xab, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x41, 0x64, 0x6d, 0x69, 0x6e)
- o = msgp.AppendBool(o, z.SchemeAdmin)
- // string "ExplicitRoles"
- o = append(o, 0xad, 0x45, 0x78, 0x70, 0x6c, 0x69, 0x63, 0x69, 0x74, 0x52, 0x6f, 0x6c, 0x65, 0x73)
- o = msgp.AppendString(o, z.ExplicitRoles)
- return
-}
-
-// UnmarshalMsg implements msgp.Unmarshaler
-func (z *TeamMember) UnmarshalMsg(bts []byte) (o []byte, err error) {
- var field []byte
- _ = field
- var zb0001 uint32
- zb0001, bts, err = msgp.ReadMapHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- for zb0001 > 0 {
- zb0001--
- field, bts, err = msgp.ReadMapKeyZC(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- switch msgp.UnsafeString(field) {
- case "TeamId":
- z.TeamId, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "TeamId")
- return
- }
- case "UserId":
- z.UserId, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "UserId")
- return
- }
- case "Roles":
- z.Roles, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- case "DeleteAt":
- z.DeleteAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "DeleteAt")
- return
- }
- case "SchemeGuest":
- z.SchemeGuest, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "SchemeGuest")
- return
- }
- case "SchemeUser":
- z.SchemeUser, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "SchemeUser")
- return
- }
- case "SchemeAdmin":
- z.SchemeAdmin, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "SchemeAdmin")
- return
- }
- case "ExplicitRoles":
- z.ExplicitRoles, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "ExplicitRoles")
- return
- }
- default:
- bts, err = msgp.Skip(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- }
- }
- o = bts
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *TeamMember) Msgsize() (s int) {
- s = 1 + 7 + msgp.StringPrefixSize + len(z.TeamId) + 7 + msgp.StringPrefixSize + len(z.UserId) + 6 + msgp.StringPrefixSize + len(z.Roles) + 9 + msgp.Int64Size + 12 + msgp.BoolSize + 11 + msgp.BoolSize + 12 + msgp.BoolSize + 14 + msgp.StringPrefixSize + len(z.ExplicitRoles)
- return
-}
-
-// DecodeMsg implements msgp.Decodable
-func (z *User) DecodeMsg(dc *msgp.Reader) (err error) {
- var zb0001 uint32
- zb0001, err = dc.ReadArrayHeader()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if zb0001 != 31 {
- err = msgp.ArrayError{Wanted: 31, Got: zb0001}
- return
- }
- z.Id, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Id")
- return
- }
- z.CreateAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "CreateAt")
- return
- }
- z.UpdateAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "UpdateAt")
- return
- }
- z.DeleteAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "DeleteAt")
- return
- }
- z.Username, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Username")
- return
- }
- z.Password, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Password")
- return
- }
- if dc.IsNil() {
- err = dc.ReadNil()
- if err != nil {
- err = msgp.WrapError(err, "AuthData")
- return
- }
- z.AuthData = nil
- } else {
- if z.AuthData == nil {
- z.AuthData = new(string)
- }
- *z.AuthData, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "AuthData")
- return
- }
- }
- z.AuthService, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "AuthService")
- return
- }
- z.Email, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Email")
- return
- }
- z.EmailVerified, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "EmailVerified")
- return
- }
- z.Nickname, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Nickname")
- return
- }
- z.FirstName, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "FirstName")
- return
- }
- z.LastName, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "LastName")
- return
- }
- z.Position, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Position")
- return
- }
- z.Roles, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- z.AllowMarketing, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "AllowMarketing")
- return
- }
- var zb0002 uint32
- zb0002, err = dc.ReadMapHeader()
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- if z.Props == nil {
- z.Props = make(StringMap, zb0002)
- } else if len(z.Props) > 0 {
- for key := range z.Props {
- delete(z.Props, key)
- }
- }
- for zb0002 > 0 {
- zb0002--
- var za0001 string
- var za0002 string
- za0001, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- za0002, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Props", za0001)
- return
- }
- z.Props[za0001] = za0002
- }
- var zb0003 uint32
- zb0003, err = dc.ReadMapHeader()
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps")
- return
- }
- if z.NotifyProps == nil {
- z.NotifyProps = make(StringMap, zb0003)
- } else if len(z.NotifyProps) > 0 {
- for key := range z.NotifyProps {
- delete(z.NotifyProps, key)
- }
- }
- for zb0003 > 0 {
- zb0003--
- var za0003 string
- var za0004 string
- za0003, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps")
- return
- }
- za0004, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps", za0003)
- return
- }
- z.NotifyProps[za0003] = za0004
- }
- z.LastPasswordUpdate, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "LastPasswordUpdate")
- return
- }
- z.LastPictureUpdate, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "LastPictureUpdate")
- return
- }
- z.FailedAttempts, err = dc.ReadInt()
- if err != nil {
- err = msgp.WrapError(err, "FailedAttempts")
- return
- }
- z.Locale, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Locale")
- return
- }
- var zb0004 uint32
- zb0004, err = dc.ReadMapHeader()
- if err != nil {
- err = msgp.WrapError(err, "Timezone")
- return
- }
- if z.Timezone == nil {
- z.Timezone = make(StringMap, zb0004)
- } else if len(z.Timezone) > 0 {
- for key := range z.Timezone {
- delete(z.Timezone, key)
- }
- }
- for zb0004 > 0 {
- zb0004--
- var za0005 string
- var za0006 string
- za0005, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Timezone")
- return
- }
- za0006, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "Timezone", za0005)
- return
- }
- z.Timezone[za0005] = za0006
- }
- z.MfaActive, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "MfaActive")
- return
- }
- z.MfaSecret, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "MfaSecret")
- return
- }
- z.LastActivityAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "LastActivityAt")
- return
- }
- z.IsBot, err = dc.ReadBool()
- if err != nil {
- err = msgp.WrapError(err, "IsBot")
- return
- }
- z.BotDescription, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "BotDescription")
- return
- }
- z.BotLastIconUpdate, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "BotLastIconUpdate")
- return
- }
- z.TermsOfServiceId, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err, "TermsOfServiceId")
- return
- }
- z.TermsOfServiceCreateAt, err = dc.ReadInt64()
- if err != nil {
- err = msgp.WrapError(err, "TermsOfServiceCreateAt")
- return
- }
- return
-}
-
-// EncodeMsg implements msgp.Encodable
-func (z *User) EncodeMsg(en *msgp.Writer) (err error) {
- // array header, size 31
- err = en.Append(0xdc, 0x0, 0x1f)
- if err != nil {
- return
- }
- err = en.WriteString(z.Id)
- if err != nil {
- err = msgp.WrapError(err, "Id")
- return
- }
- err = en.WriteInt64(z.CreateAt)
- if err != nil {
- err = msgp.WrapError(err, "CreateAt")
- return
- }
- err = en.WriteInt64(z.UpdateAt)
- if err != nil {
- err = msgp.WrapError(err, "UpdateAt")
- return
- }
- err = en.WriteInt64(z.DeleteAt)
- if err != nil {
- err = msgp.WrapError(err, "DeleteAt")
- return
- }
- err = en.WriteString(z.Username)
- if err != nil {
- err = msgp.WrapError(err, "Username")
- return
- }
- err = en.WriteString(z.Password)
- if err != nil {
- err = msgp.WrapError(err, "Password")
- return
- }
- if z.AuthData == nil {
- err = en.WriteNil()
- if err != nil {
- return
- }
- } else {
- err = en.WriteString(*z.AuthData)
- if err != nil {
- err = msgp.WrapError(err, "AuthData")
- return
- }
- }
- err = en.WriteString(z.AuthService)
- if err != nil {
- err = msgp.WrapError(err, "AuthService")
- return
- }
- err = en.WriteString(z.Email)
- if err != nil {
- err = msgp.WrapError(err, "Email")
- return
- }
- err = en.WriteBool(z.EmailVerified)
- if err != nil {
- err = msgp.WrapError(err, "EmailVerified")
- return
- }
- err = en.WriteString(z.Nickname)
- if err != nil {
- err = msgp.WrapError(err, "Nickname")
- return
- }
- err = en.WriteString(z.FirstName)
- if err != nil {
- err = msgp.WrapError(err, "FirstName")
- return
- }
- err = en.WriteString(z.LastName)
- if err != nil {
- err = msgp.WrapError(err, "LastName")
- return
- }
- err = en.WriteString(z.Position)
- if err != nil {
- err = msgp.WrapError(err, "Position")
- return
- }
- err = en.WriteString(z.Roles)
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- err = en.WriteBool(z.AllowMarketing)
- if err != nil {
- err = msgp.WrapError(err, "AllowMarketing")
- return
- }
- err = en.WriteMapHeader(uint32(len(z.Props)))
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- for za0001, za0002 := range z.Props {
- err = en.WriteString(za0001)
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- err = en.WriteString(za0002)
- if err != nil {
- err = msgp.WrapError(err, "Props", za0001)
- return
- }
- }
- err = en.WriteMapHeader(uint32(len(z.NotifyProps)))
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps")
- return
- }
- for za0003, za0004 := range z.NotifyProps {
- err = en.WriteString(za0003)
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps")
- return
- }
- err = en.WriteString(za0004)
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps", za0003)
- return
- }
- }
- err = en.WriteInt64(z.LastPasswordUpdate)
- if err != nil {
- err = msgp.WrapError(err, "LastPasswordUpdate")
- return
- }
- err = en.WriteInt64(z.LastPictureUpdate)
- if err != nil {
- err = msgp.WrapError(err, "LastPictureUpdate")
- return
- }
- err = en.WriteInt(z.FailedAttempts)
- if err != nil {
- err = msgp.WrapError(err, "FailedAttempts")
- return
- }
- err = en.WriteString(z.Locale)
- if err != nil {
- err = msgp.WrapError(err, "Locale")
- return
- }
- err = en.WriteMapHeader(uint32(len(z.Timezone)))
- if err != nil {
- err = msgp.WrapError(err, "Timezone")
- return
- }
- for za0005, za0006 := range z.Timezone {
- err = en.WriteString(za0005)
- if err != nil {
- err = msgp.WrapError(err, "Timezone")
- return
- }
- err = en.WriteString(za0006)
- if err != nil {
- err = msgp.WrapError(err, "Timezone", za0005)
- return
- }
- }
- err = en.WriteBool(z.MfaActive)
- if err != nil {
- err = msgp.WrapError(err, "MfaActive")
- return
- }
- err = en.WriteString(z.MfaSecret)
- if err != nil {
- err = msgp.WrapError(err, "MfaSecret")
- return
- }
- err = en.WriteInt64(z.LastActivityAt)
- if err != nil {
- err = msgp.WrapError(err, "LastActivityAt")
- return
- }
- err = en.WriteBool(z.IsBot)
- if err != nil {
- err = msgp.WrapError(err, "IsBot")
- return
- }
- err = en.WriteString(z.BotDescription)
- if err != nil {
- err = msgp.WrapError(err, "BotDescription")
- return
- }
- err = en.WriteInt64(z.BotLastIconUpdate)
- if err != nil {
- err = msgp.WrapError(err, "BotLastIconUpdate")
- return
- }
- err = en.WriteString(z.TermsOfServiceId)
- if err != nil {
- err = msgp.WrapError(err, "TermsOfServiceId")
- return
- }
- err = en.WriteInt64(z.TermsOfServiceCreateAt)
- if err != nil {
- err = msgp.WrapError(err, "TermsOfServiceCreateAt")
- return
- }
- return
-}
-
-// MarshalMsg implements msgp.Marshaler
-func (z *User) MarshalMsg(b []byte) (o []byte, err error) {
- o = msgp.Require(b, z.Msgsize())
- // array header, size 31
- o = append(o, 0xdc, 0x0, 0x1f)
- o = msgp.AppendString(o, z.Id)
- o = msgp.AppendInt64(o, z.CreateAt)
- o = msgp.AppendInt64(o, z.UpdateAt)
- o = msgp.AppendInt64(o, z.DeleteAt)
- o = msgp.AppendString(o, z.Username)
- o = msgp.AppendString(o, z.Password)
- if z.AuthData == nil {
- o = msgp.AppendNil(o)
- } else {
- o = msgp.AppendString(o, *z.AuthData)
- }
- o = msgp.AppendString(o, z.AuthService)
- o = msgp.AppendString(o, z.Email)
- o = msgp.AppendBool(o, z.EmailVerified)
- o = msgp.AppendString(o, z.Nickname)
- o = msgp.AppendString(o, z.FirstName)
- o = msgp.AppendString(o, z.LastName)
- o = msgp.AppendString(o, z.Position)
- o = msgp.AppendString(o, z.Roles)
- o = msgp.AppendBool(o, z.AllowMarketing)
- o = msgp.AppendMapHeader(o, uint32(len(z.Props)))
- for za0001, za0002 := range z.Props {
- o = msgp.AppendString(o, za0001)
- o = msgp.AppendString(o, za0002)
- }
- o = msgp.AppendMapHeader(o, uint32(len(z.NotifyProps)))
- for za0003, za0004 := range z.NotifyProps {
- o = msgp.AppendString(o, za0003)
- o = msgp.AppendString(o, za0004)
- }
- o = msgp.AppendInt64(o, z.LastPasswordUpdate)
- o = msgp.AppendInt64(o, z.LastPictureUpdate)
- o = msgp.AppendInt(o, z.FailedAttempts)
- o = msgp.AppendString(o, z.Locale)
- o = msgp.AppendMapHeader(o, uint32(len(z.Timezone)))
- for za0005, za0006 := range z.Timezone {
- o = msgp.AppendString(o, za0005)
- o = msgp.AppendString(o, za0006)
- }
- o = msgp.AppendBool(o, z.MfaActive)
- o = msgp.AppendString(o, z.MfaSecret)
- o = msgp.AppendInt64(o, z.LastActivityAt)
- o = msgp.AppendBool(o, z.IsBot)
- o = msgp.AppendString(o, z.BotDescription)
- o = msgp.AppendInt64(o, z.BotLastIconUpdate)
- o = msgp.AppendString(o, z.TermsOfServiceId)
- o = msgp.AppendInt64(o, z.TermsOfServiceCreateAt)
- return
-}
-
-// UnmarshalMsg implements msgp.Unmarshaler
-func (z *User) UnmarshalMsg(bts []byte) (o []byte, err error) {
- var zb0001 uint32
- zb0001, bts, err = msgp.ReadArrayHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if zb0001 != 31 {
- err = msgp.ArrayError{Wanted: 31, Got: zb0001}
- return
- }
- z.Id, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Id")
- return
- }
- z.CreateAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "CreateAt")
- return
- }
- z.UpdateAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "UpdateAt")
- return
- }
- z.DeleteAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "DeleteAt")
- return
- }
- z.Username, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Username")
- return
- }
- z.Password, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Password")
- return
- }
- if msgp.IsNil(bts) {
- bts, err = msgp.ReadNilBytes(bts)
- if err != nil {
- return
- }
- z.AuthData = nil
- } else {
- if z.AuthData == nil {
- z.AuthData = new(string)
- }
- *z.AuthData, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "AuthData")
- return
- }
- }
- z.AuthService, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "AuthService")
- return
- }
- z.Email, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Email")
- return
- }
- z.EmailVerified, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "EmailVerified")
- return
- }
- z.Nickname, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Nickname")
- return
- }
- z.FirstName, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "FirstName")
- return
- }
- z.LastName, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "LastName")
- return
- }
- z.Position, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Position")
- return
- }
- z.Roles, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Roles")
- return
- }
- z.AllowMarketing, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "AllowMarketing")
- return
- }
- var zb0002 uint32
- zb0002, bts, err = msgp.ReadMapHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- if z.Props == nil {
- z.Props = make(StringMap, zb0002)
- } else if len(z.Props) > 0 {
- for key := range z.Props {
- delete(z.Props, key)
- }
- }
- for zb0002 > 0 {
- var za0001 string
- var za0002 string
- zb0002--
- za0001, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Props")
- return
- }
- za0002, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Props", za0001)
- return
- }
- z.Props[za0001] = za0002
- }
- var zb0003 uint32
- zb0003, bts, err = msgp.ReadMapHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps")
- return
- }
- if z.NotifyProps == nil {
- z.NotifyProps = make(StringMap, zb0003)
- } else if len(z.NotifyProps) > 0 {
- for key := range z.NotifyProps {
- delete(z.NotifyProps, key)
- }
- }
- for zb0003 > 0 {
- var za0003 string
- var za0004 string
- zb0003--
- za0003, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps")
- return
- }
- za0004, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "NotifyProps", za0003)
- return
- }
- z.NotifyProps[za0003] = za0004
- }
- z.LastPasswordUpdate, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "LastPasswordUpdate")
- return
- }
- z.LastPictureUpdate, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "LastPictureUpdate")
- return
- }
- z.FailedAttempts, bts, err = msgp.ReadIntBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "FailedAttempts")
- return
- }
- z.Locale, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Locale")
- return
- }
- var zb0004 uint32
- zb0004, bts, err = msgp.ReadMapHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Timezone")
- return
- }
- if z.Timezone == nil {
- z.Timezone = make(StringMap, zb0004)
- } else if len(z.Timezone) > 0 {
- for key := range z.Timezone {
- delete(z.Timezone, key)
- }
- }
- for zb0004 > 0 {
- var za0005 string
- var za0006 string
- zb0004--
- za0005, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Timezone")
- return
- }
- za0006, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "Timezone", za0005)
- return
- }
- z.Timezone[za0005] = za0006
- }
- z.MfaActive, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "MfaActive")
- return
- }
- z.MfaSecret, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "MfaSecret")
- return
- }
- z.LastActivityAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "LastActivityAt")
- return
- }
- z.IsBot, bts, err = msgp.ReadBoolBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "IsBot")
- return
- }
- z.BotDescription, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "BotDescription")
- return
- }
- z.BotLastIconUpdate, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "BotLastIconUpdate")
- return
- }
- z.TermsOfServiceId, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "TermsOfServiceId")
- return
- }
- z.TermsOfServiceCreateAt, bts, err = msgp.ReadInt64Bytes(bts)
- if err != nil {
- err = msgp.WrapError(err, "TermsOfServiceCreateAt")
- return
- }
- o = bts
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z *User) Msgsize() (s int) {
- s = 3 + msgp.StringPrefixSize + len(z.Id) + msgp.Int64Size + msgp.Int64Size + msgp.Int64Size + msgp.StringPrefixSize + len(z.Username) + msgp.StringPrefixSize + len(z.Password)
- if z.AuthData == nil {
- s += msgp.NilSize
- } else {
- s += msgp.StringPrefixSize + len(*z.AuthData)
- }
- s += msgp.StringPrefixSize + len(z.AuthService) + msgp.StringPrefixSize + len(z.Email) + msgp.BoolSize + msgp.StringPrefixSize + len(z.Nickname) + msgp.StringPrefixSize + len(z.FirstName) + msgp.StringPrefixSize + len(z.LastName) + msgp.StringPrefixSize + len(z.Position) + msgp.StringPrefixSize + len(z.Roles) + msgp.BoolSize + msgp.MapHeaderSize
- if z.Props != nil {
- for za0001, za0002 := range z.Props {
- _ = za0002
- s += msgp.StringPrefixSize + len(za0001) + msgp.StringPrefixSize + len(za0002)
- }
- }
- s += msgp.MapHeaderSize
- if z.NotifyProps != nil {
- for za0003, za0004 := range z.NotifyProps {
- _ = za0004
- s += msgp.StringPrefixSize + len(za0003) + msgp.StringPrefixSize + len(za0004)
- }
- }
- s += msgp.Int64Size + msgp.Int64Size + msgp.IntSize + msgp.StringPrefixSize + len(z.Locale) + msgp.MapHeaderSize
- if z.Timezone != nil {
- for za0005, za0006 := range z.Timezone {
- _ = za0006
- s += msgp.StringPrefixSize + len(za0005) + msgp.StringPrefixSize + len(za0006)
- }
- }
- s += msgp.BoolSize + msgp.StringPrefixSize + len(z.MfaSecret) + msgp.Int64Size + msgp.BoolSize + msgp.StringPrefixSize + len(z.BotDescription) + msgp.Int64Size + msgp.StringPrefixSize + len(z.TermsOfServiceId) + msgp.Int64Size
- return
-}
-
-// DecodeMsg implements msgp.Decodable
-func (z *UserMap) DecodeMsg(dc *msgp.Reader) (err error) {
- var zb0003 uint32
- zb0003, err = dc.ReadMapHeader()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if (*z) == nil {
- (*z) = make(UserMap, zb0003)
- } else if len((*z)) > 0 {
- for key := range *z {
- delete((*z), key)
- }
- }
- for zb0003 > 0 {
- zb0003--
- var zb0001 string
- var zb0002 *User
- zb0001, err = dc.ReadString()
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if dc.IsNil() {
- err = dc.ReadNil()
- if err != nil {
- err = msgp.WrapError(err, zb0001)
- return
- }
- zb0002 = nil
- } else {
- if zb0002 == nil {
- zb0002 = new(User)
- }
- err = zb0002.DecodeMsg(dc)
- if err != nil {
- err = msgp.WrapError(err, zb0001)
- return
- }
- }
- (*z)[zb0001] = zb0002
- }
- return
-}
-
-// EncodeMsg implements msgp.Encodable
-func (z UserMap) EncodeMsg(en *msgp.Writer) (err error) {
- err = en.WriteMapHeader(uint32(len(z)))
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- for zb0004, zb0005 := range z {
- err = en.WriteString(zb0004)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if zb0005 == nil {
- err = en.WriteNil()
- if err != nil {
- return
- }
- } else {
- err = zb0005.EncodeMsg(en)
- if err != nil {
- err = msgp.WrapError(err, zb0004)
- return
- }
- }
- }
- return
-}
-
-// MarshalMsg implements msgp.Marshaler
-func (z UserMap) MarshalMsg(b []byte) (o []byte, err error) {
- o = msgp.Require(b, z.Msgsize())
- o = msgp.AppendMapHeader(o, uint32(len(z)))
- for zb0004, zb0005 := range z {
- o = msgp.AppendString(o, zb0004)
- if zb0005 == nil {
- o = msgp.AppendNil(o)
- } else {
- o, err = zb0005.MarshalMsg(o)
- if err != nil {
- err = msgp.WrapError(err, zb0004)
- return
- }
- }
- }
- return
-}
-
-// UnmarshalMsg implements msgp.Unmarshaler
-func (z *UserMap) UnmarshalMsg(bts []byte) (o []byte, err error) {
- var zb0003 uint32
- zb0003, bts, err = msgp.ReadMapHeaderBytes(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if (*z) == nil {
- (*z) = make(UserMap, zb0003)
- } else if len((*z)) > 0 {
- for key := range *z {
- delete((*z), key)
- }
- }
- for zb0003 > 0 {
- var zb0001 string
- var zb0002 *User
- zb0003--
- zb0001, bts, err = msgp.ReadStringBytes(bts)
- if err != nil {
- err = msgp.WrapError(err)
- return
- }
- if msgp.IsNil(bts) {
- bts, err = msgp.ReadNilBytes(bts)
- if err != nil {
- return
- }
- zb0002 = nil
- } else {
- if zb0002 == nil {
- zb0002 = new(User)
- }
- bts, err = zb0002.UnmarshalMsg(bts)
- if err != nil {
- err = msgp.WrapError(err, zb0001)
- return
- }
- }
- (*z)[zb0001] = zb0002
- }
- o = bts
- return
-}
-
-// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
-func (z UserMap) Msgsize() (s int) {
- s = msgp.MapHeaderSize
- if z != nil {
- for zb0004, zb0005 := range z {
- _ = zb0005
- s += msgp.StringPrefixSize + len(zb0004)
- if zb0005 == nil {
- s += msgp.NilSize
- } else {
- s += zb0005.Msgsize()
- }
- }
- }
- return
-}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/session.go b/vendor/github.com/mattermost/mattermost-server/v5/model/session.go
index 976e1229..334c7175 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/session.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/session.go
@@ -9,7 +9,7 @@ import (
"strconv"
"strings"
- "github.com/mattermost/mattermost-server/v5/mlog"
+ "github.com/mattermost/mattermost-server/v5/shared/mlog"
)
const (
@@ -25,11 +25,16 @@ const (
SESSION_PROP_IS_BOT = "is_bot"
SESSION_PROP_IS_BOT_VALUE = "true"
SESSION_TYPE_USER_ACCESS_TOKEN = "UserAccessToken"
+ SESSION_TYPE_CLOUD_KEY = "CloudKey"
+ SESSION_TYPE_REMOTECLUSTER_TOKEN = "RemoteClusterToken"
SESSION_PROP_IS_GUEST = "is_guest"
SESSION_ACTIVITY_TIMEOUT = 1000 * 60 * 5 // 5 minutes
SESSION_USER_ACCESS_TOKEN_EXPIRY = 100 * 365 // 100 years
)
+//msgp StringMap
+type StringMap map[string]string
+
//msgp:tuple Session
// Session contains the user session details.
@@ -53,20 +58,20 @@ type Session struct {
// Returns true if the session is unrestricted, which should grant it
// with all permissions. This is used for local mode sessions
-func (me *Session) IsUnrestricted() bool {
- return me.Local
+func (s *Session) IsUnrestricted() bool {
+ return s.Local
}
-func (me *Session) DeepCopy() *Session {
- copySession := *me
+func (s *Session) DeepCopy() *Session {
+ copySession := *s
- if me.Props != nil {
- copySession.Props = CopyStringMap(me.Props)
+ if s.Props != nil {
+ copySession.Props = CopyStringMap(s.Props)
}
- if me.TeamMembers != nil {
- copySession.TeamMembers = make([]*TeamMember, len(me.TeamMembers))
- for index, tm := range me.TeamMembers {
+ if s.TeamMembers != nil {
+ copySession.TeamMembers = make([]*TeamMember, len(s.TeamMembers))
+ for index, tm := range s.TeamMembers {
copySession.TeamMembers[index] = new(TeamMember)
*copySession.TeamMembers[index] = *tm
}
@@ -75,45 +80,45 @@ func (me *Session) DeepCopy() *Session {
return &copySession
}
-func (me *Session) ToJson() string {
- b, _ := json.Marshal(me)
+func (s *Session) ToJson() string {
+ b, _ := json.Marshal(s)
return string(b)
}
func SessionFromJson(data io.Reader) *Session {
- var me *Session
- json.NewDecoder(data).Decode(&me)
- return me
+ var s *Session
+ json.NewDecoder(data).Decode(&s)
+ return s
}
-func (me *Session) PreSave() {
- if me.Id == "" {
- me.Id = NewId()
+func (s *Session) PreSave() {
+ if s.Id == "" {
+ s.Id = NewId()
}
- if me.Token == "" {
- me.Token = NewId()
+ if s.Token == "" {
+ s.Token = NewId()
}
- me.CreateAt = GetMillis()
- me.LastActivityAt = me.CreateAt
+ s.CreateAt = GetMillis()
+ s.LastActivityAt = s.CreateAt
- if me.Props == nil {
- me.Props = make(map[string]string)
+ if s.Props == nil {
+ s.Props = make(map[string]string)
}
}
-func (me *Session) Sanitize() {
- me.Token = ""
+func (s *Session) Sanitize() {
+ s.Token = ""
}
-func (me *Session) IsExpired() bool {
+func (s *Session) IsExpired() bool {
- if me.ExpiresAt <= 0 {
+ if s.ExpiresAt <= 0 {
return false
}
- if GetMillis() > me.ExpiresAt {
+ if GetMillis() > s.ExpiresAt {
return true
}
@@ -123,25 +128,25 @@ func (me *Session) IsExpired() bool {
// Deprecated: SetExpireInDays is deprecated and should not be used.
// Use (*App).SetSessionExpireInDays instead which handles the
// cases where the new ExpiresAt is not relative to CreateAt.
-func (me *Session) SetExpireInDays(days int) {
- if me.CreateAt == 0 {
- me.ExpiresAt = GetMillis() + (1000 * 60 * 60 * 24 * int64(days))
+func (s *Session) SetExpireInDays(days int) {
+ if s.CreateAt == 0 {
+ s.ExpiresAt = GetMillis() + (1000 * 60 * 60 * 24 * int64(days))
} else {
- me.ExpiresAt = me.CreateAt + (1000 * 60 * 60 * 24 * int64(days))
+ s.ExpiresAt = s.CreateAt + (1000 * 60 * 60 * 24 * int64(days))
}
}
-func (me *Session) AddProp(key string, value string) {
+func (s *Session) AddProp(key string, value string) {
- if me.Props == nil {
- me.Props = make(map[string]string)
+ if s.Props == nil {
+ s.Props = make(map[string]string)
}
- me.Props[key] = value
+ s.Props[key] = value
}
-func (me *Session) GetTeamByTeamId(teamId string) *TeamMember {
- for _, team := range me.TeamMembers {
+func (s *Session) GetTeamByTeamId(teamId string) *TeamMember {
+ for _, team := range s.TeamMembers {
if team.TeamId == teamId {
return team
}
@@ -150,77 +155,77 @@ func (me *Session) GetTeamByTeamId(teamId string) *TeamMember {
return nil
}
-func (me *Session) IsMobileApp() bool {
- return len(me.DeviceId) > 0 || me.IsMobile()
+func (s *Session) IsMobileApp() bool {
+ return s.DeviceId != "" || s.IsMobile()
}
-func (me *Session) IsMobile() bool {
- val, ok := me.Props[USER_AUTH_SERVICE_IS_MOBILE]
+func (s *Session) IsMobile() bool {
+ val, ok := s.Props[USER_AUTH_SERVICE_IS_MOBILE]
if !ok {
return false
}
isMobile, err := strconv.ParseBool(val)
if err != nil {
- mlog.Error("Error parsing boolean property from Session", mlog.Err(err))
+ mlog.Debug("Error parsing boolean property from Session", mlog.Err(err))
return false
}
return isMobile
}
-func (me *Session) IsSaml() bool {
- val, ok := me.Props[USER_AUTH_SERVICE_IS_SAML]
+func (s *Session) IsSaml() bool {
+ val, ok := s.Props[USER_AUTH_SERVICE_IS_SAML]
if !ok {
return false
}
isSaml, err := strconv.ParseBool(val)
if err != nil {
- mlog.Error("Error parsing boolean property from Session", mlog.Err(err))
+ mlog.Debug("Error parsing boolean property from Session", mlog.Err(err))
return false
}
return isSaml
}
-func (me *Session) IsOAuthUser() bool {
- val, ok := me.Props[USER_AUTH_SERVICE_IS_OAUTH]
+func (s *Session) IsOAuthUser() bool {
+ val, ok := s.Props[USER_AUTH_SERVICE_IS_OAUTH]
if !ok {
return false
}
isOAuthUser, err := strconv.ParseBool(val)
if err != nil {
- mlog.Error("Error parsing boolean property from Session", mlog.Err(err))
+ mlog.Debug("Error parsing boolean property from Session", mlog.Err(err))
return false
}
return isOAuthUser
}
-func (me *Session) IsSSOLogin() bool {
- return me.IsOAuthUser() || me.IsSaml()
+func (s *Session) IsSSOLogin() bool {
+ return s.IsOAuthUser() || s.IsSaml()
}
-func (me *Session) GetUserRoles() []string {
- return strings.Fields(me.Roles)
+func (s *Session) GetUserRoles() []string {
+ return strings.Fields(s.Roles)
}
-func (me *Session) GenerateCSRF() string {
+func (s *Session) GenerateCSRF() string {
token := NewId()
- me.AddProp("csrf", token)
+ s.AddProp("csrf", token)
return token
}
-func (me *Session) GetCSRF() string {
- if me.Props == nil {
+func (s *Session) GetCSRF() string {
+ if s.Props == nil {
return ""
}
- return me.Props["csrf"]
+ return s.Props["csrf"]
}
func SessionsToJson(o []*Session) string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func SessionsFromJson(data io.Reader) []*Session {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/session_serial_gen.go b/vendor/github.com/mattermost/mattermost-server/v5/model/session_serial_gen.go
new file mode 100644
index 00000000..612bbb89
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/session_serial_gen.go
@@ -0,0 +1,540 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+// Code generated by github.com/tinylib/msgp DO NOT EDIT.
+
+import (
+ "github.com/tinylib/msgp/msgp"
+)
+
+// DecodeMsg implements msgp.Decodable
+func (z *Session) DecodeMsg(dc *msgp.Reader) (err error) {
+ var zb0001 uint32
+ zb0001, err = dc.ReadArrayHeader()
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if zb0001 != 13 {
+ err = msgp.ArrayError{Wanted: 13, Got: zb0001}
+ return
+ }
+ z.Id, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Id")
+ return
+ }
+ z.Token, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Token")
+ return
+ }
+ z.CreateAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "CreateAt")
+ return
+ }
+ z.ExpiresAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "ExpiresAt")
+ return
+ }
+ z.LastActivityAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "LastActivityAt")
+ return
+ }
+ z.UserId, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "UserId")
+ return
+ }
+ z.DeviceId, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "DeviceId")
+ return
+ }
+ z.Roles, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ z.IsOAuth, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "IsOAuth")
+ return
+ }
+ z.ExpiredNotify, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "ExpiredNotify")
+ return
+ }
+ var zb0002 uint32
+ zb0002, err = dc.ReadMapHeader()
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ if z.Props == nil {
+ z.Props = make(StringMap, zb0002)
+ } else if len(z.Props) > 0 {
+ for key := range z.Props {
+ delete(z.Props, key)
+ }
+ }
+ for zb0002 > 0 {
+ zb0002--
+ var za0001 string
+ var za0002 string
+ za0001, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ za0002, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Props", za0001)
+ return
+ }
+ z.Props[za0001] = za0002
+ }
+ var zb0003 uint32
+ zb0003, err = dc.ReadArrayHeader()
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers")
+ return
+ }
+ if cap(z.TeamMembers) >= int(zb0003) {
+ z.TeamMembers = (z.TeamMembers)[:zb0003]
+ } else {
+ z.TeamMembers = make([]*TeamMember, zb0003)
+ }
+ for za0003 := range z.TeamMembers {
+ if dc.IsNil() {
+ err = dc.ReadNil()
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers", za0003)
+ return
+ }
+ z.TeamMembers[za0003] = nil
+ } else {
+ if z.TeamMembers[za0003] == nil {
+ z.TeamMembers[za0003] = new(TeamMember)
+ }
+ err = z.TeamMembers[za0003].DecodeMsg(dc)
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers", za0003)
+ return
+ }
+ }
+ }
+ z.Local, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "Local")
+ return
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z *Session) EncodeMsg(en *msgp.Writer) (err error) {
+ // array header, size 13
+ err = en.Append(0x9d)
+ if err != nil {
+ return
+ }
+ err = en.WriteString(z.Id)
+ if err != nil {
+ err = msgp.WrapError(err, "Id")
+ return
+ }
+ err = en.WriteString(z.Token)
+ if err != nil {
+ err = msgp.WrapError(err, "Token")
+ return
+ }
+ err = en.WriteInt64(z.CreateAt)
+ if err != nil {
+ err = msgp.WrapError(err, "CreateAt")
+ return
+ }
+ err = en.WriteInt64(z.ExpiresAt)
+ if err != nil {
+ err = msgp.WrapError(err, "ExpiresAt")
+ return
+ }
+ err = en.WriteInt64(z.LastActivityAt)
+ if err != nil {
+ err = msgp.WrapError(err, "LastActivityAt")
+ return
+ }
+ err = en.WriteString(z.UserId)
+ if err != nil {
+ err = msgp.WrapError(err, "UserId")
+ return
+ }
+ err = en.WriteString(z.DeviceId)
+ if err != nil {
+ err = msgp.WrapError(err, "DeviceId")
+ return
+ }
+ err = en.WriteString(z.Roles)
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ err = en.WriteBool(z.IsOAuth)
+ if err != nil {
+ err = msgp.WrapError(err, "IsOAuth")
+ return
+ }
+ err = en.WriteBool(z.ExpiredNotify)
+ if err != nil {
+ err = msgp.WrapError(err, "ExpiredNotify")
+ return
+ }
+ err = en.WriteMapHeader(uint32(len(z.Props)))
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ for za0001, za0002 := range z.Props {
+ err = en.WriteString(za0001)
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ err = en.WriteString(za0002)
+ if err != nil {
+ err = msgp.WrapError(err, "Props", za0001)
+ return
+ }
+ }
+ err = en.WriteArrayHeader(uint32(len(z.TeamMembers)))
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers")
+ return
+ }
+ for za0003 := range z.TeamMembers {
+ if z.TeamMembers[za0003] == nil {
+ err = en.WriteNil()
+ if err != nil {
+ return
+ }
+ } else {
+ err = z.TeamMembers[za0003].EncodeMsg(en)
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers", za0003)
+ return
+ }
+ }
+ }
+ err = en.WriteBool(z.Local)
+ if err != nil {
+ err = msgp.WrapError(err, "Local")
+ return
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z *Session) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ // array header, size 13
+ o = append(o, 0x9d)
+ o = msgp.AppendString(o, z.Id)
+ o = msgp.AppendString(o, z.Token)
+ o = msgp.AppendInt64(o, z.CreateAt)
+ o = msgp.AppendInt64(o, z.ExpiresAt)
+ o = msgp.AppendInt64(o, z.LastActivityAt)
+ o = msgp.AppendString(o, z.UserId)
+ o = msgp.AppendString(o, z.DeviceId)
+ o = msgp.AppendString(o, z.Roles)
+ o = msgp.AppendBool(o, z.IsOAuth)
+ o = msgp.AppendBool(o, z.ExpiredNotify)
+ o = msgp.AppendMapHeader(o, uint32(len(z.Props)))
+ for za0001, za0002 := range z.Props {
+ o = msgp.AppendString(o, za0001)
+ o = msgp.AppendString(o, za0002)
+ }
+ o = msgp.AppendArrayHeader(o, uint32(len(z.TeamMembers)))
+ for za0003 := range z.TeamMembers {
+ if z.TeamMembers[za0003] == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o, err = z.TeamMembers[za0003].MarshalMsg(o)
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers", za0003)
+ return
+ }
+ }
+ }
+ o = msgp.AppendBool(o, z.Local)
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *Session) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ var zb0001 uint32
+ zb0001, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if zb0001 != 13 {
+ err = msgp.ArrayError{Wanted: 13, Got: zb0001}
+ return
+ }
+ z.Id, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Id")
+ return
+ }
+ z.Token, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Token")
+ return
+ }
+ z.CreateAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "CreateAt")
+ return
+ }
+ z.ExpiresAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "ExpiresAt")
+ return
+ }
+ z.LastActivityAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastActivityAt")
+ return
+ }
+ z.UserId, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "UserId")
+ return
+ }
+ z.DeviceId, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "DeviceId")
+ return
+ }
+ z.Roles, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ z.IsOAuth, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "IsOAuth")
+ return
+ }
+ z.ExpiredNotify, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "ExpiredNotify")
+ return
+ }
+ var zb0002 uint32
+ zb0002, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ if z.Props == nil {
+ z.Props = make(StringMap, zb0002)
+ } else if len(z.Props) > 0 {
+ for key := range z.Props {
+ delete(z.Props, key)
+ }
+ }
+ for zb0002 > 0 {
+ var za0001 string
+ var za0002 string
+ zb0002--
+ za0001, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ za0002, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Props", za0001)
+ return
+ }
+ z.Props[za0001] = za0002
+ }
+ var zb0003 uint32
+ zb0003, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers")
+ return
+ }
+ if cap(z.TeamMembers) >= int(zb0003) {
+ z.TeamMembers = (z.TeamMembers)[:zb0003]
+ } else {
+ z.TeamMembers = make([]*TeamMember, zb0003)
+ }
+ for za0003 := range z.TeamMembers {
+ if msgp.IsNil(bts) {
+ bts, err = msgp.ReadNilBytes(bts)
+ if err != nil {
+ return
+ }
+ z.TeamMembers[za0003] = nil
+ } else {
+ if z.TeamMembers[za0003] == nil {
+ z.TeamMembers[za0003] = new(TeamMember)
+ }
+ bts, err = z.TeamMembers[za0003].UnmarshalMsg(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "TeamMembers", za0003)
+ return
+ }
+ }
+ }
+ z.Local, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Local")
+ return
+ }
+ o = bts
+ return
+}
+
+// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
+func (z *Session) Msgsize() (s int) {
+ s = 1 + msgp.StringPrefixSize + len(z.Id) + msgp.StringPrefixSize + len(z.Token) + msgp.Int64Size + msgp.Int64Size + msgp.Int64Size + msgp.StringPrefixSize + len(z.UserId) + msgp.StringPrefixSize + len(z.DeviceId) + msgp.StringPrefixSize + len(z.Roles) + msgp.BoolSize + msgp.BoolSize + msgp.MapHeaderSize
+ if z.Props != nil {
+ for za0001, za0002 := range z.Props {
+ _ = za0002
+ s += msgp.StringPrefixSize + len(za0001) + msgp.StringPrefixSize + len(za0002)
+ }
+ }
+ s += msgp.ArrayHeaderSize
+ for za0003 := range z.TeamMembers {
+ if z.TeamMembers[za0003] == nil {
+ s += msgp.NilSize
+ } else {
+ s += z.TeamMembers[za0003].Msgsize()
+ }
+ }
+ s += msgp.BoolSize
+ return
+}
+
+// DecodeMsg implements msgp.Decodable
+func (z *StringMap) DecodeMsg(dc *msgp.Reader) (err error) {
+ var zb0003 uint32
+ zb0003, err = dc.ReadMapHeader()
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if (*z) == nil {
+ (*z) = make(StringMap, zb0003)
+ } else if len((*z)) > 0 {
+ for key := range *z {
+ delete((*z), key)
+ }
+ }
+ for zb0003 > 0 {
+ zb0003--
+ var zb0001 string
+ var zb0002 string
+ zb0001, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ zb0002, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, zb0001)
+ return
+ }
+ (*z)[zb0001] = zb0002
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z StringMap) EncodeMsg(en *msgp.Writer) (err error) {
+ err = en.WriteMapHeader(uint32(len(z)))
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ for zb0004, zb0005 := range z {
+ err = en.WriteString(zb0004)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ err = en.WriteString(zb0005)
+ if err != nil {
+ err = msgp.WrapError(err, zb0004)
+ return
+ }
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z StringMap) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ o = msgp.AppendMapHeader(o, uint32(len(z)))
+ for zb0004, zb0005 := range z {
+ o = msgp.AppendString(o, zb0004)
+ o = msgp.AppendString(o, zb0005)
+ }
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *StringMap) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ var zb0003 uint32
+ zb0003, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if (*z) == nil {
+ (*z) = make(StringMap, zb0003)
+ } else if len((*z)) > 0 {
+ for key := range *z {
+ delete((*z), key)
+ }
+ }
+ for zb0003 > 0 {
+ var zb0001 string
+ var zb0002 string
+ zb0003--
+ zb0001, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ zb0002, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, zb0001)
+ return
+ }
+ (*z)[zb0001] = zb0002
+ }
+ o = bts
+ return
+}
+
+// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
+func (z StringMap) Msgsize() (s int) {
+ s = msgp.MapHeaderSize
+ if z != nil {
+ for zb0004, zb0005 := range z {
+ _ = zb0005
+ s += msgp.StringPrefixSize + len(zb0004) + msgp.StringPrefixSize + len(zb0005)
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/shared_channel.go b/vendor/github.com/mattermost/mattermost-server/v5/model/shared_channel.go
new file mode 100644
index 00000000..e3643812
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/shared_channel.go
@@ -0,0 +1,273 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+import (
+ "encoding/json"
+ "io"
+ "net/http"
+ "unicode/utf8"
+)
+
+// SharedChannel represents a channel that can be synchronized with a remote cluster.
+// If "home" is true, then the shared channel is homed locally and "SharedChannelRemote"
+// table contains the remote clusters that have been invited.
+// If "home" is false, then the shared channel is homed remotely, and "RemoteId"
+// field points to the remote cluster connection in "RemoteClusters" table.
+type SharedChannel struct {
+ ChannelId string `json:"id"`
+ TeamId string `json:"team_id"`
+ Home bool `json:"home"`
+ ReadOnly bool `json:"readonly"`
+ ShareName string `json:"name"`
+ ShareDisplayName string `json:"display_name"`
+ SharePurpose string `json:"purpose"`
+ ShareHeader string `json:"header"`
+ CreatorId string `json:"creator_id"`
+ CreateAt int64 `json:"create_at"`
+ UpdateAt int64 `json:"update_at"`
+ RemoteId string `json:"remote_id,omitempty"` // if not "home"
+ Type string `db:"-"`
+}
+
+func (sc *SharedChannel) ToJson() string {
+ b, _ := json.Marshal(sc)
+ return string(b)
+}
+
+func SharedChannelFromJson(data io.Reader) (*SharedChannel, error) {
+ var sc *SharedChannel
+ err := json.NewDecoder(data).Decode(&sc)
+ return sc, err
+}
+
+func (sc *SharedChannel) IsValid() *AppError {
+ if !IsValidId(sc.ChannelId) {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.id.app_error", nil, "ChannelId="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if sc.Type != CHANNEL_DIRECT && !IsValidId(sc.TeamId) {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.id.app_error", nil, "TeamId="+sc.TeamId, http.StatusBadRequest)
+ }
+
+ if sc.CreateAt == 0 {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if sc.UpdateAt == 0 {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.update_at.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if utf8.RuneCountInString(sc.ShareDisplayName) > CHANNEL_DISPLAY_NAME_MAX_RUNES {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.display_name.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if !IsValidChannelIdentifier(sc.ShareName) {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.2_or_more.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if utf8.RuneCountInString(sc.ShareHeader) > CHANNEL_HEADER_MAX_RUNES {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.header.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if utf8.RuneCountInString(sc.SharePurpose) > CHANNEL_PURPOSE_MAX_RUNES {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.purpose.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if !IsValidId(sc.CreatorId) {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.creator_id.app_error", nil, "CreatorId="+sc.CreatorId, http.StatusBadRequest)
+ }
+
+ if !sc.Home {
+ if !IsValidId(sc.RemoteId) {
+ return NewAppError("SharedChannel.IsValid", "model.channel.is_valid.id.app_error", nil, "RemoteId="+sc.RemoteId, http.StatusBadRequest)
+ }
+ }
+ return nil
+}
+
+func (sc *SharedChannel) PreSave() {
+ sc.ShareName = SanitizeUnicode(sc.ShareName)
+ sc.ShareDisplayName = SanitizeUnicode(sc.ShareDisplayName)
+
+ sc.CreateAt = GetMillis()
+ sc.UpdateAt = sc.CreateAt
+}
+
+func (sc *SharedChannel) PreUpdate() {
+ sc.UpdateAt = GetMillis()
+ sc.ShareName = SanitizeUnicode(sc.ShareName)
+ sc.ShareDisplayName = SanitizeUnicode(sc.ShareDisplayName)
+}
+
+// SharedChannelRemote represents a remote cluster that has been invited
+// to a shared channel.
+type SharedChannelRemote struct {
+ Id string `json:"id"`
+ ChannelId string `json:"channel_id"`
+ CreatorId string `json:"creator_id"`
+ CreateAt int64 `json:"create_at"`
+ UpdateAt int64 `json:"update_at"`
+ IsInviteAccepted bool `json:"is_invite_accepted"`
+ IsInviteConfirmed bool `json:"is_invite_confirmed"`
+ RemoteId string `json:"remote_id"`
+ LastPostUpdateAt int64 `json:"last_post_update_at"`
+ LastPostId string `json:"last_post_id"`
+}
+
+func (sc *SharedChannelRemote) ToJson() string {
+ b, _ := json.Marshal(sc)
+ return string(b)
+}
+
+func SharedChannelRemoteFromJson(data io.Reader) (*SharedChannelRemote, error) {
+ var sc *SharedChannelRemote
+ err := json.NewDecoder(data).Decode(&sc)
+ return sc, err
+}
+
+func (sc *SharedChannelRemote) IsValid() *AppError {
+ if !IsValidId(sc.Id) {
+ return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.id.app_error", nil, "Id="+sc.Id, http.StatusBadRequest)
+ }
+
+ if !IsValidId(sc.ChannelId) {
+ return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.id.app_error", nil, "ChannelId="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if sc.CreateAt == 0 {
+ return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.create_at.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if sc.UpdateAt == 0 {
+ return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.update_at.app_error", nil, "id="+sc.ChannelId, http.StatusBadRequest)
+ }
+
+ if !IsValidId(sc.CreatorId) {
+ return NewAppError("SharedChannelRemote.IsValid", "model.channel.is_valid.creator_id.app_error", nil, "id="+sc.CreatorId, http.StatusBadRequest)
+ }
+ return nil
+}
+
+func (sc *SharedChannelRemote) PreSave() {
+ if sc.Id == "" {
+ sc.Id = NewId()
+ }
+ sc.CreateAt = GetMillis()
+ sc.UpdateAt = sc.CreateAt
+}
+
+func (sc *SharedChannelRemote) PreUpdate() {
+ sc.UpdateAt = GetMillis()
+}
+
+type SharedChannelRemoteStatus struct {
+ ChannelId string `json:"channel_id"`
+ DisplayName string `json:"display_name"`
+ SiteURL string `json:"site_url"`
+ LastPingAt int64 `json:"last_ping_at"`
+ NextSyncAt int64 `json:"next_sync_at"`
+ ReadOnly bool `json:"readonly"`
+ IsInviteAccepted bool `json:"is_invite_accepted"`
+ Token string `json:"token"`
+}
+
+// SharedChannelUser stores a lastSyncAt timestamp on behalf of a remote cluster for
+// each user that has been synchronized.
+type SharedChannelUser struct {
+ Id string `json:"id"`
+ UserId string `json:"user_id"`
+ ChannelId string `json:"channel_id"`
+ RemoteId string `json:"remote_id"`
+ CreateAt int64 `json:"create_at"`
+ LastSyncAt int64 `json:"last_sync_at"`
+}
+
+func (scu *SharedChannelUser) PreSave() {
+ scu.Id = NewId()
+ scu.CreateAt = GetMillis()
+}
+
+func (scu *SharedChannelUser) IsValid() *AppError {
+ if !IsValidId(scu.Id) {
+ return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.id.app_error", nil, "Id="+scu.Id, http.StatusBadRequest)
+ }
+
+ if !IsValidId(scu.UserId) {
+ return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.id.app_error", nil, "UserId="+scu.UserId, http.StatusBadRequest)
+ }
+
+ if !IsValidId(scu.ChannelId) {
+ return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.id.app_error", nil, "ChannelId="+scu.ChannelId, http.StatusBadRequest)
+ }
+
+ if !IsValidId(scu.RemoteId) {
+ return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.id.app_error", nil, "RemoteId="+scu.RemoteId, http.StatusBadRequest)
+ }
+
+ if scu.CreateAt == 0 {
+ return NewAppError("SharedChannelUser.IsValid", "model.channel.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
+ }
+ return nil
+}
+
+type GetUsersForSyncFilter struct {
+ CheckProfileImage bool
+ ChannelID string
+ Limit uint64
+}
+
+// SharedChannelAttachment stores a lastSyncAt timestamp on behalf of a remote cluster for
+// each file attachment that has been synchronized.
+type SharedChannelAttachment struct {
+ Id string `json:"id"`
+ FileId string `json:"file_id"`
+ RemoteId string `json:"remote_id"`
+ CreateAt int64 `json:"create_at"`
+ LastSyncAt int64 `json:"last_sync_at"`
+}
+
+func (scf *SharedChannelAttachment) PreSave() {
+ if scf.Id == "" {
+ scf.Id = NewId()
+ }
+ if scf.CreateAt == 0 {
+ scf.CreateAt = GetMillis()
+ scf.LastSyncAt = scf.CreateAt
+ } else {
+ scf.LastSyncAt = GetMillis()
+ }
+}
+
+func (scf *SharedChannelAttachment) IsValid() *AppError {
+ if !IsValidId(scf.Id) {
+ return NewAppError("SharedChannelAttachment.IsValid", "model.channel.is_valid.id.app_error", nil, "Id="+scf.Id, http.StatusBadRequest)
+ }
+
+ if !IsValidId(scf.FileId) {
+ return NewAppError("SharedChannelAttachment.IsValid", "model.channel.is_valid.id.app_error", nil, "FileId="+scf.FileId, http.StatusBadRequest)
+ }
+
+ if !IsValidId(scf.RemoteId) {
+ return NewAppError("SharedChannelAttachment.IsValid", "model.channel.is_valid.id.app_error", nil, "RemoteId="+scf.RemoteId, http.StatusBadRequest)
+ }
+
+ if scf.CreateAt == 0 {
+ return NewAppError("SharedChannelAttachment.IsValid", "model.channel.is_valid.create_at.app_error", nil, "", http.StatusBadRequest)
+ }
+ return nil
+}
+
+type SharedChannelFilterOpts struct {
+ TeamId string
+ CreatorId string
+ ExcludeHome bool
+ ExcludeRemote bool
+}
+
+type SharedChannelRemoteFilterOpts struct {
+ ChannelId string
+ RemoteId string
+ InclUnconfirmed bool
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/slack_attachment.go b/vendor/github.com/mattermost/mattermost-server/v5/model/slack_attachment.go
index a85c6be2..371baaab 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/slack_attachment.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/slack_attachment.go
@@ -179,6 +179,9 @@ func ParseSlackAttachment(post *Post, attachments []*SlackAttachment) {
attachment.Pretext = ParseSlackLinksToMarkdown(attachment.Pretext)
for _, field := range attachment.Fields {
+ if field == nil {
+ continue
+ }
if value, ok := field.Value.(string); ok {
field.Value = ParseSlackLinksToMarkdown(value)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/status.go b/vendor/github.com/mattermost/mattermost-server/v5/model/status.go
index 1f32422a..f6f3a67a 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/status.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/status.go
@@ -25,6 +25,8 @@ type Status struct {
Manual bool `json:"manual"`
LastActivityAt int64 `json:"last_activity_at"`
ActiveChannel string `json:"active_channel,omitempty" db:"-"`
+ DNDEndTime int64 `json:"dnd_end_time"`
+ PrevStatus string `json:"-"`
}
func (o *Status) ToJson() string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/switch_request.go b/vendor/github.com/mattermost/mattermost-server/v5/model/switch_request.go
index 0ec4db7d..bdb90045 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/switch_request.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/switch_request.go
@@ -34,14 +34,16 @@ func (o *SwitchRequest) EmailToOAuth() bool {
(o.NewService == USER_AUTH_SERVICE_SAML ||
o.NewService == USER_AUTH_SERVICE_GITLAB ||
o.NewService == SERVICE_GOOGLE ||
- o.NewService == SERVICE_OFFICE365)
+ o.NewService == SERVICE_OFFICE365 ||
+ o.NewService == SERVICE_OPENID)
}
func (o *SwitchRequest) OAuthToEmail() bool {
return (o.CurrentService == USER_AUTH_SERVICE_SAML ||
o.CurrentService == USER_AUTH_SERVICE_GITLAB ||
o.CurrentService == SERVICE_GOOGLE ||
- o.CurrentService == SERVICE_OFFICE365) && o.NewService == USER_AUTH_SERVICE_EMAIL
+ o.CurrentService == SERVICE_OFFICE365 ||
+ o.CurrentService == SERVICE_OPENID) && o.NewService == USER_AUTH_SERVICE_EMAIL
}
func (o *SwitchRequest) EmailToLdap() bool {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/system.go b/vendor/github.com/mattermost/mattermost-server/v5/model/system.go
index 4e76c959..b7cda1ef 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/system.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/system.go
@@ -14,6 +14,7 @@ const (
SYSTEM_RAN_UNIT_TESTS = "RanUnitTests"
SYSTEM_LAST_SECURITY_TIME = "LastSecurityTime"
SYSTEM_ACTIVE_LICENSE_ID = "ActiveLicenseId"
+ SYSTEM_LICENSE_RENEWAL_TOKEN = "LicenseRenewalToken"
SYSTEM_LAST_COMPLIANCE_TIME = "LastComplianceTime"
SYSTEM_ASYMMETRIC_SIGNING_KEY = "AsymmetricSigningKey"
SYSTEM_POST_ACTION_COOKIE_SECRET = "PostActionCookieSecret"
@@ -31,10 +32,13 @@ const (
SYSTEM_WARN_METRIC_NUMBER_OF_ACTIVE_USERS_500 = "warn_metric_number_of_active_users_500"
SYSTEM_WARN_METRIC_NUMBER_OF_POSTS_2M = "warn_metric_number_of_posts_2M"
SYSTEM_WARN_METRIC_LAST_RUN_TIMESTAMP_KEY = "LastWarnMetricRunTimestamp"
+ SYSTEM_METRIC_SUPPORT_EMAIL_NOT_CONFIGURED = "warn_metric_support_email_not_configured"
+ SYSTEM_FIRST_ADMIN_VISIT_MARKETPLACE = "FirstAdminVisitMarketplace"
AWS_METERING_REPORT_INTERVAL = 1
AWS_METERING_DIMENSION_USAGE_HRS = "UsageHrs"
USER_LIMIT_OVERAGE_CYCLE_END_DATE = "UserLimitOverageCycleEndDate"
OVER_USER_LIMIT_FORGIVEN_COUNT = "OverUserLimitForgivenCount"
+ OVER_USER_LIMIT_LAST_EMAIL_SENT = "OverUserLimitLastEmailSent"
)
const (
@@ -85,6 +89,22 @@ type ServerBusyState struct {
Expires_ts string `json:"expires_ts,omitempty"`
}
+type SupportPacket struct {
+ ServerOS string `yaml:"server_os"`
+ ServerArchitecture string `yaml:"server_architecture"`
+ DatabaseType string `yaml:"database_type"`
+ DatabaseVersion string `yaml:"database_version"`
+ LdapVendorName string `yaml:"ldap_vendor_name,omitempty"`
+ LdapVendorVersion string `yaml:"ldap_vendor_version,omitempty"`
+ ElasticServerVersion string `yaml:"elastic_server_version,omitempty"`
+ ElasticServerPlugins []string `yaml:"elastic_server_plugins,omitempty"`
+}
+
+type FileData struct {
+ Filename string
+ Body []byte
+}
+
func (sbs *ServerBusyState) ToJson() string {
b, _ := json.Marshal(sbs)
return string(b)
@@ -151,13 +171,21 @@ var WarnMetricsTable = map[string]WarnMetric{
IsBotOnly: false,
IsRunOnce: true,
},
+ SYSTEM_METRIC_SUPPORT_EMAIL_NOT_CONFIGURED: {
+ Id: SYSTEM_METRIC_SUPPORT_EMAIL_NOT_CONFIGURED,
+ Limit: -1,
+ IsBotOnly: true,
+ IsRunOnce: false,
+ SkipAction: true,
+ },
}
type WarnMetric struct {
- Id string
- Limit int64
- IsBotOnly bool
- IsRunOnce bool
+ Id string
+ Limit int64
+ IsBotOnly bool
+ IsRunOnce bool
+ SkipAction bool
}
type WarnMetricDisplayTexts struct {
@@ -182,9 +210,8 @@ func WarnMetricStatusFromJson(data io.Reader) *WarnMetricStatus {
var o WarnMetricStatus
if err := json.NewDecoder(data).Decode(&o); err != nil {
return nil
- } else {
- return &o
}
+ return &o
}
func MapWarnMetricStatusToJson(o map[string]*WarnMetricStatus) string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/team.go b/vendor/github.com/mattermost/mattermost-server/v5/model/team.go
index 381eb8bb..fc752f30 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/team.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/team.go
@@ -42,6 +42,7 @@ type Team struct {
LastTeamIconUpdate int64 `json:"last_team_icon_update,omitempty"`
SchemeId *string `json:"scheme_id"`
GroupConstrained *bool `json:"group_constrained"`
+ PolicyID *string `json:"policy_id" db:"-"`
}
type TeamPatch struct {
@@ -152,7 +153,7 @@ func (o *Team) IsValid() *AppError {
return NewAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
- if len(o.Email) > 0 && !IsValidEmail(o.Email) {
+ if o.Email != "" && !IsValidEmail(o.Email) {
return NewAppError("Team.IsValid", "model.team.is_valid.email.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
@@ -168,7 +169,7 @@ func (o *Team) IsValid() *AppError {
return NewAppError("Team.IsValid", "model.team.is_valid.description.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
- if len(o.InviteId) == 0 {
+ if o.InviteId == "" {
return NewAppError("Team.IsValid", "model.team.is_valid.invite_id.app_error", nil, "id="+o.Id, http.StatusBadRequest)
}
@@ -208,7 +209,7 @@ func (o *Team) PreSave() {
o.Description = SanitizeUnicode(o.Description)
o.CompanyName = SanitizeUnicode(o.CompanyName)
- if len(o.InviteId) == 0 {
+ if o.InviteId == "" {
o.InviteId = NewId()
}
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/team_member.go b/vendor/github.com/mattermost/mattermost-server/v5/model/team_member.go
index b747f17c..f5f1cc61 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/team_member.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/team_member.go
@@ -15,6 +15,9 @@ const (
USERNAME = "Username"
)
+//msgp:tuple TeamMember
+// This struct's serializer methods are auto-generated. If a new field is added/removed,
+// please run make gen-serialized.
type TeamMember struct {
TeamId string `json:"team_id"`
UserId string `json:"user_id"`
@@ -26,28 +29,37 @@ type TeamMember struct {
ExplicitRoles string `json:"explicit_roles"`
}
+//msgp:ignore TeamUnread
type TeamUnread struct {
- TeamId string `json:"team_id"`
- MsgCount int64 `json:"msg_count"`
- MentionCount int64 `json:"mention_count"`
+ TeamId string `json:"team_id"`
+ MsgCount int64 `json:"msg_count"`
+ MentionCount int64 `json:"mention_count"`
+ MentionCountRoot int64 `json:"mention_count_root"`
+ MsgCountRoot int64 `json:"msg_count_root"`
+ ThreadCount int64 `json:"thread_count"`
+ ThreadMentionCount int64 `json:"thread_mention_count"`
}
+//msgp:ignore TeamMemberForExport
type TeamMemberForExport struct {
TeamMember
TeamName string
}
+//msgp:ignore TeamMemberWithError
type TeamMemberWithError struct {
UserId string `json:"user_id"`
Member *TeamMember `json:"member"`
Error *AppError `json:"error"`
}
+//msgp:ignore EmailInviteWithError
type EmailInviteWithError struct {
Email string `json:"email"`
Error *AppError `json:"error"`
}
+//msgp:ignore TeamMembersGetOptions
type TeamMembersGetOptions struct {
// Sort the team members. Accepts "Username", but defaults to "Id".
Sort string
@@ -98,11 +110,11 @@ func EmailInviteWithErrorToEmails(o []*EmailInviteWithError) []string {
}
func EmailInviteWithErrorToJson(o []*EmailInviteWithError) string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func EmailInviteWithErrorToString(o *EmailInviteWithError) string {
@@ -120,11 +132,11 @@ func TeamMembersWithErrorToTeamMembers(o []*TeamMemberWithError) []*TeamMember {
}
func TeamMembersWithErrorToJson(o []*TeamMemberWithError) string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func TeamMemberWithErrorToString(o *TeamMemberWithError) string {
@@ -138,11 +150,11 @@ func TeamMembersWithErrorFromJson(data io.Reader) []*TeamMemberWithError {
}
func TeamMembersToJson(o []*TeamMember) string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func TeamMembersFromJson(data io.Reader) []*TeamMember {
@@ -152,11 +164,11 @@ func TeamMembersFromJson(data io.Reader) []*TeamMember {
}
func TeamsUnreadToJson(o []*TeamUnread) string {
- if b, err := json.Marshal(o); err != nil {
+ b, err := json.Marshal(o)
+ if err != nil {
return "[]"
- } else {
- return string(b)
}
+ return string(b)
}
func TeamsUnreadFromJson(data io.Reader) []*TeamUnread {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/team_member_serial_gen.go b/vendor/github.com/mattermost/mattermost-server/v5/model/team_member_serial_gen.go
new file mode 100644
index 00000000..044a608a
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/team_member_serial_gen.go
@@ -0,0 +1,193 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+// Code generated by github.com/tinylib/msgp DO NOT EDIT.
+
+import (
+ "github.com/tinylib/msgp/msgp"
+)
+
+// DecodeMsg implements msgp.Decodable
+func (z *TeamMember) DecodeMsg(dc *msgp.Reader) (err error) {
+ var zb0001 uint32
+ zb0001, err = dc.ReadArrayHeader()
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if zb0001 != 8 {
+ err = msgp.ArrayError{Wanted: 8, Got: zb0001}
+ return
+ }
+ z.TeamId, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "TeamId")
+ return
+ }
+ z.UserId, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "UserId")
+ return
+ }
+ z.Roles, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ z.DeleteAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "DeleteAt")
+ return
+ }
+ z.SchemeGuest, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeGuest")
+ return
+ }
+ z.SchemeUser, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeUser")
+ return
+ }
+ z.SchemeAdmin, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeAdmin")
+ return
+ }
+ z.ExplicitRoles, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "ExplicitRoles")
+ return
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z *TeamMember) EncodeMsg(en *msgp.Writer) (err error) {
+ // array header, size 8
+ err = en.Append(0x98)
+ if err != nil {
+ return
+ }
+ err = en.WriteString(z.TeamId)
+ if err != nil {
+ err = msgp.WrapError(err, "TeamId")
+ return
+ }
+ err = en.WriteString(z.UserId)
+ if err != nil {
+ err = msgp.WrapError(err, "UserId")
+ return
+ }
+ err = en.WriteString(z.Roles)
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ err = en.WriteInt64(z.DeleteAt)
+ if err != nil {
+ err = msgp.WrapError(err, "DeleteAt")
+ return
+ }
+ err = en.WriteBool(z.SchemeGuest)
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeGuest")
+ return
+ }
+ err = en.WriteBool(z.SchemeUser)
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeUser")
+ return
+ }
+ err = en.WriteBool(z.SchemeAdmin)
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeAdmin")
+ return
+ }
+ err = en.WriteString(z.ExplicitRoles)
+ if err != nil {
+ err = msgp.WrapError(err, "ExplicitRoles")
+ return
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z *TeamMember) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ // array header, size 8
+ o = append(o, 0x98)
+ o = msgp.AppendString(o, z.TeamId)
+ o = msgp.AppendString(o, z.UserId)
+ o = msgp.AppendString(o, z.Roles)
+ o = msgp.AppendInt64(o, z.DeleteAt)
+ o = msgp.AppendBool(o, z.SchemeGuest)
+ o = msgp.AppendBool(o, z.SchemeUser)
+ o = msgp.AppendBool(o, z.SchemeAdmin)
+ o = msgp.AppendString(o, z.ExplicitRoles)
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *TeamMember) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ var zb0001 uint32
+ zb0001, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if zb0001 != 8 {
+ err = msgp.ArrayError{Wanted: 8, Got: zb0001}
+ return
+ }
+ z.TeamId, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "TeamId")
+ return
+ }
+ z.UserId, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "UserId")
+ return
+ }
+ z.Roles, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ z.DeleteAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "DeleteAt")
+ return
+ }
+ z.SchemeGuest, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeGuest")
+ return
+ }
+ z.SchemeUser, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeUser")
+ return
+ }
+ z.SchemeAdmin, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "SchemeAdmin")
+ return
+ }
+ z.ExplicitRoles, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "ExplicitRoles")
+ return
+ }
+ o = bts
+ return
+}
+
+// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
+func (z *TeamMember) Msgsize() (s int) {
+ s = 1 + msgp.StringPrefixSize + len(z.TeamId) + msgp.StringPrefixSize + len(z.UserId) + msgp.StringPrefixSize + len(z.Roles) + msgp.Int64Size + msgp.BoolSize + msgp.BoolSize + msgp.BoolSize + msgp.StringPrefixSize + len(z.ExplicitRoles)
+ return
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/team_search.go b/vendor/github.com/mattermost/mattermost-server/v5/model/team_search.go
index f9de5801..e24b8438 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/team_search.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/team_search.go
@@ -9,12 +9,17 @@ import (
)
type TeamSearch struct {
- Term string `json:"term"`
- Page *int `json:"page,omitempty"`
- PerPage *int `json:"per_page,omitempty"`
- AllowOpenInvite *bool `json:"allow_open_invite,omitempty"`
- GroupConstrained *bool `json:"group_constrained,omitempty"`
- IncludeGroupConstrained *bool `json:"include_group_constrained,omitempty"`
+ Term string `json:"term"`
+ Page *int `json:"page,omitempty"`
+ PerPage *int `json:"per_page,omitempty"`
+ AllowOpenInvite *bool `json:"allow_open_invite,omitempty"`
+ GroupConstrained *bool `json:"group_constrained,omitempty"`
+ IncludeGroupConstrained *bool `json:"include_group_constrained,omitempty"`
+ PolicyID *string `json:"policy_id,omitempty"`
+ ExcludePolicyConstrained *bool `json:"exclude_policy_constrained,omitempty"`
+ IncludePolicyID *bool `json:"-"`
+ IncludeDeleted *bool `json:"-"`
+ TeamType *string `json:"-"`
}
func (t *TeamSearch) IsPaginated() bool {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/thread.go b/vendor/github.com/mattermost/mattermost-server/v5/model/thread.go
index ec091c00..fe4a4014 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/thread.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/thread.go
@@ -16,23 +16,24 @@ type Thread struct {
}
type ThreadResponse struct {
- PostId string `json:"id"`
- ReplyCount int64 `json:"reply_count"`
- LastReplyAt int64 `json:"last_reply_at"`
- LastViewedAt int64 `json:"last_viewed_at"`
- Participants []*User `json:"participants"`
- Post *Post `json:"post"`
+ PostId string `json:"id"`
+ ReplyCount int64 `json:"reply_count"`
+ LastReplyAt int64 `json:"last_reply_at"`
+ LastViewedAt int64 `json:"last_viewed_at"`
+ Participants []*User `json:"participants"`
+ Post *Post `json:"post"`
+ UnreadReplies int64 `json:"unread_replies"`
+ UnreadMentions int64 `json:"unread_mentions"`
}
type Threads struct {
- Total int64 `json:"total"`
- Threads []*ThreadResponse `json:"threads"`
+ Total int64 `json:"total"`
+ TotalUnreadThreads int64 `json:"total_unread_threads"`
+ TotalUnreadMentions int64 `json:"total_unread_mentions"`
+ Threads []*ThreadResponse `json:"threads"`
}
type GetUserThreadsOpts struct {
- // Page specifies which part of the results to return, by PageSize. Default = 0
- Page uint64
-
// PageSize specifies the size of the returned chunk of results. Default = 30
PageSize uint64
@@ -44,6 +45,32 @@ type GetUserThreadsOpts struct {
// Since filters the threads based on their LastUpdateAt timestamp.
Since uint64
+
+ // Before specifies thread id as a cursor for pagination and will return `PageSize` threads before the cursor
+ Before string
+
+ // After specifies thread id as a cursor for pagination and will return `PageSize` threads after the cursor
+ After string
+
+ // Unread will make sure that only threads with unread replies are returned
+ Unread bool
+
+ // TotalsOnly will not fetch any threads and just fetch the total counts
+ TotalsOnly bool
+
+ // TeamOnly will only fetch threads and unreads for the specified team and excludes DMs/GMs
+ TeamOnly bool
+}
+
+func (o *ThreadResponse) ToJson() string {
+ b, _ := json.Marshal(o)
+ return string(b)
+}
+
+func ThreadResponseFromJson(s string) (*ThreadResponse, error) {
+ var t ThreadResponse
+ err := json.Unmarshal([]byte(s), &t)
+ return &t, err
}
func (o *Threads) ToJson() string {
@@ -56,6 +83,12 @@ func (o *Thread) ToJson() string {
return string(b)
}
+func ThreadFromJson(s string) (*Thread, error) {
+ var t Thread
+ err := json.Unmarshal([]byte(s), &t)
+ return &t, err
+}
+
func (o *Thread) Etag() string {
return Etag(o.PostId, o.LastReplyAt)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/token.go b/vendor/github.com/mattermost/mattermost-server/v5/model/token.go
index 0730778c..2dcf4143 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/token.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/token.go
@@ -3,7 +3,9 @@
package model
-import "net/http"
+import (
+ "net/http"
+)
const (
TOKEN_SIZE = 64
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/upload_session.go b/vendor/github.com/mattermost/mattermost-server/v5/model/upload_session.go
index 663ee0b1..c5f09083 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/upload_session.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/upload_session.go
@@ -18,6 +18,9 @@ const (
UploadTypeImport UploadType = "import"
)
+// UploadNoUserID is a "fake" user id used by the API layer when in local mode.
+const UploadNoUserID = "nouser"
+
// UploadSession contains information used to keep track of a file upload.
type UploadSession struct {
// The unique identifier for the session.
@@ -29,7 +32,7 @@ type UploadSession struct {
// The id of the user performing the upload.
UserId string `json:"user_id"`
// The id of the channel to upload to.
- ChannelId string `json:"channel_id"`
+ ChannelId string `json:"channel_id,omitempty"`
// The name of the file to upload.
Filename string `json:"filename"`
// The path where the file is stored.
@@ -39,6 +42,10 @@ type UploadSession struct {
// The amount of received data in bytes. If equal to FileSize it means the
// upload has finished.
FileOffset int64 `json:"file_offset"`
+ // Id of remote cluster if uploading for shared channel
+ RemoteId string `json:"remote_id"`
+ // Requested file id if uploading for shared channel
+ ReqFileId string `json:"req_file_id"`
}
// ToJson serializes the UploadSession into JSON and returns it as string.
@@ -109,7 +116,7 @@ func (us *UploadSession) IsValid() *AppError {
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.type.app_error", nil, err.Error(), http.StatusBadRequest)
}
- if !IsValidId(us.UserId) {
+ if !IsValidId(us.UserId) && us.UserId != UploadNoUserID {
return NewAppError("UploadSession.IsValid", "model.upload_session.is_valid.user_id.app_error", nil, "id="+us.Id, http.StatusBadRequest)
}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/user.go b/vendor/github.com/mattermost/mattermost-server/v5/model/user.go
index dd4e2ba8..1745d726 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/user.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/user.go
@@ -9,17 +9,17 @@ import (
"fmt"
"io"
"io/ioutil"
- "math/rand"
"net/http"
"regexp"
"sort"
"strings"
- "time"
"unicode/utf8"
- "github.com/mattermost/mattermost-server/v5/services/timezones"
"golang.org/x/crypto/bcrypt"
"golang.org/x/text/language"
+
+ "github.com/mattermost/mattermost-server/v5/services/timezones"
+ "github.com/mattermost/mattermost-server/v5/shared/mlog"
)
const (
@@ -57,6 +57,7 @@ const (
USER_NAME_MIN_LENGTH = 1
USER_PASSWORD_MAX_LENGTH = 72
USER_LOCALE_MAX_LENGTH = 5
+ USER_TIMEZONE_MAX_RUNES = 256
)
//msgp:tuple User
@@ -90,12 +91,14 @@ type User struct {
Timezone StringMap `json:"timezone"`
MfaActive bool `json:"mfa_active,omitempty"`
MfaSecret string `json:"mfa_secret,omitempty"`
+ RemoteId *string `json:"remote_id,omitempty"`
LastActivityAt int64 `db:"-" json:"last_activity_at,omitempty"`
IsBot bool `db:"-" json:"is_bot,omitempty"`
BotDescription string `db:"-" json:"bot_description,omitempty"`
BotLastIconUpdate int64 `db:"-" json:"bot_last_icon_update,omitempty"`
TermsOfServiceId string `db:"-" json:"terms_of_service_id,omitempty"`
TermsOfServiceCreateAt int64 `db:"-" json:"terms_of_service_create_at,omitempty"`
+ DisableWelcomeEmail bool `db:"-" json:"disable_welcome_email"`
}
//msgp UserMap
@@ -104,11 +107,13 @@ type User struct {
// It is used to generate methods which can be used for fast serialization/de-serialization.
type UserMap map[string]*User
+//msgp:ignore UserUpdate
type UserUpdate struct {
Old *User
New *User
}
+//msgp:ignore UserPatch
type UserPatch struct {
Username *string `json:"username"`
Password *string `json:"password,omitempty"`
@@ -121,14 +126,17 @@ type UserPatch struct {
NotifyProps StringMap `json:"notify_props,omitempty"`
Locale *string `json:"locale"`
Timezone StringMap `json:"timezone"`
+ RemoteId *string `json:"remote_id"`
}
+//msgp:ignore UserAuth
type UserAuth struct {
- Password string `json:"password,omitempty"`
+ Password string `json:"password,omitempty"` // DEPRECATED: It is not used.
AuthData *string `json:"auth_data,omitempty"`
AuthService string `json:"auth_service,omitempty"`
}
+//msgp:ignore UserForIndexing
type UserForIndexing struct {
Id string `json:"id"`
Username string `json:"username"`
@@ -142,6 +150,7 @@ type UserForIndexing struct {
ChannelsIds []string `json:"channel_id"`
}
+//msgp:ignore ViewUsersRestrictions
type ViewUsersRestrictions struct {
Teams []string
Channels []string
@@ -158,6 +167,7 @@ func (r *ViewUsersRestrictions) Hash() string {
return fmt.Sprintf("%x", hash.Sum(nil))
}
+//msgp:ignore UserSlice
type UserSlice []*User
func (u UserSlice) Usernames() []string {
@@ -262,11 +272,17 @@ func (u *User) IsValid() *AppError {
return InvalidUserError("update_at", u.Id)
}
- if !IsValidUsername(u.Username) {
- return InvalidUserError("username", u.Id)
+ if u.IsRemote() {
+ if !IsValidUsernameAllowRemote(u.Username) {
+ return InvalidUserError("username", u.Id)
+ }
+ } else {
+ if !IsValidUsername(u.Username) {
+ return InvalidUserError("username", u.Id)
+ }
}
- if len(u.Email) > USER_EMAIL_MAX_LENGTH || len(u.Email) == 0 || !IsValidEmail(u.Email) {
+ if len(u.Email) > USER_EMAIL_MAX_LENGTH || u.Email == "" || !IsValidEmail(u.Email) {
return InvalidUserError("email", u.Id)
}
@@ -290,11 +306,11 @@ func (u *User) IsValid() *AppError {
return InvalidUserError("auth_data", u.Id)
}
- if u.AuthData != nil && len(*u.AuthData) > 0 && len(u.AuthService) == 0 {
+ if u.AuthData != nil && *u.AuthData != "" && u.AuthService == "" {
return InvalidUserError("auth_data_type", u.Id)
}
- if len(u.Password) > 0 && u.AuthData != nil && len(*u.AuthData) > 0 {
+ if u.Password != "" && u.AuthData != nil && *u.AuthData != "" {
return InvalidUserError("auth_data_pwd", u.Id)
}
@@ -306,6 +322,14 @@ func (u *User) IsValid() *AppError {
return InvalidUserError("locale", u.Id)
}
+ if len(u.Timezone) > 0 {
+ if tzJSON, err := json.Marshal(u.Timezone); err != nil {
+ return NewAppError("User.IsValid", "model.user.is_valid.marshal.app_error", nil, err.Error(), http.StatusInternalServerError)
+ } else if utf8.RuneCount(tzJSON) > USER_TIMEZONE_MAX_RUNES {
+ return InvalidUserError("timezone_limit", u.Id)
+ }
+ }
+
return nil
}
@@ -373,7 +397,7 @@ func (u *User) PreSave() {
u.Timezone = timezones.DefaultUserTimezone()
}
- if len(u.Password) > 0 {
+ if u.Password != "" {
u.Password = HashPassword(u.Password)
}
}
@@ -406,7 +430,7 @@ func (u *User) PreUpdate() {
splitKeys := strings.Split(u.NotifyProps[MENTION_KEYS_NOTIFY_PROP], ",")
goodKeys := []string{}
for _, key := range splitKeys {
- if len(key) > 0 {
+ if key != "" {
goodKeys = append(goodKeys, strings.ToLower(key))
}
}
@@ -497,6 +521,10 @@ func (u *User) Patch(patch *UserPatch) {
if patch.Timezone != nil {
u.Timezone = patch.Timezone
}
+
+ if patch.RemoteId != nil {
+ u.RemoteId = patch.RemoteId
+ }
}
// ToJson convert a User to a json string
@@ -553,6 +581,7 @@ func (u *User) SanitizeInput(isAdmin bool) {
u.FailedAttempts = 0
u.MfaActive = false
u.MfaSecret = ""
+ u.Email = strings.TrimSpace(u.Email)
}
func (u *User) ClearNonProfileFields() {
@@ -588,12 +617,22 @@ func (u *User) AddNotifyProp(key string, value string) {
u.NotifyProps[key] = value
}
+func (u *User) SetCustomStatus(cs *CustomStatus) {
+ u.MakeNonNil()
+ u.Props[UserPropsKeyCustomStatus] = cs.ToJson()
+}
+
+func (u *User) ClearCustomStatus() {
+ u.MakeNonNil()
+ u.Props[UserPropsKeyCustomStatus] = ""
+}
+
func (u *User) GetFullName() string {
- if len(u.FirstName) > 0 && len(u.LastName) > 0 {
+ if u.FirstName != "" && u.LastName != "" {
return u.FirstName + " " + u.LastName
- } else if len(u.FirstName) > 0 {
+ } else if u.FirstName != "" {
return u.FirstName
- } else if len(u.LastName) > 0 {
+ } else if u.LastName != "" {
return u.LastName
} else {
return ""
@@ -604,13 +643,13 @@ func (u *User) getDisplayName(baseName, nameFormat string) string {
displayName := baseName
if nameFormat == SHOW_NICKNAME_FULLNAME {
- if len(u.Nickname) > 0 {
+ if u.Nickname != "" {
displayName = u.Nickname
- } else if fullName := u.GetFullName(); len(fullName) > 0 {
+ } else if fullName := u.GetFullName(); fullName != "" {
displayName = fullName
}
} else if nameFormat == SHOW_FULLNAME {
- if fullName := u.GetFullName(); len(fullName) > 0 {
+ if fullName := u.GetFullName(); fullName != "" {
displayName = fullName
}
}
@@ -691,7 +730,10 @@ func (u *User) IsSSOUser() bool {
}
func (u *User) IsOAuthUser() bool {
- return u.AuthService == USER_AUTH_SERVICE_GITLAB
+ return u.AuthService == SERVICE_GITLAB ||
+ u.AuthService == SERVICE_GOOGLE ||
+ u.AuthService == SERVICE_OFFICE365 ||
+ u.AuthService == SERVICE_OPENID
}
func (u *User) IsLDAPUser() bool {
@@ -706,6 +748,61 @@ func (u *User) GetPreferredTimezone() string {
return GetPreferredTimezone(u.Timezone)
}
+// IsRemote returns true if the user belongs to a remote cluster (has RemoteId).
+func (u *User) IsRemote() bool {
+ return u.RemoteId != nil && *u.RemoteId != ""
+}
+
+// GetRemoteID returns the remote id for this user or "" if not a remote user.
+func (u *User) GetRemoteID() string {
+ if u.RemoteId != nil {
+ return *u.RemoteId
+ }
+ return ""
+}
+
+// GetProp fetches a prop value by name.
+func (u *User) GetProp(name string) (string, bool) {
+ val, ok := u.Props[name]
+ return val, ok
+}
+
+// SetProp sets a prop value by name, creating the map if nil.
+// Not thread safe.
+func (u *User) SetProp(name string, value string) {
+ if u.Props == nil {
+ u.Props = make(map[string]string)
+ }
+ u.Props[name] = value
+}
+
+func (u *User) ToPatch() *UserPatch {
+ return &UserPatch{
+ Username: &u.Username, Password: &u.Password,
+ Nickname: &u.Nickname, FirstName: &u.FirstName, LastName: &u.LastName,
+ Position: &u.Position, Email: &u.Email,
+ Props: u.Props, NotifyProps: u.NotifyProps,
+ Locale: &u.Locale, Timezone: u.Timezone,
+ }
+}
+
+func (u *UserPatch) SetField(fieldName string, fieldValue string) {
+ switch fieldName {
+ case "FirstName":
+ u.FirstName = &fieldValue
+ case "LastName":
+ u.LastName = &fieldValue
+ case "Nickname":
+ u.Nickname = &fieldValue
+ case "Email":
+ u.Email = &fieldValue
+ case "Position":
+ u.Position = &fieldValue
+ case "Username":
+ u.Username = &fieldValue
+ }
+}
+
// UserFromJson will decode the input and return a User
func UserFromJson(data io.Reader) *User {
var user *User
@@ -758,9 +855,10 @@ func HashPassword(password string) string {
}
// ComparePassword compares the hash
+// This function is deprecated and will be removed in a future release.
func ComparePassword(hash string, password string) bool {
- if len(password) == 0 || len(hash) == 0 {
+ if password == "" || hash == "" {
return false
}
@@ -769,12 +867,13 @@ func ComparePassword(hash string, password string) bool {
}
var validUsernameChars = regexp.MustCompile(`^[a-z0-9\.\-_]+$`)
+var validUsernameCharsForRemote = regexp.MustCompile(`^[a-z0-9\.\-_:]+$`)
-var restrictedUsernames = []string{
- "all",
- "channel",
- "matterbot",
- "system",
+var restrictedUsernames = map[string]struct{}{
+ "all": {},
+ "channel": {},
+ "matterbot": {},
+ "system": {},
}
func IsValidUsername(s string) bool {
@@ -786,17 +885,25 @@ func IsValidUsername(s string) bool {
return false
}
- for _, restrictedUsername := range restrictedUsernames {
- if s == restrictedUsername {
- return false
- }
+ _, found := restrictedUsernames[s]
+ return !found
+}
+
+func IsValidUsernameAllowRemote(s string) bool {
+ if len(s) < USER_NAME_MIN_LENGTH || len(s) > USER_NAME_MAX_LENGTH {
+ return false
}
- return true
+ if !validUsernameCharsForRemote.MatchString(s) {
+ return false
+ }
+
+ _, found := restrictedUsernames[s]
+ return !found
}
-func CleanUsername(s string) string {
- s = NormalizeUsername(strings.Replace(s, " ", "-", -1))
+func CleanUsername(username string) string {
+ s := NormalizeUsername(strings.Replace(username, " ", "-", -1))
for _, value := range reservedName {
if s == value {
@@ -817,6 +924,8 @@ func CleanUsername(s string) string {
if !IsValidUsername(s) {
s = "a" + NewId()
+ mlog.Warn("Generating new username since provided username was invalid",
+ mlog.String("provided_username", username), mlog.String("new_username", s))
}
return s
@@ -858,6 +967,7 @@ func IsValidLocale(locale string) bool {
return true
}
+//msgp:ignore UserWithGroups
type UserWithGroups struct {
User
GroupIDs *string `json:"-"`
@@ -872,12 +982,13 @@ func (u *UserWithGroups) GetGroupIDs() []string {
return nil
}
trimmed := strings.TrimSpace(*u.GroupIDs)
- if len(trimmed) == 0 {
+ if trimmed == "" {
return nil
}
return strings.Split(trimmed, ",")
}
+//msgp:ignore UsersWithGroupsAndCount
type UsersWithGroupsAndCount struct {
Users []*UserWithGroups `json:"users"`
Count int64 `json:"total_count"`
@@ -889,27 +1000,3 @@ func UsersWithGroupsAndCountFromJson(data io.Reader) *UsersWithGroupsAndCount {
json.Unmarshal(bodyBytes, uwg)
return uwg
}
-
-var passwordRandomSource = rand.NewSource(time.Now().Unix())
-var passwordSpecialChars = "!$%^&*(),."
-var passwordNumbers = "0123456789"
-var passwordUpperCaseLetters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-var passwordLowerCaseLetters = "abcdefghijklmnopqrstuvwxyz"
-var passwordAllChars = passwordSpecialChars + passwordNumbers + passwordUpperCaseLetters + passwordLowerCaseLetters
-
-func GeneratePassword(minimumLength int) string {
- r := rand.New(passwordRandomSource)
-
- // Make sure we are guaranteed at least one of each type to meet any possible password complexity requirements.
- password := string([]rune(passwordUpperCaseLetters)[r.Intn(len(passwordUpperCaseLetters))]) +
- string([]rune(passwordNumbers)[r.Intn(len(passwordNumbers))]) +
- string([]rune(passwordLowerCaseLetters)[r.Intn(len(passwordLowerCaseLetters))]) +
- string([]rune(passwordSpecialChars)[r.Intn(len(passwordSpecialChars))])
-
- for len(password) < minimumLength {
- i := r.Intn(len(passwordAllChars))
- password = password + string([]rune(passwordAllChars)[i])
- }
-
- return password
-}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/user_autocomplete.go b/vendor/github.com/mattermost/mattermost-server/v5/model/user_autocomplete.go
index 48a892e2..118e138d 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/user_autocomplete.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/user_autocomplete.go
@@ -31,11 +31,10 @@ func UserAutocompleteFromJson(data io.Reader) *UserAutocomplete {
decoder := json.NewDecoder(data)
autocomplete := new(UserAutocomplete)
err := decoder.Decode(&autocomplete)
- if err == nil {
- return autocomplete
- } else {
+ if err != nil {
return nil
}
+ return autocomplete
}
func (o *UserAutocompleteInChannel) ToJson() string {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/user_serial_gen.go b/vendor/github.com/mattermost/mattermost-server/v5/model/user_serial_gen.go
new file mode 100644
index 00000000..fb40b577
--- /dev/null
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/user_serial_gen.go
@@ -0,0 +1,826 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+package model
+
+// Code generated by github.com/tinylib/msgp DO NOT EDIT.
+
+import (
+ "github.com/tinylib/msgp/msgp"
+)
+
+// DecodeMsg implements msgp.Decodable
+func (z *User) DecodeMsg(dc *msgp.Reader) (err error) {
+ var zb0001 uint32
+ zb0001, err = dc.ReadArrayHeader()
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if zb0001 != 32 {
+ err = msgp.ArrayError{Wanted: 32, Got: zb0001}
+ return
+ }
+ z.Id, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Id")
+ return
+ }
+ z.CreateAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "CreateAt")
+ return
+ }
+ z.UpdateAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "UpdateAt")
+ return
+ }
+ z.DeleteAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "DeleteAt")
+ return
+ }
+ z.Username, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Username")
+ return
+ }
+ z.Password, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Password")
+ return
+ }
+ if dc.IsNil() {
+ err = dc.ReadNil()
+ if err != nil {
+ err = msgp.WrapError(err, "AuthData")
+ return
+ }
+ z.AuthData = nil
+ } else {
+ if z.AuthData == nil {
+ z.AuthData = new(string)
+ }
+ *z.AuthData, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "AuthData")
+ return
+ }
+ }
+ z.AuthService, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "AuthService")
+ return
+ }
+ z.Email, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Email")
+ return
+ }
+ z.EmailVerified, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "EmailVerified")
+ return
+ }
+ z.Nickname, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Nickname")
+ return
+ }
+ z.FirstName, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "FirstName")
+ return
+ }
+ z.LastName, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "LastName")
+ return
+ }
+ z.Position, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Position")
+ return
+ }
+ z.Roles, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ z.AllowMarketing, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "AllowMarketing")
+ return
+ }
+ err = z.Props.DecodeMsg(dc)
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ err = z.NotifyProps.DecodeMsg(dc)
+ if err != nil {
+ err = msgp.WrapError(err, "NotifyProps")
+ return
+ }
+ z.LastPasswordUpdate, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "LastPasswordUpdate")
+ return
+ }
+ z.LastPictureUpdate, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "LastPictureUpdate")
+ return
+ }
+ z.FailedAttempts, err = dc.ReadInt()
+ if err != nil {
+ err = msgp.WrapError(err, "FailedAttempts")
+ return
+ }
+ z.Locale, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "Locale")
+ return
+ }
+ err = z.Timezone.DecodeMsg(dc)
+ if err != nil {
+ err = msgp.WrapError(err, "Timezone")
+ return
+ }
+ z.MfaActive, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "MfaActive")
+ return
+ }
+ z.MfaSecret, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "MfaSecret")
+ return
+ }
+ if dc.IsNil() {
+ err = dc.ReadNil()
+ if err != nil {
+ err = msgp.WrapError(err, "RemoteId")
+ return
+ }
+ z.RemoteId = nil
+ } else {
+ if z.RemoteId == nil {
+ z.RemoteId = new(string)
+ }
+ *z.RemoteId, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "RemoteId")
+ return
+ }
+ }
+ z.LastActivityAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "LastActivityAt")
+ return
+ }
+ z.IsBot, err = dc.ReadBool()
+ if err != nil {
+ err = msgp.WrapError(err, "IsBot")
+ return
+ }
+ z.BotDescription, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "BotDescription")
+ return
+ }
+ z.BotLastIconUpdate, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "BotLastIconUpdate")
+ return
+ }
+ z.TermsOfServiceId, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err, "TermsOfServiceId")
+ return
+ }
+ z.TermsOfServiceCreateAt, err = dc.ReadInt64()
+ if err != nil {
+ err = msgp.WrapError(err, "TermsOfServiceCreateAt")
+ return
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z *User) EncodeMsg(en *msgp.Writer) (err error) {
+ // array header, size 32
+ err = en.Append(0xdc, 0x0, 0x20)
+ if err != nil {
+ return
+ }
+ err = en.WriteString(z.Id)
+ if err != nil {
+ err = msgp.WrapError(err, "Id")
+ return
+ }
+ err = en.WriteInt64(z.CreateAt)
+ if err != nil {
+ err = msgp.WrapError(err, "CreateAt")
+ return
+ }
+ err = en.WriteInt64(z.UpdateAt)
+ if err != nil {
+ err = msgp.WrapError(err, "UpdateAt")
+ return
+ }
+ err = en.WriteInt64(z.DeleteAt)
+ if err != nil {
+ err = msgp.WrapError(err, "DeleteAt")
+ return
+ }
+ err = en.WriteString(z.Username)
+ if err != nil {
+ err = msgp.WrapError(err, "Username")
+ return
+ }
+ err = en.WriteString(z.Password)
+ if err != nil {
+ err = msgp.WrapError(err, "Password")
+ return
+ }
+ if z.AuthData == nil {
+ err = en.WriteNil()
+ if err != nil {
+ return
+ }
+ } else {
+ err = en.WriteString(*z.AuthData)
+ if err != nil {
+ err = msgp.WrapError(err, "AuthData")
+ return
+ }
+ }
+ err = en.WriteString(z.AuthService)
+ if err != nil {
+ err = msgp.WrapError(err, "AuthService")
+ return
+ }
+ err = en.WriteString(z.Email)
+ if err != nil {
+ err = msgp.WrapError(err, "Email")
+ return
+ }
+ err = en.WriteBool(z.EmailVerified)
+ if err != nil {
+ err = msgp.WrapError(err, "EmailVerified")
+ return
+ }
+ err = en.WriteString(z.Nickname)
+ if err != nil {
+ err = msgp.WrapError(err, "Nickname")
+ return
+ }
+ err = en.WriteString(z.FirstName)
+ if err != nil {
+ err = msgp.WrapError(err, "FirstName")
+ return
+ }
+ err = en.WriteString(z.LastName)
+ if err != nil {
+ err = msgp.WrapError(err, "LastName")
+ return
+ }
+ err = en.WriteString(z.Position)
+ if err != nil {
+ err = msgp.WrapError(err, "Position")
+ return
+ }
+ err = en.WriteString(z.Roles)
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ err = en.WriteBool(z.AllowMarketing)
+ if err != nil {
+ err = msgp.WrapError(err, "AllowMarketing")
+ return
+ }
+ err = z.Props.EncodeMsg(en)
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ err = z.NotifyProps.EncodeMsg(en)
+ if err != nil {
+ err = msgp.WrapError(err, "NotifyProps")
+ return
+ }
+ err = en.WriteInt64(z.LastPasswordUpdate)
+ if err != nil {
+ err = msgp.WrapError(err, "LastPasswordUpdate")
+ return
+ }
+ err = en.WriteInt64(z.LastPictureUpdate)
+ if err != nil {
+ err = msgp.WrapError(err, "LastPictureUpdate")
+ return
+ }
+ err = en.WriteInt(z.FailedAttempts)
+ if err != nil {
+ err = msgp.WrapError(err, "FailedAttempts")
+ return
+ }
+ err = en.WriteString(z.Locale)
+ if err != nil {
+ err = msgp.WrapError(err, "Locale")
+ return
+ }
+ err = z.Timezone.EncodeMsg(en)
+ if err != nil {
+ err = msgp.WrapError(err, "Timezone")
+ return
+ }
+ err = en.WriteBool(z.MfaActive)
+ if err != nil {
+ err = msgp.WrapError(err, "MfaActive")
+ return
+ }
+ err = en.WriteString(z.MfaSecret)
+ if err != nil {
+ err = msgp.WrapError(err, "MfaSecret")
+ return
+ }
+ if z.RemoteId == nil {
+ err = en.WriteNil()
+ if err != nil {
+ return
+ }
+ } else {
+ err = en.WriteString(*z.RemoteId)
+ if err != nil {
+ err = msgp.WrapError(err, "RemoteId")
+ return
+ }
+ }
+ err = en.WriteInt64(z.LastActivityAt)
+ if err != nil {
+ err = msgp.WrapError(err, "LastActivityAt")
+ return
+ }
+ err = en.WriteBool(z.IsBot)
+ if err != nil {
+ err = msgp.WrapError(err, "IsBot")
+ return
+ }
+ err = en.WriteString(z.BotDescription)
+ if err != nil {
+ err = msgp.WrapError(err, "BotDescription")
+ return
+ }
+ err = en.WriteInt64(z.BotLastIconUpdate)
+ if err != nil {
+ err = msgp.WrapError(err, "BotLastIconUpdate")
+ return
+ }
+ err = en.WriteString(z.TermsOfServiceId)
+ if err != nil {
+ err = msgp.WrapError(err, "TermsOfServiceId")
+ return
+ }
+ err = en.WriteInt64(z.TermsOfServiceCreateAt)
+ if err != nil {
+ err = msgp.WrapError(err, "TermsOfServiceCreateAt")
+ return
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z *User) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ // array header, size 32
+ o = append(o, 0xdc, 0x0, 0x20)
+ o = msgp.AppendString(o, z.Id)
+ o = msgp.AppendInt64(o, z.CreateAt)
+ o = msgp.AppendInt64(o, z.UpdateAt)
+ o = msgp.AppendInt64(o, z.DeleteAt)
+ o = msgp.AppendString(o, z.Username)
+ o = msgp.AppendString(o, z.Password)
+ if z.AuthData == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendString(o, *z.AuthData)
+ }
+ o = msgp.AppendString(o, z.AuthService)
+ o = msgp.AppendString(o, z.Email)
+ o = msgp.AppendBool(o, z.EmailVerified)
+ o = msgp.AppendString(o, z.Nickname)
+ o = msgp.AppendString(o, z.FirstName)
+ o = msgp.AppendString(o, z.LastName)
+ o = msgp.AppendString(o, z.Position)
+ o = msgp.AppendString(o, z.Roles)
+ o = msgp.AppendBool(o, z.AllowMarketing)
+ o, err = z.Props.MarshalMsg(o)
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ o, err = z.NotifyProps.MarshalMsg(o)
+ if err != nil {
+ err = msgp.WrapError(err, "NotifyProps")
+ return
+ }
+ o = msgp.AppendInt64(o, z.LastPasswordUpdate)
+ o = msgp.AppendInt64(o, z.LastPictureUpdate)
+ o = msgp.AppendInt(o, z.FailedAttempts)
+ o = msgp.AppendString(o, z.Locale)
+ o, err = z.Timezone.MarshalMsg(o)
+ if err != nil {
+ err = msgp.WrapError(err, "Timezone")
+ return
+ }
+ o = msgp.AppendBool(o, z.MfaActive)
+ o = msgp.AppendString(o, z.MfaSecret)
+ if z.RemoteId == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o = msgp.AppendString(o, *z.RemoteId)
+ }
+ o = msgp.AppendInt64(o, z.LastActivityAt)
+ o = msgp.AppendBool(o, z.IsBot)
+ o = msgp.AppendString(o, z.BotDescription)
+ o = msgp.AppendInt64(o, z.BotLastIconUpdate)
+ o = msgp.AppendString(o, z.TermsOfServiceId)
+ o = msgp.AppendInt64(o, z.TermsOfServiceCreateAt)
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *User) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ var zb0001 uint32
+ zb0001, bts, err = msgp.ReadArrayHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if zb0001 != 32 {
+ err = msgp.ArrayError{Wanted: 32, Got: zb0001}
+ return
+ }
+ z.Id, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Id")
+ return
+ }
+ z.CreateAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "CreateAt")
+ return
+ }
+ z.UpdateAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "UpdateAt")
+ return
+ }
+ z.DeleteAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "DeleteAt")
+ return
+ }
+ z.Username, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Username")
+ return
+ }
+ z.Password, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Password")
+ return
+ }
+ if msgp.IsNil(bts) {
+ bts, err = msgp.ReadNilBytes(bts)
+ if err != nil {
+ return
+ }
+ z.AuthData = nil
+ } else {
+ if z.AuthData == nil {
+ z.AuthData = new(string)
+ }
+ *z.AuthData, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AuthData")
+ return
+ }
+ }
+ z.AuthService, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AuthService")
+ return
+ }
+ z.Email, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Email")
+ return
+ }
+ z.EmailVerified, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "EmailVerified")
+ return
+ }
+ z.Nickname, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Nickname")
+ return
+ }
+ z.FirstName, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "FirstName")
+ return
+ }
+ z.LastName, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastName")
+ return
+ }
+ z.Position, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Position")
+ return
+ }
+ z.Roles, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Roles")
+ return
+ }
+ z.AllowMarketing, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "AllowMarketing")
+ return
+ }
+ bts, err = z.Props.UnmarshalMsg(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Props")
+ return
+ }
+ bts, err = z.NotifyProps.UnmarshalMsg(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "NotifyProps")
+ return
+ }
+ z.LastPasswordUpdate, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastPasswordUpdate")
+ return
+ }
+ z.LastPictureUpdate, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastPictureUpdate")
+ return
+ }
+ z.FailedAttempts, bts, err = msgp.ReadIntBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "FailedAttempts")
+ return
+ }
+ z.Locale, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Locale")
+ return
+ }
+ bts, err = z.Timezone.UnmarshalMsg(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "Timezone")
+ return
+ }
+ z.MfaActive, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "MfaActive")
+ return
+ }
+ z.MfaSecret, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "MfaSecret")
+ return
+ }
+ if msgp.IsNil(bts) {
+ bts, err = msgp.ReadNilBytes(bts)
+ if err != nil {
+ return
+ }
+ z.RemoteId = nil
+ } else {
+ if z.RemoteId == nil {
+ z.RemoteId = new(string)
+ }
+ *z.RemoteId, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "RemoteId")
+ return
+ }
+ }
+ z.LastActivityAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "LastActivityAt")
+ return
+ }
+ z.IsBot, bts, err = msgp.ReadBoolBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "IsBot")
+ return
+ }
+ z.BotDescription, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "BotDescription")
+ return
+ }
+ z.BotLastIconUpdate, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "BotLastIconUpdate")
+ return
+ }
+ z.TermsOfServiceId, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "TermsOfServiceId")
+ return
+ }
+ z.TermsOfServiceCreateAt, bts, err = msgp.ReadInt64Bytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err, "TermsOfServiceCreateAt")
+ return
+ }
+ o = bts
+ return
+}
+
+// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
+func (z *User) Msgsize() (s int) {
+ s = 3 + msgp.StringPrefixSize + len(z.Id) + msgp.Int64Size + msgp.Int64Size + msgp.Int64Size + msgp.StringPrefixSize + len(z.Username) + msgp.StringPrefixSize + len(z.Password)
+ if z.AuthData == nil {
+ s += msgp.NilSize
+ } else {
+ s += msgp.StringPrefixSize + len(*z.AuthData)
+ }
+ s += msgp.StringPrefixSize + len(z.AuthService) + msgp.StringPrefixSize + len(z.Email) + msgp.BoolSize + msgp.StringPrefixSize + len(z.Nickname) + msgp.StringPrefixSize + len(z.FirstName) + msgp.StringPrefixSize + len(z.LastName) + msgp.StringPrefixSize + len(z.Position) + msgp.StringPrefixSize + len(z.Roles) + msgp.BoolSize + z.Props.Msgsize() + z.NotifyProps.Msgsize() + msgp.Int64Size + msgp.Int64Size + msgp.IntSize + msgp.StringPrefixSize + len(z.Locale) + z.Timezone.Msgsize() + msgp.BoolSize + msgp.StringPrefixSize + len(z.MfaSecret)
+ if z.RemoteId == nil {
+ s += msgp.NilSize
+ } else {
+ s += msgp.StringPrefixSize + len(*z.RemoteId)
+ }
+ s += msgp.Int64Size + msgp.BoolSize + msgp.StringPrefixSize + len(z.BotDescription) + msgp.Int64Size + msgp.StringPrefixSize + len(z.TermsOfServiceId) + msgp.Int64Size
+ return
+}
+
+// DecodeMsg implements msgp.Decodable
+func (z *UserMap) DecodeMsg(dc *msgp.Reader) (err error) {
+ var zb0003 uint32
+ zb0003, err = dc.ReadMapHeader()
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if (*z) == nil {
+ (*z) = make(UserMap, zb0003)
+ } else if len((*z)) > 0 {
+ for key := range *z {
+ delete((*z), key)
+ }
+ }
+ for zb0003 > 0 {
+ zb0003--
+ var zb0001 string
+ var zb0002 *User
+ zb0001, err = dc.ReadString()
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if dc.IsNil() {
+ err = dc.ReadNil()
+ if err != nil {
+ err = msgp.WrapError(err, zb0001)
+ return
+ }
+ zb0002 = nil
+ } else {
+ if zb0002 == nil {
+ zb0002 = new(User)
+ }
+ err = zb0002.DecodeMsg(dc)
+ if err != nil {
+ err = msgp.WrapError(err, zb0001)
+ return
+ }
+ }
+ (*z)[zb0001] = zb0002
+ }
+ return
+}
+
+// EncodeMsg implements msgp.Encodable
+func (z UserMap) EncodeMsg(en *msgp.Writer) (err error) {
+ err = en.WriteMapHeader(uint32(len(z)))
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ for zb0004, zb0005 := range z {
+ err = en.WriteString(zb0004)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if zb0005 == nil {
+ err = en.WriteNil()
+ if err != nil {
+ return
+ }
+ } else {
+ err = zb0005.EncodeMsg(en)
+ if err != nil {
+ err = msgp.WrapError(err, zb0004)
+ return
+ }
+ }
+ }
+ return
+}
+
+// MarshalMsg implements msgp.Marshaler
+func (z UserMap) MarshalMsg(b []byte) (o []byte, err error) {
+ o = msgp.Require(b, z.Msgsize())
+ o = msgp.AppendMapHeader(o, uint32(len(z)))
+ for zb0004, zb0005 := range z {
+ o = msgp.AppendString(o, zb0004)
+ if zb0005 == nil {
+ o = msgp.AppendNil(o)
+ } else {
+ o, err = zb0005.MarshalMsg(o)
+ if err != nil {
+ err = msgp.WrapError(err, zb0004)
+ return
+ }
+ }
+ }
+ return
+}
+
+// UnmarshalMsg implements msgp.Unmarshaler
+func (z *UserMap) UnmarshalMsg(bts []byte) (o []byte, err error) {
+ var zb0003 uint32
+ zb0003, bts, err = msgp.ReadMapHeaderBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if (*z) == nil {
+ (*z) = make(UserMap, zb0003)
+ } else if len((*z)) > 0 {
+ for key := range *z {
+ delete((*z), key)
+ }
+ }
+ for zb0003 > 0 {
+ var zb0001 string
+ var zb0002 *User
+ zb0003--
+ zb0001, bts, err = msgp.ReadStringBytes(bts)
+ if err != nil {
+ err = msgp.WrapError(err)
+ return
+ }
+ if msgp.IsNil(bts) {
+ bts, err = msgp.ReadNilBytes(bts)
+ if err != nil {
+ return
+ }
+ zb0002 = nil
+ } else {
+ if zb0002 == nil {
+ zb0002 = new(User)
+ }
+ bts, err = zb0002.UnmarshalMsg(bts)
+ if err != nil {
+ err = msgp.WrapError(err, zb0001)
+ return
+ }
+ }
+ (*z)[zb0001] = zb0002
+ }
+ o = bts
+ return
+}
+
+// Msgsize returns an upper bound estimate of the number of bytes occupied by the serialized message
+func (z UserMap) Msgsize() (s int) {
+ s = msgp.MapHeaderSize
+ if z != nil {
+ for zb0004, zb0005 := range z {
+ _ = zb0005
+ s += msgp.StringPrefixSize + len(zb0004)
+ if zb0005 == nil {
+ s += msgp.NilSize
+ } else {
+ s += zb0005.Msgsize()
+ }
+ }
+ }
+ return
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go b/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
index 3aed19da..0c5a272c 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/utils.go
@@ -18,10 +18,11 @@ import (
"regexp"
"strconv"
"strings"
+ "sync"
"time"
"unicode"
- goi18n "github.com/mattermost/go-i18n/i18n"
+ "github.com/mattermost/mattermost-server/v5/shared/i18n"
"github.com/pborman/uuid"
)
@@ -30,10 +31,10 @@ const (
UPPERCASE_LETTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
NUMBERS = "0123456789"
SYMBOLS = " !\"\\#$%&'()*+,-./:;<=>?@[]^_`|~"
+ MB = 1 << 20
)
type StringInterface map[string]interface{}
-type StringMap map[string]string
type StringArray []string
func (sa StringArray) Remove(input string) StringArray {
@@ -72,10 +73,13 @@ func (sa StringArray) Equals(input StringArray) bool {
return true
}
-var translateFunc goi18n.TranslateFunc = nil
+var translateFunc i18n.TranslateFunc
+var translateFuncOnce sync.Once
-func AppErrorInit(t goi18n.TranslateFunc) {
- translateFunc = t
+func AppErrorInit(t i18n.TranslateFunc) {
+ translateFuncOnce.Do(func() {
+ translateFunc = t
+ })
}
type AppError struct {
@@ -93,7 +97,7 @@ func (er *AppError) Error() string {
return er.Where + ": " + er.Message + ", " + er.DetailedError
}
-func (er *AppError) Translate(T goi18n.TranslateFunc) {
+func (er *AppError) Translate(T i18n.TranslateFunc) {
if T == nil {
er.Message = er.Id
return
@@ -106,12 +110,11 @@ func (er *AppError) Translate(T goi18n.TranslateFunc) {
}
}
-func (er *AppError) SystemMessage(T goi18n.TranslateFunc) string {
+func (er *AppError) SystemMessage(T i18n.TranslateFunc) string {
if er.params == nil {
return T(er.Id)
- } else {
- return T(er.Id, er.params)
}
+ return T(er.Id, er.params)
}
func (er *AppError) ToJson() string {
@@ -132,11 +135,10 @@ func AppErrorFromJson(data io.Reader) *AppError {
decoder := json.NewDecoder(strings.NewReader(str))
var er AppError
err := decoder.Decode(&er)
- if err == nil {
- return &er
- } else {
+ if err != nil {
return NewAppError("AppErrorFromJson", "model.utils.decode_json.app_error", nil, "body: "+str, http.StatusInternalServerError)
}
+ return &er
}
func NewAppError(where string, id string, params map[string]interface{}, details string, status int) *AppError {
@@ -183,14 +185,6 @@ func NewRandomString(length int) string {
return encoding.EncodeToString(data)[:length]
}
-// NewRandomBase32String returns a base32 encoded string of a random slice
-// of bytes of the given size. The resulting entropy will be (8 * size) bits.
-func NewRandomBase32String(size int) string {
- data := make([]byte, size)
- rand.Read(data)
- return base32.StdEncoding.EncodeToString(data)
-}
-
// GetMillis is a convenience method to get milliseconds since epoch.
func GetMillis() int64 {
return time.Now().UnixNano() / int64(time.Millisecond)
@@ -201,6 +195,11 @@ func GetMillisForTime(thisTime time.Time) int64 {
return thisTime.UnixNano() / int64(time.Millisecond)
}
+// GetTimeForMillis is a convenience method to get time.Time for milliseconds since epoch.
+func GetTimeForMillis(millis int64) time.Time {
+ return time.Unix(0, millis*int64(time.Millisecond))
+}
+
// PadDateStringZeros is a convenience method to pad 2 digit date parts with zeros to meet ISO 8601 format
func PadDateStringZeros(dateString string) string {
parts := strings.Split(dateString, "-")
@@ -254,9 +253,8 @@ func MapFromJson(data io.Reader) map[string]string {
var objmap map[string]string
if err := decoder.Decode(&objmap); err != nil {
return make(map[string]string)
- } else {
- return objmap
}
+ return objmap
}
// MapFromJson will decode the key/value pair map
@@ -266,9 +264,8 @@ func MapBoolFromJson(data io.Reader) map[string]bool {
var objmap map[string]bool
if err := decoder.Decode(&objmap); err != nil {
return make(map[string]bool)
- } else {
- return objmap
}
+ return objmap
}
func ArrayToJson(objmap []string) string {
@@ -282,9 +279,8 @@ func ArrayFromJson(data io.Reader) []string {
var objmap []string
if err := decoder.Decode(&objmap); err != nil {
return make([]string, 0)
- } else {
- return objmap
}
+ return objmap
}
func ArrayFromInterface(data interface{}) []string {
@@ -315,9 +311,8 @@ func StringInterfaceFromJson(data io.Reader) map[string]interface{} {
var objmap map[string]interface{}
if err := decoder.Decode(&objmap); err != nil {
return make(map[string]interface{})
- } else {
- return objmap
}
+ return objmap
}
func StringToJson(s string) string {
@@ -331,14 +326,19 @@ func StringFromJson(data io.Reader) string {
var s string
if err := decoder.Decode(&s); err != nil {
return ""
- } else {
- return s
}
+ return s
+}
+
+// ToJson serializes an arbitrary data type to JSON, discarding the error.
+func ToJson(v interface{}) []byte {
+ b, _ := json.Marshal(v)
+ return b
}
func GetServerIpAddress(iface string) string {
var addrs []net.Addr
- if len(iface) == 0 {
+ if iface == "" {
var err error
addrs, err = net.InterfaceAddrs()
if err != nil {
@@ -397,6 +397,7 @@ var reservedName = []string{
"channel",
"claim",
"error",
+ "files",
"help",
"landing",
"login",
@@ -437,6 +438,12 @@ func IsValidAlphaNumHyphenUnderscore(s string, withFormat bool) bool {
return validSimpleAlphaNumHyphenUnderscore.MatchString(s)
}
+func IsValidAlphaNumHyphenUnderscorePlus(s string) bool {
+
+ validSimpleAlphaNumHyphenUnderscorePlus := regexp.MustCompile(`^[a-zA-Z0-9+_-]+$`)
+ return validSimpleAlphaNumHyphenUnderscorePlus.MatchString(s)
+}
+
func Etag(parts ...interface{}) string {
etag := CurrentVersion
@@ -486,25 +493,6 @@ func ParseHashtags(text string) (string, string) {
return strings.TrimSpace(hashtagString), strings.TrimSpace(plainString)
}
-func IsFileExtImage(ext string) bool {
- ext = strings.ToLower(ext)
- for _, imgExt := range IMAGE_EXTENSIONS {
- if ext == imgExt {
- return true
- }
- }
- return false
-}
-
-func GetImageMimeType(ext string) string {
- ext = strings.ToLower(ext)
- if len(IMAGE_MIME_TYPES[ext]) == 0 {
- return "image"
- } else {
- return IMAGE_MIME_TYPES[ext]
- }
-}
-
func ClearMentionTags(post string) string {
post = strings.Replace(post, "<mention>", "", -1)
post = strings.Replace(post, "</mention>", "", -1)
@@ -721,3 +709,18 @@ func filterBlocklist(r rune) rune {
return r
}
+
+// UniqueStrings returns a unique subset of the string slice provided.
+func UniqueStrings(input []string) []string {
+ u := make([]string, 0, len(input))
+ m := make(map[string]bool)
+
+ for _, val := range input {
+ if _, ok := m[val]; !ok {
+ m[val] = true
+ u = append(u, val)
+ }
+ }
+
+ return u
+}
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/version.go b/vendor/github.com/mattermost/mattermost-server/v5/model/version.go
index 63145660..36acddf2 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/version.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/version.go
@@ -13,6 +13,17 @@ import (
// It should be maintained in chronological order with most current
// release at the front of the list.
var versions = []string{
+ "5.39.0",
+ "5.38.2",
+ "5.38.1",
+ "5.38.0",
+ "5.37.0",
+ "5.36.0",
+ "5.35.0",
+ "5.34.0",
+ "5.33.0",
+ "5.32.0",
+ "5.31.0",
"5.30.0",
"5.29.0",
"5.28.0",
@@ -148,9 +159,8 @@ func IsCurrentVersion(versionToCheck string) bool {
if toCheckMajor == currentMajor && toCheckMinor == currentMinor {
return true
- } else {
- return false
}
+ return false
}
func IsPreviousVersionsSupported(versionToCheck string) bool {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_message.go b/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_message.go
index a4f92f80..9a845d36 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_message.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_message.go
@@ -70,6 +70,10 @@ const (
WEBSOCKET_WARN_METRIC_STATUS_RECEIVED = "warn_metric_status_received"
WEBSOCKET_WARN_METRIC_STATUS_REMOVED = "warn_metric_status_removed"
WEBSOCKET_EVENT_CLOUD_PAYMENT_STATUS_UPDATED = "cloud_payment_status_updated"
+ WEBSOCKET_EVENT_THREAD_UPDATED = "thread_updated"
+ WEBSOCKET_EVENT_THREAD_FOLLOW_CHANGED = "thread_follow_changed"
+ WEBSOCKET_EVENT_THREAD_READ_CHANGED = "thread_read_changed"
+ WEBSOCKET_FIRST_ADMIN_VISIT_MARKETPLACE_STATUS_RECEIVED = "first_admin_visit_marketplace_status_received"
)
type WebSocketMessage interface {
diff --git a/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_request.go b/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_request.go
index 6628a5c9..f18f1285 100644
--- a/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_request.go
+++ b/vendor/github.com/mattermost/mattermost-server/v5/model/websocket_request.go
@@ -7,7 +7,7 @@ import (
"encoding/json"
"io"
- goi18n "github.com/mattermost/go-i18n/i18n"
+ "github.com/mattermost/mattermost-server/v5/shared/i18n"
)
// WebSocketRequest represents a request made to the server through a websocket.
@@ -18,9 +18,9 @@ type WebSocketRequest struct {
Data map[string]interface{} `json:"data"` // The metadata for an action.
// Server-provided fields
- Session Session `json:"-"`
- T goi18n.TranslateFunc `json:"-"`
- Locale string `json:"-"`
+ Session Session `json:"-"`
+ T i18n.TranslateFunc `json:"-"`
+ Locale string `json:"-"`
}
func (o *WebSocketRequest) ToJson() string {