diff --git a/api/api.pb.go b/api/api.pb.go index 32d4a1ca3..565f77b76 100644 --- a/api/api.pb.go +++ b/api/api.pb.go @@ -55,7 +55,7 @@ func (x Friend_State) String() string { } func (Friend_State) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{27, 0} + return fileDescriptor_1b40cafcd4234784, []int{28, 0} } // The group role status. @@ -91,7 +91,7 @@ func (x GroupUserList_GroupUser_State) String() string { } func (GroupUserList_GroupUser_State) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{32, 0, 0} + return fileDescriptor_1b40cafcd4234784, []int{33, 0, 0} } // The group role status. @@ -127,7 +127,7 @@ func (x UserGroupList_UserGroup_State) String() string { } func (UserGroupList_UserGroup_State) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{73, 0, 0} + return fileDescriptor_1b40cafcd4234784, []int{74, 0, 0} } // A user with additional account details. Always the current user. @@ -1651,6 +1651,65 @@ func (m *DeleteStorageObjectsRequest) GetObjectIds() []*DeleteStorageObjectId { return nil } +// Represents an event to be passed through the server to registered event handlers. +type Event struct { + // An event name, type, category, or identifier. + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + // Arbitrary event property values. + Properties map[string]string `protobuf:"bytes,2,rep,name=properties,proto3" json:"properties,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + // The time when the event was triggered. + Timestamp *timestamp.Timestamp `protobuf:"bytes,3,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Event) Reset() { *m = Event{} } +func (m *Event) String() string { return proto.CompactTextString(m) } +func (*Event) ProtoMessage() {} +func (*Event) Descriptor() ([]byte, []int) { + return fileDescriptor_1b40cafcd4234784, []int{27} +} + +func (m *Event) XXX_Unmarshal(b []byte) error { + return xxx_messageInfo_Event.Unmarshal(m, b) +} +func (m *Event) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + return xxx_messageInfo_Event.Marshal(b, m, deterministic) +} +func (m *Event) XXX_Merge(src proto.Message) { + xxx_messageInfo_Event.Merge(m, src) +} +func (m *Event) XXX_Size() int { + return xxx_messageInfo_Event.Size(m) +} +func (m *Event) XXX_DiscardUnknown() { + xxx_messageInfo_Event.DiscardUnknown(m) +} + +var xxx_messageInfo_Event proto.InternalMessageInfo + +func (m *Event) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Event) GetProperties() map[string]string { + if m != nil { + return m.Properties + } + return nil +} + +func (m *Event) GetTimestamp() *timestamp.Timestamp { + if m != nil { + return m.Timestamp + } + return nil +} + // A friend of a user. type Friend struct { // The user object. @@ -1666,7 +1725,7 @@ func (m *Friend) Reset() { *m = Friend{} } func (m *Friend) String() string { return proto.CompactTextString(m) } func (*Friend) ProtoMessage() {} func (*Friend) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{27} + return fileDescriptor_1b40cafcd4234784, []int{28} } func (m *Friend) XXX_Unmarshal(b []byte) error { @@ -1714,7 +1773,7 @@ func (m *Friends) Reset() { *m = Friends{} } func (m *Friends) String() string { return proto.CompactTextString(m) } func (*Friends) ProtoMessage() {} func (*Friends) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{28} + return fileDescriptor_1b40cafcd4234784, []int{29} } func (m *Friends) XXX_Unmarshal(b []byte) error { @@ -1759,7 +1818,7 @@ func (m *GetUsersRequest) Reset() { *m = GetUsersRequest{} } func (m *GetUsersRequest) String() string { return proto.CompactTextString(m) } func (*GetUsersRequest) ProtoMessage() {} func (*GetUsersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{29} + return fileDescriptor_1b40cafcd4234784, []int{30} } func (m *GetUsersRequest) XXX_Unmarshal(b []byte) error { @@ -1836,7 +1895,7 @@ func (m *Group) Reset() { *m = Group{} } func (m *Group) String() string { return proto.CompactTextString(m) } func (*Group) ProtoMessage() {} func (*Group) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{30} + return fileDescriptor_1b40cafcd4234784, []int{31} } func (m *Group) XXX_Unmarshal(b []byte) error { @@ -1956,7 +2015,7 @@ func (m *GroupList) Reset() { *m = GroupList{} } func (m *GroupList) String() string { return proto.CompactTextString(m) } func (*GroupList) ProtoMessage() {} func (*GroupList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{31} + return fileDescriptor_1b40cafcd4234784, []int{32} } func (m *GroupList) XXX_Unmarshal(b []byte) error { @@ -2004,7 +2063,7 @@ func (m *GroupUserList) Reset() { *m = GroupUserList{} } func (m *GroupUserList) String() string { return proto.CompactTextString(m) } func (*GroupUserList) ProtoMessage() {} func (*GroupUserList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{32} + return fileDescriptor_1b40cafcd4234784, []int{33} } func (m *GroupUserList) XXX_Unmarshal(b []byte) error { @@ -2047,7 +2106,7 @@ func (m *GroupUserList_GroupUser) Reset() { *m = GroupUserList_GroupUser func (m *GroupUserList_GroupUser) String() string { return proto.CompactTextString(m) } func (*GroupUserList_GroupUser) ProtoMessage() {} func (*GroupUserList_GroupUser) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{32, 0} + return fileDescriptor_1b40cafcd4234784, []int{33, 0} } func (m *GroupUserList_GroupUser) XXX_Unmarshal(b []byte) error { @@ -2097,7 +2156,7 @@ func (m *ImportFacebookFriendsRequest) Reset() { *m = ImportFacebookFrie func (m *ImportFacebookFriendsRequest) String() string { return proto.CompactTextString(m) } func (*ImportFacebookFriendsRequest) ProtoMessage() {} func (*ImportFacebookFriendsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{33} + return fileDescriptor_1b40cafcd4234784, []int{34} } func (m *ImportFacebookFriendsRequest) XXX_Unmarshal(b []byte) error { @@ -2145,7 +2204,7 @@ func (m *JoinGroupRequest) Reset() { *m = JoinGroupRequest{} } func (m *JoinGroupRequest) String() string { return proto.CompactTextString(m) } func (*JoinGroupRequest) ProtoMessage() {} func (*JoinGroupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{34} + return fileDescriptor_1b40cafcd4234784, []int{35} } func (m *JoinGroupRequest) XXX_Unmarshal(b []byte) error { @@ -2186,7 +2245,7 @@ func (m *JoinTournamentRequest) Reset() { *m = JoinTournamentRequest{} } func (m *JoinTournamentRequest) String() string { return proto.CompactTextString(m) } func (*JoinTournamentRequest) ProtoMessage() {} func (*JoinTournamentRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{35} + return fileDescriptor_1b40cafcd4234784, []int{36} } func (m *JoinTournamentRequest) XXX_Unmarshal(b []byte) error { @@ -2229,7 +2288,7 @@ func (m *KickGroupUsersRequest) Reset() { *m = KickGroupUsersRequest{} } func (m *KickGroupUsersRequest) String() string { return proto.CompactTextString(m) } func (*KickGroupUsersRequest) ProtoMessage() {} func (*KickGroupUsersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{36} + return fileDescriptor_1b40cafcd4234784, []int{37} } func (m *KickGroupUsersRequest) XXX_Unmarshal(b []byte) error { @@ -2299,7 +2358,7 @@ func (m *LeaderboardRecord) Reset() { *m = LeaderboardRecord{} } func (m *LeaderboardRecord) String() string { return proto.CompactTextString(m) } func (*LeaderboardRecord) ProtoMessage() {} func (*LeaderboardRecord) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{37} + return fileDescriptor_1b40cafcd4234784, []int{38} } func (m *LeaderboardRecord) XXX_Unmarshal(b []byte) error { @@ -2423,7 +2482,7 @@ func (m *LeaderboardRecordList) Reset() { *m = LeaderboardRecordList{} } func (m *LeaderboardRecordList) String() string { return proto.CompactTextString(m) } func (*LeaderboardRecordList) ProtoMessage() {} func (*LeaderboardRecordList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{38} + return fileDescriptor_1b40cafcd4234784, []int{39} } func (m *LeaderboardRecordList) XXX_Unmarshal(b []byte) error { @@ -2485,7 +2544,7 @@ func (m *LeaveGroupRequest) Reset() { *m = LeaveGroupRequest{} } func (m *LeaveGroupRequest) String() string { return proto.CompactTextString(m) } func (*LeaveGroupRequest) ProtoMessage() {} func (*LeaveGroupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{39} + return fileDescriptor_1b40cafcd4234784, []int{40} } func (m *LeaveGroupRequest) XXX_Unmarshal(b []byte) error { @@ -2528,7 +2587,7 @@ func (m *LinkFacebookRequest) Reset() { *m = LinkFacebookRequest{} } func (m *LinkFacebookRequest) String() string { return proto.CompactTextString(m) } func (*LinkFacebookRequest) ProtoMessage() {} func (*LinkFacebookRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{40} + return fileDescriptor_1b40cafcd4234784, []int{41} } func (m *LinkFacebookRequest) XXX_Unmarshal(b []byte) error { @@ -2582,7 +2641,7 @@ func (m *ListChannelMessagesRequest) Reset() { *m = ListChannelMessagesR func (m *ListChannelMessagesRequest) String() string { return proto.CompactTextString(m) } func (*ListChannelMessagesRequest) ProtoMessage() {} func (*ListChannelMessagesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{41} + return fileDescriptor_1b40cafcd4234784, []int{42} } func (m *ListChannelMessagesRequest) XXX_Unmarshal(b []byte) error { @@ -2648,7 +2707,7 @@ func (m *ListGroupsRequest) Reset() { *m = ListGroupsRequest{} } func (m *ListGroupsRequest) String() string { return proto.CompactTextString(m) } func (*ListGroupsRequest) ProtoMessage() {} func (*ListGroupsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{42} + return fileDescriptor_1b40cafcd4234784, []int{43} } func (m *ListGroupsRequest) XXX_Unmarshal(b []byte) error { @@ -2703,7 +2762,7 @@ func (m *ListGroupUsersRequest) Reset() { *m = ListGroupUsersRequest{} } func (m *ListGroupUsersRequest) String() string { return proto.CompactTextString(m) } func (*ListGroupUsersRequest) ProtoMessage() {} func (*ListGroupUsersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{43} + return fileDescriptor_1b40cafcd4234784, []int{44} } func (m *ListGroupUsersRequest) XXX_Unmarshal(b []byte) error { @@ -2750,7 +2809,7 @@ func (m *ListLeaderboardRecordsAroundOwnerRequest) Reset() { func (m *ListLeaderboardRecordsAroundOwnerRequest) String() string { return proto.CompactTextString(m) } func (*ListLeaderboardRecordsAroundOwnerRequest) ProtoMessage() {} func (*ListLeaderboardRecordsAroundOwnerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{44} + return fileDescriptor_1b40cafcd4234784, []int{45} } func (m *ListLeaderboardRecordsAroundOwnerRequest) XXX_Unmarshal(b []byte) error { @@ -2811,7 +2870,7 @@ func (m *ListLeaderboardRecordsRequest) Reset() { *m = ListLeaderboardRe func (m *ListLeaderboardRecordsRequest) String() string { return proto.CompactTextString(m) } func (*ListLeaderboardRecordsRequest) ProtoMessage() {} func (*ListLeaderboardRecordsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{45} + return fileDescriptor_1b40cafcd4234784, []int{46} } func (m *ListLeaderboardRecordsRequest) XXX_Unmarshal(b []byte) error { @@ -2883,7 +2942,7 @@ func (m *ListMatchesRequest) Reset() { *m = ListMatchesRequest{} } func (m *ListMatchesRequest) String() string { return proto.CompactTextString(m) } func (*ListMatchesRequest) ProtoMessage() {} func (*ListMatchesRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{46} + return fileDescriptor_1b40cafcd4234784, []int{47} } func (m *ListMatchesRequest) XXX_Unmarshal(b []byte) error { @@ -2961,7 +3020,7 @@ func (m *ListNotificationsRequest) Reset() { *m = ListNotificationsReque func (m *ListNotificationsRequest) String() string { return proto.CompactTextString(m) } func (*ListNotificationsRequest) ProtoMessage() {} func (*ListNotificationsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{47} + return fileDescriptor_1b40cafcd4234784, []int{48} } func (m *ListNotificationsRequest) XXX_Unmarshal(b []byte) error { @@ -3015,7 +3074,7 @@ func (m *ListStorageObjectsRequest) Reset() { *m = ListStorageObjectsReq func (m *ListStorageObjectsRequest) String() string { return proto.CompactTextString(m) } func (*ListStorageObjectsRequest) ProtoMessage() {} func (*ListStorageObjectsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{48} + return fileDescriptor_1b40cafcd4234784, []int{49} } func (m *ListStorageObjectsRequest) XXX_Unmarshal(b []byte) error { @@ -3083,7 +3142,7 @@ func (m *ListTournamentRecordsAroundOwnerRequest) Reset() { func (m *ListTournamentRecordsAroundOwnerRequest) String() string { return proto.CompactTextString(m) } func (*ListTournamentRecordsAroundOwnerRequest) ProtoMessage() {} func (*ListTournamentRecordsAroundOwnerRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{49} + return fileDescriptor_1b40cafcd4234784, []int{50} } func (m *ListTournamentRecordsAroundOwnerRequest) XXX_Unmarshal(b []byte) error { @@ -3144,7 +3203,7 @@ func (m *ListTournamentRecordsRequest) Reset() { *m = ListTournamentReco func (m *ListTournamentRecordsRequest) String() string { return proto.CompactTextString(m) } func (*ListTournamentRecordsRequest) ProtoMessage() {} func (*ListTournamentRecordsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{50} + return fileDescriptor_1b40cafcd4234784, []int{51} } func (m *ListTournamentRecordsRequest) XXX_Unmarshal(b []byte) error { @@ -3216,7 +3275,7 @@ func (m *ListTournamentsRequest) Reset() { *m = ListTournamentsRequest{} func (m *ListTournamentsRequest) String() string { return proto.CompactTextString(m) } func (*ListTournamentsRequest) ProtoMessage() {} func (*ListTournamentsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{51} + return fileDescriptor_1b40cafcd4234784, []int{52} } func (m *ListTournamentsRequest) XXX_Unmarshal(b []byte) error { @@ -3292,7 +3351,7 @@ func (m *ListUserGroupsRequest) Reset() { *m = ListUserGroupsRequest{} } func (m *ListUserGroupsRequest) String() string { return proto.CompactTextString(m) } func (*ListUserGroupsRequest) ProtoMessage() {} func (*ListUserGroupsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{52} + return fileDescriptor_1b40cafcd4234784, []int{53} } func (m *ListUserGroupsRequest) XXX_Unmarshal(b []byte) error { @@ -3339,7 +3398,7 @@ func (m *Match) Reset() { *m = Match{} } func (m *Match) String() string { return proto.CompactTextString(m) } func (*Match) ProtoMessage() {} func (*Match) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{53} + return fileDescriptor_1b40cafcd4234784, []int{54} } func (m *Match) XXX_Unmarshal(b []byte) error { @@ -3401,7 +3460,7 @@ func (m *MatchList) Reset() { *m = MatchList{} } func (m *MatchList) String() string { return proto.CompactTextString(m) } func (*MatchList) ProtoMessage() {} func (*MatchList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{54} + return fileDescriptor_1b40cafcd4234784, []int{55} } func (m *MatchList) XXX_Unmarshal(b []byte) error { @@ -3454,7 +3513,7 @@ func (m *Notification) Reset() { *m = Notification{} } func (m *Notification) String() string { return proto.CompactTextString(m) } func (*Notification) ProtoMessage() {} func (*Notification) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{55} + return fileDescriptor_1b40cafcd4234784, []int{56} } func (m *Notification) XXX_Unmarshal(b []byte) error { @@ -3539,7 +3598,7 @@ func (m *NotificationList) Reset() { *m = NotificationList{} } func (m *NotificationList) String() string { return proto.CompactTextString(m) } func (*NotificationList) ProtoMessage() {} func (*NotificationList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{56} + return fileDescriptor_1b40cafcd4234784, []int{57} } func (m *NotificationList) XXX_Unmarshal(b []byte) error { @@ -3589,7 +3648,7 @@ func (m *PromoteGroupUsersRequest) Reset() { *m = PromoteGroupUsersReque func (m *PromoteGroupUsersRequest) String() string { return proto.CompactTextString(m) } func (*PromoteGroupUsersRequest) ProtoMessage() {} func (*PromoteGroupUsersRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{57} + return fileDescriptor_1b40cafcd4234784, []int{58} } func (m *PromoteGroupUsersRequest) XXX_Unmarshal(b []byte) error { @@ -3641,7 +3700,7 @@ func (m *ReadStorageObjectId) Reset() { *m = ReadStorageObjectId{} } func (m *ReadStorageObjectId) String() string { return proto.CompactTextString(m) } func (*ReadStorageObjectId) ProtoMessage() {} func (*ReadStorageObjectId) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{58} + return fileDescriptor_1b40cafcd4234784, []int{59} } func (m *ReadStorageObjectId) XXX_Unmarshal(b []byte) error { @@ -3696,7 +3755,7 @@ func (m *ReadStorageObjectsRequest) Reset() { *m = ReadStorageObjectsReq func (m *ReadStorageObjectsRequest) String() string { return proto.CompactTextString(m) } func (*ReadStorageObjectsRequest) ProtoMessage() {} func (*ReadStorageObjectsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{59} + return fileDescriptor_1b40cafcd4234784, []int{60} } func (m *ReadStorageObjectsRequest) XXX_Unmarshal(b []byte) error { @@ -3741,7 +3800,7 @@ func (m *Rpc) Reset() { *m = Rpc{} } func (m *Rpc) String() string { return proto.CompactTextString(m) } func (*Rpc) ProtoMessage() {} func (*Rpc) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{60} + return fileDescriptor_1b40cafcd4234784, []int{61} } func (m *Rpc) XXX_Unmarshal(b []byte) error { @@ -3800,7 +3859,7 @@ func (m *Session) Reset() { *m = Session{} } func (m *Session) String() string { return proto.CompactTextString(m) } func (*Session) ProtoMessage() {} func (*Session) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{61} + return fileDescriptor_1b40cafcd4234784, []int{62} } func (m *Session) XXX_Unmarshal(b []byte) error { @@ -3871,7 +3930,7 @@ func (m *StorageObject) Reset() { *m = StorageObject{} } func (m *StorageObject) String() string { return proto.CompactTextString(m) } func (*StorageObject) ProtoMessage() {} func (*StorageObject) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{62} + return fileDescriptor_1b40cafcd4234784, []int{63} } func (m *StorageObject) XXX_Unmarshal(b []byte) error { @@ -3974,7 +4033,7 @@ func (m *StorageObjectAck) Reset() { *m = StorageObjectAck{} } func (m *StorageObjectAck) String() string { return proto.CompactTextString(m) } func (*StorageObjectAck) ProtoMessage() {} func (*StorageObjectAck) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{63} + return fileDescriptor_1b40cafcd4234784, []int{64} } func (m *StorageObjectAck) XXX_Unmarshal(b []byte) error { @@ -4036,7 +4095,7 @@ func (m *StorageObjectAcks) Reset() { *m = StorageObjectAcks{} } func (m *StorageObjectAcks) String() string { return proto.CompactTextString(m) } func (*StorageObjectAcks) ProtoMessage() {} func (*StorageObjectAcks) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{64} + return fileDescriptor_1b40cafcd4234784, []int{65} } func (m *StorageObjectAcks) XXX_Unmarshal(b []byte) error { @@ -4077,7 +4136,7 @@ func (m *StorageObjects) Reset() { *m = StorageObjects{} } func (m *StorageObjects) String() string { return proto.CompactTextString(m) } func (*StorageObjects) ProtoMessage() {} func (*StorageObjects) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{65} + return fileDescriptor_1b40cafcd4234784, []int{66} } func (m *StorageObjects) XXX_Unmarshal(b []byte) error { @@ -4120,7 +4179,7 @@ func (m *StorageObjectList) Reset() { *m = StorageObjectList{} } func (m *StorageObjectList) String() string { return proto.CompactTextString(m) } func (*StorageObjectList) ProtoMessage() {} func (*StorageObjectList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{66} + return fileDescriptor_1b40cafcd4234784, []int{67} } func (m *StorageObjectList) XXX_Unmarshal(b []byte) error { @@ -4198,7 +4257,7 @@ func (m *Tournament) Reset() { *m = Tournament{} } func (m *Tournament) String() string { return proto.CompactTextString(m) } func (*Tournament) ProtoMessage() {} func (*Tournament) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{67} + return fileDescriptor_1b40cafcd4234784, []int{68} } func (m *Tournament) XXX_Unmarshal(b []byte) error { @@ -4346,7 +4405,7 @@ func (m *TournamentList) Reset() { *m = TournamentList{} } func (m *TournamentList) String() string { return proto.CompactTextString(m) } func (*TournamentList) ProtoMessage() {} func (*TournamentList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{68} + return fileDescriptor_1b40cafcd4234784, []int{69} } func (m *TournamentList) XXX_Unmarshal(b []byte) error { @@ -4400,7 +4459,7 @@ func (m *TournamentRecordList) Reset() { *m = TournamentRecordList{} } func (m *TournamentRecordList) String() string { return proto.CompactTextString(m) } func (*TournamentRecordList) ProtoMessage() {} func (*TournamentRecordList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{69} + return fileDescriptor_1b40cafcd4234784, []int{70} } func (m *TournamentRecordList) XXX_Unmarshal(b []byte) error { @@ -4472,7 +4531,7 @@ func (m *UpdateAccountRequest) Reset() { *m = UpdateAccountRequest{} } func (m *UpdateAccountRequest) String() string { return proto.CompactTextString(m) } func (*UpdateAccountRequest) ProtoMessage() {} func (*UpdateAccountRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{70} + return fileDescriptor_1b40cafcd4234784, []int{71} } func (m *UpdateAccountRequest) XXX_Unmarshal(b []byte) error { @@ -4558,7 +4617,7 @@ func (m *UpdateGroupRequest) Reset() { *m = UpdateGroupRequest{} } func (m *UpdateGroupRequest) String() string { return proto.CompactTextString(m) } func (*UpdateGroupRequest) ProtoMessage() {} func (*UpdateGroupRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{71} + return fileDescriptor_1b40cafcd4234784, []int{72} } func (m *UpdateGroupRequest) XXX_Unmarshal(b []byte) error { @@ -4664,7 +4723,7 @@ func (m *User) Reset() { *m = User{} } func (m *User) String() string { return proto.CompactTextString(m) } func (*User) ProtoMessage() {} func (*User) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{72} + return fileDescriptor_1b40cafcd4234784, []int{73} } func (m *User) XXX_Unmarshal(b []byte) error { @@ -4810,7 +4869,7 @@ func (m *UserGroupList) Reset() { *m = UserGroupList{} } func (m *UserGroupList) String() string { return proto.CompactTextString(m) } func (*UserGroupList) ProtoMessage() {} func (*UserGroupList) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{73} + return fileDescriptor_1b40cafcd4234784, []int{74} } func (m *UserGroupList) XXX_Unmarshal(b []byte) error { @@ -4853,7 +4912,7 @@ func (m *UserGroupList_UserGroup) Reset() { *m = UserGroupList_UserGroup func (m *UserGroupList_UserGroup) String() string { return proto.CompactTextString(m) } func (*UserGroupList_UserGroup) ProtoMessage() {} func (*UserGroupList_UserGroup) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{73, 0} + return fileDescriptor_1b40cafcd4234784, []int{74, 0} } func (m *UserGroupList_UserGroup) XXX_Unmarshal(b []byte) error { @@ -4901,7 +4960,7 @@ func (m *Users) Reset() { *m = Users{} } func (m *Users) String() string { return proto.CompactTextString(m) } func (*Users) ProtoMessage() {} func (*Users) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{74} + return fileDescriptor_1b40cafcd4234784, []int{75} } func (m *Users) XXX_Unmarshal(b []byte) error { @@ -4944,7 +5003,7 @@ func (m *WriteLeaderboardRecordRequest) Reset() { *m = WriteLeaderboardR func (m *WriteLeaderboardRecordRequest) String() string { return proto.CompactTextString(m) } func (*WriteLeaderboardRecordRequest) ProtoMessage() {} func (*WriteLeaderboardRecordRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{75} + return fileDescriptor_1b40cafcd4234784, []int{76} } func (m *WriteLeaderboardRecordRequest) XXX_Unmarshal(b []byte) error { @@ -5000,7 +5059,7 @@ func (m *WriteLeaderboardRecordRequest_LeaderboardRecordWrite) String() string { } func (*WriteLeaderboardRecordRequest_LeaderboardRecordWrite) ProtoMessage() {} func (*WriteLeaderboardRecordRequest_LeaderboardRecordWrite) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{75, 0} + return fileDescriptor_1b40cafcd4234784, []int{76, 0} } func (m *WriteLeaderboardRecordRequest_LeaderboardRecordWrite) XXX_Unmarshal(b []byte) error { @@ -5065,7 +5124,7 @@ func (m *WriteStorageObject) Reset() { *m = WriteStorageObject{} } func (m *WriteStorageObject) String() string { return proto.CompactTextString(m) } func (*WriteStorageObject) ProtoMessage() {} func (*WriteStorageObject) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{76} + return fileDescriptor_1b40cafcd4234784, []int{77} } func (m *WriteStorageObject) XXX_Unmarshal(b []byte) error { @@ -5141,7 +5200,7 @@ func (m *WriteStorageObjectsRequest) Reset() { *m = WriteStorageObjectsR func (m *WriteStorageObjectsRequest) String() string { return proto.CompactTextString(m) } func (*WriteStorageObjectsRequest) ProtoMessage() {} func (*WriteStorageObjectsRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{77} + return fileDescriptor_1b40cafcd4234784, []int{78} } func (m *WriteStorageObjectsRequest) XXX_Unmarshal(b []byte) error { @@ -5184,7 +5243,7 @@ func (m *WriteTournamentRecordRequest) Reset() { *m = WriteTournamentRec func (m *WriteTournamentRecordRequest) String() string { return proto.CompactTextString(m) } func (*WriteTournamentRecordRequest) ProtoMessage() {} func (*WriteTournamentRecordRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{78} + return fileDescriptor_1b40cafcd4234784, []int{79} } func (m *WriteTournamentRecordRequest) XXX_Unmarshal(b []byte) error { @@ -5240,7 +5299,7 @@ func (m *WriteTournamentRecordRequest_TournamentRecordWrite) String() string { } func (*WriteTournamentRecordRequest_TournamentRecordWrite) ProtoMessage() {} func (*WriteTournamentRecordRequest_TournamentRecordWrite) Descriptor() ([]byte, []int) { - return fileDescriptor_1b40cafcd4234784, []int{78, 0} + return fileDescriptor_1b40cafcd4234784, []int{79, 0} } func (m *WriteTournamentRecordRequest_TournamentRecordWrite) XXX_Unmarshal(b []byte) error { @@ -5313,6 +5372,8 @@ func init() { proto.RegisterType((*DeleteNotificationsRequest)(nil), "nakama.api.DeleteNotificationsRequest") proto.RegisterType((*DeleteStorageObjectId)(nil), "nakama.api.DeleteStorageObjectId") proto.RegisterType((*DeleteStorageObjectsRequest)(nil), "nakama.api.DeleteStorageObjectsRequest") + proto.RegisterType((*Event)(nil), "nakama.api.Event") + proto.RegisterMapType((map[string]string)(nil), "nakama.api.Event.PropertiesEntry") proto.RegisterType((*Friend)(nil), "nakama.api.Friend") proto.RegisterType((*Friends)(nil), "nakama.api.Friends") proto.RegisterType((*GetUsersRequest)(nil), "nakama.api.GetUsersRequest") @@ -5374,210 +5435,214 @@ func init() { func init() { proto.RegisterFile("api/api.proto", fileDescriptor_1b40cafcd4234784) } var fileDescriptor_1b40cafcd4234784 = []byte{ - // 3273 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x3a, 0x5b, 0x8f, 0x1b, 0x49, - 0xd5, 0xdb, 0xbe, 0xfb, 0x78, 0x3c, 0xe3, 0x54, 0x2e, 0x9f, 0xe3, 0x5c, 0xb7, 0x93, 0xfd, 0x92, - 0xd5, 0x7e, 0xdf, 0x64, 0x77, 0xf2, 0xed, 0x97, 0xc0, 0x42, 0x36, 0x73, 0x71, 0x22, 0x6f, 0x92, - 0x49, 0xe8, 0x99, 0x09, 0x08, 0x1e, 0xbc, 0x35, 0xdd, 0x35, 0x9e, 0x66, 0xda, 0xdd, 0xde, 0xee, - 0xf6, 0x5c, 0x56, 0xf0, 0x00, 0x42, 0x62, 0x9f, 0x10, 0xe2, 0x89, 0x17, 0x60, 0x85, 0x10, 0xda, - 0x05, 0x89, 0x5f, 0xc0, 0x3b, 0xef, 0x08, 0x10, 0x6f, 0xc0, 0x23, 0x12, 0xff, 0x00, 0x09, 0xa1, - 0x3a, 0x55, 0xdd, 0xae, 0x6e, 0xdb, 0x33, 0x76, 0x66, 0xb2, 0x2b, 0xf1, 0x62, 0x75, 0x9d, 0x3a, - 0xa7, 0xea, 0xd4, 0xa9, 0x73, 0x2f, 0x43, 0x95, 0xf6, 0xec, 0x5b, 0xb4, 0x67, 0xcf, 0xf7, 0x7c, - 0x2f, 0xf4, 0x08, 0xb8, 0x74, 0x87, 0x76, 0xe9, 0x3c, 0xed, 0xd9, 0x8d, 0x2b, 0x1d, 0xcf, 0xeb, - 0x38, 0xec, 0x16, 0xce, 0x6c, 0xf6, 0xb7, 0x6e, 0x85, 0x76, 0x97, 0x05, 0x21, 0xed, 0xf6, 0x04, - 0x72, 0xe3, 0x72, 0x1a, 0x61, 0xcf, 0xa7, 0xbd, 0x1e, 0xf3, 0x03, 0x31, 0xaf, 0xff, 0x43, 0x83, - 0xe2, 0xa2, 0x69, 0x7a, 0x7d, 0x37, 0x24, 0xd7, 0x21, 0xd7, 0x0f, 0x98, 0x5f, 0xd7, 0xae, 0x6a, - 0x37, 0x2b, 0x0b, 0xb5, 0xf9, 0xc1, 0x3e, 0xf3, 0x1b, 0x01, 0xf3, 0x0d, 0x9c, 0x25, 0xe7, 0xa0, - 0xb0, 0x47, 0x1d, 0x87, 0x85, 0xf5, 0xcc, 0x55, 0xed, 0x66, 0xd9, 0x90, 0x23, 0x72, 0x06, 0xf2, - 0xac, 0x4b, 0x6d, 0xa7, 0x9e, 0x45, 0xb0, 0x18, 0x90, 0xdb, 0x50, 0xb4, 0xd8, 0xae, 0x6d, 0xb2, - 0xa0, 0x9e, 0xbb, 0x9a, 0xbd, 0x59, 0x59, 0x38, 0xaf, 0x2e, 0x2b, 0x77, 0x5e, 0x41, 0x0c, 0x23, - 0xc2, 0x24, 0x17, 0xa0, 0x6c, 0xf6, 0x83, 0xd0, 0xeb, 0xb6, 0x6d, 0xab, 0x9e, 0xc7, 0xe5, 0x4a, - 0x02, 0xd0, 0xb2, 0xc8, 0x3b, 0x50, 0xd9, 0x65, 0xbe, 0xbd, 0x75, 0xd0, 0xe6, 0x67, 0xad, 0x17, - 0x90, 0xd9, 0xc6, 0xbc, 0x38, 0xe7, 0x7c, 0x74, 0xce, 0xf9, 0xf5, 0x48, 0x10, 0x06, 0x08, 0x74, - 0x0e, 0xd0, 0xaf, 0x40, 0x55, 0xee, 0xb9, 0x8c, 0xeb, 0x91, 0x59, 0xc8, 0xd8, 0x16, 0x9e, 0xb8, - 0x6c, 0x64, 0x6c, 0x4b, 0x41, 0x10, 0x4c, 0x0d, 0x21, 0xdc, 0x87, 0x19, 0x89, 0xd0, 0xc4, 0x03, - 0xc6, 0xc7, 0xd6, 0xd4, 0x63, 0x37, 0xa0, 0xd4, 0xa3, 0x41, 0xb0, 0xe7, 0xf9, 0x96, 0x14, 0x53, - 0x3c, 0xd6, 0x6f, 0xc0, 0x9c, 0x5c, 0xe1, 0x01, 0x35, 0xd9, 0xa6, 0xe7, 0xed, 0xf0, 0x45, 0x42, - 0x6f, 0x87, 0xb9, 0xd1, 0x22, 0x38, 0xd0, 0x7f, 0xaf, 0xc1, 0x29, 0x89, 0xf9, 0x90, 0x76, 0xd9, - 0x32, 0x73, 0x43, 0xe6, 0x73, 0xe1, 0xf4, 0x1c, 0x7a, 0xc0, 0xfc, 0x76, 0xcc, 0x57, 0x49, 0x00, - 0x5a, 0x16, 0x9f, 0xdc, 0xec, 0xbb, 0x96, 0xc3, 0xf8, 0xa4, 0xdc, 0x58, 0x00, 0x5a, 0x16, 0x79, - 0x03, 0x4e, 0xc5, 0xea, 0xd1, 0x0e, 0x98, 0xe9, 0xb9, 0x56, 0x80, 0xb7, 0x95, 0x35, 0x6a, 0xf1, - 0xc4, 0x9a, 0x80, 0x13, 0x02, 0xb9, 0x80, 0x3a, 0x61, 0x3d, 0x87, 0x8b, 0xe0, 0x37, 0xb9, 0x08, - 0xe5, 0xc0, 0xee, 0xb8, 0x34, 0xec, 0xfb, 0x4c, 0xde, 0xcb, 0x00, 0x40, 0xae, 0xc3, 0x6c, 0xaf, - 0xbf, 0xe9, 0xd8, 0x66, 0x7b, 0x87, 0x1d, 0xb4, 0xfb, 0xbe, 0x83, 0x77, 0x53, 0x36, 0x66, 0x04, - 0xf4, 0x11, 0x3b, 0xd8, 0xf0, 0x1d, 0xfd, 0xb5, 0x58, 0xc0, 0x0f, 0xf1, 0xc6, 0xc6, 0x9c, 0xfd, - 0x7a, 0x2c, 0xe6, 0xb5, 0x90, 0xd1, 0xee, 0x18, 0xac, 0x65, 0x38, 0xb5, 0x68, 0x59, 0x0f, 0x7c, - 0x9b, 0xb9, 0x56, 0x60, 0xb0, 0x0f, 0xfa, 0x2c, 0x08, 0x49, 0x0d, 0xb2, 0xb6, 0x15, 0xd4, 0xb5, - 0xab, 0xd9, 0x9b, 0x65, 0x83, 0x7f, 0x72, 0xbe, 0xb9, 0xea, 0xba, 0xb4, 0xcb, 0x82, 0x7a, 0x06, - 0xe1, 0x03, 0x80, 0xfe, 0x18, 0xce, 0x2c, 0x5a, 0xd6, 0x43, 0xdf, 0xeb, 0xf7, 0xb8, 0x9a, 0xc7, - 0xeb, 0x9c, 0x87, 0x52, 0x87, 0x03, 0x07, 0x72, 0x2e, 0xe2, 0xb8, 0x65, 0xf1, 0x29, 0x4e, 0xdf, - 0xe6, 0xfb, 0x88, 0xf5, 0x8a, 0x7c, 0xdc, 0xb2, 0x02, 0xfd, 0x63, 0x0d, 0xce, 0x2f, 0xf6, 0xc3, - 0x6d, 0xe6, 0x86, 0xb6, 0x49, 0x43, 0x26, 0xf4, 0x2c, 0x5a, 0xf3, 0x36, 0x14, 0xa9, 0x38, 0x96, - 0xb4, 0xb2, 0x51, 0xe6, 0x20, 0x49, 0x22, 0x4c, 0xb2, 0x00, 0x05, 0xd3, 0x67, 0x34, 0x64, 0x78, - 0xa3, 0xa3, 0x94, 0x7d, 0xc9, 0xf3, 0x9c, 0xe7, 0xd4, 0xe9, 0x33, 0x43, 0x62, 0x72, 0x05, 0x8c, - 0x4e, 0x28, 0x0d, 0x32, 0x1e, 0x0f, 0xb1, 0x28, 0xcd, 0x6f, 0x1a, 0x16, 0x23, 0x8b, 0x7d, 0x59, - 0x2c, 0xfe, 0x54, 0x83, 0xba, 0xca, 0x22, 0xda, 0x5a, 0xc4, 0xe1, 0x42, 0x9a, 0xc3, 0xfa, 0x08, - 0x0e, 0x05, 0xc5, 0x4b, 0x63, 0xf0, 0x0f, 0x1a, 0x5c, 0x50, 0x19, 0x8c, 0x4c, 0x39, 0xe2, 0xf1, - 0xed, 0x34, 0x8f, 0x17, 0x46, 0xf0, 0x18, 0x13, 0xbd, 0x2c, 0x36, 0xc9, 0x3c, 0xe4, 0x82, 0x03, - 0xd7, 0x44, 0x2b, 0x3e, 0x7c, 0x35, 0xc4, 0xd3, 0x3f, 0xd1, 0xe0, 0x92, 0x7a, 0xac, 0x81, 0xdf, - 0x89, 0x0e, 0x76, 0x27, 0x7d, 0xb0, 0x4b, 0x23, 0x0e, 0xa6, 0x90, 0x7d, 0x66, 0x5a, 0x2c, 0xdc, - 0xc9, 0x54, 0x5a, 0x2c, 0x49, 0x3e, 0x33, 0x2d, 0x46, 0x57, 0x36, 0x95, 0x16, 0x0b, 0x8a, 0x97, - 0xc6, 0x60, 0x13, 0x4e, 0x2f, 0x39, 0x9e, 0xb9, 0x73, 0x4c, 0x0f, 0xfa, 0x51, 0x16, 0x66, 0x97, - 0xb7, 0xa9, 0xeb, 0x32, 0xe7, 0x09, 0x0b, 0x02, 0xda, 0x61, 0xe4, 0x12, 0x80, 0x29, 0x20, 0x03, - 0xf7, 0x59, 0x96, 0x90, 0x96, 0xc5, 0xa7, 0xbb, 0x02, 0x73, 0x10, 0xa8, 0xca, 0x12, 0xd2, 0xb2, - 0xc8, 0x2d, 0xc8, 0x99, 0x9e, 0x25, 0xf8, 0xe5, 0xa6, 0x93, 0x3e, 0x65, 0xcb, 0x0d, 0x6f, 0x2f, - 0x48, 0xbd, 0xe5, 0x88, 0x3c, 0xee, 0x05, 0xcc, 0xb5, 0x44, 0x50, 0x14, 0x21, 0xab, 0x24, 0x00, - 0x2d, 0x2b, 0x21, 0x81, 0x7c, 0xca, 0x40, 0xea, 0x50, 0x34, 0x3d, 0x37, 0x64, 0x6e, 0x28, 0xa3, - 0x55, 0x34, 0xe4, 0x79, 0x86, 0x90, 0xa0, 0xc8, 0x33, 0x8a, 0x47, 0xe7, 0x19, 0x02, 0x9d, 0x03, - 0x38, 0x71, 0xbf, 0x67, 0xc5, 0xc4, 0xa5, 0xa3, 0x89, 0x05, 0x3a, 0x12, 0x7f, 0x11, 0x80, 0x67, - 0x68, 0x76, 0x80, 0x6c, 0x95, 0x8f, 0xbc, 0x69, 0x05, 0x5b, 0xff, 0x81, 0x06, 0x24, 0x79, 0x15, - 0x8f, 0xed, 0x20, 0x24, 0xff, 0x0f, 0x25, 0x29, 0x5d, 0x71, 0xad, 0x7c, 0x41, 0x45, 0xdb, 0x92, - 0x14, 0x46, 0x8c, 0x4b, 0xae, 0x40, 0xc5, 0x65, 0xfb, 0x61, 0xdb, 0xec, 0xfb, 0x81, 0xe7, 0xcb, - 0x8b, 0x02, 0x0e, 0x5a, 0x46, 0x08, 0x47, 0xe8, 0xf9, 0x6c, 0x37, 0x42, 0x10, 0x0a, 0x06, 0x1c, - 0x24, 0x10, 0xf4, 0x1f, 0x73, 0x86, 0x50, 0x30, 0x18, 0x61, 0x23, 0x15, 0x23, 0x90, 0xc3, 0xfb, - 0x10, 0x9a, 0x81, 0xdf, 0xe4, 0x2a, 0x54, 0x2c, 0x16, 0x98, 0xbe, 0xdd, 0x0b, 0x6d, 0xcf, 0x95, - 0x9b, 0xa9, 0x20, 0x1e, 0x77, 0x1d, 0xea, 0x76, 0xda, 0x21, 0xed, 0xc8, 0xad, 0x8a, 0x7c, 0xbc, - 0x4e, 0x3b, 0x5c, 0xa3, 0xe8, 0x2e, 0x0d, 0xa9, 0x8f, 0x99, 0x87, 0x50, 0x81, 0xb2, 0x80, 0x6c, - 0xf8, 0x0e, 0xdf, 0xcf, 0xeb, 0x31, 0x17, 0xef, 0xbf, 0x64, 0xe0, 0xb7, 0xfe, 0x00, 0xce, 0xac, - 0x30, 0x87, 0x85, 0xec, 0x98, 0xea, 0x7f, 0x0b, 0x88, 0x58, 0x27, 0x71, 0xc2, 0xf1, 0xe9, 0x83, - 0xfe, 0x10, 0x2e, 0x0b, 0x82, 0xc7, 0x8c, 0x5a, 0xcc, 0xdf, 0xf4, 0xa8, 0x6f, 0x19, 0xcc, 0xf4, - 0xf8, 0xaf, 0x20, 0x7e, 0x0d, 0x66, 0x9d, 0xc1, 0xdc, 0x60, 0x89, 0xaa, 0x02, 0x6d, 0x59, 0xfa, - 0x3c, 0x34, 0xc4, 0x42, 0xab, 0x5e, 0x68, 0x6f, 0x71, 0x1f, 0x63, 0x7b, 0xee, 0xf8, 0x73, 0xe8, - 0x26, 0x9c, 0x15, 0xf8, 0x6b, 0xa1, 0xe7, 0xd3, 0x0e, 0x7b, 0xba, 0xf9, 0x4d, 0x66, 0x86, 0x2d, - 0x8b, 0x5c, 0x06, 0x30, 0x3d, 0xc7, 0x61, 0x26, 0x4a, 0x5e, 0xec, 0xa5, 0x40, 0xf8, 0x52, 0x3b, - 0xec, 0x40, 0x5e, 0x09, 0xff, 0xe4, 0x86, 0xb3, 0xcb, 0xd5, 0xce, 0x73, 0xa3, 0x9b, 0x90, 0x43, - 0xbd, 0x0d, 0x17, 0x46, 0x6c, 0x12, 0x73, 0x75, 0x1f, 0xc0, 0x43, 0x48, 0x3b, 0x62, 0xae, 0xb2, - 0xf0, 0xaa, 0xaa, 0x8c, 0x23, 0x39, 0x34, 0xca, 0x9e, 0xfc, 0x0a, 0xf4, 0x4f, 0x35, 0x28, 0x88, - 0x2b, 0x9b, 0xb0, 0x64, 0x79, 0x0b, 0xf2, 0x41, 0x38, 0xf0, 0x9a, 0x87, 0xfa, 0x13, 0x81, 0xa9, - 0x3f, 0x80, 0xfc, 0x1a, 0xff, 0x20, 0x00, 0x85, 0x07, 0x46, 0xab, 0xb9, 0xba, 0x52, 0x7b, 0x85, - 0xcc, 0x41, 0xa5, 0xb5, 0xfa, 0xbc, 0xb5, 0xde, 0x6c, 0xaf, 0x35, 0x57, 0xd7, 0x6b, 0x1a, 0x39, - 0x0d, 0x73, 0x12, 0x60, 0x34, 0x97, 0x9b, 0xad, 0xe7, 0xcd, 0x95, 0x5a, 0x86, 0x54, 0xa0, 0xb8, - 0xf4, 0xf8, 0xe9, 0xf2, 0xa3, 0xe6, 0x4a, 0x2d, 0xab, 0xdf, 0x81, 0xa2, 0xd4, 0x2e, 0xf2, 0x3f, - 0x50, 0xdc, 0x12, 0x9f, 0xf2, 0xd4, 0x44, 0x65, 0x57, 0x60, 0x19, 0x11, 0x8a, 0x6e, 0xc1, 0xdc, - 0x43, 0x16, 0x26, 0x12, 0xd2, 0x29, 0xf5, 0x92, 0xbc, 0x0a, 0x33, 0x5b, 0x32, 0xc3, 0x40, 0x59, - 0x67, 0x11, 0xa1, 0x12, 0xc1, 0xb8, 0x28, 0x3f, 0xc9, 0x42, 0x1e, 0xb5, 0x36, 0x5d, 0xe7, 0xa0, - 0x03, 0xe7, 0x66, 0xeb, 0xf9, 0x8a, 0x87, 0x96, 0x90, 0x96, 0x15, 0xdb, 0x6f, 0x76, 0xbc, 0xfd, - 0xe6, 0x0e, 0xb7, 0xdf, 0x7c, 0xd2, 0x7e, 0x1b, 0xdc, 0x43, 0x85, 0xd4, 0xa2, 0x21, 0x95, 0x9e, - 0x38, 0x1e, 0xa7, 0x6c, 0xbb, 0x98, 0xb6, 0xed, 0x79, 0x69, 0xdb, 0xa5, 0xa3, 0x93, 0x1c, 0x8e, - 0xc7, 0x97, 0x63, 0x56, 0x87, 0xb5, 0x45, 0xf0, 0xe5, 0xfe, 0x35, 0x6f, 0x94, 0x39, 0x64, 0x19, - 0x83, 0xec, 0x05, 0x28, 0x77, 0xe9, 0xbe, 0x9c, 0x05, 0x9c, 0x2d, 0x75, 0xe9, 0xbe, 0x98, 0x4c, - 0x45, 0x85, 0xca, 0x71, 0xa2, 0xc2, 0xcc, 0x34, 0x51, 0x41, 0x5f, 0x85, 0x32, 0xde, 0x14, 0xfa, - 0xf3, 0xd7, 0xa1, 0x80, 0xce, 0x24, 0x52, 0xa5, 0x53, 0xaa, 0x2a, 0x09, 0x37, 0x24, 0x11, 0x78, - 0xbd, 0x9e, 0xf0, 0xde, 0x72, 0xa4, 0xff, 0x4b, 0x83, 0x6a, 0x5c, 0xf4, 0xe0, 0xa2, 0x2b, 0x50, - 0x11, 0x1e, 0x8b, 0xab, 0x50, 0xb4, 0xf2, 0xb5, 0xa1, 0x95, 0x23, 0xfc, 0xc1, 0xc8, 0x80, 0x4e, - 0x5c, 0x3d, 0x35, 0x7e, 0xa9, 0x49, 0x46, 0xf9, 0xf0, 0xe5, 0x19, 0xe8, 0xfd, 0xc8, 0x40, 0x67, - 0x01, 0xd6, 0x36, 0x9e, 0x35, 0x8d, 0xc5, 0x95, 0x27, 0xad, 0xd5, 0xda, 0x2b, 0xa4, 0x0c, 0x79, - 0xf1, 0xa9, 0x71, 0xdb, 0x7d, 0xd2, 0x7c, 0xb2, 0xd4, 0x34, 0x6a, 0x19, 0x52, 0x83, 0x99, 0xf7, - 0x9e, 0xb6, 0x56, 0xdb, 0x46, 0xf3, 0x2b, 0x1b, 0xcd, 0xb5, 0xf5, 0x5a, 0x56, 0xff, 0xbe, 0x06, - 0x17, 0x5b, 0xdd, 0x9e, 0xe7, 0xc7, 0x79, 0x78, 0x2a, 0x0e, 0xbc, 0x60, 0x0e, 0xff, 0x26, 0xe4, - 0x7d, 0x16, 0xc8, 0xfe, 0xc8, 0xe1, 0xfa, 0x28, 0x10, 0xf5, 0xff, 0x85, 0xda, 0x7b, 0x9e, 0xed, - 0x4e, 0x1a, 0x3e, 0xbe, 0x04, 0x67, 0x39, 0xfa, 0xba, 0xd7, 0x47, 0x43, 0x77, 0xc3, 0x88, 0xe6, - 0x1a, 0x54, 0xc3, 0x18, 0x38, 0x20, 0x9c, 0x19, 0x00, 0x5b, 0x96, 0xfe, 0x04, 0xce, 0x3e, 0xb2, - 0xcd, 0x9d, 0x93, 0xaa, 0x77, 0xff, 0x9e, 0x85, 0x53, 0x43, 0x61, 0x6c, 0xc2, 0xf8, 0xc5, 0xd7, - 0xf5, 0xf6, 0x5c, 0xa6, 0xb8, 0x98, 0x22, 0x8e, 0x5b, 0x16, 0xb9, 0x9b, 0x4a, 0x5b, 0x2b, 0x0b, - 0x17, 0x87, 0x04, 0xb9, 0x16, 0xfa, 0xb6, 0xdb, 0x11, 0xa2, 0x1c, 0xa4, 0x74, 0x67, 0x20, 0x1f, - 0x98, 0x9e, 0xcf, 0xd0, 0x01, 0x65, 0x0d, 0x31, 0xe0, 0xfe, 0x25, 0xe8, 0x6f, 0x8a, 0x89, 0x3c, - 0x4e, 0xc4, 0x63, 0x6e, 0xf1, 0x6e, 0xbf, 0xdb, 0x16, 0x93, 0x05, 0x61, 0xf1, 0x6e, 0xbf, 0xbb, - 0x16, 0x11, 0xc6, 0x8e, 0xa9, 0x98, 0x72, 0x4c, 0x29, 0x6f, 0x50, 0x3a, 0x8e, 0x37, 0x28, 0x4f, - 0x95, 0x23, 0xbe, 0x03, 0x15, 0xb6, 0xdf, 0xb3, 0x7d, 0xd9, 0x05, 0x83, 0xa3, 0x89, 0x05, 0x3a, - 0x12, 0x13, 0xc8, 0xf9, 0xd4, 0xdd, 0x41, 0xef, 0x95, 0x35, 0xf0, 0x9b, 0xe8, 0x50, 0xe5, 0x5e, - 0x6f, 0x20, 0x07, 0xee, 0x9d, 0xaa, 0x46, 0xa5, 0x4b, 0xf7, 0x57, 0xa5, 0x28, 0xf4, 0x3f, 0x69, - 0x70, 0x76, 0xe8, 0xae, 0xd1, 0x75, 0xdc, 0x81, 0xa2, 0x8f, 0xa3, 0xc8, 0x6d, 0x24, 0xaa, 0xc2, - 0xe1, 0x34, 0x27, 0xc2, 0x26, 0x4b, 0x50, 0x15, 0x1a, 0x10, 0x91, 0x67, 0x26, 0x21, 0x9f, 0x41, - 0x1a, 0x43, 0xae, 0x91, 0x4a, 0x52, 0xb3, 0x47, 0x25, 0xa9, 0xb9, 0xa1, 0x24, 0x75, 0x1e, 0x75, - 0x78, 0x77, 0xe2, 0x04, 0xee, 0x5b, 0x70, 0xfa, 0xb1, 0xed, 0xee, 0x9c, 0x50, 0xd1, 0x3f, 0x6d, - 0x91, 0xfe, 0x5b, 0x0d, 0x1a, 0x5c, 0xea, 0xc9, 0xac, 0x3d, 0xb6, 0xe3, 0x23, 0x4a, 0xaf, 0xb7, - 0x20, 0xef, 0xd8, 0x5d, 0x3b, 0x9c, 0xc8, 0xd7, 0x22, 0x26, 0xf9, 0x3f, 0x28, 0x6e, 0x79, 0xfe, - 0x1e, 0xf5, 0x2d, 0x69, 0x8a, 0x87, 0xf1, 0x18, 0xa1, 0x2a, 0x81, 0x27, 0x97, 0x08, 0x3c, 0x3e, - 0x9c, 0xe2, 0xdc, 0xa3, 0xac, 0x83, 0xc3, 0xea, 0x81, 0x31, 0x91, 0x6b, 0x70, 0x82, 0xec, 0xa4, - 0x27, 0xd0, 0x17, 0xe0, 0x6c, 0xbc, 0xe7, 0x84, 0x4e, 0x4f, 0xff, 0x58, 0x83, 0x9b, 0x9c, 0x68, - 0x48, 0xfd, 0x82, 0x45, 0xdf, 0xeb, 0xbb, 0xd6, 0x53, 0xa1, 0x83, 0xd3, 0x24, 0xec, 0x64, 0x21, - 0x29, 0xfc, 0x61, 0x97, 0xb6, 0x31, 0x2c, 0x7d, 0xd5, 0x49, 0x66, 0x13, 0x4e, 0x52, 0xff, 0x8d, - 0x06, 0x97, 0x46, 0xb3, 0x38, 0x25, 0x5f, 0x17, 0xa0, 0x1c, 0xed, 0x11, 0x79, 0xf8, 0x92, 0xdc, - 0x24, 0x78, 0x01, 0x79, 0x8f, 0xbd, 0xfb, 0xbf, 0x65, 0x80, 0x70, 0x86, 0x9f, 0xd0, 0xd0, 0xdc, - 0x1e, 0xa8, 0x6c, 0xbc, 0x83, 0x36, 0xf1, 0x0e, 0xf7, 0xa1, 0x4a, 0xfb, 0xe1, 0xb6, 0xe7, 0xdb, - 0x21, 0x0d, 0xed, 0xdd, 0x49, 0x3a, 0x22, 0x49, 0x02, 0xbc, 0x0b, 0xba, 0xc9, 0x9c, 0x89, 0xc2, - 0x8b, 0x40, 0xc5, 0x3a, 0xda, 0x76, 0xdb, 0x81, 0xfd, 0x21, 0x93, 0xe6, 0x7a, 0x28, 0xaf, 0xc5, - 0xae, 0xed, 0xae, 0xd9, 0x1f, 0x32, 0xa4, 0xa3, 0xfb, 0x82, 0x2e, 0x3f, 0x09, 0x1d, 0xdd, 0x47, - 0xba, 0x05, 0xc8, 0x7f, 0xd0, 0x67, 0xfe, 0x81, 0x7c, 0xe6, 0x38, 0x82, 0x47, 0x44, 0xd5, 0xf7, - 0xa1, 0xce, 0x45, 0x3c, 0xb2, 0x24, 0x7c, 0x01, 0x41, 0xbf, 0x0e, 0x35, 0x93, 0x9a, 0xdb, 0x8c, - 0x6e, 0x3a, 0x2c, 0xd9, 0x07, 0x98, 0x8b, 0xe1, 0xd2, 0x8d, 0xfe, 0x4c, 0x83, 0xf3, 0x7c, 0xeb, - 0xd1, 0x85, 0xdf, 0x7f, 0x41, 0x51, 0x26, 0x11, 0x52, 0x07, 0x0b, 0x22, 0x87, 0x48, 0x15, 0x9f, - 0x99, 0xa1, 0xe2, 0xf3, 0x04, 0xf5, 0xef, 0x27, 0x1a, 0xdc, 0xe0, 0x1c, 0xaa, 0xb9, 0xd3, 0x38, - 0x93, 0x9e, 0x24, 0x9b, 0x3a, 0x69, 0x83, 0xfe, 0xb5, 0x06, 0x17, 0x47, 0xf2, 0x37, 0x15, 0x53, - 0x9f, 0x95, 0x35, 0xff, 0x25, 0x03, 0xe7, 0x92, 0xdc, 0xc6, 0x7c, 0x2e, 0xc3, 0xac, 0x49, 0x43, - 0xd6, 0xf1, 0xfc, 0x83, 0x76, 0x10, 0x52, 0x3f, 0xd2, 0xb8, 0xc3, 0x05, 0x54, 0x8d, 0x68, 0xd6, - 0x38, 0x09, 0x79, 0x17, 0x66, 0xe2, 0x45, 0x98, 0x6b, 0x4d, 0x24, 0xe3, 0x4a, 0x44, 0xd1, 0x74, - 0x2d, 0xf2, 0x0e, 0x00, 0x6e, 0x2e, 0x92, 0xa4, 0xec, 0x04, 0xe4, 0x65, 0xc4, 0xc7, 0x2c, 0xe9, - 0x0e, 0x94, 0x98, 0x6b, 0x09, 0xd2, 0xdc, 0x04, 0xa4, 0x45, 0xe6, 0x5a, 0x48, 0x18, 0x4b, 0xb8, - 0xf0, 0x02, 0x12, 0x2e, 0x25, 0x24, 0xfc, 0xa6, 0x88, 0x5b, 0x3c, 0x64, 0x25, 0xe3, 0xe5, 0x38, - 0x63, 0xd2, 0x7f, 0xa8, 0x41, 0x1e, 0xbd, 0x2b, 0x57, 0xb3, 0x2e, 0xff, 0x50, 0x42, 0x1b, 0x8e, - 0x5b, 0x16, 0xb9, 0x3e, 0xca, 0x79, 0x96, 0x4e, 0xc2, 0x41, 0x12, 0xc8, 0xc5, 0xce, 0x31, 0x6f, - 0xe0, 0xb7, 0x7e, 0x17, 0xca, 0xc8, 0x11, 0x66, 0x8a, 0x6f, 0x80, 0xe0, 0x82, 0x8d, 0x2c, 0x5d, - 0x11, 0xcf, 0x88, 0x30, 0xf4, 0xbf, 0x6a, 0x30, 0xa3, 0xfa, 0xb1, 0xa1, 0x2e, 0x45, 0x1d, 0x8a, - 0x41, 0x1f, 0xdd, 0x4c, 0x54, 0x3f, 0xc8, 0xa1, 0xda, 0xd8, 0xcd, 0x26, 0x1b, 0xbb, 0x44, 0x36, - 0x97, 0x25, 0x8b, 0xc3, 0xfd, 0xe3, 0x7c, 0xaa, 0x7f, 0x9c, 0xca, 0xf2, 0x0b, 0x53, 0x65, 0xf9, - 0x97, 0x13, 0xcd, 0xdc, 0x22, 0xca, 0x59, 0x6d, 0xd8, 0x7e, 0x1b, 0x6a, 0xea, 0x09, 0x51, 0x46, - 0xf7, 0xa0, 0xea, 0xaa, 0xde, 0x5b, 0x4a, 0x2a, 0xf1, 0x40, 0xa0, 0x12, 0x19, 0x49, 0xf4, 0x69, - 0x5c, 0xf6, 0x33, 0xa8, 0x3f, 0xf3, 0xbd, 0xae, 0x27, 0x9b, 0x97, 0x27, 0x50, 0x10, 0xbe, 0x0f, - 0xa7, 0x0d, 0x46, 0xad, 0xe3, 0x77, 0x18, 0x15, 0x15, 0xcf, 0x26, 0x54, 0xfc, 0x1b, 0x70, 0x7e, - 0x68, 0x87, 0x98, 0xe9, 0x7b, 0x23, 0xda, 0x8b, 0x57, 0x54, 0xc1, 0x8d, 0x60, 0x4e, 0x6d, 0x2e, - 0xbe, 0x07, 0x59, 0xa3, 0x67, 0x8e, 0x52, 0xb4, 0x1e, 0x3d, 0x70, 0x3c, 0x1a, 0x17, 0xaa, 0x72, - 0xc8, 0x45, 0xb1, 0x1d, 0x86, 0xbd, 0x36, 0xe7, 0x5e, 0x6a, 0x1a, 0x1f, 0x3f, 0x62, 0x07, 0xfa, - 0x73, 0x28, 0xae, 0xb1, 0x20, 0xe0, 0xc7, 0xe3, 0xea, 0x88, 0x4a, 0x21, 0x16, 0x2d, 0x19, 0xd1, - 0x70, 0xf0, 0xb2, 0x9d, 0x51, 0x5e, 0xb6, 0xb9, 0x42, 0xf6, 0xad, 0x5e, 0x5b, 0xcc, 0x44, 0xcf, - 0x36, 0x56, 0x6f, 0x1d, 0x9f, 0xbd, 0xff, 0x9c, 0x81, 0x6a, 0xe2, 0x08, 0x27, 0x28, 0x5d, 0xce, - 0xcf, 0x2e, 0xb7, 0x68, 0xe9, 0xeb, 0xc5, 0x40, 0x6d, 0xf7, 0xe6, 0x13, 0xed, 0x5e, 0x72, 0x03, - 0xe6, 0x7a, 0xcc, 0xef, 0xda, 0x78, 0xce, 0xb6, 0xcf, 0xa8, 0x25, 0x4b, 0xe8, 0xd9, 0x01, 0x98, - 0xcb, 0x9c, 0x6b, 0xa5, 0x82, 0xb8, 0xe7, 0xdb, 0xa1, 0x78, 0x55, 0xc9, 0x1b, 0xca, 0x02, 0x5f, - 0xe5, 0xe0, 0xcf, 0xaf, 0xae, 0xd6, 0xf7, 0xa0, 0x96, 0x90, 0xec, 0xa2, 0xb9, 0x73, 0x92, 0xcd, - 0x71, 0x55, 0xec, 0xb9, 0x84, 0x52, 0x37, 0xe1, 0x54, 0x7a, 0xe3, 0x80, 0xbc, 0x09, 0x39, 0x6a, - 0xee, 0x44, 0x6a, 0x7c, 0x51, 0x55, 0xe3, 0x34, 0xb2, 0x81, 0x98, 0x7a, 0x13, 0x66, 0x93, 0x76, - 0x41, 0x6e, 0x43, 0x51, 0x68, 0x77, 0xb4, 0xcc, 0xf9, 0xb1, 0xcb, 0x18, 0x11, 0xa6, 0xfe, 0x7e, - 0x8a, 0x1b, 0x74, 0x4b, 0x2f, 0xb2, 0xd2, 0xd8, 0xf6, 0xe3, 0x2f, 0x72, 0x00, 0x83, 0xbc, 0x61, - 0xc8, 0xde, 0xb8, 0x55, 0xd8, 0xa1, 0xc3, 0x62, 0xab, 0xe0, 0x83, 0x74, 0x87, 0x39, 0x3b, 0xdc, - 0x61, 0x6e, 0x40, 0x29, 0x4a, 0x00, 0x50, 0xc0, 0x55, 0x23, 0x1e, 0xf3, 0xc2, 0x38, 0xf0, 0xfc, - 0xb0, 0xed, 0xf9, 0x16, 0xf3, 0x51, 0x8d, 0xab, 0x46, 0x99, 0x43, 0x9e, 0x72, 0x40, 0x1c, 0xba, - 0x0a, 0x38, 0x81, 0xdf, 0x22, 0x86, 0xca, 0xbc, 0xbd, 0x88, 0xf0, 0x38, 0x35, 0x1f, 0x6a, 0x98, - 0x94, 0x86, 0x1a, 0x26, 0xf8, 0x47, 0x26, 0xea, 0xb6, 0xf1, 0x25, 0x1c, 0x15, 0xb1, 0xc4, 0xd9, - 0x71, 0x9b, 0xf8, 0x47, 0x9e, 0x4b, 0x00, 0x3c, 0xbf, 0xa0, 0x26, 0x46, 0x60, 0x10, 0xec, 0x30, - 0xd7, 0x5a, 0x44, 0x00, 0x9f, 0xc6, 0xae, 0x86, 0xe8, 0x25, 0x56, 0xc4, 0x34, 0x87, 0x18, 0x1c, - 0x90, 0x68, 0x4b, 0xcd, 0x1c, 0xde, 0x96, 0xaa, 0x4e, 0x65, 0x3e, 0x5f, 0x48, 0xe4, 0x4c, 0xb3, - 0x47, 0xd2, 0x2a, 0x19, 0xd3, 0xdb, 0x4a, 0xc6, 0x34, 0x77, 0x24, 0x61, 0x9c, 0x2f, 0x35, 0xa0, - 0x64, 0xf5, 0x7d, 0x8c, 0x5d, 0xf5, 0x9a, 0xb8, 0xb3, 0x68, 0xac, 0x6f, 0xc2, 0xec, 0x40, 0x4b, - 0x50, 0x0b, 0xef, 0x42, 0x65, 0x90, 0xec, 0x46, 0x9a, 0x78, 0x4e, 0xd5, 0x44, 0x25, 0x79, 0x56, - 0x51, 0xc7, 0xaa, 0xe2, 0x1f, 0x35, 0x38, 0x93, 0x4e, 0xb8, 0xff, 0x13, 0xba, 0x5a, 0xff, 0xcc, - 0xc0, 0x99, 0x0d, 0x74, 0x6d, 0xb2, 0xf5, 0x14, 0xc5, 0x48, 0xb5, 0xb7, 0xaa, 0x4d, 0xd5, 0x5b, - 0x7d, 0x17, 0x66, 0x2c, 0x3b, 0xe8, 0x39, 0xf4, 0xa0, 0x8d, 0xd4, 0x99, 0x09, 0xa8, 0x2b, 0x92, - 0x62, 0x95, 0xa2, 0x73, 0x56, 0x9f, 0x72, 0x26, 0x49, 0x2c, 0x95, 0x87, 0x9e, 0x3b, 0xca, 0xf3, - 0x51, 0x6e, 0x02, 0xd2, 0xf8, 0x71, 0xe9, 0x2e, 0x94, 0x1c, 0x4f, 0x64, 0x47, 0xb2, 0xfc, 0x3e, - 0xe2, 0xc0, 0x11, 0x36, 0xa7, 0xe4, 0xea, 0xfc, 0xa1, 0xe7, 0xb2, 0x89, 0x6a, 0xf0, 0x18, 0x5b, - 0xff, 0x5d, 0x06, 0x88, 0x90, 0xfe, 0x84, 0x5d, 0x45, 0xee, 0xed, 0x27, 0x16, 0xaa, 0xe8, 0x90, - 0xdd, 0x1b, 0xf6, 0x87, 0x47, 0xdf, 0x86, 0xe2, 0x2d, 0x5f, 0x58, 0xa0, 0xc9, 0x6b, 0xcc, 0x4f, - 0x77, 0x8d, 0xd1, 0x7b, 0x5d, 0x61, 0xb2, 0xf7, 0x3a, 0xfd, 0x47, 0x39, 0xc8, 0xe1, 0x63, 0x52, - 0x3a, 0x48, 0xa8, 0x7f, 0xec, 0xc8, 0xa4, 0xfe, 0xd8, 0xf1, 0x6a, 0x4a, 0x53, 0xa3, 0x58, 0xa1, - 0xe8, 0xe2, 0x11, 0x7f, 0x19, 0x38, 0xfc, 0xb1, 0x32, 0xd6, 0x27, 0xf9, 0x58, 0x19, 0x6b, 0x4c, - 0x43, 0xd1, 0x18, 0xf9, 0x5e, 0x10, 0x8d, 0x13, 0x4e, 0xbb, 0x94, 0x72, 0xda, 0x57, 0xa0, 0xa2, - 0xbc, 0xd6, 0x62, 0xb4, 0x28, 0x1b, 0x30, 0x78, 0xac, 0xe5, 0xc1, 0x44, 0x48, 0x8a, 0x4f, 0x83, - 0xa0, 0x16, 0x80, 0x96, 0x45, 0xae, 0x41, 0xb5, 0x43, 0xbb, 0xcc, 0xc4, 0x50, 0xc3, 0x11, 0x2a, - 0xa2, 0x2f, 0x30, 0x00, 0x8a, 0xac, 0x3d, 0x08, 0x19, 0xc5, 0xbf, 0xd5, 0xce, 0xc8, 0x72, 0x89, - 0x8f, 0x5b, 0xd8, 0xac, 0xf5, 0x5c, 0xc7, 0x76, 0x45, 0xb4, 0x28, 0x19, 0x72, 0x94, 0x7a, 0x2b, - 0x9d, 0x4d, 0xbf, 0x95, 0xa6, 0x22, 0xcd, 0xdc, 0x71, 0x12, 0xb5, 0xda, 0x54, 0x89, 0xda, 0x77, - 0x32, 0x50, 0x8d, 0xcb, 0xe2, 0xe8, 0xf9, 0x12, 0x53, 0xab, 0xc4, 0xc3, 0xe8, 0xb5, 0xf4, 0x8b, - 0x63, 0x8c, 0x3f, 0x18, 0x19, 0xd0, 0x8f, 0xeb, 0xeb, 0xc6, 0xa7, 0x1a, 0x94, 0xe3, 0x19, 0x72, - 0x03, 0xf2, 0xb8, 0x9c, 0x74, 0x93, 0x23, 0x9e, 0x59, 0xc5, 0xfc, 0xe7, 0xf3, 0x82, 0x79, 0x0b, - 0xf2, 0x58, 0xb0, 0x91, 0xff, 0x86, 0xbc, 0xfa, 0x66, 0x3b, 0xfc, 0xcc, 0x2a, 0xa6, 0xf5, 0x8f, - 0x32, 0x70, 0x09, 0x33, 0xec, 0x63, 0xfe, 0xf1, 0x84, 0x7c, 0x0d, 0x0a, 0x22, 0xb4, 0xc9, 0xf3, - 0xde, 0x57, 0x77, 0x3c, 0x74, 0x87, 0xe1, 0xb8, 0x87, 0xe8, 0x86, 0x5c, 0xaf, 0xb1, 0x05, 0xe7, - 0x46, 0x63, 0x0c, 0xde, 0xf5, 0xb4, 0x71, 0xef, 0x7a, 0x99, 0xd4, 0xbb, 0x9e, 0x6a, 0x6e, 0xd9, - 0xa4, 0xb9, 0xe9, 0xdf, 0xcb, 0x00, 0xc1, 0x75, 0x8f, 0x5b, 0x48, 0xc5, 0xf5, 0x52, 0x76, 0x4c, - 0xbd, 0x94, 0x4b, 0x56, 0x00, 0x2b, 0xc3, 0xf5, 0xd2, 0x04, 0x1d, 0xe1, 0x74, 0x31, 0xf5, 0x60, - 0x44, 0x31, 0x35, 0x41, 0xbb, 0x29, 0x5d, 0x69, 0xe9, 0xcf, 0xa1, 0x31, 0x2c, 0x85, 0x60, 0x90, - 0x28, 0xa4, 0x32, 0xfe, 0xcb, 0x43, 0xf7, 0x3c, 0xa6, 0x80, 0xf8, 0x6e, 0x06, 0x2e, 0xe2, 0x7c, - 0x3a, 0xb1, 0x9a, 0xaa, 0x91, 0xf9, 0x3c, 0xa5, 0x66, 0xf7, 0x86, 0xb6, 0x1f, 0xb3, 0xfc, 0x7c, - 0x1a, 0x9e, 0x54, 0x32, 0x06, 0x67, 0x47, 0x22, 0x9c, 0xac, 0x8e, 0x2d, 0x7d, 0x19, 0xce, 0x9b, - 0x5e, 0x77, 0x7e, 0x9b, 0xf9, 0x9e, 0x6d, 0x3a, 0x74, 0x33, 0x50, 0xd8, 0x5f, 0x2a, 0xaf, 0xe2, - 0xf7, 0x62, 0xcf, 0x7e, 0xa6, 0x7d, 0x3d, 0x4b, 0x7b, 0xf6, 0xcf, 0x33, 0xb9, 0xd5, 0x47, 0xcf, - 0x96, 0x7e, 0x95, 0x29, 0x88, 0x99, 0xcd, 0x02, 0xde, 0xe0, 0xed, 0x7f, 0x07, 0x00, 0x00, 0xff, - 0xff, 0xfe, 0x68, 0x64, 0x13, 0x00, 0x32, 0x00, 0x00, + // 3343 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x3a, 0x5b, 0x8f, 0x1c, 0x47, + 0xd5, 0xe9, 0xb9, 0xcf, 0x99, 0x9d, 0xdd, 0x71, 0xf9, 0xf2, 0x8d, 0xc7, 0xd7, 0xb4, 0x9d, 0xcf, + 0x8e, 0xf2, 0x7d, 0xe3, 0x64, 0x4d, 0xb0, 0x49, 0x88, 0xe3, 0xbd, 0x8c, 0xad, 0x89, 0xed, 0xb5, + 0xe9, 0xb5, 0x0d, 0x82, 0x87, 0x49, 0x6d, 0x77, 0x79, 0xb6, 0xd9, 0x9e, 0xee, 0x4e, 0x77, 0xcf, + 0x5e, 0x22, 0x78, 0x00, 0x21, 0x91, 0x27, 0x84, 0x78, 0xe2, 0x05, 0x88, 0x10, 0x42, 0x09, 0x48, + 0xfc, 0x02, 0xde, 0x79, 0x47, 0xdc, 0xde, 0x80, 0x47, 0x24, 0xfe, 0x01, 0x12, 0x42, 0x75, 0xaa, + 0xfa, 0x3a, 0x33, 0xbb, 0x33, 0xde, 0x75, 0x22, 0xf1, 0x32, 0xea, 0x3a, 0x75, 0x4e, 0xd5, 0xa9, + 0x53, 0xe7, 0x5e, 0x03, 0x75, 0xea, 0x9a, 0xd7, 0xa8, 0x6b, 0xb6, 0x5d, 0xcf, 0x09, 0x1c, 0x02, + 0x36, 0xdd, 0xa2, 0x03, 0xda, 0xa6, 0xae, 0xd9, 0xba, 0xd0, 0x77, 0x9c, 0xbe, 0xc5, 0xae, 0xe1, + 0xcc, 0xc6, 0xf0, 0xd9, 0xb5, 0xc0, 0x1c, 0x30, 0x3f, 0xa0, 0x03, 0x57, 0x20, 0xb7, 0xce, 0x67, + 0x11, 0x76, 0x3c, 0xea, 0xba, 0xcc, 0xf3, 0xc5, 0xbc, 0xfa, 0x4f, 0x05, 0xca, 0x4b, 0xba, 0xee, + 0x0c, 0xed, 0x80, 0x5c, 0x86, 0xc2, 0xd0, 0x67, 0x5e, 0x53, 0xb9, 0xa8, 0x5c, 0xad, 0x2d, 0x36, + 0xda, 0xf1, 0x3e, 0xed, 0x27, 0x3e, 0xf3, 0x34, 0x9c, 0x25, 0xa7, 0xa0, 0xb4, 0x43, 0x2d, 0x8b, + 0x05, 0xcd, 0xdc, 0x45, 0xe5, 0x6a, 0x55, 0x93, 0x23, 0x72, 0x02, 0x8a, 0x6c, 0x40, 0x4d, 0xab, + 0x99, 0x47, 0xb0, 0x18, 0x90, 0xeb, 0x50, 0x36, 0xd8, 0xb6, 0xa9, 0x33, 0xbf, 0x59, 0xb8, 0x98, + 0xbf, 0x5a, 0x5b, 0x3c, 0x9d, 0x5c, 0x56, 0xee, 0xbc, 0x8a, 0x18, 0x5a, 0x88, 0x49, 0xce, 0x40, + 0x55, 0x1f, 0xfa, 0x81, 0x33, 0xe8, 0x99, 0x46, 0xb3, 0x88, 0xcb, 0x55, 0x04, 0xa0, 0x6b, 0x90, + 0xb7, 0xa1, 0xb6, 0xcd, 0x3c, 0xf3, 0xd9, 0x5e, 0x8f, 0x9f, 0xb5, 0x59, 0x42, 0x66, 0x5b, 0x6d, + 0x71, 0xce, 0x76, 0x78, 0xce, 0xf6, 0xe3, 0x50, 0x10, 0x1a, 0x08, 0x74, 0x0e, 0x50, 0x2f, 0x40, + 0x5d, 0xee, 0xb9, 0x82, 0xeb, 0x91, 0x79, 0xc8, 0x99, 0x06, 0x9e, 0xb8, 0xaa, 0xe5, 0x4c, 0x23, + 0x81, 0x20, 0x98, 0x1a, 0x41, 0xb8, 0x0d, 0x73, 0x12, 0xa1, 0x83, 0x07, 0x8c, 0x8e, 0xad, 0x24, + 0x8f, 0xdd, 0x82, 0x8a, 0x4b, 0x7d, 0x7f, 0xc7, 0xf1, 0x0c, 0x29, 0xa6, 0x68, 0xac, 0x5e, 0x81, + 0x05, 0xb9, 0xc2, 0x1d, 0xaa, 0xb3, 0x0d, 0xc7, 0xd9, 0xe2, 0x8b, 0x04, 0xce, 0x16, 0xb3, 0xc3, + 0x45, 0x70, 0xa0, 0xfe, 0x5e, 0x81, 0x63, 0x12, 0xf3, 0x2e, 0x1d, 0xb0, 0x15, 0x66, 0x07, 0xcc, + 0xe3, 0xc2, 0x71, 0x2d, 0xba, 0xc7, 0xbc, 0x5e, 0xc4, 0x57, 0x45, 0x00, 0xba, 0x06, 0x9f, 0xdc, + 0x18, 0xda, 0x86, 0xc5, 0xf8, 0xa4, 0xdc, 0x58, 0x00, 0xba, 0x06, 0x79, 0x0d, 0x8e, 0x45, 0xea, + 0xd1, 0xf3, 0x99, 0xee, 0xd8, 0x86, 0x8f, 0xb7, 0x95, 0xd7, 0x1a, 0xd1, 0xc4, 0xba, 0x80, 0x13, + 0x02, 0x05, 0x9f, 0x5a, 0x41, 0xb3, 0x80, 0x8b, 0xe0, 0x37, 0x39, 0x0b, 0x55, 0xdf, 0xec, 0xdb, + 0x34, 0x18, 0x7a, 0x4c, 0xde, 0x4b, 0x0c, 0x20, 0x97, 0x61, 0xde, 0x1d, 0x6e, 0x58, 0xa6, 0xde, + 0xdb, 0x62, 0x7b, 0xbd, 0xa1, 0x67, 0xe1, 0xdd, 0x54, 0xb5, 0x39, 0x01, 0xbd, 0xc7, 0xf6, 0x9e, + 0x78, 0x96, 0xfa, 0x4a, 0x24, 0xe0, 0xbb, 0x78, 0x63, 0x13, 0xce, 0x7e, 0x39, 0x12, 0xf3, 0x7a, + 0xc0, 0xe8, 0x60, 0x02, 0xd6, 0x0a, 0x1c, 0x5b, 0x32, 0x8c, 0x3b, 0x9e, 0xc9, 0x6c, 0xc3, 0xd7, + 0xd8, 0x07, 0x43, 0xe6, 0x07, 0xa4, 0x01, 0x79, 0xd3, 0xf0, 0x9b, 0xca, 0xc5, 0xfc, 0xd5, 0xaa, + 0xc6, 0x3f, 0x39, 0xdf, 0x5c, 0x75, 0x6d, 0x3a, 0x60, 0x7e, 0x33, 0x87, 0xf0, 0x18, 0xa0, 0xde, + 0x87, 0x13, 0x4b, 0x86, 0x71, 0xd7, 0x73, 0x86, 0x2e, 0x57, 0xf3, 0x68, 0x9d, 0xd3, 0x50, 0xe9, + 0x73, 0x60, 0x2c, 0xe7, 0x32, 0x8e, 0xbb, 0x06, 0x9f, 0xe2, 0xf4, 0x3d, 0xbe, 0x8f, 0x58, 0xaf, + 0xcc, 0xc7, 0x5d, 0xc3, 0x57, 0x3f, 0x56, 0xe0, 0xf4, 0xd2, 0x30, 0xd8, 0x64, 0x76, 0x60, 0xea, + 0x34, 0x60, 0x42, 0xcf, 0xc2, 0x35, 0xaf, 0x43, 0x99, 0x8a, 0x63, 0x49, 0x2b, 0x1b, 0x67, 0x0e, + 0x92, 0x24, 0xc4, 0x24, 0x8b, 0x50, 0xd2, 0x3d, 0x46, 0x03, 0x86, 0x37, 0x3a, 0x4e, 0xd9, 0x97, + 0x1d, 0xc7, 0x7a, 0x4a, 0xad, 0x21, 0xd3, 0x24, 0x26, 0x57, 0xc0, 0xf0, 0x84, 0xd2, 0x20, 0xa3, + 0xf1, 0x08, 0x8b, 0xd2, 0xfc, 0x66, 0x61, 0x31, 0xb4, 0xd8, 0x17, 0xc5, 0xe2, 0x4f, 0x15, 0x68, + 0x26, 0x59, 0x44, 0x5b, 0x0b, 0x39, 0x5c, 0xcc, 0x72, 0xd8, 0x1c, 0xc3, 0xa1, 0xa0, 0x78, 0x61, + 0x0c, 0xfe, 0x41, 0x81, 0x33, 0x49, 0x06, 0x43, 0x53, 0x0e, 0x79, 0x7c, 0x33, 0xcb, 0xe3, 0x99, + 0x31, 0x3c, 0x46, 0x44, 0x2f, 0x8a, 0x4d, 0xd2, 0x86, 0x82, 0xbf, 0x67, 0xeb, 0x68, 0xc5, 0xfb, + 0xaf, 0x86, 0x78, 0xea, 0x27, 0x0a, 0x9c, 0x4b, 0x1e, 0x2b, 0xf6, 0x3b, 0xe1, 0xc1, 0x6e, 0x64, + 0x0f, 0x76, 0x6e, 0xcc, 0xc1, 0x12, 0x64, 0x9f, 0x99, 0x16, 0x0b, 0x77, 0x32, 0x93, 0x16, 0x4b, + 0x92, 0xcf, 0x4c, 0x8b, 0xd1, 0x95, 0xcd, 0xa4, 0xc5, 0x82, 0xe2, 0x85, 0x31, 0xd8, 0x81, 0xe3, + 0xcb, 0x96, 0xa3, 0x6f, 0x1d, 0xd2, 0x83, 0x7e, 0x94, 0x87, 0xf9, 0x95, 0x4d, 0x6a, 0xdb, 0xcc, + 0x7a, 0xc0, 0x7c, 0x9f, 0xf6, 0x19, 0x39, 0x07, 0xa0, 0x0b, 0x48, 0xec, 0x3e, 0xab, 0x12, 0xd2, + 0x35, 0xf8, 0xf4, 0x40, 0x60, 0xc6, 0x81, 0xaa, 0x2a, 0x21, 0x5d, 0x83, 0x5c, 0x83, 0x82, 0xee, + 0x18, 0x82, 0x5f, 0x6e, 0x3a, 0xd9, 0x53, 0x76, 0xed, 0xe0, 0xfa, 0xa2, 0xd4, 0x5b, 0x8e, 0xc8, + 0xe3, 0x9e, 0xcf, 0x6c, 0x43, 0x04, 0x45, 0x11, 0xb2, 0x2a, 0x02, 0xd0, 0x35, 0x52, 0x12, 0x28, + 0x66, 0x0c, 0xa4, 0x09, 0x65, 0xdd, 0xb1, 0x03, 0x66, 0x07, 0x32, 0x5a, 0x85, 0x43, 0x9e, 0x67, + 0x08, 0x09, 0x8a, 0x3c, 0xa3, 0x7c, 0x70, 0x9e, 0x21, 0xd0, 0x39, 0x80, 0x13, 0x0f, 0x5d, 0x23, + 0x22, 0xae, 0x1c, 0x4c, 0x2c, 0xd0, 0x91, 0xf8, 0x2d, 0x00, 0x9e, 0xa1, 0x99, 0x3e, 0xb2, 0x55, + 0x3d, 0xf0, 0xa6, 0x13, 0xd8, 0xea, 0x0f, 0x14, 0x20, 0xe9, 0xab, 0xb8, 0x6f, 0xfa, 0x01, 0xf9, + 0x22, 0x54, 0xa4, 0x74, 0xc5, 0xb5, 0xf2, 0x05, 0x13, 0xda, 0x96, 0xa6, 0xd0, 0x22, 0x5c, 0x72, + 0x01, 0x6a, 0x36, 0xdb, 0x0d, 0x7a, 0xfa, 0xd0, 0xf3, 0x1d, 0x4f, 0x5e, 0x14, 0x70, 0xd0, 0x0a, + 0x42, 0x38, 0x82, 0xeb, 0xb1, 0xed, 0x10, 0x41, 0x28, 0x18, 0x70, 0x90, 0x40, 0x50, 0x7f, 0xcc, + 0x19, 0x42, 0xc1, 0x60, 0x84, 0x0d, 0x55, 0x8c, 0x40, 0x01, 0xef, 0x43, 0x68, 0x06, 0x7e, 0x93, + 0x8b, 0x50, 0x33, 0x98, 0xaf, 0x7b, 0xa6, 0x1b, 0x98, 0x8e, 0x2d, 0x37, 0x4b, 0x82, 0x78, 0xdc, + 0xb5, 0xa8, 0xdd, 0xef, 0x05, 0xb4, 0x2f, 0xb7, 0x2a, 0xf3, 0xf1, 0x63, 0xda, 0xe7, 0x1a, 0x45, + 0xb7, 0x69, 0x40, 0x3d, 0xcc, 0x3c, 0x84, 0x0a, 0x54, 0x05, 0xe4, 0x89, 0x67, 0xf1, 0xfd, 0x1c, + 0x97, 0xd9, 0x78, 0xff, 0x15, 0x0d, 0xbf, 0xd5, 0x3b, 0x70, 0x62, 0x95, 0x59, 0x2c, 0x60, 0x87, + 0x54, 0xff, 0x6b, 0x40, 0xc4, 0x3a, 0xa9, 0x13, 0x4e, 0x4e, 0x1f, 0xd4, 0xbb, 0x70, 0x5e, 0x10, + 0xdc, 0x67, 0xd4, 0x60, 0xde, 0x86, 0x43, 0x3d, 0x43, 0x63, 0xba, 0xc3, 0x7f, 0x05, 0xf1, 0x2b, + 0x30, 0x6f, 0xc5, 0x73, 0xf1, 0x12, 0xf5, 0x04, 0xb4, 0x6b, 0xa8, 0x6d, 0x68, 0x89, 0x85, 0xd6, + 0x9c, 0xc0, 0x7c, 0xc6, 0x7d, 0x8c, 0xe9, 0xd8, 0x93, 0xcf, 0xa1, 0xea, 0x70, 0x52, 0xe0, 0xaf, + 0x07, 0x8e, 0x47, 0xfb, 0xec, 0xe1, 0xc6, 0x37, 0x99, 0x1e, 0x74, 0x0d, 0x72, 0x1e, 0x40, 0x77, + 0x2c, 0x8b, 0xe9, 0x28, 0x79, 0xb1, 0x57, 0x02, 0xc2, 0x97, 0xda, 0x62, 0x7b, 0xf2, 0x4a, 0xf8, + 0x27, 0x37, 0x9c, 0x6d, 0xae, 0x76, 0x8e, 0x1d, 0xde, 0x84, 0x1c, 0xaa, 0x3d, 0x38, 0x33, 0x66, + 0x93, 0x88, 0xab, 0xdb, 0x00, 0x0e, 0x42, 0x7a, 0x21, 0x73, 0xb5, 0xc5, 0x97, 0x93, 0xca, 0x38, + 0x96, 0x43, 0xad, 0xea, 0xc8, 0x2f, 0x5f, 0xfd, 0xb3, 0x02, 0xc5, 0xce, 0x36, 0xb7, 0xd1, 0x71, + 0x5a, 0xb4, 0x04, 0xe0, 0x7a, 0x8e, 0xcb, 0xbc, 0xc0, 0x94, 0x97, 0x95, 0x59, 0x1f, 0x49, 0xdb, + 0x8f, 0x22, 0x9c, 0x8e, 0x1d, 0x78, 0x7b, 0x5a, 0x82, 0x88, 0xdc, 0x84, 0x6a, 0x94, 0x0f, 0x4b, + 0x1f, 0xb4, 0x9f, 0xed, 0xc6, 0xc8, 0xad, 0x77, 0x60, 0x21, 0xb3, 0x70, 0x28, 0x3a, 0x25, 0x16, + 0xdd, 0x09, 0x28, 0x6e, 0x73, 0xc3, 0x95, 0xe2, 0x14, 0x83, 0xb7, 0x72, 0x37, 0x15, 0xf5, 0x53, + 0x05, 0x4a, 0x42, 0x19, 0xa7, 0x2c, 0xc6, 0xde, 0x80, 0xa2, 0x1f, 0xc4, 0xf1, 0x60, 0x5f, 0x4f, + 0x29, 0x30, 0xd5, 0x3b, 0x50, 0x5c, 0xe7, 0x1f, 0x04, 0xa0, 0x74, 0x47, 0xeb, 0x76, 0xd6, 0x56, + 0x1b, 0x2f, 0x91, 0x05, 0xa8, 0x75, 0xd7, 0x9e, 0x76, 0x1f, 0x77, 0x7a, 0xeb, 0x9d, 0xb5, 0xc7, + 0x0d, 0x85, 0x1c, 0x87, 0x05, 0x09, 0xd0, 0x3a, 0x2b, 0x9d, 0xee, 0xd3, 0xce, 0x6a, 0x23, 0x47, + 0x6a, 0x50, 0x5e, 0xbe, 0xff, 0x70, 0xe5, 0x5e, 0x67, 0xb5, 0x91, 0x57, 0x6f, 0x40, 0x59, 0xda, + 0x0d, 0xf9, 0x3f, 0x28, 0x3f, 0x13, 0x9f, 0xf2, 0x3e, 0x49, 0x92, 0x5d, 0x81, 0xa5, 0x85, 0x28, + 0xaa, 0x01, 0x0b, 0x77, 0x59, 0x90, 0x4a, 0xb5, 0x67, 0xb4, 0x38, 0xf2, 0x32, 0xcc, 0x3d, 0x93, + 0xb9, 0x13, 0x6a, 0x51, 0x1e, 0x11, 0x6a, 0x21, 0x8c, 0x2b, 0xc9, 0x27, 0x79, 0x28, 0xa2, 0x3d, + 0x66, 0x2b, 0x38, 0x0c, 0x4d, 0xdc, 0x21, 0x39, 0x5e, 0x22, 0xf6, 0x48, 0x48, 0xd7, 0x88, 0x74, + 0x2a, 0x3f, 0xd9, 0x33, 0x15, 0xf6, 0xf7, 0x4c, 0xc5, 0xb4, 0x67, 0x6a, 0x71, 0xdf, 0x1b, 0x50, + 0x83, 0x06, 0x54, 0xc6, 0x98, 0x68, 0x9c, 0xf1, 0x5a, 0xe5, 0xac, 0xd7, 0x6a, 0x4b, 0xaf, 0x55, + 0x39, 0x38, 0x7d, 0xe3, 0x78, 0x7c, 0x39, 0x66, 0xf4, 0x59, 0x4f, 0xa4, 0x15, 0x3c, 0x72, 0x14, + 0xb5, 0x2a, 0x87, 0xac, 0x60, 0xfa, 0x70, 0x06, 0xaa, 0x03, 0xba, 0x2b, 0x67, 0x01, 0x67, 0x2b, + 0x03, 0xba, 0x2b, 0x26, 0x33, 0xf1, 0xae, 0x76, 0x98, 0x78, 0x37, 0x37, 0x4b, 0xbc, 0x53, 0xd7, + 0xa0, 0x8a, 0x37, 0x85, 0x91, 0xea, 0x55, 0x28, 0xa1, 0x9b, 0x0c, 0x55, 0xe9, 0x58, 0x52, 0x95, + 0x84, 0x83, 0x95, 0x08, 0xe4, 0x14, 0x94, 0x52, 0x71, 0x49, 0x8e, 0xd4, 0x7f, 0x2b, 0x50, 0x8f, + 0xca, 0x39, 0x5c, 0x74, 0x15, 0x6a, 0xc2, 0x17, 0x73, 0x15, 0x0a, 0x57, 0xbe, 0x34, 0xb2, 0x72, + 0x88, 0x1f, 0x8f, 0x34, 0xe8, 0x47, 0x75, 0x61, 0xeb, 0x97, 0x8a, 0x64, 0x94, 0x0f, 0x5f, 0x9c, + 0x81, 0xde, 0x0e, 0x0d, 0x74, 0x1e, 0x60, 0xfd, 0xc9, 0xa3, 0x8e, 0xb6, 0xb4, 0xfa, 0xa0, 0xbb, + 0xd6, 0x78, 0x89, 0x54, 0xa1, 0x28, 0x3e, 0x15, 0x6e, 0xbb, 0x0f, 0x3a, 0x0f, 0x96, 0x3b, 0x5a, + 0x23, 0x47, 0x1a, 0x30, 0xf7, 0xde, 0xc3, 0xee, 0x5a, 0x4f, 0xeb, 0x7c, 0xe5, 0x49, 0x67, 0xfd, + 0x71, 0x23, 0xaf, 0x7e, 0x5f, 0x81, 0xb3, 0xdd, 0x81, 0xeb, 0x78, 0x51, 0x85, 0x91, 0x89, 0x70, + 0xcf, 0x59, 0x9d, 0xbc, 0x0e, 0x45, 0x8f, 0xf9, 0xb2, 0xf3, 0xb3, 0xbf, 0x3e, 0x0a, 0x44, 0xf5, + 0xff, 0xa1, 0xf1, 0x9e, 0x63, 0xda, 0xd3, 0x06, 0xc6, 0x2f, 0xc3, 0x49, 0x8e, 0xfe, 0xd8, 0x19, + 0xa2, 0xa1, 0xdb, 0x41, 0x48, 0x73, 0x09, 0xea, 0x41, 0x04, 0x8c, 0x09, 0xe7, 0x62, 0x60, 0xd7, + 0x50, 0x1f, 0xc0, 0xc9, 0x7b, 0xa6, 0xbe, 0x75, 0x54, 0x95, 0xfc, 0x3f, 0xf2, 0x70, 0x6c, 0x24, + 0x40, 0x4f, 0x19, 0x99, 0xf9, 0xba, 0xce, 0x8e, 0xcd, 0x12, 0x2e, 0xa6, 0x8c, 0xe3, 0xae, 0x41, + 0x6e, 0x66, 0x12, 0xf2, 0xda, 0xe2, 0xd9, 0x11, 0x41, 0xae, 0x07, 0x9e, 0x69, 0xf7, 0x85, 0x28, + 0xe3, 0x64, 0xf5, 0x04, 0x14, 0x7d, 0xdd, 0xf1, 0x18, 0x3a, 0xa0, 0xbc, 0x26, 0x06, 0xdc, 0xbf, + 0xf8, 0xc3, 0x0d, 0x31, 0x51, 0xc4, 0x89, 0x68, 0xcc, 0x2d, 0xde, 0x1e, 0x0e, 0x7a, 0x62, 0xb2, + 0x24, 0x2c, 0xde, 0x1e, 0x0e, 0xd6, 0x43, 0xc2, 0xc8, 0x31, 0x95, 0x33, 0x8e, 0x29, 0xe3, 0x0d, + 0x2a, 0x87, 0xf1, 0x06, 0xd5, 0x99, 0xb2, 0xdf, 0xb7, 0xa1, 0xc6, 0x76, 0x5d, 0xd3, 0x93, 0xfd, + 0x3d, 0x38, 0x98, 0x58, 0xa0, 0x23, 0x31, 0x81, 0x82, 0x47, 0xed, 0x2d, 0xf4, 0x5e, 0x79, 0x0d, + 0xbf, 0x89, 0x0a, 0x75, 0xee, 0xf5, 0x62, 0x39, 0x70, 0xef, 0x54, 0xd7, 0x6a, 0x03, 0xba, 0xbb, + 0x26, 0x45, 0xa1, 0xfe, 0x49, 0x81, 0x93, 0x23, 0x77, 0x8d, 0xae, 0xe3, 0x06, 0x94, 0x3d, 0x1c, + 0x85, 0x6e, 0x23, 0x55, 0xef, 0x8e, 0x26, 0x70, 0x21, 0x36, 0x59, 0x86, 0xba, 0xd0, 0x80, 0x90, + 0x3c, 0x37, 0x0d, 0xf9, 0x1c, 0xd2, 0x68, 0x72, 0x8d, 0x4c, 0xfa, 0x9d, 0x3f, 0x28, 0xfd, 0x2e, + 0x8c, 0xa4, 0xdf, 0x6d, 0xd4, 0xe1, 0xed, 0xa9, 0x53, 0xd3, 0x6f, 0xc1, 0xf1, 0xfb, 0xa6, 0xbd, + 0x75, 0x44, 0xed, 0x8c, 0x59, 0xdb, 0x0f, 0xbf, 0x55, 0xa0, 0xc5, 0xa5, 0x9e, 0xae, 0x47, 0x22, + 0x3b, 0x3e, 0xa0, 0xa8, 0x7c, 0x03, 0x8a, 0x96, 0x39, 0x30, 0x83, 0xa9, 0x7c, 0x2d, 0x62, 0x92, + 0x2f, 0x40, 0xf9, 0x99, 0xe3, 0xed, 0x50, 0xcf, 0x98, 0x98, 0xe7, 0xc5, 0x3c, 0x86, 0xa8, 0x89, + 0xc0, 0x53, 0x48, 0x05, 0x1e, 0x0f, 0x8e, 0x71, 0xee, 0x51, 0xd6, 0xfe, 0x7e, 0x95, 0xce, 0x84, + 0xc8, 0x15, 0x9f, 0x20, 0x3f, 0xed, 0x09, 0xd4, 0x45, 0x38, 0x19, 0xed, 0x39, 0xa5, 0xd3, 0x53, + 0x3f, 0x56, 0xe0, 0x2a, 0x27, 0x1a, 0x51, 0x3f, 0x7f, 0xc9, 0x73, 0x86, 0xb6, 0xf1, 0x50, 0xe8, + 0xe0, 0x2c, 0xa5, 0x08, 0x59, 0x4c, 0x0b, 0x7f, 0xd4, 0xa5, 0x3d, 0x19, 0x95, 0x7e, 0xd2, 0x49, + 0xe6, 0x53, 0x4e, 0x52, 0xfd, 0x8d, 0x02, 0xe7, 0xc6, 0xb3, 0x38, 0x23, 0x5f, 0x67, 0xa0, 0x1a, + 0xee, 0x11, 0x7a, 0xf8, 0x8a, 0xdc, 0xc4, 0x7f, 0x0e, 0x79, 0x4f, 0xbc, 0xfb, 0xbf, 0xe7, 0x80, + 0x70, 0x86, 0x1f, 0xd0, 0x40, 0xdf, 0x8c, 0x55, 0x36, 0xda, 0x41, 0x99, 0x7a, 0x87, 0xdb, 0x50, + 0xa7, 0xc3, 0x60, 0xd3, 0xf1, 0xcc, 0x80, 0x06, 0xe6, 0xf6, 0x34, 0xbd, 0x9e, 0x34, 0x01, 0xde, + 0x05, 0xdd, 0x60, 0xd6, 0x54, 0xe1, 0x45, 0xa0, 0x62, 0x87, 0xc0, 0xb4, 0x7b, 0xbe, 0xf9, 0x21, + 0x93, 0xe6, 0xba, 0x2f, 0xaf, 0xe5, 0x81, 0x69, 0xaf, 0x9b, 0x1f, 0x32, 0xa4, 0xa3, 0xbb, 0x82, + 0xae, 0x38, 0x0d, 0x1d, 0xdd, 0x45, 0xba, 0x45, 0x28, 0x7e, 0x30, 0x64, 0xde, 0x9e, 0x7c, 0xc0, + 0x39, 0x80, 0x47, 0x44, 0x55, 0x77, 0xa1, 0xc9, 0x45, 0x3c, 0xb6, 0xd8, 0x7d, 0x0e, 0x41, 0xbf, + 0x0a, 0x0d, 0x9d, 0xea, 0x9b, 0x8c, 0x6e, 0x58, 0x2c, 0xdd, 0xe1, 0x58, 0x88, 0xe0, 0xd2, 0x8d, + 0xfe, 0x4c, 0x81, 0xd3, 0x7c, 0xeb, 0xf1, 0x25, 0xed, 0xff, 0x40, 0x59, 0x26, 0x11, 0x52, 0x07, + 0x4b, 0x22, 0x87, 0xc8, 0x94, 0xd5, 0xb9, 0x91, 0xb2, 0xfa, 0x08, 0xf5, 0xef, 0x27, 0x0a, 0x5c, + 0xe1, 0x1c, 0x26, 0x73, 0xa7, 0x49, 0x26, 0x3d, 0x4d, 0x36, 0x75, 0xd4, 0x06, 0xfd, 0x6b, 0x05, + 0xce, 0x8e, 0xe5, 0x6f, 0x26, 0xa6, 0x3e, 0x2b, 0x6b, 0xfe, 0x6b, 0x0e, 0x4e, 0xa5, 0xb9, 0x8d, + 0xf8, 0x5c, 0x81, 0x79, 0x9d, 0x06, 0xac, 0xef, 0x78, 0x7b, 0x3d, 0x3f, 0xa0, 0x5e, 0xa8, 0x71, + 0xfb, 0x0b, 0xa8, 0x1e, 0xd2, 0xac, 0x73, 0x12, 0xf2, 0x2e, 0xcc, 0x45, 0x8b, 0x30, 0xdb, 0x98, + 0x4a, 0xc6, 0xb5, 0x90, 0xa2, 0x63, 0x1b, 0xe4, 0x6d, 0x00, 0xdc, 0x5c, 0x24, 0x49, 0xf9, 0x29, + 0xc8, 0xab, 0x88, 0x8f, 0x59, 0xd2, 0x0d, 0xa8, 0x30, 0xdb, 0x10, 0xa4, 0x85, 0x29, 0x48, 0xcb, + 0xcc, 0x36, 0x90, 0x30, 0x92, 0x70, 0xe9, 0x39, 0x24, 0x5c, 0x49, 0x49, 0xf8, 0x75, 0x11, 0xb7, + 0x78, 0xc8, 0x4a, 0xc7, 0xcb, 0x49, 0xc6, 0xa4, 0xfe, 0x50, 0x81, 0x22, 0x7a, 0x57, 0xae, 0x66, + 0x03, 0xfe, 0x91, 0x08, 0x6d, 0x38, 0xee, 0x1a, 0xe4, 0xf2, 0x38, 0xe7, 0x59, 0x39, 0x0a, 0x07, + 0x49, 0xa0, 0x10, 0x39, 0xc7, 0xa2, 0x86, 0xdf, 0xea, 0x4d, 0xa8, 0x22, 0x47, 0x98, 0x29, 0xbe, + 0x06, 0x82, 0x0b, 0x36, 0xb6, 0x74, 0x45, 0x3c, 0x2d, 0xc4, 0x50, 0xff, 0xa6, 0xc0, 0x5c, 0xd2, + 0x8f, 0x8d, 0x74, 0x29, 0x9a, 0x50, 0xf6, 0x87, 0xe8, 0x66, 0xc2, 0xfa, 0x41, 0x0e, 0x93, 0x2d, + 0xeb, 0x7c, 0xba, 0x65, 0x4d, 0x64, 0xdb, 0x5c, 0xb2, 0x38, 0xda, 0x19, 0x2f, 0x66, 0x3a, 0xe3, + 0x99, 0x2c, 0xbf, 0x34, 0x53, 0x96, 0x7f, 0x3e, 0xd5, 0xa6, 0x2e, 0xa3, 0x9c, 0x93, 0xad, 0xe8, + 0x6f, 0x43, 0x23, 0x79, 0x42, 0x94, 0xd1, 0x2d, 0xa8, 0xdb, 0x49, 0xef, 0x2d, 0x25, 0x95, 0x7a, + 0xfa, 0x48, 0x12, 0x69, 0x69, 0xf4, 0x59, 0x5c, 0xf6, 0x23, 0x68, 0x3e, 0xf2, 0x9c, 0x81, 0x23, + 0xdb, 0xb2, 0x47, 0x50, 0x10, 0xbe, 0x0f, 0xc7, 0x35, 0x46, 0x8d, 0xc3, 0xf7, 0x4e, 0x13, 0x2a, + 0x9e, 0x4f, 0xa9, 0xf8, 0x37, 0xe0, 0xf4, 0xc8, 0x0e, 0x11, 0xd3, 0xb7, 0xc6, 0x34, 0x4e, 0x2f, + 0x24, 0x05, 0x37, 0x86, 0xb9, 0x64, 0xdb, 0xf4, 0x3d, 0xc8, 0x6b, 0xae, 0x3e, 0x4e, 0xd1, 0x5c, + 0xba, 0x67, 0x39, 0x34, 0x2a, 0x54, 0xe5, 0x90, 0x8b, 0x62, 0x33, 0x08, 0xdc, 0x1e, 0xe7, 0x5e, + 0x6a, 0x1a, 0x1f, 0xdf, 0x63, 0x7b, 0xea, 0x53, 0x28, 0xaf, 0x33, 0xdf, 0xe7, 0xc7, 0xe3, 0xea, + 0x88, 0x4a, 0x21, 0x16, 0xad, 0x68, 0xe1, 0x30, 0x7e, 0xb3, 0xcf, 0x25, 0xde, 0xec, 0xb9, 0x42, + 0x0e, 0x0d, 0xb7, 0x27, 0x66, 0xc2, 0x07, 0x29, 0xc3, 0x7d, 0x8c, 0x0f, 0xfa, 0x7f, 0xc9, 0x41, + 0x3d, 0x75, 0x84, 0x23, 0x94, 0x6e, 0xdc, 0x77, 0x2d, 0x24, 0xfa, 0xae, 0xc9, 0x46, 0x76, 0x31, + 0xd5, 0xc8, 0x26, 0x57, 0x60, 0xc1, 0x65, 0xde, 0xc0, 0xc4, 0x73, 0xf6, 0x3c, 0x46, 0x0d, 0x59, + 0x42, 0xcf, 0xc7, 0x60, 0x2e, 0x73, 0xae, 0x95, 0x09, 0xc4, 0x1d, 0xcf, 0x0c, 0xc4, 0x7b, 0x51, + 0x51, 0x4b, 0x2c, 0xf0, 0x55, 0x0e, 0xfe, 0xfc, 0xea, 0x6a, 0x75, 0x07, 0x1a, 0x29, 0xc9, 0x2e, + 0xe9, 0x5b, 0x47, 0xd9, 0xf6, 0x4f, 0x8a, 0xbd, 0x90, 0x52, 0xea, 0x0e, 0x1c, 0xcb, 0x6e, 0xec, + 0x93, 0xd7, 0xa1, 0x40, 0xf5, 0xad, 0x50, 0x8d, 0xcf, 0x26, 0xd5, 0x38, 0x8b, 0xac, 0x21, 0xa6, + 0xda, 0x81, 0xf9, 0xb4, 0x5d, 0x90, 0xeb, 0x50, 0x16, 0xda, 0x1d, 0x2e, 0x73, 0x7a, 0xe2, 0x32, + 0x5a, 0x88, 0xa9, 0xbe, 0x9f, 0xe1, 0x06, 0xdd, 0xd2, 0xf3, 0xac, 0x34, 0xb1, 0xfd, 0xf8, 0x8b, + 0x02, 0x40, 0x9c, 0x37, 0x8c, 0xd8, 0x1b, 0xb7, 0x0a, 0x33, 0xb0, 0xa2, 0xee, 0x3f, 0x0e, 0xb2, + 0x1d, 0xe6, 0xfc, 0x68, 0x87, 0xb9, 0x05, 0x95, 0x30, 0x01, 0x40, 0x01, 0xd7, 0xb5, 0x68, 0xcc, + 0x0b, 0x63, 0xdf, 0xf1, 0x82, 0x9e, 0xe3, 0x19, 0xcc, 0x43, 0x35, 0xae, 0x6b, 0x55, 0x0e, 0x79, + 0xc8, 0x01, 0x51, 0xe8, 0x2a, 0xe1, 0x04, 0x7e, 0x8b, 0x18, 0x2a, 0xf3, 0xf6, 0x32, 0xc2, 0xa3, + 0xd4, 0x7c, 0xa4, 0x61, 0x52, 0x19, 0x69, 0x98, 0xe0, 0x5f, 0xb4, 0xa8, 0xdd, 0xc3, 0x37, 0x7e, + 0x54, 0xc4, 0x0a, 0x67, 0xc7, 0xee, 0xe0, 0x5f, 0x94, 0xce, 0x01, 0xf0, 0xfc, 0x82, 0xea, 0x18, + 0x81, 0x41, 0xb0, 0xc3, 0x6c, 0x63, 0x09, 0x01, 0x7c, 0x1a, 0xbb, 0x1a, 0xa2, 0x97, 0x58, 0x13, + 0xd3, 0x1c, 0xa2, 0x71, 0x40, 0xaa, 0x2d, 0x35, 0xb7, 0x7f, 0x5b, 0xaa, 0x3e, 0x93, 0xf9, 0x7c, + 0x29, 0x95, 0x33, 0xcd, 0x1f, 0xfc, 0xae, 0x13, 0x67, 0x4c, 0x6f, 0x26, 0x32, 0xa6, 0x85, 0x03, + 0x09, 0xa3, 0x7c, 0xa9, 0x05, 0x15, 0x63, 0xe8, 0x61, 0xec, 0x6a, 0x36, 0xc4, 0x9d, 0x85, 0x63, + 0x75, 0x03, 0xe6, 0x63, 0x2d, 0x41, 0x2d, 0xbc, 0x09, 0xb5, 0x38, 0xd9, 0x0d, 0x35, 0xf1, 0x54, + 0x52, 0x13, 0x13, 0xc9, 0x73, 0x12, 0x75, 0xa2, 0x2a, 0xfe, 0x51, 0x81, 0x13, 0xd9, 0x84, 0xfb, + 0xbf, 0xa1, 0xab, 0xf5, 0xaf, 0x1c, 0x9c, 0x78, 0x82, 0xae, 0x4d, 0xb6, 0x9e, 0xc2, 0x18, 0x99, + 0xec, 0xad, 0x2a, 0x33, 0xf5, 0x56, 0xdf, 0x85, 0x39, 0xc3, 0xf4, 0x5d, 0x8b, 0xee, 0xf5, 0x90, + 0x3a, 0x37, 0x05, 0x75, 0x4d, 0x52, 0xac, 0x51, 0x74, 0xce, 0xc9, 0xa7, 0x9c, 0x69, 0x12, 0xcb, + 0xc4, 0x43, 0xcf, 0x8d, 0xc4, 0xf3, 0x51, 0x61, 0x0a, 0xd2, 0xe8, 0x71, 0xe9, 0x26, 0x54, 0x2c, + 0x47, 0x64, 0x47, 0xb2, 0xfc, 0x3e, 0xe0, 0xc0, 0x21, 0x36, 0xa7, 0xe4, 0xea, 0xfc, 0xa1, 0x63, + 0xb3, 0xa9, 0x6a, 0xf0, 0x08, 0x5b, 0xfd, 0x5d, 0x0e, 0x88, 0x90, 0xfe, 0x94, 0x5d, 0x45, 0xee, + 0xed, 0xa7, 0x16, 0xaa, 0xe8, 0x90, 0xdd, 0x1a, 0xf5, 0x87, 0x07, 0xdf, 0x46, 0xc2, 0x5b, 0x3e, + 0xb7, 0x40, 0xd3, 0xd7, 0x58, 0x9c, 0xed, 0x1a, 0xc3, 0xf7, 0xba, 0xd2, 0x74, 0xef, 0x75, 0xea, + 0x8f, 0x0a, 0x50, 0xc0, 0xc7, 0xa4, 0x6c, 0x90, 0x48, 0xfe, 0x65, 0x25, 0x97, 0xf9, 0xcb, 0xca, + 0xcb, 0x19, 0x4d, 0x0d, 0x63, 0x45, 0x42, 0x17, 0x0f, 0xf8, 0x33, 0xc4, 0xfe, 0x8f, 0x95, 0x91, + 0x3e, 0xc9, 0xc7, 0xca, 0x48, 0x63, 0x5a, 0x09, 0x8d, 0x91, 0xef, 0x05, 0xe1, 0x38, 0xe5, 0xb4, + 0x2b, 0x19, 0xa7, 0x7d, 0x01, 0x6a, 0x89, 0xd7, 0x5a, 0x8c, 0x16, 0x55, 0x0d, 0xe2, 0xc7, 0x5a, + 0x1e, 0x4c, 0x84, 0xa4, 0xf8, 0x34, 0x08, 0x6a, 0x01, 0xe8, 0x1a, 0xe4, 0x12, 0xd4, 0xfb, 0x74, + 0xc0, 0x74, 0x0c, 0x35, 0x1c, 0xa1, 0x26, 0xfa, 0x02, 0x31, 0x50, 0x64, 0xed, 0x7e, 0xc0, 0x28, + 0xfe, 0x61, 0x78, 0x4e, 0x96, 0x4b, 0x7c, 0xdc, 0xc5, 0x66, 0xad, 0x63, 0x5b, 0xa6, 0x2d, 0xa2, + 0x45, 0x45, 0x93, 0xa3, 0xcc, 0x5b, 0xe9, 0x7c, 0xf6, 0xad, 0x34, 0x13, 0x69, 0x16, 0x0e, 0x93, + 0xa8, 0x35, 0x66, 0x4a, 0xd4, 0xbe, 0x93, 0x83, 0x7a, 0x54, 0x16, 0x87, 0xcf, 0x97, 0x98, 0x5a, + 0xa5, 0x1e, 0x46, 0x2f, 0x65, 0x5f, 0x1c, 0x23, 0xfc, 0x78, 0xa4, 0xc1, 0x30, 0xaa, 0xaf, 0x5b, + 0x9f, 0x2a, 0x50, 0x8d, 0x66, 0xc8, 0x15, 0x28, 0xe2, 0x72, 0xd2, 0x4d, 0x8e, 0x79, 0x66, 0x15, + 0xf3, 0x9f, 0xcf, 0x0b, 0xe6, 0x35, 0x28, 0x62, 0xc1, 0x46, 0xfe, 0x17, 0x8a, 0xc9, 0x37, 0xdb, + 0xd1, 0x67, 0x56, 0x31, 0xad, 0x7e, 0x94, 0x83, 0x73, 0x98, 0x61, 0x1f, 0xf2, 0x2f, 0x35, 0xe4, + 0x6b, 0x50, 0x12, 0xa1, 0x4d, 0x9e, 0xf7, 0x76, 0x72, 0xc7, 0x7d, 0x77, 0x18, 0x8d, 0x7b, 0x88, + 0xae, 0xc9, 0xf5, 0x5a, 0xcf, 0xe0, 0xd4, 0x78, 0x8c, 0xf8, 0x5d, 0x4f, 0x99, 0xf4, 0xae, 0x97, + 0xcb, 0xbc, 0xeb, 0x25, 0xcd, 0x2d, 0x9f, 0x36, 0x37, 0xf5, 0x7b, 0x39, 0x20, 0xb8, 0xee, 0x61, + 0x0b, 0xa9, 0xa8, 0x5e, 0xca, 0x4f, 0xa8, 0x97, 0x0a, 0xe9, 0x0a, 0x60, 0x75, 0xb4, 0x5e, 0x9a, + 0xa2, 0x23, 0x9c, 0x2d, 0xa6, 0xee, 0x8c, 0x29, 0xa6, 0xa6, 0x68, 0x37, 0x65, 0x2b, 0x2d, 0xf5, + 0x29, 0xb4, 0x46, 0xa5, 0xe0, 0xc7, 0x89, 0x42, 0x26, 0xe3, 0x3f, 0x3f, 0x72, 0xcf, 0x13, 0x0a, + 0x88, 0xef, 0xe6, 0xe0, 0x2c, 0xce, 0x67, 0x13, 0xab, 0x99, 0x1a, 0x99, 0x4f, 0x33, 0x6a, 0x76, + 0x6b, 0x64, 0xfb, 0x09, 0xcb, 0xb7, 0xb3, 0xf0, 0xb4, 0x92, 0x31, 0x38, 0x39, 0x16, 0xe1, 0x68, + 0x75, 0x6c, 0xf9, 0x1d, 0x38, 0xad, 0x3b, 0x83, 0xf6, 0x26, 0xf3, 0x1c, 0x53, 0xb7, 0xe8, 0x86, + 0x9f, 0x60, 0x7f, 0xb9, 0xba, 0x86, 0xdf, 0x4b, 0xae, 0xf9, 0x48, 0xf9, 0x7a, 0x9e, 0xba, 0xe6, + 0xcf, 0x73, 0x85, 0xb5, 0x7b, 0x8f, 0x96, 0x7f, 0x95, 0x2b, 0x89, 0x99, 0x8d, 0x12, 0xde, 0xe0, + 0xf5, 0xff, 0x04, 0x00, 0x00, 0xff, 0xff, 0x03, 0x76, 0x61, 0x6e, 0xda, 0x32, 0x00, 0x00, } diff --git a/api/api.proto b/api/api.proto index e32e714c4..96b684084 100644 --- a/api/api.proto +++ b/api/api.proto @@ -288,6 +288,16 @@ message DeleteStorageObjectsRequest { repeated DeleteStorageObjectId object_ids = 1; } +// Represents an event to be passed through the server to registered event handlers. +message Event { + // An event name, type, category, or identifier. + string name = 1; + // Arbitrary event property values. + map properties = 2; + // The time when the event was triggered. + google.protobuf.Timestamp timestamp = 3; +} + // A friend of a user. message Friend { // The friendship status. diff --git a/runtime/runtime.go b/runtime/runtime.go index e0d90566b..56ceb53c8 100644 --- a/runtime/runtime.go +++ b/runtime/runtime.go @@ -101,7 +101,7 @@ const ( RUNTIME_CTX_ENV = "env" // The mode associated with the execution context. It's one of these values: - // "run_once", "rpc", "before", "after", "match", "matchmaker", "leaderboard_reset", "tournament_reset", "tournament_end". + // "event", "run_once", "rpc", "before", "after", "match", "matchmaker", "leaderboard_reset", "tournament_reset", "tournament_end". RUNTIME_CTX_MODE = "execution_mode" // Query params that was passed through from HTTP request. @@ -647,6 +647,12 @@ type Initializer interface { // RegisterAfterGetUsers can be used to perform additional logic after retrieving users. RegisterAfterGetUsers(fn func(ctx context.Context, logger Logger, db *sql.DB, nk NakamaModule, out *api.Users, in *api.GetUsersRequest) error) error + + // RegisterEventSessionStart can be used to define functions triggered when client sessions start. + RegisterEventSessionStart(fn func(ctx context.Context, logger Logger, evt *api.Event)) error + + // RegisterEventSessionStart can be used to define functions triggered when client sessions end. + RegisterEventSessionEnd(fn func(ctx context.Context, logger Logger, evt *api.Event)) error } type Leaderboard interface { diff --git a/sample_go_module/sample.go b/sample_go_module/sample.go index d84d21452..b06a35c77 100644 --- a/sample_go_module/sample.go +++ b/sample_go_module/sample.go @@ -37,6 +37,12 @@ func InitModule(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runti }); err != nil { return err } + if err := initializer.RegisterEventSessionStart(eventSessionStart); err != nil { + return err + } + if err := initializer.RegisterEventSessionEnd(eventSessionEnd); err != nil { + return err + } return nil } @@ -129,3 +135,11 @@ func (m *Match) MatchTerminate(ctx context.Context, logger runtime.Logger, db *s return state } + +func eventSessionStart(ctx context.Context, logger runtime.Logger, evt *api.Event) { + logger.Printf("session start %v %v", ctx, evt) +} + +func eventSessionEnd(ctx context.Context, logger runtime.Logger, evt *api.Event) { + logger.Printf("session end %v %v", ctx, evt) +} diff --git a/server/api.go b/server/api.go index 10a247aac..77d4f7dca 100644 --- a/server/api.go +++ b/server/api.go @@ -177,7 +177,7 @@ func StartApiServer(logger *zap.Logger, startupLogger *zap.Logger, db *sql.DB, j grpcGatewayRouter := mux.NewRouter() // Special case routes. Do NOT enable compression on WebSocket route, it results in "http: response.Write on hijacked connection" errors. grpcGatewayRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(200) }).Methods("GET") - grpcGatewayRouter.HandleFunc("/ws", NewSocketWsAcceptor(logger, config, sessionRegistry, matchmaker, tracker, jsonpbMarshaler, jsonpbUnmarshaler, pipeline)).Methods("GET") + grpcGatewayRouter.HandleFunc("/ws", NewSocketWsAcceptor(logger, config, sessionRegistry, matchmaker, tracker, runtime, jsonpbMarshaler, jsonpbUnmarshaler, pipeline)).Methods("GET") // Enable stats recording on all request paths except: // "/" is not tracked at all. diff --git a/server/config.go b/server/config.go index 0cca8b5e4..d7c7f4971 100644 --- a/server/config.go +++ b/server/config.go @@ -185,6 +185,12 @@ func CheckConfig(logger *zap.Logger, config Config) map[string]string { if config.GetRuntime().CallStackSize < 1 { logger.Fatal("Runtime instance call stack size must be >= 1", zap.Int("runtime.call_stack_size", config.GetRuntime().CallStackSize)) } + if config.GetRuntime().EventQueueSize < 1 { + logger.Fatal("Runtime event queue stack size must be >= 1", zap.Int("runtime.event_queue_size", config.GetRuntime().EventQueueSize)) + } + if config.GetRuntime().EventQueueWorkers < 1 { + logger.Fatal("Runtime event queue workers must be >= 1", zap.Int("runtime.event_queue_workers", config.GetRuntime().EventQueueWorkers)) + } if config.GetRuntime().RegistrySize < 128 { logger.Fatal("Runtime instance registry size must be >= 128", zap.Int("runtime.registry_size", config.GetRuntime().RegistrySize)) } @@ -591,27 +597,31 @@ func NewSocialConfig() *SocialConfig { // RuntimeConfig is configuration relevant to the Runtime Lua VM. type RuntimeConfig struct { - Environment map[string]string `yaml:"-" json:"-"` - Env []string `yaml:"env" json:"env" usage:"Values to pass into Runtime as environment variables."` - Path string `yaml:"path" json:"path" usage:"Path for the server to scan for Lua and Go library files."` - HTTPKey string `yaml:"http_key" json:"http_key" usage:"Runtime HTTP Invocation key."` - MinCount int `yaml:"min_count" json:"min_count" usage:"Minimum number of runtime instances to allocate. Default 16."` - MaxCount int `yaml:"max_count" json:"max_count" usage:"Maximum number of runtime instances to allocate. Default 256."` - CallStackSize int `yaml:"call_stack_size" json:"call_stack_size" usage:"Size of each runtime instance's call stack. Default 128."` - RegistrySize int `yaml:"registry_size" json:"registry_size" usage:"Size of each runtime instance's registry. Default 512."` + Environment map[string]string `yaml:"-" json:"-"` + Env []string `yaml:"env" json:"env" usage:"Values to pass into Runtime as environment variables."` + Path string `yaml:"path" json:"path" usage:"Path for the server to scan for Lua and Go library files."` + HTTPKey string `yaml:"http_key" json:"http_key" usage:"Runtime HTTP Invocation key."` + MinCount int `yaml:"min_count" json:"min_count" usage:"Minimum number of runtime instances to allocate. Default 16."` + MaxCount int `yaml:"max_count" json:"max_count" usage:"Maximum number of runtime instances to allocate. Default 256."` + CallStackSize int `yaml:"call_stack_size" json:"call_stack_size" usage:"Size of each runtime instance's call stack. Default 128."` + RegistrySize int `yaml:"registry_size" json:"registry_size" usage:"Size of each runtime instance's registry. Default 512."` + EventQueueSize int `yaml:"event_queue_size" json:"event_queue_size" usage:"Size of the event queue buffer. Default 8192."` + EventQueueWorkers int `yaml:"event_queue_workers" json:"event_queue_workers" usage:"Number of workers to use for concurrent processing of events. Default 8."` } // NewRuntimeConfig creates a new RuntimeConfig struct. func NewRuntimeConfig() *RuntimeConfig { return &RuntimeConfig{ - Environment: make(map[string]string, 0), - Env: make([]string, 0), - Path: "", - HTTPKey: "defaultkey", - MinCount: 16, - MaxCount: 256, - CallStackSize: 128, - RegistrySize: 512, + Environment: make(map[string]string, 0), + Env: make([]string, 0), + Path: "", + HTTPKey: "defaultkey", + MinCount: 16, + MaxCount: 256, + CallStackSize: 128, + RegistrySize: 512, + EventQueueSize: 8192, + EventQueueWorkers: 8, } } diff --git a/server/runtime.go b/server/runtime.go index 369ed9c1c..15dd93d83 100644 --- a/server/runtime.go +++ b/server/runtime.go @@ -17,12 +17,11 @@ package server import ( "context" "database/sql" + "github.com/heroiclabs/nakama/runtime" "os" "path/filepath" "strings" - "github.com/heroiclabs/nakama/runtime" - "github.com/gofrs/uuid" "github.com/golang/protobuf/jsonpb" "github.com/heroiclabs/nakama/api" @@ -170,12 +169,18 @@ type ( RuntimeTournamentResetFunction func(ctx context.Context, tournament *api.Tournament, end, reset int64) error RuntimeLeaderboardResetFunction func(ctx context.Context, leaderboard runtime.Leaderboard, reset int64) error + + RuntimeEventFunction func(ctx context.Context, logger runtime.Logger, evt *api.Event) + + RuntimeEventSessionStartFunction func(userID, username string, expiry int64, sessionID, clientIP, clientPort string, evtTimeSec int64) + RuntimeEventSessionEndFunction func(userID, username string, expiry int64, sessionID, clientIP, clientPort string, evtTimeSec int64) ) type RuntimeExecutionMode int const ( - RuntimeExecutionModeRunOnce RuntimeExecutionMode = iota + RuntimeExecutionModeEvent RuntimeExecutionMode = iota + RuntimeExecutionModeRunOnce RuntimeExecutionModeRPC RuntimeExecutionModeBefore RuntimeExecutionModeAfter @@ -189,6 +194,8 @@ const ( func (e RuntimeExecutionMode) String() string { switch e { + case RuntimeExecutionModeEvent: + return "event" case RuntimeExecutionModeRunOnce: return "run_once" case RuntimeExecutionModeRPC: @@ -225,6 +232,11 @@ type RuntimeMatchCore interface { Cancel() } +type RuntimeEventFunctions struct { + sessionStartFunction RuntimeEventSessionStartFunction + sessionEndFunction RuntimeEventSessionEndFunction +} + type RuntimeBeforeReqFunctions struct { beforeGetAccountFunction RuntimeBeforeGetAccountFunction beforeUpdateAccountFunction RuntimeBeforeUpdateAccountFunction @@ -362,6 +374,8 @@ type Runtime struct { tournamentResetFunction RuntimeTournamentResetFunction leaderboardResetFunction RuntimeLeaderboardResetFunction + + eventFunctions *RuntimeEventFunctions } func NewRuntime(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, leaderboardRankCache LeaderboardRankCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter) (*Runtime, error) { @@ -389,7 +403,11 @@ func NewRuntime(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbMarshaler * return nil, err } - goModules, goRpcFunctions, goBeforeRtFunctions, goAfterRtFunctions, goBeforeReqFunctions, goAfterReqFunctions, goMatchmakerMatchedFunction, goMatchCreateFn, goTournamentEndFunction, goTournamentResetFunction, goLeaderboardResetFunction, goSetMatchCreateFn, goMatchNamesListFn, err := NewRuntimeProviderGo(logger, startupLogger, db, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, runtimeConfig.Path, paths) + startupLogger.Info("Initialising runtime event queue processor") + eventQueue := NewRuntimeEventQueue(logger, config) + startupLogger.Info("Runtime event queue processor started", zap.Int("size", config.GetRuntime().EventQueueSize), zap.Int("workers", config.GetRuntime().EventQueueWorkers)) + + goModules, goRpcFunctions, goBeforeRtFunctions, goAfterRtFunctions, goBeforeReqFunctions, goAfterReqFunctions, goMatchmakerMatchedFunction, goMatchCreateFn, goTournamentEndFunction, goTournamentResetFunction, goLeaderboardResetFunction, allEventFunctions, goSetMatchCreateFn, goMatchNamesListFn, err := NewRuntimeProviderGo(logger, startupLogger, db, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router, runtimeConfig.Path, paths, eventQueue) if err != nil { startupLogger.Error("Error initialising Go runtime provider", zap.Error(err)) return nil, err @@ -413,6 +431,13 @@ func NewRuntime(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbMarshaler * } startupLogger.Info("Found runtime modules", zap.Int("count", len(allModules)), zap.Strings("modules", allModules)) + if allEventFunctions.sessionStartFunction != nil { + startupLogger.Info("Registered event function invocation", zap.String("id", "session_start")) + } + if allEventFunctions.sessionEndFunction != nil { + startupLogger.Info("Registered event function invocation", zap.String("id", "session_end")) + } + allRpcFunctions := make(map[string]RuntimeRpcFunction, len(goRpcFunctions)+len(luaRpcFunctions)) for id, fn := range luaRpcFunctions { allRpcFunctions[id] = fn @@ -1302,6 +1327,7 @@ func NewRuntime(logger, startupLogger *zap.Logger, db *sql.DB, jsonpbMarshaler * tournamentEndFunction: allTournamentEndFunction, tournamentResetFunction: allTournamentResetFunction, leaderboardResetFunction: allLeaderboardResetFunction, + eventFunctions: allEventFunctions, }, nil } @@ -1792,3 +1818,11 @@ func (r *Runtime) TournamentReset() RuntimeTournamentResetFunction { func (r *Runtime) LeaderboardReset() RuntimeLeaderboardResetFunction { return r.leaderboardResetFunction } + +func (r *Runtime) EventSessionStart() RuntimeEventSessionStartFunction { + return r.eventFunctions.sessionStartFunction +} + +func (r *Runtime) EventSessionEnd() RuntimeEventSessionEndFunction { + return r.eventFunctions.sessionEndFunction +} diff --git a/server/runtime_event.go b/server/runtime_event.go new file mode 100644 index 000000000..ef02d0a27 --- /dev/null +++ b/server/runtime_event.go @@ -0,0 +1,68 @@ +// Copyright 2019 The Nakama Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package server + +import ( + "context" + "go.uber.org/zap" +) + +type RuntimeEventQueue struct { + logger *zap.Logger + + ch chan func() + + ctx context.Context + ctxCancelFn context.CancelFunc +} + +func NewRuntimeEventQueue(logger *zap.Logger, config Config) *RuntimeEventQueue { + b := &RuntimeEventQueue{ + logger: logger, + + ch: make(chan func(), config.GetRuntime().EventQueueSize), + } + b.ctx, b.ctxCancelFn = context.WithCancel(context.Background()) + + // Start a fixed number of workers. + for i := 0; i < config.GetRuntime().EventQueueWorkers; i++ { + go func() { + for { + select { + case <-b.ctx.Done(): + return + case fn := <-b.ch: + fn() + } + } + }() + } + + return b +} + +func (b *RuntimeEventQueue) Queue(fn func()) { + select { + case b.ch <- fn: + // Event queued successfully. + default: + // Event queue is full, drop it to avoid blocking the caller. + b.logger.Warn("Runtime event queue full, events may be lost") + } +} + +func (b *RuntimeEventQueue) Stop() { + b.ctxCancelFn() +} diff --git a/server/runtime_go.go b/server/runtime_go.go index f3fca8e32..a8eb84d3a 100644 --- a/server/runtime_go.go +++ b/server/runtime_go.go @@ -18,18 +18,18 @@ import ( "context" "database/sql" "errors" - "path/filepath" - "plugin" - "strings" - "sync" - "github.com/gofrs/uuid" + "github.com/golang/protobuf/ptypes/timestamp" "github.com/heroiclabs/nakama/api" "github.com/heroiclabs/nakama/rtapi" "github.com/heroiclabs/nakama/runtime" "github.com/heroiclabs/nakama/social" "go.uber.org/zap" "google.golang.org/grpc/codes" + "path/filepath" + "plugin" + "strings" + "sync" ) // No need for a stateful RuntimeProviderGo here. @@ -50,10 +50,23 @@ type RuntimeGoInitializer struct { tournamentReset RuntimeTournamentResetFunction leaderboardReset RuntimeLeaderboardResetFunction + sessionStartFunctions []RuntimeEventFunction + sessionEndFunctions []RuntimeEventFunction + match map[string]func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule) (runtime.Match, error) matchLock *sync.RWMutex } +func (ri *RuntimeGoInitializer) RegisterEventSessionStart(fn func(ctx context.Context, logger runtime.Logger, evt *api.Event)) error { + ri.sessionStartFunctions = append(ri.sessionStartFunctions, fn) + return nil +} + +func (ri *RuntimeGoInitializer) RegisterEventSessionEnd(fn func(ctx context.Context, logger runtime.Logger, evt *api.Event)) error { + ri.sessionEndFunctions = append(ri.sessionEndFunctions, fn) + return nil +} + func (ri *RuntimeGoInitializer) RegisterRpc(id string, fn func(ctx context.Context, logger runtime.Logger, db *sql.DB, nk runtime.NakamaModule, payload string) (string, error)) error { id = strings.ToLower(id) ri.rpc[id] = func(ctx context.Context, queryParams map[string][]string, userID, username string, expiry int64, sessionID, clientIP, clientPort, payload string) (string, error, codes.Code) { @@ -1736,7 +1749,7 @@ func (ri *RuntimeGoInitializer) RegisterMatch(name string, fn func(ctx context.C return nil } -func NewRuntimeProviderGo(logger, startupLogger *zap.Logger, db *sql.DB, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, leaderboardRankCache LeaderboardRankCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, rootPath string, paths []string) ([]string, map[string]RuntimeRpcFunction, map[string]RuntimeBeforeRtFunction, map[string]RuntimeAfterRtFunction, *RuntimeBeforeReqFunctions, *RuntimeAfterReqFunctions, RuntimeMatchmakerMatchedFunction, RuntimeMatchCreateFunction, RuntimeTournamentEndFunction, RuntimeTournamentResetFunction, RuntimeLeaderboardResetFunction, func(RuntimeMatchCreateFunction), func() []string, error) { +func NewRuntimeProviderGo(logger, startupLogger *zap.Logger, db *sql.DB, config Config, socialClient *social.Client, leaderboardCache LeaderboardCache, leaderboardRankCache LeaderboardRankCache, leaderboardScheduler LeaderboardScheduler, sessionRegistry SessionRegistry, matchRegistry MatchRegistry, tracker Tracker, streamManager StreamManager, router MessageRouter, rootPath string, paths []string, eventQueue *RuntimeEventQueue) ([]string, map[string]RuntimeRpcFunction, map[string]RuntimeBeforeRtFunction, map[string]RuntimeAfterRtFunction, *RuntimeBeforeReqFunctions, *RuntimeAfterReqFunctions, RuntimeMatchmakerMatchedFunction, RuntimeMatchCreateFunction, RuntimeTournamentEndFunction, RuntimeTournamentResetFunction, RuntimeLeaderboardResetFunction, *RuntimeEventFunctions, func(RuntimeMatchCreateFunction), func() []string, error) { runtimeLogger := NewRuntimeGoLogger(logger) env := config.GetRuntime().Environment nk := NewRuntimeGoNakamaModule(logger, db, config, socialClient, leaderboardCache, leaderboardRankCache, leaderboardScheduler, sessionRegistry, matchRegistry, tracker, streamManager, router) @@ -1785,6 +1798,9 @@ func NewRuntimeProviderGo(logger, startupLogger *zap.Logger, db *sql.DB, config beforeReq: &RuntimeBeforeReqFunctions{}, afterReq: &RuntimeAfterReqFunctions{}, + sessionStartFunctions: make([]RuntimeEventFunction, 0), + sessionEndFunctions: make([]RuntimeEventFunction, 0), + match: match, matchLock: matchLock, } @@ -1807,32 +1823,62 @@ func NewRuntimeProviderGo(logger, startupLogger *zap.Logger, db *sql.DB, config p, err := plugin.Open(path) if err != nil { startupLogger.Error("Could not open Go module", zap.String("path", path), zap.Error(err)) - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err } // Look up the required initialisation function. f, err := p.Lookup("InitModule") if err != nil { startupLogger.Fatal("Error looking up InitModule function in Go module", zap.String("name", name)) - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, err } // Ensure the function has the correct signature. fn, ok := f.(func(context.Context, runtime.Logger, *sql.DB, runtime.NakamaModule, runtime.Initializer) error) if !ok { startupLogger.Fatal("Error reading InitModule function in Go module", zap.String("name", name)) - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, errors.New("error reading InitModule function in Go module") + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, errors.New("error reading InitModule function in Go module") } // Run the initialisation. if err = fn(ctx, runtimeLogger, db, nk, initializer); err != nil { startupLogger.Fatal("Error returned by InitModule function in Go module", zap.String("name", name), zap.Error(err)) - return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, errors.New("error returned by InitModule function in Go module") + return nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, errors.New("error returned by InitModule function in Go module") } modulePaths = append(modulePaths, relPath) } startupLogger.Info("Go runtime modules loaded") - return modulePaths, initializer.rpc, initializer.beforeRt, initializer.afterRt, initializer.beforeReq, initializer.afterReq, initializer.matchmakerMatched, matchCreateFn, initializer.tournamentEnd, initializer.tournamentReset, initializer.leaderboardReset, nk.SetMatchCreateFn, matchNamesListFn, nil + events := &RuntimeEventFunctions{} + if len(initializer.sessionStartFunctions) > 0 { + events.sessionStartFunction = func(userID, username string, expiry int64, sessionID, clientIP, clientPort string, evtTimeSec int64) { + ctx := NewRuntimeGoContext(context.Background(), initializer.env, RuntimeExecutionModeEvent, nil, expiry, userID, username, sessionID, clientIP, clientPort) + evt := &api.Event{ + Name: "session_start", + Timestamp: ×tamp.Timestamp{Seconds: evtTimeSec}, + } + eventQueue.Queue(func() { + for _, fn := range initializer.sessionStartFunctions { + fn(ctx, initializer.logger, evt) + } + }) + } + } + if len(initializer.sessionEndFunctions) > 0 { + events.sessionEndFunction = func(userID, username string, expiry int64, sessionID, clientIP, clientPort string, evtTimeSec int64) { + ctx := NewRuntimeGoContext(context.Background(), initializer.env, RuntimeExecutionModeEvent, nil, expiry, userID, username, sessionID, clientIP, clientPort) + evt := &api.Event{ + Name: "session_end", + Timestamp: ×tamp.Timestamp{Seconds: evtTimeSec}, + } + eventQueue.Queue(func() { + for _, fn := range initializer.sessionEndFunctions { + fn(ctx, initializer.logger, evt) + } + }) + } + } + + return modulePaths, initializer.rpc, initializer.beforeRt, initializer.afterRt, initializer.beforeReq, initializer.afterReq, initializer.matchmakerMatched, matchCreateFn, initializer.tournamentEnd, initializer.tournamentReset, initializer.leaderboardReset, events, nk.SetMatchCreateFn, matchNamesListFn, nil } diff --git a/server/session_ws.go b/server/session_ws.go index 0bf88a18e..aad3acf9c 100644 --- a/server/session_ws.go +++ b/server/session_ws.go @@ -61,6 +61,7 @@ type sessionWS struct { sessionRegistry SessionRegistry matchmaker Matchmaker tracker Tracker + runtime *Runtime stopped bool conn *websocket.Conn @@ -70,7 +71,7 @@ type sessionWS struct { outgoingCh chan []byte } -func NewSessionWS(logger *zap.Logger, config Config, format SessionFormat, userID uuid.UUID, username string, expiry int64, clientIP string, clientPort string, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, conn *websocket.Conn, sessionRegistry SessionRegistry, matchmaker Matchmaker, tracker Tracker) Session { +func NewSessionWS(logger *zap.Logger, config Config, format SessionFormat, userID uuid.UUID, username string, expiry int64, clientIP string, clientPort string, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, conn *websocket.Conn, sessionRegistry SessionRegistry, matchmaker Matchmaker, tracker Tracker, runtime *Runtime) Session { sessionID := uuid.Must(uuid.NewV4()) sessionLogger := logger.With(zap.String("uid", userID.String()), zap.String("sid", sessionID.String())) @@ -108,6 +109,7 @@ func NewSessionWS(logger *zap.Logger, config Config, format SessionFormat, userI sessionRegistry: sessionRegistry, matchmaker: matchmaker, tracker: tracker, + runtime: runtime, stopped: false, conn: conn, @@ -166,6 +168,11 @@ func (s *sessionWS) Consume(processRequest func(logger *zap.Logger, session Sess return nil }) + // Fire an event for session start. + if fn := s.runtime.EventSessionStart(); fn != nil { + fn(s.userID.String(), s.username.Load(), s.expiry, s.id.String(), s.clientIP, s.clientPort, time.Now().UTC().Unix()) + } + // Start a routine to process outbound messages. go s.processOutgoing() @@ -431,4 +438,9 @@ func (s *sessionWS) Close() { } s.logger.Info("Closed client connection") + + // Fire an event for session end. + if fn := s.runtime.EventSessionEnd(); fn != nil { + fn(s.userID.String(), s.username.Load(), s.expiry, s.id.String(), s.clientIP, s.clientPort, time.Now().UTC().Unix()) + } } diff --git a/server/socket_ws.go b/server/socket_ws.go index 2bdc6a956..bd7560247 100644 --- a/server/socket_ws.go +++ b/server/socket_ws.go @@ -28,7 +28,7 @@ import ( var SocketWsStatsCtx = context.Background() -func NewSocketWsAcceptor(logger *zap.Logger, config Config, sessionRegistry SessionRegistry, matchmaker Matchmaker, tracker Tracker, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, pipeline *Pipeline) func(http.ResponseWriter, *http.Request) { +func NewSocketWsAcceptor(logger *zap.Logger, config Config, sessionRegistry SessionRegistry, matchmaker Matchmaker, tracker Tracker, runtime *Runtime, jsonpbMarshaler *jsonpb.Marshaler, jsonpbUnmarshaler *jsonpb.Unmarshaler, pipeline *Pipeline) func(http.ResponseWriter, *http.Request) { upgrader := &websocket.Upgrader{ ReadBufferSize: int(config.GetSocket().MaxMessageSizeBytes), WriteBufferSize: int(config.GetSocket().MaxMessageSizeBytes), @@ -85,7 +85,7 @@ func NewSocketWsAcceptor(logger *zap.Logger, config Config, sessionRegistry Sess _, span := trace.StartSpan(SocketWsStatsCtx, "nakama.session.ws") // Wrap the connection for application handling. - session := NewSessionWS(logger, config, format, userID, username, expiry, clientIP, clientPort, jsonpbMarshaler, jsonpbUnmarshaler, conn, sessionRegistry, matchmaker, tracker) + session := NewSessionWS(logger, config, format, userID, username, expiry, clientIP, clientPort, jsonpbMarshaler, jsonpbUnmarshaler, conn, sessionRegistry, matchmaker, tracker, runtime) // Add to the session registry. sessionRegistry.Add(session)