feat(BridgeMessage): Add new type of chat message content: BridgeMessage

BridgeMessage is a type of chat message content which will be sent from  Matterbridge.
It contains fields:
- bridge name - depends on the used bridge, eg. "discord", "slack", etc...
- user name - username the message was received from
- content - message content
- user avatar
- message id
- parent message id - used in case of replies

Message is saved to a separated table: bridge_messages, similarly to discord messages.
The user_messages table is untouched.
bridge_messages table contains user_messages_id in order to join with user_messages table.

Issue #13098
This commit is contained in:
Michal Iskierko 2024-01-03 11:29:21 +01:00 committed by Michał Iskierko
parent 7d1927396a
commit 73a5189398
17 changed files with 968 additions and 657 deletions

View File

@ -195,6 +195,6 @@ func setRPCs(networks []params.Network, request *requests.WalletSecretsConfig) [
return networksWithRPC return networksWithRPC
} }
func buildDefaultNetworks(request *requests.CreateAccount) []params.Network { func BuildDefaultNetworks(request *requests.CreateAccount) []params.Network {
return setRPCs(defaultNetworks, &request.WalletSecretsConfig) return setRPCs(defaultNetworks, &request.WalletSecretsConfig)
} }

View File

@ -19,7 +19,7 @@ func TestBuildDefaultNetworks(t *testing.T) {
}, },
} }
actualNetworks := buildDefaultNetworks(request) actualNetworks := BuildDefaultNetworks(request)
require.Len(t, actualNetworks, 6) require.Len(t, actualNetworks, 6)
@ -62,7 +62,7 @@ func TestBuildDefaultNetworksGanache(t *testing.T) {
}, },
} }
actualNetworks := buildDefaultNetworks(request) actualNetworks := BuildDefaultNetworks(request)
require.Len(t, actualNetworks, 6) require.Len(t, actualNetworks, 6)

View File

@ -280,7 +280,7 @@ func defaultNodeConfig(installationID string, request *requests.CreateAccount) (
nodeConfig.LogEnabled = false nodeConfig.LogEnabled = false
} }
nodeConfig.Networks = buildDefaultNetworks(request) nodeConfig.Networks = BuildDefaultNetworks(request)
return nodeConfig, nil return nodeConfig, nil
} }

View File

@ -85,7 +85,7 @@ func _1619446565_postgres_make_anon_metrics_tableDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1619446565_postgres_make_anon_metrics_table.down.sql", size: 24, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1619446565_postgres_make_anon_metrics_table.down.sql", size: 24, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x75, 0xea, 0x1, 0x74, 0xe6, 0xa3, 0x11, 0xd0, 0x86, 0x87, 0x7e, 0x31, 0xb4, 0x1a, 0x27, 0x5d, 0xda, 0x77, 0xa3, 0xf5, 0x1d, 0x88, 0x79, 0xcf, 0xd5, 0x95, 0x75, 0xd, 0x47, 0xa1, 0x90, 0x5}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x75, 0xea, 0x1, 0x74, 0xe6, 0xa3, 0x11, 0xd0, 0x86, 0x87, 0x7e, 0x31, 0xb4, 0x1a, 0x27, 0x5d, 0xda, 0x77, 0xa3, 0xf5, 0x1d, 0x88, 0x79, 0xcf, 0xd5, 0x95, 0x75, 0xd, 0x47, 0xa1, 0x90, 0x5}}
return a, nil return a, nil
} }
@ -105,7 +105,7 @@ func _1619446565_postgres_make_anon_metrics_tableUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1619446565_postgres_make_anon_metrics_table.up.sql", size: 443, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1619446565_postgres_make_anon_metrics_table.up.sql", size: 443, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd5, 0xdc, 0x72, 0x28, 0x3c, 0xf6, 0x94, 0xb0, 0x47, 0x3d, 0xca, 0x55, 0x3d, 0xf7, 0x83, 0xb8, 0x7d, 0x2f, 0x1e, 0x98, 0xb7, 0xde, 0xa, 0xff, 0xa0, 0x52, 0x60, 0x83, 0x56, 0xc5, 0xd1, 0xa2}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xd5, 0xdc, 0x72, 0x28, 0x3c, 0xf6, 0x94, 0xb0, 0x47, 0x3d, 0xca, 0x55, 0x3d, 0xf7, 0x83, 0xb8, 0x7d, 0x2f, 0x1e, 0x98, 0xb7, 0xde, 0xa, 0xff, 0xa0, 0x52, 0x60, 0x83, 0x56, 0xc5, 0xd1, 0xa2}}
return a, nil return a, nil
} }
@ -125,7 +125,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 380, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "doc.go", size: 380, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0x1, 0xd4, 0xd6, 0xc7, 0x44, 0xd4, 0xfd, 0x7b, 0x69, 0x1f, 0xe3, 0xe, 0x48, 0x14, 0x99, 0xf0, 0x8e, 0x43, 0xae, 0x54, 0x64, 0xa2, 0x8b, 0x82, 0x1c, 0x2b, 0xb, 0xec, 0xf5, 0xb3, 0xfc}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0x1, 0xd4, 0xd6, 0xc7, 0x44, 0xd4, 0xfd, 0x7b, 0x69, 0x1f, 0xe3, 0xe, 0x48, 0x14, 0x99, 0xf0, 0x8e, 0x43, 0xae, 0x54, 0x64, 0xa2, 0x8b, 0x82, 0x1c, 0x2b, 0xb, 0xec, 0xf5, 0xb3, 0xfc}}
return a, nil return a, nil
} }

View File

