diff --git a/server/api/tumdev/campus_backend.pb.go b/server/api/tumdev/campus_backend.pb.go
index 2ad4593f..9595a889 100644
--- a/server/api/tumdev/campus_backend.pb.go
+++ b/server/api/tumdev/campus_backend.pb.go
@@ -3746,6 +3746,229 @@ func (x *GetCanteenHeadCountReply) GetTimestamp() *timestamppb.Timestamp {
return nil
}
+type ListStudentClubRequest struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+}
+
+func (x *ListStudentClubRequest) Reset() {
+ *x = ListStudentClubRequest{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[58]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ListStudentClubRequest) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListStudentClubRequest) ProtoMessage() {}
+
+func (x *ListStudentClubRequest) ProtoReflect() protoreflect.Message {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[58]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListStudentClubRequest.ProtoReflect.Descriptor instead.
+func (*ListStudentClubRequest) Descriptor() ([]byte, []int) {
+ return file_tumdev_campus_backend_proto_rawDescGZIP(), []int{58}
+}
+
+type ListStudentClubReply struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Collections []*StudentClubCollection `protobuf:"bytes,1,rep,name=collections,proto3" json:"collections,omitempty"`
+}
+
+func (x *ListStudentClubReply) Reset() {
+ *x = ListStudentClubReply{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[59]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *ListStudentClubReply) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*ListStudentClubReply) ProtoMessage() {}
+
+func (x *ListStudentClubReply) ProtoReflect() protoreflect.Message {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[59]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use ListStudentClubReply.ProtoReflect.Descriptor instead.
+func (*ListStudentClubReply) Descriptor() ([]byte, []int) {
+ return file_tumdev_campus_backend_proto_rawDescGZIP(), []int{59}
+}
+
+func (x *ListStudentClubReply) GetCollections() []*StudentClubCollection {
+ if x != nil {
+ return x.Collections
+ }
+ return nil
+}
+
+type StudentClub struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ // The name of the club
+ Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"`
+ // How the club describes itsself
+ Description *string `protobuf:"bytes,2,opt,name=description,proto3,oneof" json:"description,omitempty"`
+ // Where the clubs main internet presence is
+ LinkUrl *string `protobuf:"bytes,3,opt,name=link_url,json=linkUrl,proto3,oneof" json:"link_url,omitempty"`
+ // Where to find a image for this club
+ CoverUrl *string `protobuf:"bytes,4,opt,name=cover_url,json=coverUrl,proto3,oneof" json:"cover_url,omitempty"`
+}
+
+func (x *StudentClub) Reset() {
+ *x = StudentClub{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[60]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *StudentClub) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StudentClub) ProtoMessage() {}
+
+func (x *StudentClub) ProtoReflect() protoreflect.Message {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[60]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StudentClub.ProtoReflect.Descriptor instead.
+func (*StudentClub) Descriptor() ([]byte, []int) {
+ return file_tumdev_campus_backend_proto_rawDescGZIP(), []int{60}
+}
+
+func (x *StudentClub) GetName() string {
+ if x != nil {
+ return x.Name
+ }
+ return ""
+}
+
+func (x *StudentClub) GetDescription() string {
+ if x != nil && x.Description != nil {
+ return *x.Description
+ }
+ return ""
+}
+
+func (x *StudentClub) GetLinkUrl() string {
+ if x != nil && x.LinkUrl != nil {
+ return *x.LinkUrl
+ }
+ return ""
+}
+
+func (x *StudentClub) GetCoverUrl() string {
+ if x != nil && x.CoverUrl != nil {
+ return *x.CoverUrl
+ }
+ return ""
+}
+
+type StudentClubCollection struct {
+ state protoimpl.MessageState
+ sizeCache protoimpl.SizeCache
+ unknownFields protoimpl.UnknownFields
+
+ Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"`
+ Description string `protobuf:"bytes,2,opt,name=description,proto3" json:"description,omitempty"`
+ Clubs []*StudentClub `protobuf:"bytes,3,rep,name=clubs,proto3" json:"clubs,omitempty"`
+}
+
+func (x *StudentClubCollection) Reset() {
+ *x = StudentClubCollection{}
+ if protoimpl.UnsafeEnabled {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[61]
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ ms.StoreMessageInfo(mi)
+ }
+}
+
+func (x *StudentClubCollection) String() string {
+ return protoimpl.X.MessageStringOf(x)
+}
+
+func (*StudentClubCollection) ProtoMessage() {}
+
+func (x *StudentClubCollection) ProtoReflect() protoreflect.Message {
+ mi := &file_tumdev_campus_backend_proto_msgTypes[61]
+ if protoimpl.UnsafeEnabled && x != nil {
+ ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
+ if ms.LoadMessageInfo() == nil {
+ ms.StoreMessageInfo(mi)
+ }
+ return ms
+ }
+ return mi.MessageOf(x)
+}
+
+// Deprecated: Use StudentClubCollection.ProtoReflect.Descriptor instead.
+func (*StudentClubCollection) Descriptor() ([]byte, []int) {
+ return file_tumdev_campus_backend_proto_rawDescGZIP(), []int{61}
+}
+
+func (x *StudentClubCollection) GetTitle() string {
+ if x != nil {
+ return x.Title
+ }
+ return ""
+}
+
+func (x *StudentClubCollection) GetDescription() string {
+ if x != nil {
+ return x.Description
+ }
+ return ""
+}
+
+func (x *StudentClubCollection) GetClubs() []*StudentClub {
+ if x != nil {
+ return x.Clubs
+ }
+ return nil
+}
+
var File_tumdev_campus_backend_proto protoreflect.FileDescriptor
var file_tumdev_campus_backend_proto_rawDesc = []byte{
@@ -4160,166 +4383,198 @@ var file_tumdev_campus_backend_proto_rawDesc = []byte{
0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67,
0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54,
0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74,
- 0x61, 0x6d, 0x70, 0x2a, 0x2f, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79, 0x70,
- 0x65, 0x12, 0x07, 0x0a, 0x03, 0x49, 0x4f, 0x53, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x4e,
- 0x44, 0x52, 0x4f, 0x49, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x49, 0x4e, 0x44, 0x4f,
- 0x57, 0x53, 0x10, 0x02, 0x32, 0xd9, 0x12, 0x0a, 0x06, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x12,
- 0x64, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x41, 0x6c, 0x65, 0x72, 0x74,
- 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73,
- 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e,
- 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x41, 0x6c, 0x65, 0x72,
- 0x74, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16, 0x62,
- 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x0c, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x2f, 0x61,
- 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x69, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77,
- 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c,
- 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74,
- 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
- 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x62, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
- 0x73, 0x12, 0x0d, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73,
- 0x12, 0x49, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x12, 0x14, 0x2e, 0x61,
- 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
- 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77,
- 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x62, 0x04,
- 0x6e, 0x65, 0x77, 0x73, 0x12, 0x05, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x12, 0x72, 0x0a, 0x12, 0x4c,
- 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67,
- 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74,
- 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74,
- 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22,
- 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x63, 0x61, 0x6e,
- 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x65, 0x74, 0x12,
- 0x63, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67,
- 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52,
- 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e,
- 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e,
- 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x3a,
- 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67,
- 0x2f, 0x67, 0x65, 0x74, 0x12, 0x75, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61,
- 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x2e, 0x61, 0x70,
- 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52,
- 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61,
+ 0x61, 0x6d, 0x70, 0x22, 0x18, 0x0a, 0x16, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x75, 0x64, 0x65,
+ 0x6e, 0x74, 0x43, 0x6c, 0x75, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x54, 0x0a,
+ 0x14, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x75, 0x62,
+ 0x52, 0x65, 0x70, 0x6c, 0x79, 0x12, 0x3c, 0x0a, 0x0b, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74,
+ 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x70, 0x69,
+ 0x2e, 0x53, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x75, 0x62, 0x43, 0x6f, 0x6c, 0x6c,
+ 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x22, 0xb5, 0x01, 0x0a, 0x0b, 0x53, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x43,
+ 0x6c, 0x75, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
+ 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72,
+ 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b,
+ 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x88, 0x01, 0x01, 0x12, 0x1e,
+ 0x0a, 0x08, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
+ 0x48, 0x01, 0x52, 0x07, 0x6c, 0x69, 0x6e, 0x6b, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01, 0x12, 0x20,
+ 0x0a, 0x09, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28,
+ 0x09, 0x48, 0x02, 0x52, 0x08, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x72, 0x6c, 0x88, 0x01, 0x01,
+ 0x42, 0x0e, 0x0a, 0x0c, 0x5f, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e,
+ 0x42, 0x0b, 0x0a, 0x09, 0x5f, 0x6c, 0x69, 0x6e, 0x6b, 0x5f, 0x75, 0x72, 0x6c, 0x42, 0x0c, 0x0a,
+ 0x0a, 0x5f, 0x63, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x75, 0x72, 0x6c, 0x22, 0x77, 0x0a, 0x15, 0x53,
+ 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x75, 0x62, 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63,
+ 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20,
+ 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x64, 0x65,
+ 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52,
+ 0x0b, 0x64, 0x65, 0x73, 0x63, 0x72, 0x69, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x26, 0x0a, 0x05,
+ 0x63, 0x6c, 0x75, 0x62, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x61, 0x70,
+ 0x69, 0x2e, 0x53, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x75, 0x62, 0x52, 0x05, 0x63,
+ 0x6c, 0x75, 0x62, 0x73, 0x2a, 0x2f, 0x0a, 0x0a, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x54, 0x79,
+ 0x70, 0x65, 0x12, 0x07, 0x0a, 0x03, 0x49, 0x4f, 0x53, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x41,
+ 0x4e, 0x44, 0x52, 0x4f, 0x49, 0x44, 0x10, 0x01, 0x12, 0x0b, 0x0a, 0x07, 0x57, 0x49, 0x4e, 0x44,
+ 0x4f, 0x57, 0x53, 0x10, 0x02, 0x32, 0xbc, 0x13, 0x0a, 0x06, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73,
+ 0x12, 0x64, 0x0a, 0x0e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x41, 0x6c, 0x65, 0x72,
+ 0x74, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77,
+ 0x73, 0x41, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x41, 0x6c, 0x65,
+ 0x72, 0x74, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1c, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x16,
+ 0x62, 0x06, 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x0c, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x2f,
+ 0x61, 0x6c, 0x65, 0x72, 0x74, 0x73, 0x12, 0x69, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65,
+ 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+ 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73,
+ 0x74, 0x4e, 0x65, 0x77, 0x73, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c,
+ 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x62, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63,
+ 0x65, 0x73, 0x12, 0x0d, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65,
+ 0x73, 0x12, 0x49, 0x0a, 0x08, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x12, 0x14, 0x2e,
+ 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65, 0x77, 0x73, 0x52, 0x65, 0x71, 0x75,
+ 0x65, 0x73, 0x74, 0x1a, 0x12, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x65,
+ 0x77, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x13, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0d, 0x62,
+ 0x04, 0x6e, 0x65, 0x77, 0x73, 0x12, 0x05, 0x2f, 0x6e, 0x65, 0x77, 0x73, 0x12, 0x72, 0x0a, 0x12,
+ 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e,
+ 0x67, 0x73, 0x12, 0x1e, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e,
+ 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e,
+ 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79,
+ 0x22, 0x1e, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x63, 0x61,
+ 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x67, 0x65, 0x74,
+ 0x12, 0x63, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e,
+ 0x67, 0x73, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68,
+ 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69,
+ 0x6e, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15,
+ 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e,
+ 0x67, 0x2f, 0x67, 0x65, 0x74, 0x12, 0x75, 0x0a, 0x13, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43,
+ 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12, 0x1f, 0x2e, 0x61,
0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e,
- 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1e, 0x82, 0xd3, 0xe4,
- 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e,
- 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, 0x69, 0x0a, 0x10, 0x43,
- 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x12,
- 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x68,
- 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a, 0x2e,
- 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61,
- 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02,
- 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69,
- 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, 0x8c, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74, 0x41,
+ 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e,
+ 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65,
+ 0x6e, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1e, 0x82, 0xd3,
+ 0xe4, 0x93, 0x02, 0x18, 0x3a, 0x01, 0x2a, 0x22, 0x13, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65,
+ 0x6e, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, 0x69, 0x0a, 0x10,
+ 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67,
+ 0x12, 0x1c, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73,
+ 0x68, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1a,
+ 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x69, 0x73, 0x68, 0x52,
+ 0x61, 0x74, 0x69, 0x6e, 0x67, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93,
+ 0x02, 0x15, 0x3a, 0x01, 0x2a, 0x22, 0x10, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74,
+ 0x69, 0x6e, 0x67, 0x2f, 0x6e, 0x65, 0x77, 0x12, 0x8c, 0x01, 0x0a, 0x15, 0x4c, 0x69, 0x73, 0x74,
+ 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67,
+ 0x73, 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69,
+ 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41,
0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73,
- 0x12, 0x21, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c,
- 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x1a, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76,
- 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x44, 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x52,
- 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x62, 0x0b, 0x72, 0x61,
- 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x2f, 0x64, 0x69, 0x73, 0x68,
- 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, 0x61, 0x74, 0x69, 0x6e,
- 0x67, 0x54, 0x61, 0x67, 0x73, 0x12, 0x6f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d,
- 0x65, 0x54, 0x61, 0x67, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74,
- 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x61,
- 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27, 0x62,
- 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x2f, 0x64,
- 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x44, 0x69,
- 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74, 0x41,
+ 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2f, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x29, 0x62, 0x0b, 0x72,
+ 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x1a, 0x2f, 0x64, 0x69, 0x73,
+ 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, 0x61, 0x74, 0x69,
+ 0x6e, 0x67, 0x54, 0x61, 0x67, 0x73, 0x12, 0x6f, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61,
+ 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73,
+ 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x54,
+ 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x2d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x27,
+ 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61, 0x67, 0x73, 0x12, 0x18, 0x2f,
+ 0x64, 0x69, 0x73, 0x68, 0x2f, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x44,
+ 0x69, 0x73, 0x68, 0x54, 0x61, 0x67, 0x73, 0x12, 0x98, 0x01, 0x0a, 0x18, 0x4c, 0x69, 0x73, 0x74,
+ 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e,
+ 0x54, 0x61, 0x67, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41,
0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x54,
- 0x61, 0x67, 0x73, 0x12, 0x24, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76,
- 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x54, 0x61,
- 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e,
- 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61, 0x6e,
- 0x74, 0x65, 0x65, 0x6e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x32, 0x82,
- 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74, 0x61,
- 0x67, 0x73, 0x12, 0x1d, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61, 0x74,
- 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61, 0x67,
- 0x73, 0x12, 0x67, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e,
- 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74,
- 0x65, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70,
- 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x52, 0x65,
- 0x70, 0x6c, 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x62, 0x07, 0x63, 0x61, 0x6e,
- 0x74, 0x65, 0x65, 0x6e, 0x12, 0x14, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x61,
- 0x6c, 0x6c, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x12, 0x51, 0x0a, 0x0a, 0x4c, 0x69,
- 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c,
- 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
- 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65,
- 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x62, 0x04,
- 0x64, 0x69, 0x73, 0x68, 0x12, 0x07, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x62, 0x0a,
- 0x0d, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x12, 0x19,
- 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f,
- 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69, 0x2e,
- 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65, 0x70,
- 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x75, 0x70, 0x64,
- 0x61, 0x74, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e,
- 0x7d, 0x12, 0x55, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x12,
- 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73,
- 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69,
- 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x19, 0x82,
- 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x2f, 0x7b,
- 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x67, 0x0a, 0x0e, 0x43, 0x72, 0x65, 0x61,
- 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x1a, 0x2e, 0x61, 0x70, 0x69,
- 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x52,
- 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65,
- 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c, 0x79,
- 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63, 0x68,
- 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x09, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x28,
- 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74,
- 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70,
- 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
- 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61,
- 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x21, 0x82, 0xd3,
- 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x75, 0x70,
- 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x7d, 0x12,
- 0x73, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
- 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x28, 0x82, 0xd3, 0xe4, 0x93,
- 0x02, 0x22, 0x12, 0x20, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
- 0x6e, 0x73, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
- 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x90, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69,
- 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x12,
- 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74,
+ 0x61, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x22, 0x2e, 0x61, 0x70, 0x69,
+ 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x43, 0x61,
+ 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x54, 0x61, 0x67, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x32,
+ 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2c, 0x62, 0x0b, 0x72, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x5f, 0x74,
+ 0x61, 0x67, 0x73, 0x12, 0x1d, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x72, 0x61,
+ 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x61, 0x6c, 0x6c, 0x52, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x54, 0x61,
+ 0x67, 0x73, 0x12, 0x67, 0x0a, 0x0c, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65,
+ 0x6e, 0x73, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e,
+ 0x74, 0x65, 0x65, 0x6e, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61,
+ 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x52,
+ 0x65, 0x70, 0x6c, 0x79, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x62, 0x07, 0x63, 0x61,
+ 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x12, 0x14, 0x2f, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f,
+ 0x61, 0x6c, 0x6c, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x73, 0x12, 0x51, 0x0a, 0x0a, 0x4c,
+ 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e,
+ 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x69, 0x73, 0x68,
+ 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x15, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0f, 0x62,
+ 0x04, 0x64, 0x69, 0x73, 0x68, 0x12, 0x07, 0x2f, 0x64, 0x69, 0x73, 0x68, 0x65, 0x73, 0x12, 0x62,
+ 0x0a, 0x0d, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x12,
+ 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e,
+ 0x6f, 0x74, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x61, 0x70, 0x69,
+ 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x52, 0x65,
+ 0x70, 0x6c, 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x12, 0x15, 0x2f, 0x75, 0x70,
+ 0x64, 0x61, 0x74, 0x65, 0x6e, 0x6f, 0x74, 0x65, 0x2f, 0x7b, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f,
+ 0x6e, 0x7d, 0x12, 0x55, 0x0a, 0x0a, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73,
+ 0x12, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65,
+ 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c,
+ 0x69, 0x73, 0x74, 0x4d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x19,
+ 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x6d, 0x6f, 0x76, 0x69, 0x65, 0x73, 0x2f,
+ 0x7b, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x67, 0x0a, 0x0e, 0x43, 0x72, 0x65,
+ 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x1a, 0x2e, 0x61, 0x70,
+ 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b,
+ 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72,
+ 0x65, 0x61, 0x74, 0x65, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x70, 0x6c,
+ 0x79, 0x22, 0x1d, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x17, 0x3a, 0x0a, 0x61, 0x74, 0x74, 0x61, 0x63,
+ 0x68, 0x6d, 0x65, 0x6e, 0x74, 0x22, 0x09, 0x2f, 0x66, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b,
+ 0x28, 0x01, 0x12, 0x6c, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53,
+ 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55,
+ 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65,
+ 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x55, 0x70, 0x6c, 0x6f,
+ 0x61, 0x64, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x21, 0x82,
+ 0xd3, 0xe4, 0x93, 0x02, 0x1b, 0x12, 0x19, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x75,
+ 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x7d,
+ 0x12, 0x73, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
+ 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74,
+ 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
+ 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x28, 0x82, 0xd3, 0xe4,
+ 0x93, 0x02, 0x22, 0x12, 0x20, 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
+ 0x6f, 0x6e, 0x73, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
+ 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x90, 0x01, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d,
- 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28, 0x2f,
- 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63, 0x6f,
- 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4d, 0x65,
- 0x6d, 0x62, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65,
- 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61, 0x70,
- 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c, 0x79,
- 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x6d, 0x65, 0x6d, 0x62, 0x65,
- 0x72, 0x73, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7e, 0x0a, 0x13, 0x47,
- 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75,
- 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74,
- 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71, 0x75,
- 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e,
- 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x70,
- 0x6c, 0x79, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x63, 0x61, 0x6e,
- 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2f, 0x7b,
- 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x54, 0x0a, 0x0c, 0x43,
- 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70,
- 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65,
- 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61,
- 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x12, 0x82,
- 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x3a, 0x01, 0x2a, 0x22, 0x07, 0x2f, 0x64, 0x65, 0x76, 0x69, 0x63,
- 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63,
- 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65,
- 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70,
- 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65,
- 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x64, 0x65,
- 0x76, 0x69, 0x63, 0x65, 0x2f, 0x7b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x7d,
- 0x42, 0x5e, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x2e, 0x74, 0x75, 0x6d, 0x2e, 0x63, 0x61, 0x6d, 0x70,
- 0x75, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0e, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x41, 0x70,
- 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
- 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x55, 0x4d, 0x2d, 0x44, 0x65, 0x76, 0x2f, 0x43, 0x61, 0x6d,
- 0x70, 0x75, 0x73, 0x2d, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f, 0x61, 0x70, 0x69, 0xaa,
- 0x02, 0x0e, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x41, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f,
- 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+ 0x12, 0x22, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69,
+ 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x1a, 0x20, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f,
+ 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x72,
+ 0x6d, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x30, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x2a, 0x12, 0x28,
+ 0x2f, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2f, 0x63,
+ 0x6f, 0x6e, 0x66, 0x69, 0x72, 0x6d, 0x2f, 0x7b, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61,
+ 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x52, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x4d,
+ 0x65, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4d,
+ 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x61,
+ 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x4d, 0x65, 0x6d, 0x62, 0x65, 0x72, 0x52, 0x65, 0x70, 0x6c,
+ 0x79, 0x22, 0x19, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x13, 0x12, 0x11, 0x2f, 0x6d, 0x65, 0x6d, 0x62,
+ 0x65, 0x72, 0x73, 0x2f, 0x7b, 0x6c, 0x72, 0x7a, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x7e, 0x0a, 0x13,
+ 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f,
+ 0x75, 0x6e, 0x74, 0x12, 0x1f, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61, 0x6e,
+ 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65, 0x71,
+ 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x47, 0x65, 0x74, 0x43, 0x61,
+ 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x48, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x65,
+ 0x70, 0x6c, 0x79, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x1f, 0x2f, 0x63, 0x61,
+ 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x2f, 0x68, 0x65, 0x61, 0x64, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x2f,
+ 0x7b, 0x63, 0x61, 0x6e, 0x74, 0x65, 0x65, 0x6e, 0x5f, 0x69, 0x64, 0x7d, 0x12, 0x54, 0x0a, 0x0c,
+ 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61,
+ 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52,
+ 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x72, 0x65,
+ 0x61, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x12,
+ 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x0c, 0x3a, 0x01, 0x2a, 0x22, 0x07, 0x2f, 0x64, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x12, 0x5d, 0x0a, 0x0c, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69,
+ 0x63, 0x65, 0x12, 0x18, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61,
+ 0x70, 0x69, 0x2e, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x52,
+ 0x65, 0x70, 0x6c, 0x79, 0x22, 0x1b, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x15, 0x2a, 0x13, 0x2f, 0x64,
+ 0x65, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x7b, 0x64, 0x65, 0x76, 0x69, 0x63, 0x65, 0x5f, 0x69, 0x64,
+ 0x7d, 0x12, 0x61, 0x0a, 0x0f, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74,
+ 0x43, 0x6c, 0x75, 0x62, 0x12, 0x1b, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53,
+ 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x75, 0x62, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73,
+ 0x74, 0x1a, 0x19, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x53, 0x74, 0x75, 0x64,
+ 0x65, 0x6e, 0x74, 0x43, 0x6c, 0x75, 0x62, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x22, 0x16, 0x82, 0xd3,
+ 0xe4, 0x93, 0x02, 0x10, 0x2a, 0x0e, 0x2f, 0x73, 0x74, 0x75, 0x64, 0x65, 0x6e, 0x74, 0x5f, 0x63,
+ 0x6c, 0x75, 0x62, 0x73, 0x42, 0x5e, 0x0a, 0x12, 0x61, 0x70, 0x70, 0x2e, 0x74, 0x75, 0x6d, 0x2e,
+ 0x63, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x42, 0x0e, 0x43, 0x61, 0x6d, 0x70,
+ 0x75, 0x73, 0x41, 0x70, 0x69, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x25, 0x67, 0x69,
+ 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x54, 0x55, 0x4d, 0x2d, 0x44, 0x65, 0x76,
+ 0x2f, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x2d, 0x42, 0x61, 0x63, 0x6b, 0x65, 0x6e, 0x64, 0x2f,
+ 0x61, 0x70, 0x69, 0xaa, 0x02, 0x0e, 0x43, 0x61, 0x6d, 0x70, 0x75, 0x73, 0x41, 0x70, 0x69, 0x50,
+ 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -4335,7 +4590,7 @@ func file_tumdev_campus_backend_proto_rawDescGZIP() []byte {
}
var file_tumdev_campus_backend_proto_enumTypes = make([]protoimpl.EnumInfo, 2)
-var file_tumdev_campus_backend_proto_msgTypes = make([]protoimpl.MessageInfo, 58)
+var file_tumdev_campus_backend_proto_msgTypes = make([]protoimpl.MessageInfo, 62)
var file_tumdev_campus_backend_proto_goTypes = []any{
(DeviceType)(0), // 0: api.DeviceType
(CreateFeedbackRequest_Recipient)(0), // 1: api.CreateFeedbackRequest.Recipient
@@ -4397,93 +4652,101 @@ var file_tumdev_campus_backend_proto_goTypes = []any{
(*GetNotificationConfirmReply)(nil), // 57: api.GetNotificationConfirmReply
(*GetCanteenHeadCountRequest)(nil), // 58: api.GetCanteenHeadCountRequest
(*GetCanteenHeadCountReply)(nil), // 59: api.GetCanteenHeadCountReply
- (*timestamppb.Timestamp)(nil), // 60: google.protobuf.Timestamp
+ (*ListStudentClubRequest)(nil), // 60: api.ListStudentClubRequest
+ (*ListStudentClubReply)(nil), // 61: api.ListStudentClubReply
+ (*StudentClub)(nil), // 62: api.StudentClub
+ (*StudentClubCollection)(nil), // 63: api.StudentClubCollection
+ (*timestamppb.Timestamp)(nil), // 64: google.protobuf.Timestamp
}
var file_tumdev_campus_backend_proto_depIdxs = []int32{
0, // 0: api.CreateDeviceRequest.device_type:type_name -> api.DeviceType
0, // 1: api.DeleteDeviceRequest.device_type:type_name -> api.DeviceType
- 60, // 2: api.News.created:type_name -> google.protobuf.Timestamp
- 60, // 3: api.News.date:type_name -> google.protobuf.Timestamp
+ 64, // 2: api.News.created:type_name -> google.protobuf.Timestamp
+ 64, // 3: api.News.date:type_name -> google.protobuf.Timestamp
6, // 4: api.ListNewsReply.news:type_name -> api.News
- 60, // 5: api.ListNewsRequest.oldest_date_at:type_name -> google.protobuf.Timestamp
+ 64, // 5: api.ListNewsRequest.oldest_date_at:type_name -> google.protobuf.Timestamp
11, // 6: api.ListNewsSourcesReply.sources:type_name -> api.NewsSource
14, // 7: api.ListNewsAlertsReply.alerts:type_name -> api.NewsAlert
- 60, // 8: api.NewsAlert.created:type_name -> google.protobuf.Timestamp
- 60, // 9: api.NewsAlert.from:type_name -> google.protobuf.Timestamp
- 60, // 10: api.NewsAlert.to:type_name -> google.protobuf.Timestamp
- 60, // 11: api.ListCanteenRatingsRequest.from:type_name -> google.protobuf.Timestamp
- 60, // 12: api.ListCanteenRatingsRequest.to:type_name -> google.protobuf.Timestamp
+ 64, // 8: api.NewsAlert.created:type_name -> google.protobuf.Timestamp
+ 64, // 9: api.NewsAlert.from:type_name -> google.protobuf.Timestamp
+ 64, // 10: api.NewsAlert.to:type_name -> google.protobuf.Timestamp
+ 64, // 11: api.ListCanteenRatingsRequest.from:type_name -> google.protobuf.Timestamp
+ 64, // 12: api.ListCanteenRatingsRequest.to:type_name -> google.protobuf.Timestamp
19, // 13: api.ListCanteenRatingsReply.rating:type_name -> api.SingleRatingReply
33, // 14: api.ListCanteenRatingsReply.rating_tags:type_name -> api.RatingTagResult
- 60, // 15: api.GetDishRatingsRequest.from:type_name -> google.protobuf.Timestamp
- 60, // 16: api.GetDishRatingsRequest.to:type_name -> google.protobuf.Timestamp
+ 64, // 15: api.GetDishRatingsRequest.from:type_name -> google.protobuf.Timestamp
+ 64, // 16: api.GetDishRatingsRequest.to:type_name -> google.protobuf.Timestamp
19, // 17: api.GetDishRatingsReply.rating:type_name -> api.SingleRatingReply
33, // 18: api.GetDishRatingsReply.rating_tags:type_name -> api.RatingTagResult
33, // 19: api.GetDishRatingsReply.name_tags:type_name -> api.RatingTagResult
32, // 20: api.SingleRatingReply.rating_tags:type_name -> api.RatingTagNewRequest
- 60, // 21: api.SingleRatingReply.visited:type_name -> google.protobuf.Timestamp
+ 64, // 21: api.SingleRatingReply.visited:type_name -> google.protobuf.Timestamp
31, // 22: api.CreateCanteenRatingRequest.rating_tags:type_name -> api.RatingTag
31, // 23: api.CreateDishRatingRequest.rating_tags:type_name -> api.RatingTag
30, // 24: api.ListAvailableDishTagsReply.rating_tags:type_name -> api.TagsOverview
30, // 25: api.ListNameTagsReply.rating_tags:type_name -> api.TagsOverview
30, // 26: api.ListAvailableCanteenTagsReply.rating_tags:type_name -> api.TagsOverview
36, // 27: api.ListCanteensReply.canteen:type_name -> api.Canteen
- 60, // 28: api.ListMoviesRequest.oldest_date_at:type_name -> google.protobuf.Timestamp
+ 64, // 28: api.ListMoviesRequest.oldest_date_at:type_name -> google.protobuf.Timestamp
44, // 29: api.ListMoviesReply.movies:type_name -> api.Movie
- 60, // 30: api.Movie.date:type_name -> google.protobuf.Timestamp
- 60, // 31: api.Movie.created:type_name -> google.protobuf.Timestamp
+ 64, // 30: api.Movie.date:type_name -> google.protobuf.Timestamp
+ 64, // 31: api.Movie.created:type_name -> google.protobuf.Timestamp
1, // 32: api.CreateFeedbackRequest.recipient:type_name -> api.CreateFeedbackRequest.Recipient
46, // 33: api.CreateFeedbackRequest.location:type_name -> api.Coordinate
- 60, // 34: api.GetCanteenHeadCountReply.timestamp:type_name -> google.protobuf.Timestamp
- 12, // 35: api.Campus.ListNewsAlerts:input_type -> api.ListNewsAlertsRequest
- 9, // 36: api.Campus.ListNewsSources:input_type -> api.ListNewsSourcesRequest
- 8, // 37: api.Campus.ListNews:input_type -> api.ListNewsRequest
- 15, // 38: api.Campus.ListCanteenRatings:input_type -> api.ListCanteenRatingsRequest
- 17, // 39: api.Campus.GetDishRatings:input_type -> api.GetDishRatingsRequest
- 21, // 40: api.Campus.CreateCanteenRating:input_type -> api.CreateCanteenRatingRequest
- 23, // 41: api.Campus.CreateDishRating:input_type -> api.CreateDishRatingRequest
- 24, // 42: api.Campus.ListAvailableDishTags:input_type -> api.ListAvailableDishTagsRequest
- 26, // 43: api.Campus.ListNameTags:input_type -> api.ListNameTagsRequest
- 28, // 44: api.Campus.ListAvailableCanteenTags:input_type -> api.ListAvailableCanteenTagsRequest
- 34, // 45: api.Campus.ListCanteens:input_type -> api.ListCanteensRequest
- 37, // 46: api.Campus.ListDishes:input_type -> api.ListDishesRequest
- 40, // 47: api.Campus.GetUpdateNote:input_type -> api.GetUpdateNoteRequest
- 42, // 48: api.Campus.ListMovies:input_type -> api.ListMoviesRequest
- 45, // 49: api.Campus.CreateFeedback:input_type -> api.CreateFeedbackRequest
- 52, // 50: api.Campus.GetUploadStatus:input_type -> api.GetUploadStatusRequest
- 54, // 51: api.Campus.GetNotification:input_type -> api.GetNotificationRequest
- 56, // 52: api.Campus.GetNotificationConfirm:input_type -> api.GetNotificationConfirmRequest
- 50, // 53: api.Campus.GetMember:input_type -> api.GetMemberRequest
- 58, // 54: api.Campus.GetCanteenHeadCount:input_type -> api.GetCanteenHeadCountRequest
- 2, // 55: api.Campus.CreateDevice:input_type -> api.CreateDeviceRequest
- 4, // 56: api.Campus.DeleteDevice:input_type -> api.DeleteDeviceRequest
- 13, // 57: api.Campus.ListNewsAlerts:output_type -> api.ListNewsAlertsReply
- 10, // 58: api.Campus.ListNewsSources:output_type -> api.ListNewsSourcesReply
- 7, // 59: api.Campus.ListNews:output_type -> api.ListNewsReply
- 16, // 60: api.Campus.ListCanteenRatings:output_type -> api.ListCanteenRatingsReply
- 18, // 61: api.Campus.GetDishRatings:output_type -> api.GetDishRatingsReply
- 20, // 62: api.Campus.CreateCanteenRating:output_type -> api.CreateCanteenRatingReply
- 22, // 63: api.Campus.CreateDishRating:output_type -> api.CreateDishRatingReply
- 25, // 64: api.Campus.ListAvailableDishTags:output_type -> api.ListAvailableDishTagsReply
- 27, // 65: api.Campus.ListNameTags:output_type -> api.ListNameTagsReply
- 29, // 66: api.Campus.ListAvailableCanteenTags:output_type -> api.ListAvailableCanteenTagsReply
- 35, // 67: api.Campus.ListCanteens:output_type -> api.ListCanteensReply
- 38, // 68: api.Campus.ListDishes:output_type -> api.ListDishesReply
- 41, // 69: api.Campus.GetUpdateNote:output_type -> api.GetUpdateNoteReply
- 43, // 70: api.Campus.ListMovies:output_type -> api.ListMoviesReply
- 47, // 71: api.Campus.CreateFeedback:output_type -> api.CreateFeedbackReply
- 53, // 72: api.Campus.GetUploadStatus:output_type -> api.GetUploadStatusReply
- 55, // 73: api.Campus.GetNotification:output_type -> api.GetNotificationReply
- 57, // 74: api.Campus.GetNotificationConfirm:output_type -> api.GetNotificationConfirmReply
- 51, // 75: api.Campus.GetMember:output_type -> api.GetMemberReply
- 59, // 76: api.Campus.GetCanteenHeadCount:output_type -> api.GetCanteenHeadCountReply
- 3, // 77: api.Campus.CreateDevice:output_type -> api.CreateDeviceReply
- 5, // 78: api.Campus.DeleteDevice:output_type -> api.DeleteDeviceReply
- 57, // [57:79] is the sub-list for method output_type
- 35, // [35:57] is the sub-list for method input_type
- 35, // [35:35] is the sub-list for extension type_name
- 35, // [35:35] is the sub-list for extension extendee
- 0, // [0:35] is the sub-list for field type_name
+ 64, // 34: api.GetCanteenHeadCountReply.timestamp:type_name -> google.protobuf.Timestamp
+ 63, // 35: api.ListStudentClubReply.collections:type_name -> api.StudentClubCollection
+ 62, // 36: api.StudentClubCollection.clubs:type_name -> api.StudentClub
+ 12, // 37: api.Campus.ListNewsAlerts:input_type -> api.ListNewsAlertsRequest
+ 9, // 38: api.Campus.ListNewsSources:input_type -> api.ListNewsSourcesRequest
+ 8, // 39: api.Campus.ListNews:input_type -> api.ListNewsRequest
+ 15, // 40: api.Campus.ListCanteenRatings:input_type -> api.ListCanteenRatingsRequest
+ 17, // 41: api.Campus.GetDishRatings:input_type -> api.GetDishRatingsRequest
+ 21, // 42: api.Campus.CreateCanteenRating:input_type -> api.CreateCanteenRatingRequest
+ 23, // 43: api.Campus.CreateDishRating:input_type -> api.CreateDishRatingRequest
+ 24, // 44: api.Campus.ListAvailableDishTags:input_type -> api.ListAvailableDishTagsRequest
+ 26, // 45: api.Campus.ListNameTags:input_type -> api.ListNameTagsRequest
+ 28, // 46: api.Campus.ListAvailableCanteenTags:input_type -> api.ListAvailableCanteenTagsRequest
+ 34, // 47: api.Campus.ListCanteens:input_type -> api.ListCanteensRequest
+ 37, // 48: api.Campus.ListDishes:input_type -> api.ListDishesRequest
+ 40, // 49: api.Campus.GetUpdateNote:input_type -> api.GetUpdateNoteRequest
+ 42, // 50: api.Campus.ListMovies:input_type -> api.ListMoviesRequest
+ 45, // 51: api.Campus.CreateFeedback:input_type -> api.CreateFeedbackRequest
+ 52, // 52: api.Campus.GetUploadStatus:input_type -> api.GetUploadStatusRequest
+ 54, // 53: api.Campus.GetNotification:input_type -> api.GetNotificationRequest
+ 56, // 54: api.Campus.GetNotificationConfirm:input_type -> api.GetNotificationConfirmRequest
+ 50, // 55: api.Campus.GetMember:input_type -> api.GetMemberRequest
+ 58, // 56: api.Campus.GetCanteenHeadCount:input_type -> api.GetCanteenHeadCountRequest
+ 2, // 57: api.Campus.CreateDevice:input_type -> api.CreateDeviceRequest
+ 4, // 58: api.Campus.DeleteDevice:input_type -> api.DeleteDeviceRequest
+ 60, // 59: api.Campus.ListStudentClub:input_type -> api.ListStudentClubRequest
+ 13, // 60: api.Campus.ListNewsAlerts:output_type -> api.ListNewsAlertsReply
+ 10, // 61: api.Campus.ListNewsSources:output_type -> api.ListNewsSourcesReply
+ 7, // 62: api.Campus.ListNews:output_type -> api.ListNewsReply
+ 16, // 63: api.Campus.ListCanteenRatings:output_type -> api.ListCanteenRatingsReply
+ 18, // 64: api.Campus.GetDishRatings:output_type -> api.GetDishRatingsReply
+ 20, // 65: api.Campus.CreateCanteenRating:output_type -> api.CreateCanteenRatingReply
+ 22, // 66: api.Campus.CreateDishRating:output_type -> api.CreateDishRatingReply
+ 25, // 67: api.Campus.ListAvailableDishTags:output_type -> api.ListAvailableDishTagsReply
+ 27, // 68: api.Campus.ListNameTags:output_type -> api.ListNameTagsReply
+ 29, // 69: api.Campus.ListAvailableCanteenTags:output_type -> api.ListAvailableCanteenTagsReply
+ 35, // 70: api.Campus.ListCanteens:output_type -> api.ListCanteensReply
+ 38, // 71: api.Campus.ListDishes:output_type -> api.ListDishesReply
+ 41, // 72: api.Campus.GetUpdateNote:output_type -> api.GetUpdateNoteReply
+ 43, // 73: api.Campus.ListMovies:output_type -> api.ListMoviesReply
+ 47, // 74: api.Campus.CreateFeedback:output_type -> api.CreateFeedbackReply
+ 53, // 75: api.Campus.GetUploadStatus:output_type -> api.GetUploadStatusReply
+ 55, // 76: api.Campus.GetNotification:output_type -> api.GetNotificationReply
+ 57, // 77: api.Campus.GetNotificationConfirm:output_type -> api.GetNotificationConfirmReply
+ 51, // 78: api.Campus.GetMember:output_type -> api.GetMemberReply
+ 59, // 79: api.Campus.GetCanteenHeadCount:output_type -> api.GetCanteenHeadCountReply
+ 3, // 80: api.Campus.CreateDevice:output_type -> api.CreateDeviceReply
+ 5, // 81: api.Campus.DeleteDevice:output_type -> api.DeleteDeviceReply
+ 61, // 82: api.Campus.ListStudentClub:output_type -> api.ListStudentClubReply
+ 60, // [60:83] is the sub-list for method output_type
+ 37, // [37:60] is the sub-list for method input_type
+ 37, // [37:37] is the sub-list for extension type_name
+ 37, // [37:37] is the sub-list for extension extendee
+ 0, // [0:37] is the sub-list for field type_name
}
func init() { file_tumdev_campus_backend_proto_init() }
@@ -5188,14 +5451,63 @@ func file_tumdev_campus_backend_proto_init() {
return nil
}
}
+ file_tumdev_campus_backend_proto_msgTypes[58].Exporter = func(v any, i int) any {
+ switch v := v.(*ListStudentClubRequest); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tumdev_campus_backend_proto_msgTypes[59].Exporter = func(v any, i int) any {
+ switch v := v.(*ListStudentClubReply); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tumdev_campus_backend_proto_msgTypes[60].Exporter = func(v any, i int) any {
+ switch v := v.(*StudentClub); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
+ file_tumdev_campus_backend_proto_msgTypes[61].Exporter = func(v any, i int) any {
+ switch v := v.(*StudentClubCollection); i {
+ case 0:
+ return &v.state
+ case 1:
+ return &v.sizeCache
+ case 2:
+ return &v.unknownFields
+ default:
+ return nil
+ }
+ }
}
+ file_tumdev_campus_backend_proto_msgTypes[60].OneofWrappers = []any{}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_tumdev_campus_backend_proto_rawDesc,
NumEnums: 2,
- NumMessages: 58,
+ NumMessages: 62,
NumExtensions: 0,
NumServices: 1,
},
diff --git a/server/api/tumdev/campus_backend.pb.gw.go b/server/api/tumdev/campus_backend.pb.gw.go
index bf697ad9..c2942d9c 100644
--- a/server/api/tumdev/campus_backend.pb.gw.go
+++ b/server/api/tumdev/campus_backend.pb.gw.go
@@ -855,6 +855,24 @@ func local_request_Campus_DeleteDevice_0(ctx context.Context, marshaler runtime.
}
+func request_Campus_ListStudentClub_0(ctx context.Context, marshaler runtime.Marshaler, client CampusClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq ListStudentClubRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := client.ListStudentClub(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
+ return msg, metadata, err
+
+}
+
+func local_request_Campus_ListStudentClub_0(ctx context.Context, marshaler runtime.Marshaler, server CampusServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
+ var protoReq ListStudentClubRequest
+ var metadata runtime.ServerMetadata
+
+ msg, err := server.ListStudentClub(ctx, &protoReq)
+ return msg, metadata, err
+
+}
+
// RegisterCampusHandlerServer registers the http handlers for service Campus to "mux".
// UnaryRPC :call CampusServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
@@ -1393,6 +1411,31 @@ func RegisterCampusHandlerServer(ctx context.Context, mux *runtime.ServeMux, ser
})
+ mux.Handle("DELETE", pattern_Campus_ListStudentClub_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ var stream runtime.ServerTransportStream
+ ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ var annotatedContext context.Context
+ annotatedContext, err = runtime.AnnotateIncomingContext(ctx, mux, req, "/api.Campus/ListStudentClub", runtime.WithHTTPPathPattern("/student_clubs"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := local_request_Campus_ListStudentClub_0(annotatedContext, inboundMarshaler, server, req, pathParams)
+ md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
+ annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
+ if err != nil {
+ runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Campus_ListStudentClub_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
@@ -1918,6 +1961,28 @@ func RegisterCampusHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli
})
+ mux.Handle("DELETE", pattern_Campus_ListStudentClub_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
+ ctx, cancel := context.WithCancel(req.Context())
+ defer cancel()
+ inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
+ var err error
+ var annotatedContext context.Context
+ annotatedContext, err = runtime.AnnotateContext(ctx, mux, req, "/api.Campus/ListStudentClub", runtime.WithHTTPPathPattern("/student_clubs"))
+ if err != nil {
+ runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
+ return
+ }
+ resp, md, err := request_Campus_ListStudentClub_0(annotatedContext, inboundMarshaler, client, req, pathParams)
+ annotatedContext = runtime.NewServerMetadataContext(annotatedContext, md)
+ if err != nil {
+ runtime.HTTPError(annotatedContext, mux, outboundMarshaler, w, req, err)
+ return
+ }
+
+ forward_Campus_ListStudentClub_0(annotatedContext, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
+
+ })
+
return nil
}
@@ -2037,6 +2102,8 @@ var (
pattern_Campus_CreateDevice_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"device"}, ""))
pattern_Campus_DeleteDevice_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1}, []string{"device", "device_id"}, ""))
+
+ pattern_Campus_ListStudentClub_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0}, []string{"student_clubs"}, ""))
)
var (
@@ -2083,4 +2150,6 @@ var (
forward_Campus_CreateDevice_0 = runtime.ForwardResponseMessage
forward_Campus_DeleteDevice_0 = runtime.ForwardResponseMessage
+
+ forward_Campus_ListStudentClub_0 = runtime.ForwardResponseMessage
)
diff --git a/server/api/tumdev/campus_backend.proto b/server/api/tumdev/campus_backend.proto
index 5a3348d7..861c8a5b 100644
--- a/server/api/tumdev/campus_backend.proto
+++ b/server/api/tumdev/campus_backend.proto
@@ -146,6 +146,11 @@ service Campus {
rpc DeleteDevice(DeleteDeviceRequest) returns (DeleteDeviceReply) {
option (google.api.http) = {delete: "/device/{device_id}"};
}
+
+ // Delete a device from push notifications
+ rpc ListStudentClub(ListStudentClubRequest) returns (ListStudentClubReply) {
+ option (google.api.http) = {delete: "/student_clubs"};
+ }
}
enum DeviceType {
@@ -559,3 +564,22 @@ message GetCanteenHeadCountReply {
// A time stamp indicating how up to date the response is. Only valid in case percent != -1.
google.protobuf.Timestamp timestamp = 4;
}
+message ListStudentClubRequest {}
+message ListStudentClubReply {
+ repeated StudentClubCollection collections = 1;
+}
+message StudentClub {
+ // The name of the club
+ string name = 1;
+ // How the club describes itsself
+ optional string description = 2;
+ // Where the clubs main internet presence is
+ optional string link_url = 3;
+ // Where to find a image for this club
+ optional string cover_url = 4;
+}
+message StudentClubCollection {
+ string title = 1;
+ string description = 2;
+ repeated StudentClub clubs = 3;
+}
diff --git a/server/api/tumdev/campus_backend.swagger.json b/server/api/tumdev/campus_backend.swagger.json
index 4c077cd3..d2649ae9 100644
--- a/server/api/tumdev/campus_backend.swagger.json
+++ b/server/api/tumdev/campus_backend.swagger.json
@@ -787,6 +787,29 @@
]
}
},
+ "/student_clubs": {
+ "delete": {
+ "summary": "Delete a device from push notifications",
+ "operationId": "Campus_ListStudentClub",
+ "responses": {
+ "200": {
+ "description": "A successful response.",
+ "schema": {
+ "$ref": "#/definitions/apiListStudentClubReply"
+ }
+ },
+ "default": {
+ "description": "An unexpected error response.",
+ "schema": {
+ "$ref": "#/definitions/rpcStatus"
+ }
+ }
+ },
+ "tags": [
+ "Campus"
+ ]
+ }
+ },
"/updatenote/{version}": {
"get": {
"operationId": "Campus_GetUpdateNote",
@@ -1315,6 +1338,18 @@
}
}
},
+ "apiListStudentClubReply": {
+ "type": "object",
+ "properties": {
+ "collections": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "$ref": "#/definitions/apiStudentClubCollection"
+ }
+ }
+ }
+ },
"apiMovie": {
"type": "object",
"properties": {
@@ -1551,6 +1586,45 @@
}
}
},
+ "apiStudentClub": {
+ "type": "object",
+ "properties": {
+ "name": {
+ "type": "string",
+ "title": "The name of the club"
+ },
+ "description": {
+ "type": "string",
+ "title": "How the club describes itsself"
+ },
+ "linkUrl": {
+ "type": "string",
+ "title": "Where the clubs main internet presence is"
+ },
+ "coverUrl": {
+ "type": "string",
+ "title": "Where to find a image for this club"
+ }
+ }
+ },
+ "apiStudentClubCollection": {
+ "type": "object",
+ "properties": {
+ "title": {
+ "type": "string"
+ },
+ "description": {
+ "type": "string"
+ },
+ "clubs": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "$ref": "#/definitions/apiStudentClub"
+ }
+ }
+ }
+ },
"apiTagsOverview": {
"type": "object",
"properties": {
diff --git a/server/api/tumdev/campus_backend_grpc.pb.go b/server/api/tumdev/campus_backend_grpc.pb.go
index 6babac76..7d12bbb9 100644
--- a/server/api/tumdev/campus_backend_grpc.pb.go
+++ b/server/api/tumdev/campus_backend_grpc.pb.go
@@ -42,6 +42,7 @@ const (
Campus_GetCanteenHeadCount_FullMethodName = "/api.Campus/GetCanteenHeadCount"
Campus_CreateDevice_FullMethodName = "/api.Campus/CreateDevice"
Campus_DeleteDevice_FullMethodName = "/api.Campus/DeleteDevice"
+ Campus_ListStudentClub_FullMethodName = "/api.Campus/ListStudentClub"
)
// CampusClient is the client API for Campus service.
@@ -75,6 +76,8 @@ type CampusClient interface {
CreateDevice(ctx context.Context, in *CreateDeviceRequest, opts ...grpc.CallOption) (*CreateDeviceReply, error)
// Delete a device from push notifications
DeleteDevice(ctx context.Context, in *DeleteDeviceRequest, opts ...grpc.CallOption) (*DeleteDeviceReply, error)
+ // Delete a device from push notifications
+ ListStudentClub(ctx context.Context, in *ListStudentClubRequest, opts ...grpc.CallOption) (*ListStudentClubReply, error)
}
type campusClient struct {
@@ -330,6 +333,16 @@ func (c *campusClient) DeleteDevice(ctx context.Context, in *DeleteDeviceRequest
return out, nil
}
+func (c *campusClient) ListStudentClub(ctx context.Context, in *ListStudentClubRequest, opts ...grpc.CallOption) (*ListStudentClubReply, error) {
+ cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
+ out := new(ListStudentClubReply)
+ err := c.cc.Invoke(ctx, Campus_ListStudentClub_FullMethodName, in, out, cOpts...)
+ if err != nil {
+ return nil, err
+ }
+ return out, nil
+}
+
// CampusServer is the server API for Campus service.
// All implementations must embed UnimplementedCampusServer
// for forward compatibility
@@ -361,6 +374,8 @@ type CampusServer interface {
CreateDevice(context.Context, *CreateDeviceRequest) (*CreateDeviceReply, error)
// Delete a device from push notifications
DeleteDevice(context.Context, *DeleteDeviceRequest) (*DeleteDeviceReply, error)
+ // Delete a device from push notifications
+ ListStudentClub(context.Context, *ListStudentClubRequest) (*ListStudentClubReply, error)
mustEmbedUnimplementedCampusServer()
}
@@ -434,6 +449,9 @@ func (UnimplementedCampusServer) CreateDevice(context.Context, *CreateDeviceRequ
func (UnimplementedCampusServer) DeleteDevice(context.Context, *DeleteDeviceRequest) (*DeleteDeviceReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method DeleteDevice not implemented")
}
+func (UnimplementedCampusServer) ListStudentClub(context.Context, *ListStudentClubRequest) (*ListStudentClubReply, error) {
+ return nil, status.Errorf(codes.Unimplemented, "method ListStudentClub not implemented")
+}
func (UnimplementedCampusServer) mustEmbedUnimplementedCampusServer() {}
// UnsafeCampusServer may be embedded to opt out of forward compatibility for this service.
@@ -851,6 +869,24 @@ func _Campus_DeleteDevice_Handler(srv interface{}, ctx context.Context, dec func
return interceptor(ctx, in, info, handler)
}
+func _Campus_ListStudentClub_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
+ in := new(ListStudentClubRequest)
+ if err := dec(in); err != nil {
+ return nil, err
+ }
+ if interceptor == nil {
+ return srv.(CampusServer).ListStudentClub(ctx, in)
+ }
+ info := &grpc.UnaryServerInfo{
+ Server: srv,
+ FullMethod: Campus_ListStudentClub_FullMethodName,
+ }
+ handler := func(ctx context.Context, req interface{}) (interface{}, error) {
+ return srv.(CampusServer).ListStudentClub(ctx, req.(*ListStudentClubRequest))
+ }
+ return interceptor(ctx, in, info, handler)
+}
+
// Campus_ServiceDesc is the grpc.ServiceDesc for Campus service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -942,6 +978,10 @@ var Campus_ServiceDesc = grpc.ServiceDesc{
MethodName: "DeleteDevice",
Handler: _Campus_DeleteDevice_Handler,
},
+ {
+ MethodName: "ListStudentClub",
+ Handler: _Campus_ListStudentClub_Handler,
+ },
},
Streams: []grpc.StreamDesc{
{
diff --git a/server/backend/cron/cronjobs.go b/server/backend/cron/cronjobs.go
index b191bb46..8e11f02a 100644
--- a/server/backend/cron/cronjobs.go
+++ b/server/backend/cron/cronjobs.go
@@ -27,6 +27,7 @@ const (
CanteenHeadcount = "canteenHeadCount"
MovieType = "movie"
FeedbackEmail = "feedbackEmail"
+ StudentClubType = "scrapeStudentClubs"
/* MensaType = "mensa"
AlarmType = "alarm" */
@@ -46,7 +47,7 @@ func (c *CronService) Run() error {
var res []model.Crontab
c.db.Model(&model.Crontab{}).
- Find(&res, "`interval` > 0 AND (lastRun+`interval`) < ? AND type IN (?, ?, ?, ?, ?, ?)",
+ Find(&res, "`interval` > 0 AND (lastRun+`interval`) < ? AND type IN (?, ?, ?, ?, ?, ?, ?)",
time.Now().Unix(),
NewsType,
FileDownloadType,
@@ -54,6 +55,7 @@ func (c *CronService) Run() error {
CanteenHeadcount,
MovieType,
FeedbackEmail,
+ StudentClubType,
)
for _, cronjob := range res {
@@ -66,6 +68,8 @@ func (c *CronService) Run() error {
// Run each job in a separate goroutine, so we can parallelize them
switch cronjob.Type.String {
+ case StudentClubType:
+ g.Go(func() error { return c.studentClubCron() })
case NewsType:
// if this is not copied here, this may not be threads save due to go's guarantees
// loop variable cronjob captured by func literal (govet)
diff --git a/server/backend/cron/student_club_parsers/sv.go b/server/backend/cron/student_club_parsers/sv.go
new file mode 100644
index 00000000..453f5a4c
--- /dev/null
+++ b/server/backend/cron/student_club_parsers/sv.go
@@ -0,0 +1,173 @@
+package student_club_parsers
+
+import (
+ "errors"
+ "fmt"
+ "html"
+ "io"
+ "net/http"
+ "strings"
+
+ "github.com/PuerkitoBio/goquery"
+ "github.com/guregu/null"
+ "github.com/microcosm-cc/bluemonday"
+ log "github.com/sirupsen/logrus"
+)
+
+type SVStudentClub struct {
+ Name string
+ Collection string
+ Description null.String
+ ImageUrl null.String
+ ImageCaption null.String
+ LinkUrl null.String
+}
+
+type SVStudentClubCollection struct {
+ Name string
+ Description string
+}
+
+func DownloadHtml(url string) (io.ReadCloser, error) {
+ resp, err := http.Get(url)
+ if err != nil {
+ return nil, errors.New("error while getting response for request")
+ }
+ return resp.Body, nil
+}
+
+func ParseStudentClubs(reader io.Reader) ([]SVStudentClub, []SVStudentClubCollection, error) {
+ doc, err := goquery.NewDocumentFromReader(reader)
+ if err != nil {
+ log.WithError(err).Error("Error while parsing student clubs into goquery document")
+ return nil, nil, err
+ }
+ scrapedClubs := make([]SVStudentClub, 0)
+ scrapedClubCollections := make([]SVStudentClubCollection, 0)
+ currentCollectionHeader := ""
+ filterForRelevantFrames(doc).Each(func(i int, s *goquery.Selection) {
+ // section headers and regular headers best differentiated by either having a h2 or h6 tag.
+ // h2 => this is a studentClub Collection
+ // h6 => this is a studentClub
+ if s.Has("h2").Length() >= 1 {
+ collection := SVStudentClubCollection{
+ Name: parseTitle(s, "h2"),
+ Description: parseDescription(s, "p").ValueOrZero(),
+ }
+ currentCollectionHeader = collection.Name
+ scrapedClubCollections = append(scrapedClubCollections, collection)
+ } else if s.Has("h6").Length() >= 1 {
+ image, imgCaption := parseImages(s)
+ club := SVStudentClub{
+ Name: parseTitle(s, "h6"),
+ Collection: currentCollectionHeader,
+ Description: parseDescription(s, "p"),
+ ImageUrl: image,
+ ImageCaption: imgCaption,
+ LinkUrl: parseLink(s),
+ }
+ scrapedClubs = append(scrapedClubs, club)
+ } else {
+ logForSelection(log.ErrorLevel, "Cannot parse html into student clubs", s)
+ }
+ })
+ return scrapedClubs, scrapedClubCollections, nil
+}
+
+func parseImages(s *goquery.Selection) (null.String, null.String) {
+ href, exists := s.Find("img").First().Attr("src")
+ if !exists {
+ return null.String{}, null.String{}
+ }
+ sanitisedHref := bluemonday.StrictPolicy().Sanitize(href)
+ figcaption := null.String{}
+ if s.Has("figcaption").Length() >= 1 {
+ caption := s.Find("figcaption").Text()
+ figcaption = null.StringFrom(trimSpaces(caption))
+ }
+ return null.StringFrom("https://sv.tum.de" + sanitisedHref), figcaption
+}
+
+func parseLink(s *goquery.Selection) null.String {
+ href, exists := s.Find("a").First().Attr("href")
+ if !exists {
+ return null.String{}
+ }
+ sanitisedHref := bluemonday.StrictPolicy().Sanitize(href)
+ return null.StringFrom(sanitisedHref)
+}
+
+func filterForRelevantFrames(doc *goquery.Document) *goquery.Selection {
+ passesFilter := false
+ return doc.
+ Find(".frame").
+ FilterFunction(func(_ int, sel *goquery.Selection) bool {
+ if sel.HasClass("frame-type-menu_categorized_content") {
+ passesFilter = true
+ return false
+ }
+ if sel.HasClass("frame-space-before-extra-large") {
+ passesFilter = false
+ return false
+ }
+ // the selections we want are all
but there are some other frames like a