@ -281,6 +281,7 @@ func (m *Message) MarshalJSON() ([]byte, error) {
ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"` ContactRequestState ContactRequestState `json:"contactRequestState,omitempty"`
ContactVerificationState ContactVerificationState `json:"contactVerificationState,omitempty"` ContactVerificationState ContactVerificationState `json:"contactVerificationState,omitempty"`
DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"` DiscordMessage *protobuf.DiscordMessage `json:"discordMessage,omitempty"`
BridgeMessage *protobuf.BridgeMessage `json:"bridgeMessage,omitempty"`
} }
item := MessageStructType{ item := MessageStructType{
ID: m.ID, ID: m.ID,
@ -347,6 +348,11 @@ func (m *Message) MarshalJSON() ([]byte, error) {
if discordMessage := m.GetDiscordMessage(); discordMessage != nil { if discordMessage := m.GetDiscordMessage(); discordMessage != nil {
item.DiscordMessage = discordMessage item.DiscordMessage = discordMessage
} }
if bridgeMessage := m.GetBridgeMessage(); bridgeMessage != nil {
item.BridgeMessage = bridgeMessage
}
if item.From != "" { if item.From != "" {
ext, err := accountJson.ExtendStructWithPubKeyData(item.From, item) ext, err := accountJson.ExtendStructWithPubKeyData(item.From, item)
if err != nil { if err != nil {

View File

@ -102,7 +102,7 @@ func _1536754952_initial_schemaDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1536754952_initial_schema.down.sql", size: 83, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x44, 0xcf, 0x76, 0x71, 0x1f, 0x5e, 0x9a, 0x43, 0xd8, 0xcd, 0xb8, 0xc3, 0x70, 0xc3, 0x7f, 0xfc, 0x90, 0xb4, 0x25, 0x1e, 0xf4, 0x66, 0x20, 0xb8, 0x33, 0x7e, 0xb0, 0x76, 0x1f, 0xc, 0xc0, 0x75}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x44, 0xcf, 0x76, 0x71, 0x1f, 0x5e, 0x9a, 0x43, 0xd8, 0xcd, 0xb8, 0xc3, 0x70, 0xc3, 0x7f, 0xfc, 0x90, 0xb4, 0x25, 0x1e, 0xf4, 0x66, 0x20, 0xb8, 0x33, 0x7e, 0xb0, 0x76, 0x1f, 0xc, 0xc0, 0x75}}
return a, nil return a, nil
} }
@ -122,7 +122,7 @@ func _1536754952_initial_schemaUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1536754952_initial_schema.up.sql", size: 962, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x90, 0x5a, 0x59, 0x3e, 0x3, 0xe2, 0x3c, 0x81, 0x42, 0xcd, 0x4c, 0x9a, 0xe8, 0xda, 0x93, 0x2b, 0x70, 0xa4, 0xd5, 0x29, 0x3e, 0xd5, 0xc9, 0x27, 0xb6, 0xb7, 0x65, 0xff, 0x0, 0xcb, 0xde}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xea, 0x90, 0x5a, 0x59, 0x3e, 0x3, 0xe2, 0x3c, 0x81, 0x42, 0xcd, 0x4c, 0x9a, 0xe8, 0xda, 0x93, 0x2b, 0x70, 0xa4, 0xd5, 0x29, 0x3e, 0xd5, 0xc9, 0x27, 0xb6, 0xb7, 0x65, 0xff, 0x0, 0xcb, 0xde}}
return a, nil return a, nil
} }
@ -142,7 +142,7 @@ func _1539249977_update_ratchet_infoDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1539249977_update_ratchet_info.down.sql", size: 311, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xa4, 0xeb, 0xa0, 0xe6, 0xa0, 0xd4, 0x48, 0xbb, 0xad, 0x6f, 0x7d, 0x67, 0x8c, 0xbd, 0x25, 0xde, 0x1f, 0x73, 0x9a, 0xbb, 0xa8, 0xc9, 0x30, 0xb7, 0xa9, 0x7c, 0xaf, 0xb5, 0x1, 0x61, 0xdd}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x1, 0xa4, 0xeb, 0xa0, 0xe6, 0xa0, 0xd4, 0x48, 0xbb, 0xad, 0x6f, 0x7d, 0x67, 0x8c, 0xbd, 0x25, 0xde, 0x1f, 0x73, 0x9a, 0xbb, 0xa8, 0xc9, 0x30, 0xb7, 0xa9, 0x7c, 0xaf, 0xb5, 0x1, 0x61, 0xdd}}
return a, nil return a, nil
} }
@ -162,7 +162,7 @@ func _1539249977_update_ratchet_infoUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1539249977_update_ratchet_info.up.sql", size: 368, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x8e, 0xbf, 0x6f, 0xa, 0xc0, 0xe1, 0x3c, 0x42, 0x28, 0x88, 0x1d, 0xdb, 0xba, 0x1c, 0x83, 0xec, 0xba, 0xd3, 0x5f, 0x5c, 0x77, 0x5e, 0xa7, 0x46, 0x36, 0xec, 0x69, 0xa, 0x4b, 0x17, 0x79}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc, 0x8e, 0xbf, 0x6f, 0xa, 0xc0, 0xe1, 0x3c, 0x42, 0x28, 0x88, 0x1d, 0xdb, 0xba, 0x1c, 0x83, 0xec, 0xba, 0xd3, 0x5f, 0x5c, 0x77, 0x5e, 0xa7, 0x46, 0x36, 0xec, 0x69, 0xa, 0x4b, 0x17, 0x79}}
return a, nil return a, nil
} }
@ -182,7 +182,7 @@ func _1540715431_add_versionDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1540715431_add_version.down.sql", size: 127, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x9, 0x4, 0xe3, 0x76, 0x2e, 0xb8, 0x9, 0x23, 0xf0, 0x70, 0x93, 0xc4, 0x50, 0xe, 0x9d, 0x84, 0x22, 0x8c, 0x94, 0xd3, 0x24, 0x9, 0x9a, 0xc1, 0xa1, 0x48, 0x45, 0xfd, 0x40, 0x6e, 0xe6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x9, 0x4, 0xe3, 0x76, 0x2e, 0xb8, 0x9, 0x23, 0xf0, 0x70, 0x93, 0xc4, 0x50, 0xe, 0x9d, 0x84, 0x22, 0x8c, 0x94, 0xd3, 0x24, 0x9, 0x9a, 0xc1, 0xa1, 0x48, 0x45, 0xfd, 0x40, 0x6e, 0xe6}}
return a, nil return a, nil
} }
@ -202,7 +202,7 @@ func _1540715431_add_versionUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1540715431_add_version.up.sql", size: 265, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc7, 0x4c, 0x36, 0x96, 0xdf, 0x16, 0x10, 0xa6, 0x27, 0x1a, 0x79, 0x8b, 0x42, 0x83, 0x23, 0xc, 0x7e, 0xb6, 0x3d, 0x2, 0xda, 0xa4, 0xb4, 0xd, 0x27, 0x55, 0xba, 0xdc, 0xb2, 0x88, 0x8f, 0xa6}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xc7, 0x4c, 0x36, 0x96, 0xdf, 0x16, 0x10, 0xa6, 0x27, 0x1a, 0x79, 0x8b, 0x42, 0x83, 0x23, 0xc, 0x7e, 0xb6, 0x3d, 0x2, 0xda, 0xa4, 0xb4, 0xd, 0x27, 0x55, 0xba, 0xdc, 0xb2, 0x88, 0x8f, 0xa6}}
return a, nil return a, nil
} }
@ -222,7 +222,7 @@ func _1541164797_add_installationsDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1541164797_add_installations.down.sql", size: 26, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0xfd, 0xe6, 0xd8, 0xca, 0x3b, 0x38, 0x18, 0xee, 0x0, 0x5f, 0x36, 0x9e, 0x1e, 0xd, 0x19, 0x3e, 0xb4, 0x73, 0x53, 0xe9, 0xa5, 0xac, 0xdd, 0xa1, 0x2f, 0xc7, 0x6c, 0xa8, 0xd9, 0xa, 0x88}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0xfd, 0xe6, 0xd8, 0xca, 0x3b, 0x38, 0x18, 0xee, 0x0, 0x5f, 0x36, 0x9e, 0x1e, 0xd, 0x19, 0x3e, 0xb4, 0x73, 0x53, 0xe9, 0xa5, 0xac, 0xdd, 0xa1, 0x2f, 0xc7, 0x6c, 0xa8, 0xd9, 0xa, 0x88}}
return a, nil return a, nil
} }
@ -242,7 +242,7 @@ func _1541164797_add_installationsUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1541164797_add_installations.up.sql", size: 216, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2d, 0x18, 0x26, 0xb8, 0x88, 0x47, 0xdb, 0x83, 0xcc, 0xb6, 0x9d, 0x1c, 0x1, 0xae, 0x2f, 0xde, 0x97, 0x82, 0x3, 0x30, 0xa8, 0x63, 0xa1, 0x78, 0x4b, 0xa5, 0x9, 0x8, 0x75, 0xa2, 0x57, 0x81}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2d, 0x18, 0x26, 0xb8, 0x88, 0x47, 0xdb, 0x83, 0xcc, 0xb6, 0x9d, 0x1c, 0x1, 0xae, 0x2f, 0xde, 0x97, 0x82, 0x3, 0x30, 0xa8, 0x63, 0xa1, 0x78, 0x4b, 0xa5, 0x9, 0x8, 0x75, 0xa2, 0x57, 0x81}}
return a, nil return a, nil
} }
@ -262,7 +262,7 @@ func _1558084410_add_secretDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1558084410_add_secret.down.sql", size: 56, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xb, 0x65, 0xdf, 0x59, 0xbf, 0xe9, 0x5, 0x5b, 0x6f, 0xd5, 0x3a, 0xb7, 0x57, 0xe8, 0x78, 0x38, 0x73, 0x53, 0x57, 0xf7, 0x24, 0x4, 0xe4, 0xa2, 0x49, 0x22, 0xa2, 0xc6, 0xfd, 0x80, 0xa4}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x49, 0xb, 0x65, 0xdf, 0x59, 0xbf, 0xe9, 0x5, 0x5b, 0x6f, 0xd5, 0x3a, 0xb7, 0x57, 0xe8, 0x78, 0x38, 0x73, 0x53, 0x57, 0xf7, 0x24, 0x4, 0xe4, 0xa2, 0x49, 0x22, 0xa2, 0xc6, 0xfd, 0x80, 0xa4}}
return a, nil return a, nil
} }
@ -282,7 +282,7 @@ func _1558084410_add_secretUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1558084410_add_secret.up.sql", size: 301, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x32, 0x36, 0x8e, 0x47, 0xb0, 0x8f, 0xc1, 0xc6, 0xf7, 0xc6, 0x9f, 0x2d, 0x44, 0x75, 0x2b, 0x26, 0xec, 0x6, 0xa0, 0x7b, 0xa5, 0xbd, 0xc8, 0x76, 0x8a, 0x82, 0x68, 0x2, 0x42, 0xb5, 0xf4}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf5, 0x32, 0x36, 0x8e, 0x47, 0xb0, 0x8f, 0xc1, 0xc6, 0xf7, 0xc6, 0x9f, 0x2d, 0x44, 0x75, 0x2b, 0x26, 0xec, 0x6, 0xa0, 0x7b, 0xa5, 0xbd, 0xc8, 0x76, 0x8a, 0x82, 0x68, 0x2, 0x42, 0xb5, 0xf4}}
return a, nil return a, nil
} }
@ -302,7 +302,7 @@ func _1558588866_add_versionDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1558588866_add_version.down.sql", size: 47, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x52, 0x34, 0x3c, 0x46, 0x4a, 0xf0, 0x72, 0x47, 0x6f, 0x49, 0x5c, 0xc7, 0xf9, 0x32, 0xce, 0xc4, 0x3d, 0xfd, 0x61, 0xa1, 0x8b, 0x8f, 0xf2, 0x31, 0x34, 0xde, 0x15, 0x49, 0xa6, 0xde, 0xb9}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xde, 0x52, 0x34, 0x3c, 0x46, 0x4a, 0xf0, 0x72, 0x47, 0x6f, 0x49, 0x5c, 0xc7, 0xf9, 0x32, 0xce, 0xc4, 0x3d, 0xfd, 0x61, 0xa1, 0x8b, 0x8f, 0xf2, 0x31, 0x34, 0xde, 0x15, 0x49, 0xa6, 0xde, 0xb9}}
return a, nil return a, nil
} }
@ -322,7 +322,7 @@ func _1558588866_add_versionUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1558588866_add_version.up.sql", size: 57, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2a, 0xea, 0x64, 0x39, 0x61, 0x20, 0x83, 0x83, 0xb, 0x2e, 0x79, 0x64, 0xb, 0x53, 0xfa, 0xfe, 0xc6, 0xf7, 0x67, 0x42, 0xd3, 0x4f, 0xdc, 0x7e, 0x30, 0x32, 0xe8, 0x14, 0x41, 0xe9, 0xe7, 0x3b}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x2a, 0xea, 0x64, 0x39, 0x61, 0x20, 0x83, 0x83, 0xb, 0x2e, 0x79, 0x64, 0xb, 0x53, 0xfa, 0xfe, 0xc6, 0xf7, 0x67, 0x42, 0xd3, 0x4f, 0xdc, 0x7e, 0x30, 0x32, 0xe8, 0x14, 0x41, 0xe9, 0xe7, 0x3b}}
return a, nil return a, nil
} }
@ -342,7 +342,7 @@ func _1559627659_add_contact_codeDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1559627659_add_contact_code.down.sql", size: 32, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0x64, 0x6d, 0xce, 0x24, 0x42, 0x20, 0x8d, 0x4f, 0x37, 0xaa, 0x9d, 0xc, 0x57, 0x98, 0xc1, 0xd1, 0x1a, 0x34, 0xcd, 0x9f, 0x8f, 0x34, 0x86, 0xb3, 0xd3, 0xdc, 0xf1, 0x7d, 0xe5, 0x1b, 0x6e}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x5d, 0x64, 0x6d, 0xce, 0x24, 0x42, 0x20, 0x8d, 0x4f, 0x37, 0xaa, 0x9d, 0xc, 0x57, 0x98, 0xc1, 0xd1, 0x1a, 0x34, 0xcd, 0x9f, 0x8f, 0x34, 0x86, 0xb3, 0xd3, 0xdc, 0xf1, 0x7d, 0xe5, 0x1b, 0x6e}}
return a, nil return a, nil
} }
@ -362,7 +362,7 @@ func _1559627659_add_contact_codeUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1559627659_add_contact_code.up.sql", size: 198, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x16, 0xf6, 0xc2, 0x62, 0x9c, 0xd2, 0xc9, 0x1e, 0xd8, 0xea, 0xaa, 0xea, 0x95, 0x8f, 0x89, 0x6a, 0x85, 0x5d, 0x9d, 0x99, 0x78, 0x3c, 0x90, 0x66, 0x99, 0x3e, 0x4b, 0x19, 0x62, 0xfb, 0x31, 0x4d}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x16, 0xf6, 0xc2, 0x62, 0x9c, 0xd2, 0xc9, 0x1e, 0xd8, 0xea, 0xaa, 0xea, 0x95, 0x8f, 0x89, 0x6a, 0x85, 0x5d, 0x9d, 0x99, 0x78, 0x3c, 0x90, 0x66, 0x99, 0x3e, 0x4b, 0x19, 0x62, 0xfb, 0x31, 0x4d}}
return a, nil return a, nil
} }
@ -382,7 +382,7 @@ func _1561368210_add_installation_metadataDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1561368210_add_installation_metadata.down.sql", size: 35, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0xde, 0x3f, 0xd2, 0x4a, 0x50, 0x98, 0x56, 0xe3, 0xc0, 0xcd, 0x9d, 0xb0, 0x34, 0x3b, 0xe5, 0x62, 0x18, 0xb5, 0x20, 0xc9, 0x3e, 0xdc, 0x6a, 0x40, 0x36, 0x66, 0xea, 0x51, 0x8c, 0x71, 0xf5}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa8, 0xde, 0x3f, 0xd2, 0x4a, 0x50, 0x98, 0x56, 0xe3, 0xc0, 0xcd, 0x9d, 0xb0, 0x34, 0x3b, 0xe5, 0x62, 0x18, 0xb5, 0x20, 0xc9, 0x3e, 0xdc, 0x6a, 0x40, 0x36, 0x66, 0xea, 0x51, 0x8c, 0x71, 0xf5}}
return a, nil return a, nil
} }
@ -402,7 +402,7 @@ func _1561368210_add_installation_metadataUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1561368210_add_installation_metadata.up.sql", size: 267, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x71, 0x8f, 0x29, 0xb1, 0xaa, 0xd6, 0xd1, 0x8c, 0x17, 0xef, 0x6c, 0xd5, 0x80, 0xb8, 0x2c, 0xc3, 0xfe, 0xec, 0x24, 0x4d, 0xc8, 0x25, 0xd3, 0xb4, 0xcd, 0xa9, 0xac, 0x63, 0x61, 0xb2, 0x9c}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xb4, 0x71, 0x8f, 0x29, 0xb1, 0xaa, 0xd6, 0xd1, 0x8c, 0x17, 0xef, 0x6c, 0xd5, 0x80, 0xb8, 0x2c, 0xc3, 0xfe, 0xec, 0x24, 0x4d, 0xc8, 0x25, 0xd3, 0xb4, 0xcd, 0xa9, 0xac, 0x63, 0x61, 0xb2, 0x9c}}
return a, nil return a, nil
} }
@ -422,7 +422,7 @@ func _1632236298_add_communitiesDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1632236298_add_communities.down.sql", size: 151, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1632236298_add_communities.down.sql", size: 151, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x26, 0xe5, 0x47, 0xd1, 0xe5, 0xec, 0x5b, 0x3e, 0xdc, 0x22, 0xf4, 0x27, 0xee, 0x70, 0xf3, 0x9, 0x4f, 0xd2, 0x9f, 0x92, 0xf, 0x5a, 0x18, 0x11, 0xb7, 0x40, 0xab, 0xf1, 0x98, 0x72, 0xd6, 0x60}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x26, 0xe5, 0x47, 0xd1, 0xe5, 0xec, 0x5b, 0x3e, 0xdc, 0x22, 0xf4, 0x27, 0xee, 0x70, 0xf3, 0x9, 0x4f, 0xd2, 0x9f, 0x92, 0xf, 0x5a, 0x18, 0x11, 0xb7, 0x40, 0xab, 0xf1, 0x98, 0x72, 0xd6, 0x60}}
return a, nil return a, nil
} }
@ -442,7 +442,7 @@ func _1632236298_add_communitiesUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1632236298_add_communities.up.sql", size: 584, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1632236298_add_communities.up.sql", size: 584, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8f, 0xe0, 0x1, 0x6e, 0x84, 0xc, 0x35, 0xe4, 0x5a, 0xf, 0xbe, 0xcb, 0xf7, 0xd2, 0xa8, 0x25, 0xf5, 0xdb, 0x7, 0xcb, 0xa3, 0xe6, 0xf4, 0xc4, 0x1b, 0xa5, 0xec, 0x32, 0x1e, 0x1e, 0x48, 0x60}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x8f, 0xe0, 0x1, 0x6e, 0x84, 0xc, 0x35, 0xe4, 0x5a, 0xf, 0xbe, 0xcb, 0xf7, 0xd2, 0xa8, 0x25, 0xf5, 0xdb, 0x7, 0xcb, 0xa3, 0xe6, 0xf4, 0xc4, 0x1b, 0xa5, 0xec, 0x32, 0x1e, 0x1e, 0x48, 0x60}}
return a, nil return a, nil
} }
@ -462,7 +462,7 @@ func _1636536507_add_index_bundlesUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1636536507_add_index_bundles.up.sql", size: 347, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1636536507_add_index_bundles.up.sql", size: 347, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf1, 0xb9, 0x3c, 0x16, 0xfc, 0xfb, 0xb2, 0xb4, 0x3b, 0xfe, 0xdc, 0xf5, 0x9c, 0x42, 0xa0, 0xa0, 0xd4, 0xd, 0x5b, 0x97, 0x10, 0x80, 0x95, 0xe, 0x13, 0xc1, 0x18, 0x8, 0xee, 0xf, 0x99, 0xee}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xf1, 0xb9, 0x3c, 0x16, 0xfc, 0xfb, 0xb2, 0xb4, 0x3b, 0xfe, 0xdc, 0xf5, 0x9c, 0x42, 0xa0, 0xa0, 0xd4, 0xd, 0x5b, 0x97, 0x10, 0x80, 0x95, 0xe, 0x13, 0xc1, 0x18, 0x8, 0xee, 0xf, 0x99, 0xee}}
return a, nil return a, nil
} }
@ -482,7 +482,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "doc.go", size: 377, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xef, 0xaf, 0xdf, 0xcf, 0x65, 0xae, 0x19, 0xfc, 0x9d, 0x29, 0xc1, 0x91, 0xaf, 0xb5, 0xd5, 0xb1, 0x56, 0xf3, 0xee, 0xa8, 0xba, 0x13, 0x65, 0xdb, 0xab, 0xcf, 0x4e, 0xac, 0x92, 0xe9, 0x60, 0xf1}}
return a, nil return a, nil
} }

View File

@ -32,6 +32,8 @@ LEFT JOIN discord_messages m2_dm
ON m2.discord_message_id = m2_dm.id ON m2.discord_message_id = m2_dm.id
LEFT JOIN discord_message_authors m2_dm_author LEFT JOIN discord_message_authors m2_dm_author
ON m2_dm.author_id = m2_dm_author.id ON m2_dm.author_id = m2_dm_author.id
LEFT JOIN bridge_messages bm
ON m1.id = bm.user_messages_id
` `
var basicInsertDiscordMessageAuthorQuery = `INSERT OR REPLACE INTO discord_message_authors(id,name,discriminator,nickname,avatar_url, avatar_image_payload) VALUES (?,?,?,?,?,?)` var basicInsertDiscordMessageAuthorQuery = `INSERT OR REPLACE INTO discord_message_authors(id,name,discriminator,nickname,avatar_url, avatar_image_payload) VALUES (?,?,?,?,?,?)`
@ -111,6 +113,7 @@ func (db sqlitePersistence) tableUserMessagesAllFields() string {
discord_message_id` discord_message_id`
} }
// keep the same order as in tableUserMessagesScanAllFields
func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string { func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string {
return `m1.id, return `m1.id,
m1.whisper_timestamp, m1.whisper_timestamp,
@ -195,7 +198,14 @@ func (db sqlitePersistence) tableUserMessagesAllFieldsJoin() string {
COALESCE(m2.discord_message_id, ""), COALESCE(m2.discord_message_id, ""),
COALESCE(m2_dm_author.name, ""), COALESCE(m2_dm_author.name, ""),
COALESCE(m2_dm_author.nickname, ""), COALESCE(m2_dm_author.nickname, ""),
COALESCE(m2_dm_author.avatar_url, "")` COALESCE(m2_dm_author.avatar_url, ""),
COALESCE(bm.bridge_name, ""),
COALESCE(bm.user_name, ""),
COALESCE(bm.user_avatar, ""),
COALESCE(bm.user_id, ""),
COALESCE(bm.content, ""),
COALESCE(bm.message_id, ""),
COALESCE(bm.parent_message_id, "")`
} }
func (db sqlitePersistence) tableUserMessagesAllFieldsCount() int { func (db sqlitePersistence) tableUserMessagesAllFieldsCount() int {
@ -206,6 +216,7 @@ type scanner interface {
Scan(dest ...interface{}) error Scan(dest ...interface{}) error
} }
// keep the same order as in tableUserMessagesAllFieldsJoin
func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message *common.Message, others ...interface{}) error { func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message *common.Message, others ...interface{}) error {
var quotedID sql.NullString var quotedID sql.NullString
var ContentType sql.NullInt64 var ContentType sql.NullInt64
@ -243,6 +254,7 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
Reference: &protobuf.DiscordMessageReference{}, Reference: &protobuf.DiscordMessageReference{},
Attachments: []*protobuf.DiscordMessageAttachment{}, Attachments: []*protobuf.DiscordMessageAttachment{},
} }
bridgeMessage := &protobuf.BridgeMessage{}
quotedDiscordMessage := &protobuf.DiscordMessage{ quotedDiscordMessage := &protobuf.DiscordMessage{
Author: &protobuf.DiscordMessageAuthor{}, Author: &protobuf.DiscordMessageAuthor{},
@ -335,6 +347,13 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
&quotedDiscordMessage.Author.Name, &quotedDiscordMessage.Author.Name,
&quotedDiscordMessage.Author.Nickname, &quotedDiscordMessage.Author.Nickname,
&quotedDiscordMessage.Author.AvatarUrl, &quotedDiscordMessage.Author.AvatarUrl,
&bridgeMessage.BridgeName,
&bridgeMessage.UserName,
&bridgeMessage.UserAvatar,
&bridgeMessage.UserID,
&bridgeMessage.Content,
&bridgeMessage.MessageID,
&bridgeMessage.ParentMessageID,
} }
err := row.Scan(append(args, others...)...) err := row.Scan(append(args, others...)...)
if err != nil { if err != nil {
@ -456,6 +475,11 @@ func (db sqlitePersistence) tableUserMessagesScanAllFields(row scanner, message
message.Payload = &protobuf.ChatMessage_DiscordMessage{ message.Payload = &protobuf.ChatMessage_DiscordMessage{
DiscordMessage: discordMessage, DiscordMessage: discordMessage,
} }
case protobuf.ChatMessage_BRIDGE_MESSAGE:
message.Payload = &protobuf.ChatMessage_BridgeMessage{
BridgeMessage: bridgeMessage,
}
} }
return nil return nil
@ -745,7 +769,6 @@ func (db sqlitePersistence) MessageByChatID(chatID string, currCursor string, li
LIMIT ?`, cursorWhere) LIMIT ?`, cursorWhere)
query := db.buildMessagesQueryWithAdditionalFields(cursorField, where) query := db.buildMessagesQueryWithAdditionalFields(cursorField, where)
rows, err := db.db.Query( rows, err := db.db.Query(
query, query,
append(args, limit+1)..., // take one more to figure our whether a cursor should be returned append(args, limit+1)..., // take one more to figure our whether a cursor should be returned
@ -1165,6 +1188,9 @@ func (db sqlitePersistence) PinnedMessageByChatIDs(chatIDs []string, currCursor
ON ON
m2_dm.author_id = m2_dm_author.id m2_dm.author_id = m2_dm_author.id
LEFT JOIN bridge_messages bm
ON m1.id = bm.user_messages_id
WHERE WHERE
pm.pinned = 1 pm.pinned = 1
AND NOT(m1.hide) AND m1.local_chat_id IN %s %s AND NOT(m1.hide) AND m1.local_chat_id IN %s %s
@ -1500,6 +1526,10 @@ func (db sqlitePersistence) SaveMessages(messages []*common.Message) (err error)
if err != nil { if err != nil {
return return
} }
if msg.ContentType == protobuf.ChatMessage_BRIDGE_MESSAGE {
err = db.saveBridgeMessage(tx, msg.GetBridgeMessage(), msg.ID)
}
} }
return return
} }
@ -2832,3 +2862,23 @@ func getPinnedMessagesAndCursorsFromScanRows(db sqlitePersistence, rows *sql.Row
return messages, cursors, nil return messages, cursors, nil
} }
func (db sqlitePersistence) saveBridgeMessage(tx *sql.Tx, message *protobuf.BridgeMessage, userMessageID string) (err error) {
query := "INSERT INTO bridge_messages(user_messages_id,bridge_name,user_name,user_avatar,user_id,content,message_id,parent_message_id) VALUES (?,?,?,?,?,?,?,?)"
stmt, err := tx.Prepare(query)
if err != nil {
return
}
defer stmt.Close()
_, err = stmt.Exec(
userMessageID,
message.GetBridgeName(),
message.GetUserName(),
message.GetUserAvatar(),
message.GetUserID(),
message.GetContent(),
message.GetMessageID(),
message.GetParentMessageID(),
)
return
}

View File

@ -247,7 +247,9 @@ func ValidateReceivedChatMessage(message *protobuf.ChatMessage, whisperTimestamp
return errors.New("timestamp can't be 0") return errors.New("timestamp can't be 0")
} }
if message.ContentType != protobuf.ChatMessage_DISCORD_MESSAGE && (message.ContentType != protobuf.ChatMessage_IMAGE || message.Text != "") { if message.ContentType != protobuf.ChatMessage_DISCORD_MESSAGE &&
message.ContentType != protobuf.ChatMessage_BRIDGE_MESSAGE &&
(message.ContentType != protobuf.ChatMessage_IMAGE || message.Text != "") {
if err := ValidateText(message.Text); err != nil { if err := ValidateText(message.Text); err != nil {
return err return err
} }
@ -294,6 +296,24 @@ func ValidateReceivedChatMessage(message *protobuf.ChatMessage, whisperTimestamp
if image.Format == protobuf.ImageFormat_UNKNOWN_IMAGE_FORMAT { if image.Format == protobuf.ImageFormat_UNKNOWN_IMAGE_FORMAT {
return errors.New("image type unknown") return errors.New("image type unknown")
} }
case protobuf.ChatMessage_BRIDGE_MESSAGE:
if message.Payload == nil {
return errors.New("no bridge message content")
}
bridgeMessage := message.GetBridgeMessage()
if bridgeMessage == nil {
return errors.New("no bridge message content")
}
if len(bridgeMessage.UserName) == 0 {
return errors.New("no username")
}
if len(bridgeMessage.BridgeName) == 0 {
return errors.New("no bridge name")
}
if len(bridgeMessage.Content) == 0 {
return errors.New("no bridge message content text")
}
} }
if message.ContentType == protobuf.ChatMessage_AUDIO { if message.ContentType == protobuf.ChatMessage_AUDIO {

View File

@ -480,6 +480,50 @@ func (s *MessageValidatorSuite) TestValidatePlainTextMessage() {
ContentType: protobuf.ChatMessage_AUDIO, ContentType: protobuf.ChatMessage_AUDIO,
}, },
}, },
{
Name: "Valid bridge message",
WhisperTimestamp: 2,
Valid: true,
Message: &protobuf.ChatMessage{
ChatId: "a",
Text: "",
Clock: 2,
Timestamp: 3,
ResponseTo: "",
EnsName: "",
Payload: &protobuf.ChatMessage_BridgeMessage{
BridgeMessage: &protobuf.BridgeMessage{
BridgeName: "discord",
UserName: "mike",
Content: "some text",
},
},
MessageType: protobuf.MessageType_ONE_TO_ONE,
ContentType: protobuf.ChatMessage_BRIDGE_MESSAGE,
},
},
{
Name: "Invalid bridge message",
WhisperTimestamp: 2,
Valid: false,
Message: &protobuf.ChatMessage{
ChatId: "a",
Text: "",
Clock: 2,
Timestamp: 3,
ResponseTo: "",
EnsName: "",
Payload: &protobuf.ChatMessage_BridgeMessage{
BridgeMessage: &protobuf.BridgeMessage{
BridgeName: "",
UserName: "",
Content: "",
},
},
MessageType: protobuf.MessageType_ONE_TO_ONE,
ContentType: protobuf.ChatMessage_BRIDGE_MESSAGE,
},
},
} }
for _, tc := range testCases { for _, tc := range testCases {

View File

@ -0,0 +1,102 @@
package protocol
import (
"context"
"testing"
"github.com/stretchr/testify/suite"
"github.com/status-im/status-go/eth-node/crypto"
"github.com/status-im/status-go/multiaccounts"
"github.com/status-im/status-go/protocol/protobuf"
)
func TestBridgeMessageSuite(t *testing.T) {
suite.Run(t, new(BridgeMessageSuite))
}
type BridgeMessageSuite struct {
MessengerBaseTestSuite
}
func (s *BridgeMessageSuite) TestSendBridgeMessage() {
alice := s.m
alice.account = &multiaccounts.Account{KeyUID: "0xdeadbeef"}
key, err := crypto.GenerateKey()
s.Require().NoError(err)
bob, err := newMessengerWithKey(s.shh, key, s.logger, nil)
s.Require().NoError(err)
defer TearDownMessenger(&s.Suite, bob)
chatID := statusChatID
chat := CreatePublicChat(chatID, alice.transport)
err = alice.SaveChat(chat)
s.Require().NoError(err)
_, err = alice.Join(chat)
s.Require().NoError(err)
err = bob.SaveChat(chat)
s.Require().NoError(err)
_, err = bob.Join(chat)
s.Require().NoError(err)
// Send chat message from alice to bob
message := buildTestMessage(*chat)
_, err = alice.SendChatMessage(context.Background(), message)
s.NoError(err)
// Wait for message to arrive to bob
response, err := WaitOnMessengerResponse(
bob,
func(r *MessengerResponse) bool { return len(r.Messages()) > 0 },
"no messages",
)
s.Require().NoError(err)
s.Require().Len(response.Messages(), 1)
// Send bridge message
bridgeMessage := buildTestMessage(*chat)
bridgeMessage.ContentType = protobuf.ChatMessage_BRIDGE_MESSAGE
bridgeMessage.Payload = &protobuf.ChatMessage_BridgeMessage{
BridgeMessage: &protobuf.BridgeMessage{
BridgeName: "discord",
UserName: "user1",
UserAvatar: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAjklEQVR4nOzXwQmFMBAAUZXUYh32ZB32ZB02sxYQQSZGsod55/91WFgSS0RM+SyjA56ZRZhFmEWYRRT6h+M6G16zrxv6fdJpmUWYRbxsYr13dKfanpN0WmYRZhGzXz6AWYRZRIfbaX26fT9Jk07LLMIsosPt9I/dTDotswizCG+nhFmEWYRZhFnEHQAA///z1CFkYamgfQAAAABJRU5ErkJggg==",
UserID: "123",
Content: "text1",
MessageID: "456",
ParentMessageID: "789",
},
}
_, err = bob.SendChatMessage(context.Background(), bridgeMessage)
s.NoError(err)
// Wait for the bridge message to arrive to alice
response, err = WaitOnMessengerResponse(
alice,
func(r *MessengerResponse) bool { return len(r.Messages()) > 0 },
"no bridge message",
)
s.Require().NoError(err)
s.Require().Len(response.Messages(), 1)
receivedBridgeMessage := response.Messages()[0]
s.Require().Equal(receivedBridgeMessage.ContentType, protobuf.ChatMessage_BRIDGE_MESSAGE)
receivedBridgeMessagePayload := receivedBridgeMessage.GetBridgeMessage()
s.Require().NotNil(receivedBridgeMessagePayload)
s.Require().Equal(receivedBridgeMessagePayload.BridgeName, "discord")
s.Require().Equal(receivedBridgeMessagePayload.UserName, "user1")
s.Require().Equal(receivedBridgeMessagePayload.Content, "text1")
s.Require().Equal(receivedBridgeMessagePayload.UserAvatar, "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAIAAACRXR/mAAAAjklEQVR4nOzXwQmFMBAAUZXUYh32ZB32ZB02sxYQQSZGsod55/91WFgSS0RM+SyjA56ZRZhFmEWYRRT6h+M6G16zrxv6fdJpmUWYRbxsYr13dKfanpN0WmYRZhGzXz6AWYRZRIfbaX26fT9Jk07LLMIsosPt9I/dTDotswizCG+nhFmEWYRZhFnEHQAA///z1CFkYamgfQAAAABJRU5ErkJggg==")
s.Require().Equal(receivedBridgeMessagePayload.UserID, "123")
s.Require().Equal(receivedBridgeMessagePayload.MessageID, "456")
s.Require().Equal(receivedBridgeMessagePayload.ParentMessageID, "789")
}

View File

@ -42,7 +42,6 @@ func WaitOnMessengerResponse(m *Messenger, condition func(*MessengerResponse) bo
if err != nil { if err != nil {
panic(err) panic(err)
} }
if err := response.Merge(r); err != nil { if err := response.Merge(r); err != nil {
panic(err) panic(err)
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,13 @@
CREATE TABLE IF NOT EXISTS bridge_messages (
user_messages_id TEXT PRIMARY KEY NOT NULL,
bridge_name TEXT NOT NULL,
user_name TEXT NOT NULL,
user_avatar TEXT DEFAULT "",
user_id TEXT DEFAULT "",
content TEXT NOT NULL,
message_id TEXT DEFAULT "",
parent_message_id TEXT DEFAULT ""
);
CREATE INDEX idx_bridge_messages_user_messages_id
ON bridge_messages (user_messages_id);

View File

@ -1864,3 +1864,49 @@ func TestDeleteHashRatchetMessage(t *testing.T) {
require.Len(t, fetchedMessages, 1) require.Len(t, fetchedMessages, 1)
} }
func TestSaveBridgeMessage(t *testing.T) {
db, err := openTestDB()
require.NoError(t, err)
p := newSQLitePersistence(db)
require.NoError(t, err)
bridgeMessage := &protobuf.BridgeMessage{
BridgeName: "discord",
UserName: "joe",
Content: "abc",
UserAvatar: "data:image/png;base64,iVBO...",
UserID: "123",
MessageID: "456",
ParentMessageID: "789",
}
const msgID = "123"
err = p.SaveMessages([]*common.Message{{
ID: msgID,
LocalChatID: testPublicChatID,
From: testPK,
ChatMessage: &protobuf.ChatMessage{
Text: "some-text",
ContentType: protobuf.ChatMessage_BRIDGE_MESSAGE,
ChatId: testPublicChatID,
Payload: &protobuf.ChatMessage_BridgeMessage{
BridgeMessage: bridgeMessage,
},
},
}})
require.NoError(t, err)
retrievedMessages, _, err := p.MessageByChatID(testPublicChatID, "", 10)
require.NoError(t, err)
require.Len(t, retrievedMessages, 1)
require.Equal(t, "discord", retrievedMessages[0].GetBridgeMessage().BridgeName)
require.Equal(t, "joe", retrievedMessages[0].GetBridgeMessage().UserName)
require.Equal(t, "abc", retrievedMessages[0].GetBridgeMessage().Content)
require.Equal(t, "data:image/png;base64,iVBO...", retrievedMessages[0].GetBridgeMessage().UserAvatar)
require.Equal(t, "123", retrievedMessages[0].GetBridgeMessage().UserID)
require.Equal(t, "456", retrievedMessages[0].GetBridgeMessage().MessageID)
require.Equal(t, "789", retrievedMessages[0].GetBridgeMessage().ParentMessageID)
}

View File

@ -70,7 +70,7 @@ func (x UnfurledLink_LinkType) String() string {
} }
func (UnfurledLink_LinkType) EnumDescriptor() ([]byte, []int) { func (UnfurledLink_LinkType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{11, 0} return fileDescriptor_263952f55fd35689, []int{12, 0}
} }
type ChatMessage_ContentType int32 type ChatMessage_ContentType int32
@ -100,6 +100,7 @@ const (
ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED ChatMessage_ContentType = 16 ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED ChatMessage_ContentType = 16
// Only local // Only local
ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED ChatMessage_ContentType = 17 ChatMessage_SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED ChatMessage_ContentType = 17
ChatMessage_BRIDGE_MESSAGE ChatMessage_ContentType = 18
) )
var ChatMessage_ContentType_name = map[int32]string{ var ChatMessage_ContentType_name = map[int32]string{
@ -121,6 +122,7 @@ var ChatMessage_ContentType_name = map[int32]string{
15: "SYSTEM_MESSAGE_MUTUAL_EVENT_SENT", 15: "SYSTEM_MESSAGE_MUTUAL_EVENT_SENT",
16: "SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED", 16: "SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED",
17: "SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED", 17: "SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED",
18: "BRIDGE_MESSAGE",
} }
var ChatMessage_ContentType_value = map[string]int32{ var ChatMessage_ContentType_value = map[string]int32{
@ -142,6 +144,7 @@ var ChatMessage_ContentType_value = map[string]int32{
"SYSTEM_MESSAGE_MUTUAL_EVENT_SENT": 15, "SYSTEM_MESSAGE_MUTUAL_EVENT_SENT": 15,
"SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED": 16, "SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED": 16,
"SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED": 17, "SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED": 17,
"BRIDGE_MESSAGE": 18,
} }
func (x ChatMessage_ContentType) String() string { func (x ChatMessage_ContentType) String() string {
@ -149,7 +152,7 @@ func (x ChatMessage_ContentType) String() string {
} }
func (ChatMessage_ContentType) EnumDescriptor() ([]byte, []int) { func (ChatMessage_ContentType) EnumDescriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{17, 0} return fileDescriptor_263952f55fd35689, []int{18, 0}
} }
type StickerMessage struct { type StickerMessage struct {
@ -899,6 +902,93 @@ func (m *DiscordMessageAttachment) GetLocalUrl() string {
return "" return ""
} }
type BridgeMessage struct {
BridgeName string `protobuf:"bytes,1,opt,name=bridgeName,proto3" json:"bridgeName,omitempty"`
UserName string `protobuf:"bytes,2,opt,name=userName,proto3" json:"userName,omitempty"`
UserAvatar string `protobuf:"bytes,3,opt,name=userAvatar,proto3" json:"userAvatar,omitempty"`
UserID string `protobuf:"bytes,4,opt,name=userID,proto3" json:"userID,omitempty"`
Content string `protobuf:"bytes,5,opt,name=content,proto3" json:"content,omitempty"`
MessageID string `protobuf:"bytes,6,opt,name=messageID,proto3" json:"messageID,omitempty"`
ParentMessageID string `protobuf:"bytes,7,opt,name=parentMessageID,proto3" json:"parentMessageID,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
func (m *BridgeMessage) Reset() { *m = BridgeMessage{} }
func (m *BridgeMessage) String() string { return proto.CompactTextString(m) }
func (*BridgeMessage) ProtoMessage() {}
func (*BridgeMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{10}
}
func (m *BridgeMessage) XXX_Unmarshal(b []byte) error {
return xxx_messageInfo_BridgeMessage.Unmarshal(m, b)
}
func (m *BridgeMessage) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
return xxx_messageInfo_BridgeMessage.Marshal(b, m, deterministic)
}
func (m *BridgeMessage) XXX_Merge(src proto.Message) {
xxx_messageInfo_BridgeMessage.Merge(m, src)
}
func (m *BridgeMessage) XXX_Size() int {
return xxx_messageInfo_BridgeMessage.Size(m)
}
func (m *BridgeMessage) XXX_DiscardUnknown() {
xxx_messageInfo_BridgeMessage.DiscardUnknown(m)
}
var xxx_messageInfo_BridgeMessage proto.InternalMessageInfo
func (m *BridgeMessage) GetBridgeName() string {
if m != nil {
return m.BridgeName
}
return ""
}
func (m *BridgeMessage) GetUserName() string {
if m != nil {
return m.UserName
}
return ""
}
func (m *BridgeMessage) GetUserAvatar() string {
if m != nil {
return m.UserAvatar
}
return ""
}
func (m *BridgeMessage) GetUserID() string {
if m != nil {
return m.UserID
}
return ""
}
func (m *BridgeMessage) GetContent() string {
if m != nil {
return m.Content
}
return ""
}
func (m *BridgeMessage) GetMessageID() string {
if m != nil {
return m.MessageID
}
return ""
}
func (m *BridgeMessage) GetParentMessageID() string {
if m != nil {
return m.ParentMessageID
}
return ""
}
type UnfurledLinkThumbnail struct { type UnfurledLinkThumbnail struct {
Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"` Payload []byte `protobuf:"bytes,1,opt,name=payload,proto3" json:"payload,omitempty"`
Width uint32 `protobuf:"varint,2,opt,name=width,proto3" json:"width,omitempty"` Width uint32 `protobuf:"varint,2,opt,name=width,proto3" json:"width,omitempty"`
@ -912,7 +1002,7 @@ func (m *UnfurledLinkThumbnail) Reset() { *m = UnfurledLinkThumbnail{} }
func (m *UnfurledLinkThumbnail) String() string { return proto.CompactTextString(m) } func (m *UnfurledLinkThumbnail) String() string { return proto.CompactTextString(m) }
func (*UnfurledLinkThumbnail) ProtoMessage() {} func (*UnfurledLinkThumbnail) ProtoMessage() {}
func (*UnfurledLinkThumbnail) Descriptor() ([]byte, []int) { func (*UnfurledLinkThumbnail) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{10} return fileDescriptor_263952f55fd35689, []int{11}
} }
func (m *UnfurledLinkThumbnail) XXX_Unmarshal(b []byte) error { func (m *UnfurledLinkThumbnail) XXX_Unmarshal(b []byte) error {
@ -975,7 +1065,7 @@ func (m *UnfurledLink) Reset() { *m = UnfurledLink{} }
func (m *UnfurledLink) String() string { return proto.CompactTextString(m) } func (m *UnfurledLink) String() string { return proto.CompactTextString(m) }
func (*UnfurledLink) ProtoMessage() {} func (*UnfurledLink) ProtoMessage() {}
func (*UnfurledLink) Descriptor() ([]byte, []int) { func (*UnfurledLink) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{11} return fileDescriptor_263952f55fd35689, []int{12}
} }
func (m *UnfurledLink) XXX_Unmarshal(b []byte) error { func (m *UnfurledLink) XXX_Unmarshal(b []byte) error {
@ -1059,7 +1149,7 @@ func (m *UnfurledStatusContactLink) Reset() { *m = UnfurledStatusContact
func (m *UnfurledStatusContactLink) String() string { return proto.CompactTextString(m) } func (m *UnfurledStatusContactLink) String() string { return proto.CompactTextString(m) }
func (*UnfurledStatusContactLink) ProtoMessage() {} func (*UnfurledStatusContactLink) ProtoMessage() {}
func (*UnfurledStatusContactLink) Descriptor() ([]byte, []int) { func (*UnfurledStatusContactLink) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{12} return fileDescriptor_263952f55fd35689, []int{13}
} }
func (m *UnfurledStatusContactLink) XXX_Unmarshal(b []byte) error { func (m *UnfurledStatusContactLink) XXX_Unmarshal(b []byte) error {
@ -1125,7 +1215,7 @@ func (m *UnfurledStatusCommunityLink) Reset() { *m = UnfurledStatusCommu
func (m *UnfurledStatusCommunityLink) String() string { return proto.CompactTextString(m) } func (m *UnfurledStatusCommunityLink) String() string { return proto.CompactTextString(m) }
func (*UnfurledStatusCommunityLink) ProtoMessage() {} func (*UnfurledStatusCommunityLink) ProtoMessage() {}
func (*UnfurledStatusCommunityLink) Descriptor() ([]byte, []int) { func (*UnfurledStatusCommunityLink) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{13} return fileDescriptor_263952f55fd35689, []int{14}
} }
func (m *UnfurledStatusCommunityLink) XXX_Unmarshal(b []byte) error { func (m *UnfurledStatusCommunityLink) XXX_Unmarshal(b []byte) error {
@ -1211,7 +1301,7 @@ func (m *UnfurledStatusChannelLink) Reset() { *m = UnfurledStatusChannel
func (m *UnfurledStatusChannelLink) String() string { return proto.CompactTextString(m) } func (m *UnfurledStatusChannelLink) String() string { return proto.CompactTextString(m) }
func (*UnfurledStatusChannelLink) ProtoMessage() {} func (*UnfurledStatusChannelLink) ProtoMessage() {}
func (*UnfurledStatusChannelLink) Descriptor() ([]byte, []int) { func (*UnfurledStatusChannelLink) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{14} return fileDescriptor_263952f55fd35689, []int{15}
} }
func (m *UnfurledStatusChannelLink) XXX_Unmarshal(b []byte) error { func (m *UnfurledStatusChannelLink) XXX_Unmarshal(b []byte) error {
@ -1291,7 +1381,7 @@ func (m *UnfurledStatusLink) Reset() { *m = UnfurledStatusLink{} }
func (m *UnfurledStatusLink) String() string { return proto.CompactTextString(m) } func (m *UnfurledStatusLink) String() string { return proto.CompactTextString(m) }
func (*UnfurledStatusLink) ProtoMessage() {} func (*UnfurledStatusLink) ProtoMessage() {}
func (*UnfurledStatusLink) Descriptor() ([]byte, []int) { func (*UnfurledStatusLink) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{15} return fileDescriptor_263952f55fd35689, []int{16}
} }
func (m *UnfurledStatusLink) XXX_Unmarshal(b []byte) error { func (m *UnfurledStatusLink) XXX_Unmarshal(b []byte) error {
@ -1390,7 +1480,7 @@ func (m *UnfurledStatusLinks) Reset() { *m = UnfurledStatusLinks{} }
func (m *UnfurledStatusLinks) String() string { return proto.CompactTextString(m) } func (m *UnfurledStatusLinks) String() string { return proto.CompactTextString(m) }
func (*UnfurledStatusLinks) ProtoMessage() {} func (*UnfurledStatusLinks) ProtoMessage() {}
func (*UnfurledStatusLinks) Descriptor() ([]byte, []int) { func (*UnfurledStatusLinks) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{16} return fileDescriptor_263952f55fd35689, []int{17}
} }
func (m *UnfurledStatusLinks) XXX_Unmarshal(b []byte) error { func (m *UnfurledStatusLinks) XXX_Unmarshal(b []byte) error {
@ -1447,6 +1537,7 @@ type ChatMessage struct {
// *ChatMessage_Audio // *ChatMessage_Audio
// *ChatMessage_Community // *ChatMessage_Community
// *ChatMessage_DiscordMessage // *ChatMessage_DiscordMessage
// *ChatMessage_BridgeMessage
Payload isChatMessage_Payload `protobuf_oneof:"payload"` Payload isChatMessage_Payload `protobuf_oneof:"payload"`
// Grant for community chat messages // Grant for community chat messages
Grant []byte `protobuf:"bytes,13,opt,name=grant,proto3" json:"grant,omitempty"` Grant []byte `protobuf:"bytes,13,opt,name=grant,proto3" json:"grant,omitempty"`
@ -1465,7 +1556,7 @@ func (m *ChatMessage) Reset() { *m = ChatMessage{} }
func (m *ChatMessage) String() string { return proto.CompactTextString(m) } func (m *ChatMessage) String() string { return proto.CompactTextString(m) }
func (*ChatMessage) ProtoMessage() {} func (*ChatMessage) ProtoMessage() {}
func (*ChatMessage) Descriptor() ([]byte, []int) { func (*ChatMessage) Descriptor() ([]byte, []int) {
return fileDescriptor_263952f55fd35689, []int{17} return fileDescriptor_263952f55fd35689, []int{18}
} }
func (m *ChatMessage) XXX_Unmarshal(b []byte) error { func (m *ChatMessage) XXX_Unmarshal(b []byte) error {
@ -1566,6 +1657,10 @@ type ChatMessage_DiscordMessage struct {
DiscordMessage *DiscordMessage `protobuf:"bytes,99,opt,name=discord_message,json=discordMessage,proto3,oneof"` DiscordMessage *DiscordMessage `protobuf:"bytes,99,opt,name=discord_message,json=discordMessage,proto3,oneof"`
} }
type ChatMessage_BridgeMessage struct {
BridgeMessage *BridgeMessage `protobuf:"bytes,100,opt,name=bridge_message,json=bridgeMessage,proto3,oneof"`
}
func (*ChatMessage_Sticker) isChatMessage_Payload() {} func (*ChatMessage_Sticker) isChatMessage_Payload() {}
func (*ChatMessage_Image) isChatMessage_Payload() {} func (*ChatMessage_Image) isChatMessage_Payload() {}
@ -1576,6 +1671,8 @@ func (*ChatMessage_Community) isChatMessage_Payload() {}
func (*ChatMessage_DiscordMessage) isChatMessage_Payload() {} func (*ChatMessage_DiscordMessage) isChatMessage_Payload() {}
func (*ChatMessage_BridgeMessage) isChatMessage_Payload() {}
func (m *ChatMessage) GetPayload() isChatMessage_Payload { func (m *ChatMessage) GetPayload() isChatMessage_Payload {
if m != nil { if m != nil {
return m.Payload return m.Payload
@ -1618,6 +1715,13 @@ func (m *ChatMessage) GetDiscordMessage() *DiscordMessage {
return nil return nil
} }
func (m *ChatMessage) GetBridgeMessage() *BridgeMessage {
if x, ok := m.GetPayload().(*ChatMessage_BridgeMessage); ok {
return x.BridgeMessage
}
return nil
}
func (m *ChatMessage) GetGrant() []byte { func (m *ChatMessage) GetGrant() []byte {
if m != nil { if m != nil {
return m.Grant return m.Grant
@ -1668,6 +1772,7 @@ func (*ChatMessage) XXX_OneofWrappers() []interface{} {
(*ChatMessage_Audio)(nil), (*ChatMessage_Audio)(nil),
(*ChatMessage_Community)(nil), (*ChatMessage_Community)(nil),
(*ChatMessage_DiscordMessage)(nil), (*ChatMessage_DiscordMessage)(nil),
(*ChatMessage_BridgeMessage)(nil),
} }
} }
@ -1685,6 +1790,7 @@ func init() {
proto.RegisterType((*DiscordMessageAuthor)(nil), "protobuf.DiscordMessageAuthor") proto.RegisterType((*DiscordMessageAuthor)(nil), "protobuf.DiscordMessageAuthor")
proto.RegisterType((*DiscordMessageReference)(nil), "protobuf.DiscordMessageReference") proto.RegisterType((*DiscordMessageReference)(nil), "protobuf.DiscordMessageReference")
proto.RegisterType((*DiscordMessageAttachment)(nil), "protobuf.DiscordMessageAttachment") proto.RegisterType((*DiscordMessageAttachment)(nil), "protobuf.DiscordMessageAttachment")
proto.RegisterType((*BridgeMessage)(nil), "protobuf.BridgeMessage")
proto.RegisterType((*UnfurledLinkThumbnail)(nil), "protobuf.UnfurledLinkThumbnail") proto.RegisterType((*UnfurledLinkThumbnail)(nil), "protobuf.UnfurledLinkThumbnail")
proto.RegisterType((*UnfurledLink)(nil), "protobuf.UnfurledLink") proto.RegisterType((*UnfurledLink)(nil), "protobuf.UnfurledLink")
proto.RegisterType((*UnfurledStatusContactLink)(nil), "protobuf.UnfurledStatusContactLink") proto.RegisterType((*UnfurledStatusContactLink)(nil), "protobuf.UnfurledStatusContactLink")
@ -1700,121 +1806,128 @@ func init() {
} }
var fileDescriptor_263952f55fd35689 = []byte{ var fileDescriptor_263952f55fd35689 = []byte{
// 1848 bytes of a gzipped FileDescriptorProto // 1955 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xdd, 0x92, 0xdb, 0x58, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xac, 0x58, 0xdd, 0x72, 0x1b, 0x4b,
0x11, 0x8e, 0xff, 0x47, 0x2d, 0xdb, 0xa3, 0x9c, 0x4c, 0x26, 0x4e, 0xc8, 0x6c, 0x1c, 0x25, 0x5b, 0x11, 0xb6, 0xfe, 0xad, 0x5e, 0x49, 0xde, 0x4c, 0x1c, 0x47, 0x09, 0x71, 0xe2, 0x6c, 0x72, 0x2a,
0x19, 0x0a, 0x18, 0xaa, 0x26, 0x0b, 0x6c, 0x15, 0x45, 0x6d, 0x29, 0xb6, 0x92, 0x88, 0xc4, 0x1e, 0xa6, 0x00, 0x53, 0xe5, 0x1c, 0xe0, 0x54, 0x51, 0xd4, 0x61, 0x2d, 0x6d, 0xe2, 0x25, 0x91, 0xac,
0xaf, 0x2c, 0x67, 0x09, 0x37, 0x2a, 0x8d, 0x74, 0x66, 0x2c, 0x46, 0x3f, 0x46, 0x3f, 0x80, 0x79, 0x33, 0x5a, 0xe5, 0x10, 0x6e, 0xb6, 0x56, 0xbb, 0x63, 0x6b, 0xb1, 0xb4, 0x2b, 0xf6, 0x07, 0x10,
0x11, 0xde, 0x02, 0x6e, 0x28, 0xae, 0x78, 0x04, 0x8a, 0x1b, 0x8a, 0x57, 0xe0, 0x09, 0xb8, 0xe2, 0x2f, 0xc2, 0x33, 0x70, 0x03, 0x37, 0x14, 0x4f, 0x41, 0x51, 0xdc, 0xf0, 0x08, 0xf0, 0x04, 0x5c,
0x8a, 0x3a, 0x3f, 0xfa, 0xf3, 0xd8, 0x93, 0x4d, 0x6a, 0xaf, 0x7c, 0xba, 0x4f, 0x77, 0xab, 0xcf, 0x71, 0x45, 0xcd, 0xcf, 0xfe, 0xc9, 0x92, 0x73, 0x92, 0x3a, 0x57, 0x9a, 0xee, 0xe9, 0xee, 0xed,
0xd7, 0x7d, 0xfa, 0x74, 0x1b, 0x90, 0xbd, 0xb4, 0x12, 0xd3, 0xc7, 0x71, 0x6c, 0x5d, 0xe2, 0x93, 0xe9, 0xee, 0xe9, 0xf9, 0x5a, 0x80, 0xec, 0x99, 0x15, 0x99, 0x0b, 0x12, 0x86, 0xd6, 0x15, 0x39,
0x55, 0x14, 0x26, 0x21, 0xda, 0xa3, 0x3f, 0xe7, 0xe9, 0xc5, 0x03, 0x11, 0x07, 0xa9, 0x1f, 0x33, 0x59, 0x06, 0x7e, 0xe4, 0xa3, 0x5d, 0xf6, 0x33, 0x8d, 0x2f, 0x1f, 0x4a, 0xc4, 0x8b, 0x17, 0x21,
0xf6, 0x83, 0x9e, 0x1d, 0x06, 0x89, 0x65, 0x27, 0x9c, 0x14, 0xe3, 0xa5, 0x15, 0x39, 0x8c, 0x90, 0x67, 0x3f, 0x6c, 0xdb, 0xbe, 0x17, 0x59, 0x76, 0x24, 0x48, 0x29, 0x9c, 0x59, 0x81, 0xc3, 0x09,
0xbf, 0x84, 0xfe, 0x3c, 0x71, 0xed, 0x2b, 0x1c, 0x4d, 0x98, 0x29, 0x84, 0xa0, 0xb9, 0xb4, 0xe2, 0xe5, 0x0b, 0xe8, 0x8c, 0x23, 0xd7, 0xbe, 0x26, 0xc1, 0x80, 0x9b, 0x42, 0x08, 0xaa, 0x33, 0x2b,
0xe5, 0xa0, 0x36, 0xac, 0x1d, 0x0b, 0x3a, 0x5d, 0x13, 0xde, 0xca, 0xb2, 0xaf, 0x06, 0xf5, 0x61, 0x9c, 0x75, 0x4b, 0x47, 0xa5, 0xe3, 0x26, 0x66, 0x6b, 0xca, 0x5b, 0x5a, 0xf6, 0x75, 0xb7, 0x7c,
0xed, 0xb8, 0xa5, 0xd3, 0xb5, 0xfc, 0xcf, 0x1a, 0x74, 0x35, 0xdf, 0xba, 0xc4, 0x99, 0xe2, 0x00, 0x54, 0x3a, 0xae, 0x61, 0xb6, 0x56, 0xfe, 0x51, 0x82, 0x96, 0xbe, 0xb0, 0xae, 0x48, 0xa2, 0xd8,
0x3a, 0x2b, 0x6b, 0xed, 0x85, 0x96, 0x43, 0x75, 0xbb, 0x7a, 0x46, 0xa2, 0x1f, 0x41, 0xfb, 0x22, 0x85, 0xc6, 0xd2, 0x5a, 0xcd, 0x7d, 0xcb, 0x61, 0xba, 0x2d, 0x9c, 0x90, 0xe8, 0x07, 0x50, 0xbf,
0x8c, 0x7c, 0x2b, 0xa1, 0x06, 0xfa, 0xa7, 0x77, 0x4f, 0x32, 0x47, 0x4f, 0xa8, 0x85, 0x97, 0x74, 0xf4, 0x83, 0x85, 0x15, 0x31, 0x03, 0x9d, 0xd3, 0x7b, 0x27, 0x89, 0xa3, 0x27, 0xcc, 0xc2, 0x2b,
0x53, 0xe7, 0x42, 0xe8, 0x3e, 0xec, 0x59, 0xde, 0x79, 0xea, 0x9b, 0xae, 0x33, 0x68, 0x50, 0x2f, 0xb6, 0x89, 0x85, 0x10, 0x7a, 0x00, 0xbb, 0xd6, 0x7c, 0x1a, 0x2f, 0x4c, 0xd7, 0xe9, 0x56, 0x98,
0x3a, 0x94, 0xd6, 0x1c, 0x74, 0x00, 0xad, 0xdf, 0xbb, 0x4e, 0xb2, 0x1c, 0x34, 0x87, 0xb5, 0xe3, 0x17, 0x0d, 0x46, 0xeb, 0x0e, 0xda, 0x87, 0xda, 0xef, 0x5c, 0x27, 0x9a, 0x75, 0xab, 0x47, 0xa5,
0x9e, 0xce, 0x08, 0x74, 0x08, 0xed, 0x25, 0x76, 0x2f, 0x97, 0xc9, 0xa0, 0x45, 0xd9, 0x9c, 0x42, 0xe3, 0x36, 0xe6, 0x04, 0x3a, 0x80, 0xfa, 0x8c, 0xb8, 0x57, 0xb3, 0xa8, 0x5b, 0x63, 0x6c, 0x41,
0x3f, 0x04, 0xc4, 0x0d, 0x91, 0xaf, 0xc4, 0xa6, 0x1d, 0xa6, 0x41, 0x32, 0x68, 0x53, 0x19, 0x89, 0xa1, 0xef, 0x03, 0x12, 0x86, 0xe8, 0x57, 0x42, 0xd3, 0xf6, 0x63, 0x2f, 0xea, 0xd6, 0x99, 0x8c,
0x99, 0xa4, 0x1b, 0x23, 0xc2, 0x97, 0xff, 0x56, 0x83, 0xae, 0x92, 0x3a, 0x6e, 0xf8, 0xe1, 0x03, 0xcc, 0x4d, 0xb2, 0x8d, 0x1e, 0xe5, 0x2b, 0x7f, 0x2b, 0x41, 0x4b, 0x8d, 0x1d, 0xd7, 0xff, 0xf0,
0x7d, 0x01, 0xcd, 0x64, 0xbd, 0xc2, 0xfc, 0x38, 0xc3, 0xe2, 0x38, 0x65, 0x7d, 0x46, 0x18, 0xeb, 0x81, 0x3e, 0x87, 0x6a, 0xb4, 0x5a, 0x12, 0x71, 0x9c, 0xa3, 0xec, 0x38, 0x79, 0x7d, 0x4e, 0x18,
0x15, 0xd6, 0xa9, 0x34, 0x7a, 0x04, 0xa2, 0x93, 0x46, 0x56, 0xe2, 0x86, 0x81, 0xe9, 0xc7, 0xf4, 0xab, 0x25, 0xc1, 0x4c, 0x1a, 0x3d, 0x01, 0xc9, 0x89, 0x03, 0x2b, 0x72, 0x7d, 0xcf, 0x5c, 0x84,
0x68, 0x4d, 0x1d, 0x32, 0xd6, 0x24, 0x96, 0x7f, 0x02, 0x42, 0xae, 0x83, 0x0e, 0x01, 0x2d, 0xa6, 0xec, 0x68, 0x55, 0x0c, 0x09, 0x6b, 0x10, 0x2a, 0x3f, 0x82, 0x66, 0xaa, 0x83, 0x0e, 0x00, 0x4d,
0x6f, 0xa6, 0x67, 0xdf, 0x4c, 0x4d, 0x65, 0x31, 0xd6, 0xce, 0x4c, 0xe3, 0xfd, 0x4c, 0x95, 0x6e, 0x86, 0x6f, 0x86, 0x17, 0x5f, 0x0f, 0x4d, 0x75, 0xd2, 0xd7, 0x2f, 0x4c, 0xe3, 0xfd, 0x48, 0x93,
0xa1, 0x0e, 0x34, 0x14, 0x65, 0x24, 0xd5, 0xe8, 0x62, 0xa2, 0x4b, 0x75, 0xf9, 0x4f, 0x0d, 0x10, 0x77, 0x50, 0x03, 0x2a, 0xaa, 0xda, 0x93, 0x4b, 0x6c, 0x31, 0xc0, 0x72, 0x59, 0xf9, 0x63, 0x05,
0x55, 0xc7, 0x4d, 0x32, 0xbf, 0x0f, 0xa0, 0x65, 0x7b, 0xa1, 0x7d, 0x45, 0xbd, 0x6e, 0xea, 0x8c, 0x24, 0xcd, 0x71, 0xa3, 0xc4, 0xef, 0x7d, 0xa8, 0xd9, 0x73, 0xdf, 0xbe, 0x66, 0x5e, 0x57, 0x31,
0x20, 0x31, 0x4c, 0xf0, 0x1f, 0x58, 0x08, 0x04, 0x9d, 0xae, 0xd1, 0x3d, 0xe8, 0xd0, 0x34, 0xca, 0x27, 0x68, 0x0e, 0x23, 0xf2, 0x7b, 0x9e, 0x82, 0x26, 0x66, 0x6b, 0x74, 0x1f, 0x1a, 0xac, 0x8c,
0x81, 0x6e, 0x13, 0x52, 0x73, 0xd0, 0x11, 0x00, 0x4f, 0x2d, 0xb2, 0xd7, 0xa4, 0x7b, 0x02, 0xe7, 0xd2, 0x40, 0xd7, 0x29, 0xa9, 0x3b, 0xe8, 0x10, 0x40, 0x94, 0x16, 0xdd, 0xab, 0xb2, 0xbd, 0xa6,
0xb0, 0x30, 0x5c, 0x46, 0x56, 0xc0, 0xf0, 0xee, 0xea, 0x8c, 0x40, 0x5f, 0x42, 0x37, 0x53, 0xa2, 0xe0, 0xf0, 0x34, 0x5c, 0x05, 0x96, 0xc7, 0xe3, 0xdd, 0xc2, 0x9c, 0x40, 0x5f, 0x40, 0x2b, 0x51,
0xe8, 0xb4, 0x37, 0x83, 0xcd, 0x1d, 0xa4, 0x90, 0x88, 0x7e, 0x41, 0xa0, 0x31, 0x74, 0x49, 0x8e, 0x62, 0xd1, 0xa9, 0xaf, 0x27, 0x5b, 0x38, 0xc8, 0x42, 0x22, 0x2d, 0x32, 0x02, 0xf5, 0xa1, 0x45,
0xe2, 0x20, 0x61, 0x9a, 0x1d, 0xaa, 0xf9, 0xb8, 0xd0, 0x1c, 0x2d, 0xad, 0xec, 0x78, 0x27, 0x23, 0x6b, 0x94, 0x78, 0x11, 0xd7, 0x6c, 0x30, 0xcd, 0xa7, 0x99, 0x66, 0x6f, 0x66, 0x25, 0xc7, 0x3b,
0x26, 0xc9, 0xac, 0xd8, 0x05, 0x81, 0x7e, 0x01, 0xfd, 0x34, 0xb8, 0x48, 0x23, 0x0f, 0x3b, 0xa6, 0xe9, 0x71, 0x49, 0x6e, 0xc5, 0xce, 0x08, 0xf4, 0x33, 0xe8, 0xc4, 0xde, 0x65, 0x1c, 0xcc, 0x89,
0xe7, 0x06, 0x57, 0xf1, 0x60, 0x6f, 0xd8, 0x38, 0x16, 0x4f, 0x0f, 0x0b, 0x3b, 0x0b, 0xbe, 0xff, 0x63, 0xce, 0x5d, 0xef, 0x3a, 0xec, 0xee, 0x1e, 0x55, 0x8e, 0xa5, 0xd3, 0x83, 0xcc, 0xce, 0x44,
0xd6, 0x0d, 0xae, 0xf4, 0x5e, 0x5a, 0xa2, 0x62, 0xf4, 0x35, 0xdc, 0xcd, 0xd5, 0xe3, 0xc4, 0x4a, 0xec, 0xbf, 0x75, 0xbd, 0x6b, 0xdc, 0x8e, 0x73, 0x54, 0x88, 0xbe, 0x82, 0x7b, 0xa9, 0x7a, 0x18,
0xd2, 0x98, 0x5b, 0x11, 0x86, 0xb5, 0x63, 0xf1, 0xf4, 0xe8, 0xba, 0x95, 0x39, 0x95, 0xa2, 0xda, 0x59, 0x51, 0x1c, 0x0a, 0x2b, 0xcd, 0xa3, 0xd2, 0xb1, 0x74, 0x7a, 0x78, 0xd3, 0xca, 0x98, 0x49,
0xfa, 0x9d, 0xf4, 0x3a, 0x53, 0xfe, 0x47, 0x0d, 0x7a, 0x63, 0xec, 0xe1, 0x04, 0xdf, 0x1c, 0x9b, 0x31, 0x6d, 0x7c, 0x37, 0xbe, 0xc9, 0x54, 0xfe, 0x5e, 0x82, 0x76, 0x9f, 0xcc, 0x49, 0x44, 0x6e,
0x52, 0x1c, 0xea, 0x37, 0xc4, 0xa1, 0xb1, 0x33, 0x0e, 0xcd, 0x9b, 0xe2, 0xd0, 0xfa, 0xd6, 0x71, 0xcf, 0x4d, 0x2e, 0x0f, 0xe5, 0x5b, 0xf2, 0x50, 0xd9, 0x9a, 0x87, 0xea, 0x6d, 0x79, 0xa8, 0x7d,
0x38, 0x02, 0x70, 0xa8, 0xbb, 0x8e, 0x79, 0xbe, 0xa6, 0xf1, 0x13, 0x74, 0x81, 0x73, 0x5e, 0xac, 0xe3, 0x3c, 0x1c, 0x02, 0x38, 0xcc, 0x5d, 0xc7, 0x9c, 0xae, 0x58, 0xfe, 0x9a, 0xb8, 0x29, 0x38,
0xe5, 0x09, 0x1c, 0xce, 0xd7, 0x81, 0xcd, 0x4e, 0xf4, 0x32, 0x8c, 0x26, 0x1f, 0x38, 0x56, 0xd5, 0x67, 0x2b, 0x65, 0x00, 0x07, 0xe3, 0x95, 0x67, 0xf3, 0x13, 0xbd, 0xf2, 0x83, 0xc1, 0x07, 0x8e,
0xfb, 0xfa, 0x86, 0xf7, 0xf2, 0xbf, 0xeb, 0xd0, 0x1f, 0xbb, 0xb1, 0x1d, 0x46, 0x4e, 0x66, 0xa7, 0x55, 0xf4, 0xbe, 0xbc, 0xe6, 0xbd, 0xf2, 0xaf, 0x32, 0x74, 0xfa, 0x6e, 0x68, 0xfb, 0x81, 0x93,
0x0f, 0x75, 0xd7, 0xe1, 0xa5, 0xa7, 0xee, 0x3a, 0x34, 0x69, 0xb3, 0x8b, 0x26, 0xf0, 0x6b, 0xf4, 0xd8, 0xe9, 0x40, 0xd9, 0x75, 0x44, 0xeb, 0x29, 0xbb, 0x0e, 0x2b, 0xda, 0xe4, 0xa2, 0x35, 0xc5,
0x10, 0x84, 0xc4, 0xf5, 0x71, 0x9c, 0x58, 0xfe, 0x2a, 0x83, 0x24, 0x67, 0xa0, 0x63, 0xd8, 0xcf, 0x35, 0x7a, 0x04, 0xcd, 0xc8, 0x5d, 0x90, 0x30, 0xb2, 0x16, 0xcb, 0x24, 0x24, 0x29, 0x03, 0x1d,
0x09, 0x72, 0x29, 0x70, 0x96, 0xbe, 0x9b, 0x6c, 0x72, 0xbd, 0x79, 0xf6, 0x50, 0x84, 0x04, 0x3d, 0xc3, 0x5e, 0x4a, 0xd0, 0x4b, 0x41, 0x92, 0xf2, 0x5d, 0x67, 0xd3, 0xeb, 0x2d, 0xaa, 0x87, 0x45,
0x23, 0xd1, 0x4f, 0xa1, 0x6d, 0xa5, 0xc9, 0x32, 0x8c, 0x28, 0x04, 0xe2, 0xe9, 0x67, 0x05, 0x74, 0xa8, 0x89, 0x13, 0x12, 0xfd, 0x18, 0xea, 0x56, 0x1c, 0xcd, 0xfc, 0x80, 0x85, 0x40, 0x3a, 0x7d,
0x55, 0x7f, 0x15, 0x2a, 0xa5, 0x73, 0x69, 0xf4, 0x15, 0x08, 0x11, 0xbe, 0xc0, 0x11, 0x0e, 0x6c, 0x9c, 0x85, 0xae, 0xe8, 0xaf, 0xca, 0xa4, 0xb0, 0x90, 0x46, 0x5f, 0x42, 0x33, 0x20, 0x97, 0x24,
0x96, 0xc3, 0x62, 0x39, 0x87, 0xab, 0xaa, 0x7a, 0x26, 0xa8, 0x17, 0x3a, 0x68, 0x0c, 0xa2, 0x95, 0x20, 0x9e, 0xcd, 0x6b, 0x58, 0xca, 0xd7, 0x70, 0x51, 0x15, 0x27, 0x82, 0x38, 0xd3, 0x41, 0x7d,
0x24, 0x96, 0xbd, 0xf4, 0x71, 0x90, 0x64, 0xe9, 0x2b, 0xef, 0xfc, 0x7a, 0x2e, 0xaa, 0x97, 0xd5, 0x90, 0xac, 0x28, 0xb2, 0xec, 0xd9, 0x82, 0x78, 0x51, 0x52, 0xbe, 0xca, 0xd6, 0xaf, 0xa7, 0xa2,
0xe4, 0xff, 0xd4, 0xe0, 0x60, 0x9b, 0x9f, 0xdb, 0xd0, 0x0d, 0x2c, 0x3f, 0x47, 0x97, 0xac, 0xd1, 0x38, 0xaf, 0xa6, 0xfc, 0xa7, 0x04, 0xfb, 0x9b, 0xfc, 0xdc, 0x14, 0x5d, 0xcf, 0x5a, 0xa4, 0xd1,
0x53, 0xe8, 0x39, 0x6e, 0x6c, 0x47, 0xae, 0xef, 0x06, 0x56, 0x12, 0x46, 0x1c, 0xe1, 0x2a, 0x13, 0xa5, 0x6b, 0xf4, 0x1c, 0xda, 0x8e, 0x1b, 0xda, 0x81, 0xbb, 0x70, 0x3d, 0x2b, 0xf2, 0x03, 0x11,
0x3d, 0x80, 0xbd, 0xc0, 0xb5, 0xaf, 0xa8, 0x36, 0x83, 0x37, 0xa7, 0x49, 0x7c, 0xac, 0xdf, 0x59, 0xe1, 0x22, 0x13, 0x3d, 0x84, 0x5d, 0xcf, 0xb5, 0xaf, 0x99, 0x36, 0x0f, 0x6f, 0x4a, 0xd3, 0xfc,
0x89, 0x15, 0x2d, 0x22, 0x8f, 0x23, 0x5b, 0x30, 0xd0, 0x09, 0x20, 0x46, 0xd0, 0xd2, 0x3b, 0xe3, 0x58, 0xbf, 0xb5, 0x22, 0x2b, 0x98, 0x04, 0x73, 0x11, 0xd9, 0x8c, 0x81, 0x4e, 0x00, 0x71, 0x82,
0xf5, 0xb5, 0x4d, 0xf3, 0x77, 0xcb, 0x0e, 0xf9, 0x92, 0x17, 0xda, 0x96, 0x47, 0x8c, 0x75, 0xd8, 0xb5, 0xde, 0x91, 0xe8, 0xaf, 0x75, 0x56, 0xbf, 0x1b, 0x76, 0xe8, 0x97, 0xe6, 0xbe, 0x6d, 0xcd,
0x97, 0x32, 0x5a, 0x0e, 0xe1, 0xde, 0x0e, 0x50, 0x89, 0x13, 0x79, 0xa2, 0xf1, 0x13, 0x97, 0xee, 0xa9, 0xb1, 0x06, 0xff, 0x52, 0x42, 0x2b, 0x3e, 0xdc, 0xdf, 0x12, 0x54, 0xea, 0x44, 0x5a, 0x68,
0xcd, 0x43, 0x10, 0xec, 0xa5, 0x15, 0x04, 0xd8, 0xd3, 0xf2, 0xbc, 0xcc, 0x19, 0x24, 0x31, 0x2e, 0xe2, 0xc4, 0xb9, 0x7b, 0xf3, 0x08, 0x9a, 0xf6, 0xcc, 0xf2, 0x3c, 0x32, 0xd7, 0xd3, 0xba, 0x4c,
0x53, 0xd7, 0x73, 0xb4, 0xfc, 0xf9, 0xe1, 0xa4, 0xfc, 0xdf, 0x1a, 0x0c, 0x76, 0xc5, 0xe0, 0x1a, 0x19, 0xb4, 0x30, 0xae, 0x62, 0x77, 0xee, 0xe8, 0xe9, 0xf3, 0x23, 0x48, 0xe5, 0xbf, 0x25, 0xe8,
0xba, 0x15, 0x17, 0x36, 0x93, 0x1f, 0x49, 0xd0, 0x48, 0x23, 0x8f, 0x7f, 0x80, 0x2c, 0xc9, 0x49, 0x6e, 0xcb, 0xc1, 0x8d, 0xe8, 0x16, 0x5c, 0x58, 0x2f, 0x7e, 0x24, 0x43, 0x25, 0x0e, 0xe6, 0xe2,
0x2f, 0x5c, 0x0f, 0x4f, 0x4b, 0x98, 0x66, 0x34, 0x89, 0x0a, 0x59, 0xcf, 0xdd, 0x3f, 0xe2, 0x17, 0x03, 0x74, 0x49, 0x4f, 0x7a, 0xe9, 0xce, 0xc9, 0x30, 0x17, 0xd3, 0x84, 0xa6, 0x59, 0xa1, 0xeb,
0xeb, 0x04, 0xc7, 0x14, 0xd7, 0xa6, 0x5e, 0x65, 0xa2, 0x21, 0x94, 0xeb, 0x21, 0xbf, 0xbf, 0x95, 0xb1, 0xfb, 0x07, 0x72, 0xb6, 0x8a, 0x48, 0xc8, 0xe2, 0x5a, 0xc5, 0x45, 0x26, 0x3a, 0x82, 0x7c,
0x12, 0x59, 0x7a, 0xd2, 0x3a, 0xd5, 0x27, 0xad, 0x8c, 0xf3, 0xde, 0x06, 0xce, 0x26, 0xdc, 0x2d, 0x3f, 0x14, 0xf7, 0xb7, 0xd0, 0x22, 0x73, 0x4f, 0x5a, 0xa3, 0xf8, 0xa4, 0xe5, 0xe3, 0xbc, 0xbb,
0x17, 0x4e, 0x63, 0x99, 0xfa, 0xe7, 0x81, 0xe5, 0x7a, 0x37, 0xbc, 0x90, 0xf9, 0x43, 0x5d, 0xdf, 0x16, 0xe7, 0x7f, 0x97, 0xa0, 0x7d, 0x16, 0xb8, 0x4e, 0xf6, 0xd6, 0x3f, 0x06, 0x98, 0x32, 0x06,
0xfe, 0x50, 0x37, 0xca, 0x0f, 0xb5, 0xfc, 0x97, 0x3a, 0x74, 0xcb, 0x5f, 0xc8, 0xd0, 0xa9, 0x15, 0xf3, 0x96, 0x9f, 0x39, 0xc7, 0xa1, 0xd6, 0xe2, 0x90, 0x04, 0xc3, 0xac, 0xba, 0x52, 0x9a, 0xea,
0xe8, 0x1c, 0x40, 0x2b, 0x71, 0x13, 0x2f, 0x4b, 0x56, 0x46, 0x90, 0x13, 0x3b, 0x98, 0x24, 0xe6, 0xd2, 0xb5, 0xca, 0x72, 0x2d, 0x02, 0x90, 0xe3, 0xd0, 0xd7, 0x9c, 0x52, 0x7a, 0x5f, 0x44, 0x41,
0x8a, 0x3c, 0xa1, 0x1c, 0xcd, 0x32, 0x0b, 0xfd, 0x00, 0x6e, 0x27, 0x99, 0xbf, 0x66, 0xe6, 0x2c, 0x50, 0xb7, 0xdc, 0xd7, 0x5c, 0xa4, 0xfb, 0x49, 0xd7, 0x4a, 0x19, 0xb4, 0x23, 0x2c, 0xad, 0x80,
0x2b, 0x97, 0x52, 0xbe, 0x91, 0x25, 0xdb, 0x33, 0xd8, 0x2f, 0x84, 0x99, 0xff, 0xac, 0xa3, 0xe8, 0x78, 0xc9, 0x03, 0xa2, 0xf7, 0x45, 0x21, 0xad, 0xb3, 0x15, 0x13, 0xee, 0xe5, 0x1f, 0x08, 0x63,
0xe7, 0xec, 0x6f, 0xe8, 0x41, 0xbe, 0x0f, 0x85, 0xb2, 0xc9, 0x8f, 0xc4, 0xfa, 0x8a, 0xc2, 0xc0, 0x16, 0x2f, 0xa6, 0x9e, 0xe5, 0xce, 0x6f, 0x41, 0x02, 0x29, 0x20, 0x29, 0x6f, 0x06, 0x24, 0x95,
0x6b, 0xd6, 0x84, 0x3c, 0xe7, 0x25, 0x8c, 0xbd, 0x69, 0x8f, 0xb6, 0xbf, 0x45, 0x27, 0x14, 0xd7, 0x3c, 0x20, 0x51, 0xfe, 0x52, 0x86, 0x56, 0xfe, 0x0b, 0x49, 0x15, 0x94, 0xb2, 0x2a, 0xd8, 0x87,
0xbc, 0x55, 0x90, 0x1f, 0xc1, 0x5e, 0xc6, 0x41, 0x7b, 0xd0, 0x7c, 0xab, 0x4d, 0xdf, 0x48, 0xb7, 0x5a, 0xe4, 0x46, 0xf3, 0x24, 0x6c, 0x9c, 0xa0, 0x99, 0x75, 0x08, 0xbd, 0x80, 0x4b, 0x0a, 0x15,
0x90, 0x00, 0x2d, 0x6d, 0xa2, 0xbc, 0x52, 0xa5, 0x9a, 0xfc, 0xd7, 0x1a, 0xdc, 0xaf, 0x3e, 0x43, 0x44, 0xd0, 0xf2, 0x2c, 0xf4, 0x3d, 0xb8, 0x13, 0x25, 0xfe, 0x9a, 0x89, 0xb3, 0xfc, 0x59, 0x90,
0x23, 0xd6, 0xe4, 0x51, 0xf8, 0x8e, 0x00, 0x56, 0xe9, 0xb9, 0xe7, 0xda, 0xe6, 0x15, 0x5e, 0xf3, 0xd3, 0x8d, 0xe4, 0x52, 0xbd, 0x80, 0xbd, 0x4c, 0x98, 0xfb, 0xcf, 0x91, 0x53, 0x27, 0x65, 0x7f,
0xd0, 0x08, 0x8c, 0xf3, 0x06, 0xaf, 0xd1, 0x63, 0xe8, 0x3a, 0x6e, 0xbc, 0xf2, 0xac, 0xb5, 0x59, 0xcd, 0x0e, 0xf2, 0x5d, 0xc8, 0x94, 0x4d, 0x71, 0x24, 0x8e, 0x9f, 0x32, 0x03, 0xe7, 0x1c, 0x6c,
0xba, 0xff, 0x22, 0xe7, 0xd1, 0x84, 0xfb, 0x30, 0xb0, 0xcf, 0xa1, 0xe9, 0xda, 0x61, 0x40, 0xb1, 0xbd, 0x14, 0xad, 0x9a, 0xbf, 0xdd, 0x4f, 0x36, 0xbf, 0xb9, 0x27, 0x2c, 0xae, 0x29, 0x24, 0x52,
0x14, 0x77, 0x9d, 0x2b, 0x4f, 0x15, 0x9d, 0x0a, 0xcb, 0x7f, 0xae, 0xc3, 0xf7, 0x36, 0xdd, 0xf6, 0x9e, 0xc0, 0x6e, 0xc2, 0x41, 0xbb, 0x50, 0x7d, 0xab, 0x0f, 0xdf, 0xc8, 0x3b, 0xa8, 0x09, 0x35,
0xfd, 0x34, 0x70, 0x93, 0x35, 0x75, 0xfc, 0x31, 0x69, 0x04, 0x38, 0xc3, 0x74, 0xb3, 0xac, 0x12, 0x7d, 0xa0, 0xbe, 0xd6, 0xe4, 0x92, 0xf2, 0xd7, 0x12, 0x3c, 0x28, 0x3e, 0xb7, 0x3d, 0x0e, 0x66,
0x73, 0x9e, 0xe6, 0x7c, 0x37, 0xce, 0x3f, 0x81, 0x9e, 0x8f, 0xfd, 0x73, 0x1c, 0x65, 0x4d, 0x21, 0x59, 0xf8, 0x0e, 0x01, 0x96, 0xf1, 0x74, 0xee, 0xda, 0xe6, 0x35, 0x59, 0x89, 0xd4, 0x34, 0x39,
0xeb, 0x27, 0xbb, 0x9c, 0x49, 0x1b, 0x42, 0xfa, 0xa8, 0x85, 0x5e, 0x18, 0xf1, 0x22, 0xc6, 0x88, 0xe7, 0x0d, 0x59, 0xa1, 0xa7, 0xd0, 0x72, 0xdc, 0x70, 0x39, 0xb7, 0x56, 0x66, 0xae, 0xcf, 0x49,
0xfc, 0xdc, 0x9d, 0x8f, 0x38, 0x37, 0xfa, 0x19, 0xb4, 0xcf, 0x49, 0x79, 0x89, 0xe8, 0xdd, 0xfa, 0x82, 0xc7, 0x8a, 0xf1, 0xc3, 0x81, 0x7d, 0x09, 0x55, 0xd7, 0xf6, 0x3d, 0x16, 0x4b, 0x69, 0xdb,
0x16, 0x6a, 0x5c, 0x9c, 0x54, 0x9c, 0xcd, 0x38, 0xb3, 0x3a, 0x95, 0xc3, 0xc5, 0x48, 0x33, 0x4d, 0xb9, 0xd2, 0x52, 0xc1, 0x4c, 0x58, 0xf9, 0x73, 0x19, 0xbe, 0xb3, 0xee, 0xf6, 0x62, 0x11, 0x7b,
0xf3, 0xe2, 0x23, 0x72, 0xde, 0x22, 0x75, 0xe9, 0x45, 0xc4, 0x7e, 0xf8, 0x1b, 0x37, 0xbb, 0x37, 0x6e, 0xb4, 0x62, 0x8e, 0x3f, 0xa5, 0x80, 0x47, 0x30, 0x4c, 0x37, 0xa9, 0x2a, 0x29, 0xe5, 0xe9,
0x94, 0xb8, 0x06, 0x62, 0xe3, 0x83, 0x20, 0x36, 0xaf, 0x83, 0xb8, 0x1d, 0x9f, 0x11, 0x08, 0x79, 0xce, 0xb7, 0xe3, 0xfc, 0x33, 0x68, 0x2f, 0xc8, 0x62, 0x4a, 0x82, 0x04, 0xfc, 0x72, 0xdc, 0xdc,
0xb8, 0xf8, 0xfb, 0xf9, 0xf9, 0xae, 0xd6, 0xa9, 0x12, 0x7c, 0xbd, 0xd0, 0x93, 0xff, 0x57, 0x03, 0x12, 0x4c, 0x06, 0x7c, 0xd9, 0xe3, 0xed, 0xcf, 0xfd, 0x40, 0x5c, 0x2b, 0x4e, 0xa4, 0xe7, 0x6e,
0x74, 0xbd, 0xcb, 0xda, 0x52, 0x16, 0xbe, 0x62, 0x8f, 0xb8, 0x65, 0xb3, 0xc6, 0x56, 0x3c, 0x7d, 0x7c, 0xc4, 0xb9, 0xd1, 0x4f, 0xa0, 0x3e, 0xa5, 0x6d, 0x34, 0x60, 0x3d, 0xe4, 0x1b, 0xa8, 0x09,
0xb2, 0xfb, 0x5b, 0xf9, 0xfd, 0x78, 0x7d, 0x4b, 0xcf, 0xb4, 0x90, 0x5a, 0x76, 0xb7, 0xf1, 0x11, 0x71, 0xda, 0x59, 0xd7, 0xf3, 0xcc, 0xfb, 0x71, 0x1a, 0x2e, 0x4e, 0x9a, 0x71, 0x9c, 0x36, 0x59,
0xee, 0xbe, 0xbe, 0x55, 0x72, 0x98, 0xfa, 0xc1, 0x50, 0xe7, 0x17, 0x62, 0xb7, 0x1f, 0x45, 0xfc, 0x49, 0xf0, 0x26, 0xb1, 0xcb, 0x2e, 0x22, 0x59, 0xf8, 0xbf, 0x76, 0x93, 0x7b, 0xc3, 0x88, 0x1b,
0xa8, 0x1f, 0x8c, 0x7c, 0x21, 0xe4, 0xa5, 0x54, 0xbe, 0x84, 0x3b, 0x5b, 0x3a, 0x4c, 0x34, 0xdb, 0x41, 0xac, 0x7c, 0x30, 0x88, 0xd5, 0x9b, 0x41, 0xdc, 0x1c, 0x9f, 0x1e, 0x34, 0xd3, 0x74, 0x09,
0xd5, 0x9f, 0xd6, 0x68, 0x9b, 0xf0, 0xf0, 0xa6, 0xfe, 0x74, 0x7b, 0x7b, 0xfa, 0x2f, 0x00, 0xb1, 0x9c, 0xf0, 0xd9, 0x36, 0x88, 0x58, 0x48, 0x3e, 0xce, 0xf4, 0x94, 0xff, 0x95, 0x00, 0xdd, 0x44,
0xd4, 0x59, 0xef, 0xe8, 0xe2, 0x2a, 0xfd, 0x56, 0x9d, 0xee, 0x94, 0xfa, 0xad, 0x6c, 0xac, 0x68, 0x93, 0x1b, 0xda, 0xc2, 0x97, 0xbc, 0xf9, 0x59, 0x36, 0x07, 0xf0, 0xd2, 0xe9, 0xb3, 0xed, 0xdf,
0x94, 0xc6, 0x8a, 0x47, 0x20, 0x46, 0x38, 0x5e, 0x85, 0x41, 0x8c, 0xcd, 0x24, 0xe4, 0xa9, 0x03, 0x4a, 0xef, 0xc7, 0xf9, 0x0e, 0x4e, 0xb4, 0x90, 0x96, 0x77, 0xb7, 0xf2, 0x11, 0xee, 0x9e, 0xef,
0x19, 0xcb, 0x08, 0xc9, 0x84, 0x87, 0x83, 0x98, 0xa5, 0x1e, 0xef, 0xbd, 0x70, 0x10, 0xd3, 0xb4, 0xe4, 0x1c, 0x66, 0x7e, 0xf0, 0xa8, 0x8b, 0x0b, 0xb1, 0xdd, 0x8f, 0x2c, 0x7f, 0xcc, 0x0f, 0x4e,
0x2b, 0xb5, 0xc2, 0xed, 0x4a, 0x2b, 0xbc, 0xd9, 0xd5, 0x76, 0x3e, 0x79, 0xba, 0xd8, 0xfb, 0xa4, 0x9e, 0x35, 0xd3, 0x56, 0xaa, 0x5c, 0xc1, 0xdd, 0x0d, 0x48, 0x1a, 0x8d, 0xb6, 0xe1, 0xf0, 0x12,
0xe9, 0xe2, 0x0b, 0xe8, 0xc4, 0x6c, 0x52, 0xe6, 0x03, 0xc1, 0xa0, 0x30, 0x50, 0x1d, 0xa1, 0x49, 0x83, 0x43, 0x8f, 0x6e, 0xc3, 0xe1, 0x9b, 0x61, 0xf8, 0x9f, 0x24, 0x90, 0x72, 0x13, 0xc4, 0x16,
0x58, 0xb9, 0x28, 0x3a, 0x81, 0x16, 0x1d, 0x3e, 0x07, 0x40, 0x75, 0x0e, 0x37, 0x26, 0xdf, 0x42, 0xb4, 0x5a, 0xc0, 0x95, 0x65, 0xb6, 0x93, 0xc3, 0x95, 0xc9, 0xf8, 0x54, 0xc9, 0x8d, 0x4f, 0x4f,
0x83, 0x89, 0x11, 0x79, 0x8b, 0x8c, 0x80, 0x03, 0x71, 0x53, 0xbe, 0x3c, 0x5a, 0x12, 0x79, 0x2a, 0x40, 0x0a, 0x48, 0xb8, 0xf4, 0xbd, 0x90, 0x98, 0x91, 0x2f, 0x4a, 0x07, 0x12, 0x96, 0xe1, 0xd3,
0x86, 0x3e, 0x2b, 0xa7, 0x6f, 0x97, 0x54, 0xcb, 0x6a, 0x5e, 0x8e, 0x60, 0xdf, 0x61, 0x0d, 0x4b, 0x49, 0x96, 0x78, 0x21, 0x2f, 0x3d, 0xf1, 0x66, 0x11, 0x2f, 0x64, 0x65, 0x97, 0x83, 0xfc, 0xf5,
0xf6, 0x5f, 0xc1, 0xc0, 0xde, 0xf4, 0xbe, 0xda, 0xd1, 0xbc, 0xbe, 0xa5, 0xf7, 0x9d, 0x6a, 0x57, 0x02, 0xe4, 0x5f, 0x47, 0xef, 0x8d, 0x4f, 0x9e, 0xa2, 0x76, 0x3f, 0x69, 0x8a, 0xfa, 0x1c, 0x1a,
0x9e, 0x8f, 0x19, 0xbd, 0xf2, 0x98, 0xb1, 0x59, 0x43, 0xfa, 0xd7, 0x6b, 0xc8, 0x0a, 0x86, 0xfc, 0x21, 0xff, 0x47, 0x40, 0x0c, 0x3e, 0xdd, 0xcc, 0x40, 0xf1, 0xaf, 0x02, 0x9a, 0x56, 0x21, 0x8a,
0x9e, 0x99, 0x11, 0xfe, 0x6d, 0x8a, 0xe3, 0xc4, 0x5c, 0x45, 0xe1, 0xca, 0xba, 0xb4, 0x12, 0x9e, 0x4e, 0xa0, 0xc6, 0x86, 0xec, 0x2e, 0x30, 0x9d, 0x83, 0xb5, 0x09, 0x3f, 0xd3, 0xe0, 0x62, 0x54,
0xc4, 0x78, 0xb0, 0x4f, 0xdd, 0x79, 0x56, 0x8a, 0x06, 0xd3, 0xd0, 0x99, 0xc2, 0x2c, 0x97, 0x27, 0xde, 0xa2, 0xa3, 0x6e, 0x57, 0x5a, 0x97, 0xcf, 0x8f, 0xd0, 0x54, 0x9e, 0x89, 0xa1, 0xc7, 0xf9,
0x99, 0x8b, 0xf5, 0x23, 0xfb, 0xa6, 0xed, 0x2d, 0x33, 0xa0, 0xf4, 0x31, 0x33, 0xe0, 0xe7, 0xd0, 0xf2, 0x6d, 0xd1, 0x6e, 0x59, 0xac, 0xcb, 0x1e, 0xec, 0x39, 0x1c, 0x98, 0x25, 0xff, 0x89, 0x74,
0xa2, 0xff, 0x8e, 0x0c, 0x6e, 0x53, 0xaf, 0xf6, 0x4b, 0x21, 0x26, 0x6c, 0x9d, 0xed, 0xee, 0x1e, 0xed, 0x75, 0xef, 0x8b, 0xc8, 0xed, 0x7c, 0x07, 0x77, 0x9c, 0xe2, 0xf4, 0xf1, 0x73, 0xe8, 0x70,
0x15, 0xd1, 0x27, 0x8f, 0x8a, 0x7f, 0x6f, 0x80, 0x38, 0xaa, 0x74, 0x6a, 0x07, 0xd9, 0xf8, 0x3f, 0x0c, 0x93, 0xda, 0x70, 0x98, 0x8d, 0xfb, 0x99, 0x8d, 0x02, 0x0c, 0x3a, 0xdf, 0xc1, 0xed, 0x69,
0x3a, 0x9b, 0x1a, 0xea, 0xd4, 0xc8, 0xfe, 0x00, 0xe8, 0x03, 0x18, 0xea, 0xaf, 0x0c, 0x73, 0xf6, 0x01, 0x17, 0xa5, 0x03, 0x59, 0x3b, 0x3f, 0x90, 0xad, 0x77, 0xa1, 0xce, 0xcd, 0x2e, 0xb4, 0x84,
0x56, 0xd1, 0xa6, 0x52, 0x0d, 0x89, 0xd0, 0x99, 0x1b, 0xda, 0xe8, 0x8d, 0xaa, 0x4b, 0x75, 0x04, 0x23, 0x71, 0x53, 0xcd, 0x80, 0xfc, 0x26, 0x26, 0x61, 0x64, 0x2e, 0x03, 0x7f, 0x69, 0x5d, 0x59,
0xd0, 0x9e, 0x1b, 0x8a, 0xb1, 0x98, 0x4b, 0x0d, 0xd2, 0x2e, 0xa8, 0x93, 0xb3, 0x5f, 0x6a, 0x52, 0x91, 0xb8, 0x06, 0xa4, 0xbb, 0xc7, 0x9c, 0x79, 0x91, 0xcb, 0x27, 0xd7, 0xc0, 0x5c, 0x61, 0x94,
0x13, 0xdd, 0x83, 0x3b, 0x86, 0xae, 0x4c, 0xe7, 0xca, 0xc8, 0xd0, 0xce, 0x88, 0xc5, 0xc9, 0x44, 0xca, 0xd3, 0xda, 0x27, 0xf8, 0xd0, 0xbe, 0x6d, 0x7b, 0xc3, 0xb4, 0x2c, 0x7f, 0xcc, 0xb4, 0xfc,
0x99, 0x8e, 0xa5, 0x16, 0x3a, 0x86, 0xa7, 0xf3, 0xf7, 0x73, 0x43, 0x9d, 0x98, 0x13, 0x75, 0x3e, 0x19, 0xd4, 0xd8, 0xff, 0x48, 0xdd, 0x3b, 0xcc, 0xab, 0xbd, 0x5c, 0x91, 0x50, 0x36, 0xe6, 0xbb,
0x57, 0x5e, 0xa9, 0xf9, 0xd7, 0x66, 0xba, 0xf6, 0x4e, 0x31, 0x54, 0xf3, 0x95, 0x7e, 0xb6, 0x98, 0xdb, 0x87, 0x6a, 0xf4, 0xc9, 0x43, 0xf5, 0x3f, 0x2b, 0x20, 0xf5, 0x0a, 0x98, 0x76, 0x3f, 0xf9,
0x49, 0xed, 0xa2, 0xf9, 0xe8, 0x90, 0x25, 0xfd, 0x4b, 0x42, 0xda, 0x43, 0x3d, 0x10, 0x88, 0xb1, 0xa3, 0xa4, 0x77, 0x31, 0x34, 0xb4, 0xa1, 0x91, 0xfc, 0x55, 0xd2, 0x01, 0x30, 0xb4, 0x5f, 0x1a,
0xc5, 0x54, 0x33, 0xde, 0x4b, 0x02, 0x3a, 0x04, 0xb4, 0x61, 0xee, 0x95, 0x32, 0x93, 0x00, 0xdd, 0xe6, 0xe8, 0xad, 0xaa, 0x0f, 0xe5, 0x12, 0x92, 0xa0, 0x31, 0x36, 0xf4, 0xde, 0x1b, 0x0d, 0xcb,
0x81, 0x7d, 0x62, 0x57, 0x19, 0x19, 0xa6, 0xae, 0x7e, 0xbd, 0x50, 0xe7, 0x86, 0x24, 0x12, 0xe6, 0x65, 0x04, 0x50, 0x1f, 0x1b, 0xaa, 0x31, 0x19, 0xcb, 0x15, 0x0a, 0x38, 0xb4, 0xc1, 0xc5, 0x2f,
0x58, 0x9b, 0x8f, 0xce, 0xf4, 0x71, 0x26, 0x2d, 0x75, 0xd1, 0x7d, 0xb8, 0xab, 0x8d, 0xd5, 0xa9, 0x74, 0xb9, 0x8a, 0xee, 0xc3, 0x5d, 0x03, 0xab, 0xc3, 0xb1, 0xda, 0x33, 0xf4, 0x0b, 0x6a, 0x71,
0xa1, 0x19, 0xef, 0xcd, 0x77, 0xaa, 0xae, 0xbd, 0xd4, 0x46, 0x0a, 0xf1, 0x59, 0xea, 0xa1, 0xc7, 0x30, 0x50, 0x87, 0x7d, 0xb9, 0x86, 0x8e, 0xe1, 0xf9, 0xf8, 0xfd, 0xd8, 0xd0, 0x06, 0xe6, 0x40,
0x70, 0xb4, 0x61, 0x7c, 0xa6, 0x4d, 0xa7, 0x6a, 0xa1, 0xdd, 0x47, 0x4f, 0x61, 0xb8, 0x21, 0x32, 0x1b, 0x8f, 0xd5, 0xd7, 0x5a, 0xfa, 0xb5, 0x11, 0xd6, 0xdf, 0xa9, 0x86, 0x66, 0xbe, 0xc6, 0x17,
0x59, 0x18, 0x0b, 0xe5, 0xad, 0xa9, 0xbe, 0x23, 0x67, 0x9a, 0xab, 0x53, 0x43, 0xda, 0xdf, 0x72, 0x93, 0x91, 0x5c, 0xcf, 0xe0, 0x4b, 0x83, 0x2e, 0xd9, 0x9f, 0x37, 0xf2, 0x2e, 0x6a, 0x43, 0x93,
0xe8, 0x8a, 0x94, 0x32, 0x1a, 0xa9, 0x33, 0x43, 0x1d, 0x4b, 0x12, 0x7a, 0x06, 0x4f, 0x6e, 0x92, 0x1a, 0x9b, 0x0c, 0x75, 0xe3, 0xbd, 0xdc, 0x44, 0x07, 0x80, 0xd6, 0xcc, 0xbd, 0x56, 0x47, 0x32,
0xd4, 0xd5, 0xc9, 0xd9, 0x3b, 0x75, 0x2c, 0xdd, 0x2e, 0x95, 0xef, 0x17, 0xbd, 0x5f, 0x8b, 0x27, 0xa0, 0xbb, 0xb0, 0x47, 0xed, 0xaa, 0x3d, 0xc3, 0xc4, 0xda, 0x57, 0x13, 0x6d, 0x6c, 0xc8, 0x12,
0x3f, 0xfe, 0x79, 0x96, 0x01, 0xe7, 0x6d, 0xba, 0x7a, 0xfe, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0x65, 0xf6, 0xf5, 0x71, 0xef, 0x02, 0xf7, 0x13, 0x69, 0xb9, 0x85, 0x1e, 0xc0, 0x3d, 0xbd, 0xaf,
0x7a, 0x8b, 0x01, 0x4b, 0xb1, 0x13, 0x00, 0x00, 0x0d, 0x0d, 0xdd, 0x78, 0x6f, 0xbe, 0xd3, 0xb0, 0xfe, 0x4a, 0xef, 0xa9, 0xd4, 0x67, 0xb9, 0x8d,
0x9e, 0xc2, 0xe1, 0x9a, 0xf1, 0x91, 0x3e, 0x1c, 0x6a, 0x99, 0x76, 0x07, 0x3d, 0x87, 0xa3, 0x35,
0x91, 0xc1, 0xc4, 0x98, 0xa8, 0x6f, 0x4d, 0xed, 0x1d, 0x3d, 0xd3, 0x58, 0x1b, 0x1a, 0xf2, 0xde,
0x86, 0x43, 0x17, 0xa4, 0xd4, 0x5e, 0x4f, 0x1b, 0x19, 0x5a, 0x5f, 0x96, 0xd1, 0x0b, 0x78, 0x76,
0x9b, 0x24, 0xd6, 0x06, 0x17, 0xef, 0xb4, 0xbe, 0x7c, 0x07, 0x21, 0xe8, 0x9c, 0x61, 0xbd, 0x4f,
0x05, 0x84, 0x33, 0x28, 0xf7, 0x28, 0x9c, 0xb5, 0x7f, 0x25, 0x9d, 0xfc, 0xf0, 0xa7, 0x49, 0x55,
0x4c, 0xeb, 0x6c, 0xf5, 0xf2, 0xff, 0x01, 0x00, 0x00, 0xff, 0xff, 0xb2, 0xe8, 0x1f, 0x95, 0xef,
0x14, 0x00, 0x00,
} }

View File

@ -109,6 +109,16 @@ message DiscordMessageAttachment {
string localUrl = 8; string localUrl = 8;
} }
message BridgeMessage {
string bridgeName = 1;
string userName = 2;
string userAvatar = 3;
string userID = 4;
string content = 5;
string messageID = 6;
string parentMessageID = 7;
}
message UnfurledLinkThumbnail { message UnfurledLinkThumbnail {
bytes payload = 1; bytes payload = 1;
uint32 width = 2; uint32 width = 2;
@ -204,6 +214,7 @@ message ChatMessage {
AudioMessage audio = 11; AudioMessage audio = 11;
bytes community = 12; bytes community = 12;
DiscordMessage discord_message = 99; DiscordMessage discord_message = 99;
BridgeMessage bridge_message = 100;
} }
// Grant for community chat messages // Grant for community chat messages
@ -245,5 +256,6 @@ message ChatMessage {
SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED = 16; SYSTEM_MESSAGE_MUTUAL_EVENT_ACCEPTED = 16;
// Only local // Only local
SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED = 17; SYSTEM_MESSAGE_MUTUAL_EVENT_REMOVED = 17;
BRIDGE_MESSAGE = 18;
} }
} }

View File

@ -88,7 +88,7 @@ func _1561059284_add_waku_keysDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561059284_add_waku_keys.down.sql", size: 22, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1561059284_add_waku_keys.down.sql", size: 22, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe5, 0x2a, 0x7e, 0x9, 0xa3, 0xdd, 0xc6, 0x3, 0xfa, 0xaa, 0x98, 0xa0, 0x26, 0x5e, 0x67, 0x43, 0xe6, 0x20, 0xfd, 0x10, 0xfd, 0x60, 0x89, 0x17, 0x13, 0x87, 0x1b, 0x44, 0x36, 0x79, 0xb6, 0x60}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xe5, 0x2a, 0x7e, 0x9, 0xa3, 0xdd, 0xc6, 0x3, 0xfa, 0xaa, 0x98, 0xa0, 0x26, 0x5e, 0x67, 0x43, 0xe6, 0x20, 0xfd, 0x10, 0xfd, 0x60, 0x89, 0x17, 0x13, 0x87, 0x1b, 0x44, 0x36, 0x79, 0xb6, 0x60}}
return a, nil return a, nil
} }
@ -108,7 +108,7 @@ func _1561059284_add_waku_keysUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1561059284_add_waku_keys.up.sql", size: 109, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1561059284_add_waku_keys.up.sql", size: 109, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa9, 0x5c, 0x8, 0x32, 0xef, 0x12, 0x88, 0x21, 0xd, 0x7a, 0x42, 0x4d, 0xe7, 0x2d, 0x6c, 0x99, 0xb6, 0x1, 0xf1, 0xba, 0x2c, 0x40, 0x8d, 0xa9, 0x4b, 0xe6, 0xc4, 0x21, 0xec, 0x47, 0x6b, 0xf7}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0xa9, 0x5c, 0x8, 0x32, 0xef, 0x12, 0x88, 0x21, 0xd, 0x7a, 0x42, 0x4d, 0xe7, 0x2d, 0x6c, 0x99, 0xb6, 0x1, 0xf1, 0xba, 0x2c, 0x40, 0x8d, 0xa9, 0x4b, 0xe6, 0xc4, 0x21, 0xec, 0x47, 0x6b, 0xf7}}
return a, nil return a, nil
} }
@ -128,7 +128,7 @@ func _1616691080_add_wakuv2_keysDownSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1616691080_add_wakuV2_keys.down.sql", size: 24, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1616691080_add_wakuV2_keys.down.sql", size: 24, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x42, 0xb6, 0x23, 0x70, 0xb8, 0x63, 0x18, 0x61, 0xea, 0x35, 0x6e, 0xae, 0xe9, 0x71, 0x89, 0xa, 0xa5, 0x72, 0xa2, 0x64, 0xaa, 0x45, 0x1, 0xf, 0xfc, 0xee, 0x1b, 0xd9, 0xd2, 0x27, 0xf4, 0xe2}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x42, 0xb6, 0x23, 0x70, 0xb8, 0x63, 0x18, 0x61, 0xea, 0x35, 0x6e, 0xae, 0xe9, 0x71, 0x89, 0xa, 0xa5, 0x72, 0xa2, 0x64, 0xaa, 0x45, 0x1, 0xf, 0xfc, 0xee, 0x1b, 0xd9, 0xd2, 0x27, 0xf4, 0xe2}}
return a, nil return a, nil
} }
@ -148,7 +148,7 @@ func _1616691080_add_wakuv2_keysUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1616691080_add_wakuV2_keys.up.sql", size: 111, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1616691080_add_wakuV2_keys.up.sql", size: 111, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x10, 0xf0, 0x97, 0x25, 0xfe, 0x96, 0x2c, 0xa8, 0x62, 0x4a, 0x71, 0x75, 0xff, 0x5f, 0x43, 0x1e, 0x71, 0x53, 0xf1, 0xde, 0xf, 0xcf, 0xcd, 0x87, 0x15, 0x61, 0x9d, 0x25, 0x2e, 0xaf, 0x18, 0x99}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x10, 0xf0, 0x97, 0x25, 0xfe, 0x96, 0x2c, 0xa8, 0x62, 0x4a, 0x71, 0x75, 0xff, 0x5f, 0x43, 0x1e, 0x71, 0x53, 0xf1, 0xde, 0xf, 0xcf, 0xcd, 0x87, 0x15, 0x61, 0x9d, 0x25, 0x2e, 0xaf, 0x18, 0x99}}
return a, nil return a, nil
} }
@ -168,7 +168,7 @@ func _1634723014_add_wakuv2_keysUpSql() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "1634723014_add_wakuV2_keys.up.sql", size: 125, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "1634723014_add_wakuV2_keys.up.sql", size: 125, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7e, 0xe1, 0x7a, 0x1e, 0x6, 0xad, 0x1b, 0x37, 0xdb, 0xea, 0x94, 0xaf, 0xe0, 0x7d, 0xc9, 0xd6, 0xda, 0x52, 0x71, 0x8a, 0x44, 0xb3, 0xa6, 0x7b, 0x1e, 0x90, 0xdb, 0x1e, 0x5a, 0xa, 0x40, 0x26}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x7e, 0xe1, 0x7a, 0x1e, 0x6, 0xad, 0x1b, 0x37, 0xdb, 0xea, 0x94, 0xaf, 0xe0, 0x7d, 0xc9, 0xd6, 0xda, 0x52, 0x71, 0x8a, 0x44, 0xb3, 0xa6, 0x7b, 0x1e, 0x90, 0xdb, 0x1e, 0x5a, 0xa, 0x40, 0x26}}
return a, nil return a, nil
} }
@ -188,7 +188,7 @@ func docGo() (*asset, error) {
return nil, err return nil, err
} }
info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1704739012, 0)} info := bindataFileInfo{name: "doc.go", size: 373, mode: os.FileMode(0644), modTime: time.Unix(1706102358, 0)}
a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}} a := &asset{bytes: bytes, info: info, digest: [32]uint8{0x23, 0x6a, 0xc1, 0xce, 0x94, 0xf6, 0xef, 0xf1, 0x97, 0x95, 0xb, 0x35, 0xaf, 0x5f, 0xe7, 0x5f, 0xac, 0x6e, 0xb8, 0xab, 0xba, 0xb5, 0x35, 0x97, 0x22, 0x36, 0x11, 0xce, 0x44, 0xfc, 0xfa, 0xac}}
return a, nil return a, nil
} }