From c268551a16929a2cbea6891951feff91926bba59 Mon Sep 17 00:00:00 2001 From: boojack Date: Sun, 26 Apr 2026 11:50:26 +0800 Subject: [PATCH] feat(memos): choose created or updated time for memos (#5894) --- proto/api/v1/instance_service.proto | 4 +- proto/api/v1/memo_service.proto | 10 +- proto/api/v1/user_service.proto | 7 +- proto/gen/api/v1/instance_service.pb.go | 18 +- proto/gen/api/v1/memo_service.pb.go | 157 ++++++++---------- proto/gen/api/v1/user_service.pb.go | 32 ++-- proto/gen/openapi.yaml | 25 +-- proto/gen/store/instance_setting.pb.go | 16 +- proto/store/instance_setting.proto | 4 +- server/router/api/v1/instance_service.go | 2 - server/router/api/v1/memo_service.go | 71 ++------ .../router/api/v1/memo_service_converter.go | 42 +---- .../router/api/v1/test/memo_service_test.go | 149 +++++++++++++---- server/router/api/v1/user_service_stats.go | 30 +--- .../memoShareImagePreviewModel.ts | 2 +- web/src/components/MemoCommentSection.tsx | 2 +- web/src/components/MemoDisplaySettingMenu.tsx | 24 ++- .../MemoMetadata/Relation/LinkMemoDialog.tsx | 2 +- .../components/MemoView/MemoViewContext.tsx | 6 +- .../MemoView/components/MemoHeader.tsx | 11 +- .../PagedMemoList/PagedMemoList.tsx | 2 +- .../Settings/MemoRelatedSettings.tsx | 7 - .../components/UserMemoMap/UserMemoMap.tsx | 6 +- web/src/contexts/ViewContext.tsx | 32 +++- web/src/hooks/useFilteredMemoStats.ts | 8 +- web/src/hooks/useMemoFilters.ts | 9 +- web/src/hooks/useMemoSorting.ts | 23 ++- web/src/locales/en.json | 4 + web/src/locales/zh-Hans.json | 4 + web/src/locales/zh-Hant.json | 4 + web/src/pages/Home.tsx | 2 +- web/src/pages/MemoDetail.tsx | 2 +- web/src/pages/UserProfile.tsx | 2 +- web/src/types/proto/api/v1/ai_service_pb.ts | 6 +- .../proto/api/v1/attachment_service_pb.ts | 14 +- web/src/types/proto/api/v1/auth_service_pb.ts | 10 +- web/src/types/proto/api/v1/common_pb.ts | 2 +- web/src/types/proto/api/v1/idp_service_pb.ts | 12 +- .../types/proto/api/v1/instance_service_pb.ts | 25 +-- web/src/types/proto/api/v1/memo_service_pb.ts | 49 +++--- .../types/proto/api/v1/shortcut_service_pb.ts | 8 +- web/src/types/proto/api/v1/user_service_pb.ts | 62 +++---- .../types/proto/google/api/annotations_pb.ts | 2 +- web/src/types/proto/google/api/client_pb.ts | 46 ++--- .../proto/google/api/field_behavior_pb.ts | 2 +- web/src/types/proto/google/api/http_pb.ts | 2 +- .../types/proto/google/api/launch_stage_pb.ts | 2 +- web/src/types/proto/google/api/resource_pb.ts | 2 +- web/src/types/proto/google/type/color_pb.ts | 4 +- 49 files changed, 483 insertions(+), 484 deletions(-) diff --git a/proto/api/v1/instance_service.proto b/proto/api/v1/instance_service.proto index 91bbcf632..1ab587570 100644 --- a/proto/api/v1/instance_service.proto +++ b/proto/api/v1/instance_service.proto @@ -158,8 +158,8 @@ message InstanceSetting { // Memo-related instance settings and policies. message MemoRelatedSetting { - // display_with_update_time orders and displays memo with update time. - bool display_with_update_time = 2; + reserved 2; + reserved "display_with_update_time"; // content_length_limit is the limit of content length. Unit is byte. int32 content_length_limit = 3; // enable_double_click_edit enables editing on double click. diff --git a/proto/api/v1/memo_service.proto b/proto/api/v1/memo_service.proto index 9f697d173..56c3eeab0 100644 --- a/proto/api/v1/memo_service.proto +++ b/proto/api/v1/memo_service.proto @@ -204,8 +204,8 @@ message Memo { // If not set on creation, the server will set it to the current time. google.protobuf.Timestamp update_time = 5 [(google.api.field_behavior) = OPTIONAL]; - // The display timestamp of the memo. - google.protobuf.Timestamp display_time = 6 [(google.api.field_behavior) = OPTIONAL]; + reserved 6; + reserved "display_time"; // Required. The content of the memo in Markdown format. string content = 7 [(google.api.field_behavior) = REQUIRED]; @@ -291,10 +291,10 @@ message ListMemosRequest { State state = 3 [(google.api.field_behavior) = OPTIONAL]; // Optional. The order to sort results by. - // Default to "display_time desc". + // Default to "create_time desc". // Supports comma-separated list of fields following AIP-132. - // Example: "pinned desc, display_time desc" or "create_time asc" - // Supported fields: pinned, display_time, create_time, update_time, name + // Example: "pinned desc, create_time desc" or "update_time asc" + // Supported fields: pinned, create_time, update_time, name string order_by = 4 [(google.api.field_behavior) = OPTIONAL]; // Optional. Filter to apply to the list results. diff --git a/proto/api/v1/user_service.proto b/proto/api/v1/user_service.proto index 1277e1f2d..c6eeb86fc 100644 --- a/proto/api/v1/user_service.proto +++ b/proto/api/v1/user_service.proto @@ -354,8 +354,8 @@ message UserStats { // Format: users/{user} string name = 1 [(google.api.field_behavior) = IDENTIFIER]; - // The timestamps when the memos were displayed. - repeated google.protobuf.Timestamp memo_display_timestamps = 2; + reserved 2; + reserved "memo_display_timestamps"; // The stats of memo types. MemoTypeStats memo_type_stats = 3; @@ -363,6 +363,9 @@ message UserStats { // The count of tags. map tag_count = 4; + // The creation timestamps of the user's memos. + repeated google.protobuf.Timestamp memo_created_timestamps = 7; + // The pinned memos of the user. repeated string pinned_memos = 5; diff --git a/proto/gen/api/v1/instance_service.pb.go b/proto/gen/api/v1/instance_service.pb.go index d308d1ec2..e0c1dd53f 100644 --- a/proto/gen/api/v1/instance_service.pb.go +++ b/proto/gen/api/v1/instance_service.pb.go @@ -756,8 +756,6 @@ func (x *InstanceSetting_StorageSetting) GetS3Config() *InstanceSetting_StorageS // Memo-related instance settings and policies. type InstanceSetting_MemoRelatedSetting struct { state protoimpl.MessageState `protogen:"open.v1"` - // display_with_update_time orders and displays memo with update time. - DisplayWithUpdateTime bool `protobuf:"varint,2,opt,name=display_with_update_time,json=displayWithUpdateTime,proto3" json:"display_with_update_time,omitempty"` // content_length_limit is the limit of content length. Unit is byte. ContentLengthLimit int32 `protobuf:"varint,3,opt,name=content_length_limit,json=contentLengthLimit,proto3" json:"content_length_limit,omitempty"` // enable_double_click_edit enables editing on double click. @@ -798,13 +796,6 @@ func (*InstanceSetting_MemoRelatedSetting) Descriptor() ([]byte, []int) { return file_api_v1_instance_service_proto_rawDescGZIP(), []int{2, 2} } -func (x *InstanceSetting_MemoRelatedSetting) GetDisplayWithUpdateTime() bool { - if x != nil { - return x.DisplayWithUpdateTime - } - return false -} - func (x *InstanceSetting_MemoRelatedSetting) GetContentLengthLimit() int32 { if x != nil { return x.ContentLengthLimit @@ -1392,7 +1383,7 @@ const file_api_v1_instance_service_proto_rawDesc = "" + "\x04demo\x18\x03 \x01(\bR\x04demo\x12!\n" + "\finstance_url\x18\x06 \x01(\tR\vinstanceUrl\x12(\n" + "\x05admin\x18\a \x01(\v2\x12.memos.api.v1.UserR\x05admin\"\x1b\n" + - "\x19GetInstanceProfileRequest\"\xff\x19\n" + + "\x19GetInstanceProfileRequest\"\xe6\x19\n" + "\x0fInstanceSetting\x12\x17\n" + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12W\n" + "\x0fgeneral_setting\x18\x02 \x01(\v2,.memos.api.v1.InstanceSetting.GeneralSettingH\x00R\x0egeneralSetting\x12W\n" + @@ -1431,12 +1422,11 @@ const file_api_v1_instance_service_proto_rawDesc = "" + "\x18STORAGE_TYPE_UNSPECIFIED\x10\x00\x12\f\n" + "\bDATABASE\x10\x01\x12\t\n" + "\x05LOCAL\x10\x02\x12\x06\n" + - "\x02S3\x10\x03\x1a\xd6\x01\n" + - "\x12MemoRelatedSetting\x127\n" + - "\x18display_with_update_time\x18\x02 \x01(\bR\x15displayWithUpdateTime\x120\n" + + "\x02S3\x10\x03\x1a\xbd\x01\n" + + "\x12MemoRelatedSetting\x120\n" + "\x14content_length_limit\x18\x03 \x01(\x05R\x12contentLengthLimit\x127\n" + "\x18enable_double_click_edit\x18\x04 \x01(\bR\x15enableDoubleClickEdit\x12\x1c\n" + - "\treactions\x18\a \x03(\tR\treactions\x1ao\n" + + "\treactions\x18\a \x03(\tR\treactionsJ\x04\b\x02\x10\x03R\x18display_with_update_time\x1ao\n" + "\vTagMetadata\x12=\n" + "\x10background_color\x18\x01 \x01(\v2\x12.google.type.ColorR\x0fbackgroundColor\x12!\n" + "\fblur_content\x18\x02 \x01(\bR\vblurContent\x1a\xba\x01\n" + diff --git a/proto/gen/api/v1/memo_service.pb.go b/proto/gen/api/v1/memo_service.pb.go index e56ad14e2..cdda2c346 100644 --- a/proto/gen/api/v1/memo_service.pb.go +++ b/proto/gen/api/v1/memo_service.pb.go @@ -228,8 +228,6 @@ type Memo struct { // The last update timestamp. // If not set on creation, the server will set it to the current time. UpdateTime *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=update_time,json=updateTime,proto3" json:"update_time,omitempty"` - // The display timestamp of the memo. - DisplayTime *timestamppb.Timestamp `protobuf:"bytes,6,opt,name=display_time,json=displayTime,proto3" json:"display_time,omitempty"` // Required. The content of the memo in Markdown format. Content string `protobuf:"bytes,7,opt,name=content,proto3" json:"content,omitempty"` // The visibility of the memo. @@ -322,13 +320,6 @@ func (x *Memo) GetUpdateTime() *timestamppb.Timestamp { return nil } -func (x *Memo) GetDisplayTime() *timestamppb.Timestamp { - if x != nil { - return x.DisplayTime - } - return nil -} - func (x *Memo) GetContent() string { if x != nil { return x.Content @@ -538,10 +529,10 @@ type ListMemosRequest struct { // Default to `NORMAL`. Set to `ARCHIVED` to list archived memos. State State `protobuf:"varint,3,opt,name=state,proto3,enum=memos.api.v1.State" json:"state,omitempty"` // Optional. The order to sort results by. - // Default to "display_time desc". + // Default to "create_time desc". // Supports comma-separated list of fields following AIP-132. - // Example: "pinned desc, display_time desc" or "create_time asc" - // Supported fields: pinned, display_time, create_time, update_time, name + // Example: "pinned desc, create_time desc" or "update_time asc" + // Supported fields: pinned, create_time, update_time, name OrderBy string `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"` // Optional. Filter to apply to the list results. // Filter is a CEL expression to filter memos. @@ -2124,7 +2115,7 @@ const file_api_v1_memo_service_proto_rawDesc = "" + "\rreaction_type\x18\x04 \x01(\tB\x03\xe0A\x02R\freactionType\x12@\n" + "\vcreate_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x03R\n" + "createTime:X\xeaAU\n" + - "\x15memos.api.v1/Reaction\x12!memos/{memo}/reactions/{reaction}\x1a\x04name*\treactions2\breaction\"\xee\b\n" + + "\x15memos.api.v1/Reaction\x12!memos/{memo}/reactions/{reaction}\x1a\x04name*\treactions2\breaction\"\xbe\b\n" + "\x04Memo\x12\x17\n" + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12.\n" + "\x05state\x18\x02 \x01(\x0e2\x13.memos.api.v1.StateB\x03\xe0A\x02R\x05state\x123\n" + @@ -2133,8 +2124,7 @@ const file_api_v1_memo_service_proto_rawDesc = "" + "\vcreate_time\x18\x04 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x01R\n" + "createTime\x12@\n" + "\vupdate_time\x18\x05 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x01R\n" + - "updateTime\x12B\n" + - "\fdisplay_time\x18\x06 \x01(\v2\x1a.google.protobuf.TimestampB\x03\xe0A\x01R\vdisplayTime\x12\x1d\n" + + "updateTime\x12\x1d\n" + "\acontent\x18\a \x01(\tB\x03\xe0A\x02R\acontent\x12=\n" + "\n" + "visibility\x18\t \x01(\x0e2\x18.memos.api.v1.VisibilityB\x03\xe0A\x02R\n" + @@ -2158,7 +2148,7 @@ const file_api_v1_memo_service_proto_rawDesc = "" + "\x05title\x18\x05 \x01(\tR\x05title:7\xeaA4\n" + "\x11memos.api.v1/Memo\x12\fmemos/{memo}\x1a\x04name*\x05memos2\x04memoB\t\n" + "\a_parentB\v\n" + - "\t_location\"u\n" + + "\t_locationJ\x04\b\x06\x10\aR\fdisplay_time\"u\n" + "\bLocation\x12%\n" + "\vplaceholder\x18\x01 \x01(\tB\x03\xe0A\x01R\vplaceholder\x12\x1f\n" + "\blatitude\x18\x02 \x01(\x01B\x03\xe0A\x01R\blatitude\x12!\n" + @@ -2377,74 +2367,73 @@ var file_api_v1_memo_service_proto_depIdxs = []int32{ 34, // 1: memos.api.v1.Memo.state:type_name -> memos.api.v1.State 33, // 2: memos.api.v1.Memo.create_time:type_name -> google.protobuf.Timestamp 33, // 3: memos.api.v1.Memo.update_time:type_name -> google.protobuf.Timestamp - 33, // 4: memos.api.v1.Memo.display_time:type_name -> google.protobuf.Timestamp - 0, // 5: memos.api.v1.Memo.visibility:type_name -> memos.api.v1.Visibility - 35, // 6: memos.api.v1.Memo.attachments:type_name -> memos.api.v1.Attachment - 14, // 7: memos.api.v1.Memo.relations:type_name -> memos.api.v1.MemoRelation - 2, // 8: memos.api.v1.Memo.reactions:type_name -> memos.api.v1.Reaction - 31, // 9: memos.api.v1.Memo.property:type_name -> memos.api.v1.Memo.Property - 4, // 10: memos.api.v1.Memo.location:type_name -> memos.api.v1.Location - 3, // 11: memos.api.v1.CreateMemoRequest.memo:type_name -> memos.api.v1.Memo - 34, // 12: memos.api.v1.ListMemosRequest.state:type_name -> memos.api.v1.State - 3, // 13: memos.api.v1.ListMemosResponse.memos:type_name -> memos.api.v1.Memo - 3, // 14: memos.api.v1.UpdateMemoRequest.memo:type_name -> memos.api.v1.Memo - 36, // 15: memos.api.v1.UpdateMemoRequest.update_mask:type_name -> google.protobuf.FieldMask - 35, // 16: memos.api.v1.SetMemoAttachmentsRequest.attachments:type_name -> memos.api.v1.Attachment - 35, // 17: memos.api.v1.ListMemoAttachmentsResponse.attachments:type_name -> memos.api.v1.Attachment - 32, // 18: memos.api.v1.MemoRelation.memo:type_name -> memos.api.v1.MemoRelation.Memo - 32, // 19: memos.api.v1.MemoRelation.related_memo:type_name -> memos.api.v1.MemoRelation.Memo - 1, // 20: memos.api.v1.MemoRelation.type:type_name -> memos.api.v1.MemoRelation.Type - 14, // 21: memos.api.v1.SetMemoRelationsRequest.relations:type_name -> memos.api.v1.MemoRelation - 14, // 22: memos.api.v1.ListMemoRelationsResponse.relations:type_name -> memos.api.v1.MemoRelation - 3, // 23: memos.api.v1.CreateMemoCommentRequest.comment:type_name -> memos.api.v1.Memo - 3, // 24: memos.api.v1.ListMemoCommentsResponse.memos:type_name -> memos.api.v1.Memo - 2, // 25: memos.api.v1.ListMemoReactionsResponse.reactions:type_name -> memos.api.v1.Reaction - 2, // 26: memos.api.v1.UpsertMemoReactionRequest.reaction:type_name -> memos.api.v1.Reaction - 33, // 27: memos.api.v1.MemoShare.create_time:type_name -> google.protobuf.Timestamp - 33, // 28: memos.api.v1.MemoShare.expire_time:type_name -> google.protobuf.Timestamp - 25, // 29: memos.api.v1.CreateMemoShareRequest.memo_share:type_name -> memos.api.v1.MemoShare - 25, // 30: memos.api.v1.ListMemoSharesResponse.memo_shares:type_name -> memos.api.v1.MemoShare - 5, // 31: memos.api.v1.MemoService.CreateMemo:input_type -> memos.api.v1.CreateMemoRequest - 6, // 32: memos.api.v1.MemoService.ListMemos:input_type -> memos.api.v1.ListMemosRequest - 8, // 33: memos.api.v1.MemoService.GetMemo:input_type -> memos.api.v1.GetMemoRequest - 9, // 34: memos.api.v1.MemoService.UpdateMemo:input_type -> memos.api.v1.UpdateMemoRequest - 10, // 35: memos.api.v1.MemoService.DeleteMemo:input_type -> memos.api.v1.DeleteMemoRequest - 11, // 36: memos.api.v1.MemoService.SetMemoAttachments:input_type -> memos.api.v1.SetMemoAttachmentsRequest - 12, // 37: memos.api.v1.MemoService.ListMemoAttachments:input_type -> memos.api.v1.ListMemoAttachmentsRequest - 15, // 38: memos.api.v1.MemoService.SetMemoRelations:input_type -> memos.api.v1.SetMemoRelationsRequest - 16, // 39: memos.api.v1.MemoService.ListMemoRelations:input_type -> memos.api.v1.ListMemoRelationsRequest - 18, // 40: memos.api.v1.MemoService.CreateMemoComment:input_type -> memos.api.v1.CreateMemoCommentRequest - 19, // 41: memos.api.v1.MemoService.ListMemoComments:input_type -> memos.api.v1.ListMemoCommentsRequest - 21, // 42: memos.api.v1.MemoService.ListMemoReactions:input_type -> memos.api.v1.ListMemoReactionsRequest - 23, // 43: memos.api.v1.MemoService.UpsertMemoReaction:input_type -> memos.api.v1.UpsertMemoReactionRequest - 24, // 44: memos.api.v1.MemoService.DeleteMemoReaction:input_type -> memos.api.v1.DeleteMemoReactionRequest - 26, // 45: memos.api.v1.MemoService.CreateMemoShare:input_type -> memos.api.v1.CreateMemoShareRequest - 27, // 46: memos.api.v1.MemoService.ListMemoShares:input_type -> memos.api.v1.ListMemoSharesRequest - 29, // 47: memos.api.v1.MemoService.DeleteMemoShare:input_type -> memos.api.v1.DeleteMemoShareRequest - 30, // 48: memos.api.v1.MemoService.GetMemoByShare:input_type -> memos.api.v1.GetMemoByShareRequest - 3, // 49: memos.api.v1.MemoService.CreateMemo:output_type -> memos.api.v1.Memo - 7, // 50: memos.api.v1.MemoService.ListMemos:output_type -> memos.api.v1.ListMemosResponse - 3, // 51: memos.api.v1.MemoService.GetMemo:output_type -> memos.api.v1.Memo - 3, // 52: memos.api.v1.MemoService.UpdateMemo:output_type -> memos.api.v1.Memo - 37, // 53: memos.api.v1.MemoService.DeleteMemo:output_type -> google.protobuf.Empty - 37, // 54: memos.api.v1.MemoService.SetMemoAttachments:output_type -> google.protobuf.Empty - 13, // 55: memos.api.v1.MemoService.ListMemoAttachments:output_type -> memos.api.v1.ListMemoAttachmentsResponse - 37, // 56: memos.api.v1.MemoService.SetMemoRelations:output_type -> google.protobuf.Empty - 17, // 57: memos.api.v1.MemoService.ListMemoRelations:output_type -> memos.api.v1.ListMemoRelationsResponse - 3, // 58: memos.api.v1.MemoService.CreateMemoComment:output_type -> memos.api.v1.Memo - 20, // 59: memos.api.v1.MemoService.ListMemoComments:output_type -> memos.api.v1.ListMemoCommentsResponse - 22, // 60: memos.api.v1.MemoService.ListMemoReactions:output_type -> memos.api.v1.ListMemoReactionsResponse - 2, // 61: memos.api.v1.MemoService.UpsertMemoReaction:output_type -> memos.api.v1.Reaction - 37, // 62: memos.api.v1.MemoService.DeleteMemoReaction:output_type -> google.protobuf.Empty - 25, // 63: memos.api.v1.MemoService.CreateMemoShare:output_type -> memos.api.v1.MemoShare - 28, // 64: memos.api.v1.MemoService.ListMemoShares:output_type -> memos.api.v1.ListMemoSharesResponse - 37, // 65: memos.api.v1.MemoService.DeleteMemoShare:output_type -> google.protobuf.Empty - 3, // 66: memos.api.v1.MemoService.GetMemoByShare:output_type -> memos.api.v1.Memo - 49, // [49:67] is the sub-list for method output_type - 31, // [31:49] is the sub-list for method input_type - 31, // [31:31] is the sub-list for extension type_name - 31, // [31:31] is the sub-list for extension extendee - 0, // [0:31] is the sub-list for field type_name + 0, // 4: memos.api.v1.Memo.visibility:type_name -> memos.api.v1.Visibility + 35, // 5: memos.api.v1.Memo.attachments:type_name -> memos.api.v1.Attachment + 14, // 6: memos.api.v1.Memo.relations:type_name -> memos.api.v1.MemoRelation + 2, // 7: memos.api.v1.Memo.reactions:type_name -> memos.api.v1.Reaction + 31, // 8: memos.api.v1.Memo.property:type_name -> memos.api.v1.Memo.Property + 4, // 9: memos.api.v1.Memo.location:type_name -> memos.api.v1.Location + 3, // 10: memos.api.v1.CreateMemoRequest.memo:type_name -> memos.api.v1.Memo + 34, // 11: memos.api.v1.ListMemosRequest.state:type_name -> memos.api.v1.State + 3, // 12: memos.api.v1.ListMemosResponse.memos:type_name -> memos.api.v1.Memo + 3, // 13: memos.api.v1.UpdateMemoRequest.memo:type_name -> memos.api.v1.Memo + 36, // 14: memos.api.v1.UpdateMemoRequest.update_mask:type_name -> google.protobuf.FieldMask + 35, // 15: memos.api.v1.SetMemoAttachmentsRequest.attachments:type_name -> memos.api.v1.Attachment + 35, // 16: memos.api.v1.ListMemoAttachmentsResponse.attachments:type_name -> memos.api.v1.Attachment + 32, // 17: memos.api.v1.MemoRelation.memo:type_name -> memos.api.v1.MemoRelation.Memo + 32, // 18: memos.api.v1.MemoRelation.related_memo:type_name -> memos.api.v1.MemoRelation.Memo + 1, // 19: memos.api.v1.MemoRelation.type:type_name -> memos.api.v1.MemoRelation.Type + 14, // 20: memos.api.v1.SetMemoRelationsRequest.relations:type_name -> memos.api.v1.MemoRelation + 14, // 21: memos.api.v1.ListMemoRelationsResponse.relations:type_name -> memos.api.v1.MemoRelation + 3, // 22: memos.api.v1.CreateMemoCommentRequest.comment:type_name -> memos.api.v1.Memo + 3, // 23: memos.api.v1.ListMemoCommentsResponse.memos:type_name -> memos.api.v1.Memo + 2, // 24: memos.api.v1.ListMemoReactionsResponse.reactions:type_name -> memos.api.v1.Reaction + 2, // 25: memos.api.v1.UpsertMemoReactionRequest.reaction:type_name -> memos.api.v1.Reaction + 33, // 26: memos.api.v1.MemoShare.create_time:type_name -> google.protobuf.Timestamp + 33, // 27: memos.api.v1.MemoShare.expire_time:type_name -> google.protobuf.Timestamp + 25, // 28: memos.api.v1.CreateMemoShareRequest.memo_share:type_name -> memos.api.v1.MemoShare + 25, // 29: memos.api.v1.ListMemoSharesResponse.memo_shares:type_name -> memos.api.v1.MemoShare + 5, // 30: memos.api.v1.MemoService.CreateMemo:input_type -> memos.api.v1.CreateMemoRequest + 6, // 31: memos.api.v1.MemoService.ListMemos:input_type -> memos.api.v1.ListMemosRequest + 8, // 32: memos.api.v1.MemoService.GetMemo:input_type -> memos.api.v1.GetMemoRequest + 9, // 33: memos.api.v1.MemoService.UpdateMemo:input_type -> memos.api.v1.UpdateMemoRequest + 10, // 34: memos.api.v1.MemoService.DeleteMemo:input_type -> memos.api.v1.DeleteMemoRequest + 11, // 35: memos.api.v1.MemoService.SetMemoAttachments:input_type -> memos.api.v1.SetMemoAttachmentsRequest + 12, // 36: memos.api.v1.MemoService.ListMemoAttachments:input_type -> memos.api.v1.ListMemoAttachmentsRequest + 15, // 37: memos.api.v1.MemoService.SetMemoRelations:input_type -> memos.api.v1.SetMemoRelationsRequest + 16, // 38: memos.api.v1.MemoService.ListMemoRelations:input_type -> memos.api.v1.ListMemoRelationsRequest + 18, // 39: memos.api.v1.MemoService.CreateMemoComment:input_type -> memos.api.v1.CreateMemoCommentRequest + 19, // 40: memos.api.v1.MemoService.ListMemoComments:input_type -> memos.api.v1.ListMemoCommentsRequest + 21, // 41: memos.api.v1.MemoService.ListMemoReactions:input_type -> memos.api.v1.ListMemoReactionsRequest + 23, // 42: memos.api.v1.MemoService.UpsertMemoReaction:input_type -> memos.api.v1.UpsertMemoReactionRequest + 24, // 43: memos.api.v1.MemoService.DeleteMemoReaction:input_type -> memos.api.v1.DeleteMemoReactionRequest + 26, // 44: memos.api.v1.MemoService.CreateMemoShare:input_type -> memos.api.v1.CreateMemoShareRequest + 27, // 45: memos.api.v1.MemoService.ListMemoShares:input_type -> memos.api.v1.ListMemoSharesRequest + 29, // 46: memos.api.v1.MemoService.DeleteMemoShare:input_type -> memos.api.v1.DeleteMemoShareRequest + 30, // 47: memos.api.v1.MemoService.GetMemoByShare:input_type -> memos.api.v1.GetMemoByShareRequest + 3, // 48: memos.api.v1.MemoService.CreateMemo:output_type -> memos.api.v1.Memo + 7, // 49: memos.api.v1.MemoService.ListMemos:output_type -> memos.api.v1.ListMemosResponse + 3, // 50: memos.api.v1.MemoService.GetMemo:output_type -> memos.api.v1.Memo + 3, // 51: memos.api.v1.MemoService.UpdateMemo:output_type -> memos.api.v1.Memo + 37, // 52: memos.api.v1.MemoService.DeleteMemo:output_type -> google.protobuf.Empty + 37, // 53: memos.api.v1.MemoService.SetMemoAttachments:output_type -> google.protobuf.Empty + 13, // 54: memos.api.v1.MemoService.ListMemoAttachments:output_type -> memos.api.v1.ListMemoAttachmentsResponse + 37, // 55: memos.api.v1.MemoService.SetMemoRelations:output_type -> google.protobuf.Empty + 17, // 56: memos.api.v1.MemoService.ListMemoRelations:output_type -> memos.api.v1.ListMemoRelationsResponse + 3, // 57: memos.api.v1.MemoService.CreateMemoComment:output_type -> memos.api.v1.Memo + 20, // 58: memos.api.v1.MemoService.ListMemoComments:output_type -> memos.api.v1.ListMemoCommentsResponse + 22, // 59: memos.api.v1.MemoService.ListMemoReactions:output_type -> memos.api.v1.ListMemoReactionsResponse + 2, // 60: memos.api.v1.MemoService.UpsertMemoReaction:output_type -> memos.api.v1.Reaction + 37, // 61: memos.api.v1.MemoService.DeleteMemoReaction:output_type -> google.protobuf.Empty + 25, // 62: memos.api.v1.MemoService.CreateMemoShare:output_type -> memos.api.v1.MemoShare + 28, // 63: memos.api.v1.MemoService.ListMemoShares:output_type -> memos.api.v1.ListMemoSharesResponse + 37, // 64: memos.api.v1.MemoService.DeleteMemoShare:output_type -> google.protobuf.Empty + 3, // 65: memos.api.v1.MemoService.GetMemoByShare:output_type -> memos.api.v1.Memo + 48, // [48:66] is the sub-list for method output_type + 30, // [30:48] is the sub-list for method input_type + 30, // [30:30] is the sub-list for extension type_name + 30, // [30:30] is the sub-list for extension extendee + 0, // [0:30] is the sub-list for field type_name } func init() { file_api_v1_memo_service_proto_init() } diff --git a/proto/gen/api/v1/user_service.pb.go b/proto/gen/api/v1/user_service.pb.go index 1db7e632b..f4dafc428 100644 --- a/proto/gen/api/v1/user_service.pb.go +++ b/proto/gen/api/v1/user_service.pb.go @@ -849,12 +849,12 @@ type UserStats struct { // The resource name of the user whose stats these are. // Format: users/{user} Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` - // The timestamps when the memos were displayed. - MemoDisplayTimestamps []*timestamppb.Timestamp `protobuf:"bytes,2,rep,name=memo_display_timestamps,json=memoDisplayTimestamps,proto3" json:"memo_display_timestamps,omitempty"` // The stats of memo types. MemoTypeStats *UserStats_MemoTypeStats `protobuf:"bytes,3,opt,name=memo_type_stats,json=memoTypeStats,proto3" json:"memo_type_stats,omitempty"` // The count of tags. TagCount map[string]int32 `protobuf:"bytes,4,rep,name=tag_count,json=tagCount,proto3" json:"tag_count,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"varint,2,opt,name=value"` + // The creation timestamps of the user's memos. + MemoCreatedTimestamps []*timestamppb.Timestamp `protobuf:"bytes,7,rep,name=memo_created_timestamps,json=memoCreatedTimestamps,proto3" json:"memo_created_timestamps,omitempty"` // The pinned memos of the user. PinnedMemos []string `protobuf:"bytes,5,rep,name=pinned_memos,json=pinnedMemos,proto3" json:"pinned_memos,omitempty"` // Total memo count. @@ -900,23 +900,23 @@ func (x *UserStats) GetName() string { return "" } -func (x *UserStats) GetMemoDisplayTimestamps() []*timestamppb.Timestamp { +func (x *UserStats) GetMemoTypeStats() *UserStats_MemoTypeStats { if x != nil { - return x.MemoDisplayTimestamps + return x.MemoTypeStats } return nil } -func (x *UserStats) GetMemoTypeStats() *UserStats_MemoTypeStats { +func (x *UserStats) GetTagCount() map[string]int32 { if x != nil { - return x.MemoTypeStats + return x.TagCount } return nil } -func (x *UserStats) GetTagCount() map[string]int32 { +func (x *UserStats) GetMemoCreatedTimestamps() []*timestamppb.Timestamp { if x != nil { - return x.TagCount + return x.MemoCreatedTimestamps } return nil } @@ -3172,12 +3172,12 @@ const file_api_v1_user_service_proto_rawDesc = "" + "\x11DeleteUserRequest\x12-\n" + "\x04name\x18\x01 \x01(\tB\x19\xe0A\x02\xfaA\x13\n" + "\x11memos.api.v1/UserR\x04name\x12\x19\n" + - "\x05force\x18\x02 \x01(\bB\x03\xe0A\x01R\x05force\"\xe4\x04\n" + + "\x05force\x18\x02 \x01(\bB\x03\xe0A\x01R\x05force\"\x83\x05\n" + "\tUserStats\x12\x17\n" + - "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12R\n" + - "\x17memo_display_timestamps\x18\x02 \x03(\v2\x1a.google.protobuf.TimestampR\x15memoDisplayTimestamps\x12M\n" + + "\x04name\x18\x01 \x01(\tB\x03\xe0A\bR\x04name\x12M\n" + "\x0fmemo_type_stats\x18\x03 \x01(\v2%.memos.api.v1.UserStats.MemoTypeStatsR\rmemoTypeStats\x12B\n" + - "\ttag_count\x18\x04 \x03(\v2%.memos.api.v1.UserStats.TagCountEntryR\btagCount\x12!\n" + + "\ttag_count\x18\x04 \x03(\v2%.memos.api.v1.UserStats.TagCountEntryR\btagCount\x12R\n" + + "\x17memo_created_timestamps\x18\a \x03(\v2\x1a.google.protobuf.TimestampR\x15memoCreatedTimestamps\x12!\n" + "\fpinned_memos\x18\x05 \x03(\tR\vpinnedMemos\x12(\n" + "\x10total_memo_count\x18\x06 \x01(\x05R\x0etotalMemoCount\x1a\x8b\x01\n" + "\rMemoTypeStats\x12\x1d\n" + @@ -3192,7 +3192,7 @@ const file_api_v1_user_service_proto_rawDesc = "" + "\rTagCountEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\x05R\x05value:\x028\x01:?\xeaA<\n" + - "\x16memos.api.v1/UserStats\x12\fusers/{user}*\tuserStats2\tuserStats\"D\n" + + "\x16memos.api.v1/UserStats\x12\fusers/{user}*\tuserStats2\tuserStatsJ\x04\b\x02\x10\x03R\x17memo_display_timestamps\"D\n" + "\x13GetUserStatsRequest\x12-\n" + "\x04name\x18\x01 \x01(\tB\x19\xe0A\x02\xfaA\x13\n" + "\x11memos.api.v1/UserR\x04name\"\x19\n" + @@ -3475,9 +3475,9 @@ var file_api_v1_user_service_proto_depIdxs = []int32{ 4, // 7: memos.api.v1.CreateUserRequest.user:type_name -> memos.api.v1.User 4, // 8: memos.api.v1.UpdateUserRequest.user:type_name -> memos.api.v1.User 53, // 9: memos.api.v1.UpdateUserRequest.update_mask:type_name -> google.protobuf.FieldMask - 52, // 10: memos.api.v1.UserStats.memo_display_timestamps:type_name -> google.protobuf.Timestamp - 45, // 11: memos.api.v1.UserStats.memo_type_stats:type_name -> memos.api.v1.UserStats.MemoTypeStats - 46, // 12: memos.api.v1.UserStats.tag_count:type_name -> memos.api.v1.UserStats.TagCountEntry + 45, // 10: memos.api.v1.UserStats.memo_type_stats:type_name -> memos.api.v1.UserStats.MemoTypeStats + 46, // 11: memos.api.v1.UserStats.tag_count:type_name -> memos.api.v1.UserStats.TagCountEntry + 52, // 12: memos.api.v1.UserStats.memo_created_timestamps:type_name -> google.protobuf.Timestamp 13, // 13: memos.api.v1.ListAllUserStatsResponse.stats:type_name -> memos.api.v1.UserStats 47, // 14: memos.api.v1.UserSetting.general_setting:type_name -> memos.api.v1.UserSetting.GeneralSetting 48, // 15: memos.api.v1.UserSetting.webhooks_setting:type_name -> memos.api.v1.UserSetting.WebhooksSetting diff --git a/proto/gen/openapi.yaml b/proto/gen/openapi.yaml index 4d4faddb3..5350c4566 100644 --- a/proto/gen/openapi.yaml +++ b/proto/gen/openapi.yaml @@ -579,10 +579,10 @@ paths: in: query description: |- Optional. The order to sort results by. - Default to "display_time desc". + Default to "create_time desc". Supports comma-separated list of fields following AIP-132. - Example: "pinned desc, display_time desc" or "create_time asc" - Supported fields: pinned, display_time, create_time, update_time, name + Example: "pinned desc, create_time desc" or "update_time asc" + Supported fields: pinned, create_time, update_time, name schema: type: string - name: filter @@ -2626,9 +2626,6 @@ components: InstanceSetting_MemoRelatedSetting: type: object properties: - displayWithUpdateTime: - type: boolean - description: display_with_update_time orders and displays memo with update time. contentLengthLimit: type: integer description: content_length_limit is the limit of content length. Unit is byte. @@ -2959,10 +2956,6 @@ components: The last update timestamp. If not set on creation, the server will set it to the current time. format: date-time - displayTime: - type: string - description: The display timestamp of the memo. - format: date-time content: type: string description: Required. The content of the memo in Markdown format. @@ -3637,12 +3630,6 @@ components: description: |- The resource name of the user whose stats these are. Format: users/{user} - memoDisplayTimestamps: - type: array - items: - type: string - format: date-time - description: The timestamps when the memos were displayed. memoTypeStats: allOf: - $ref: '#/components/schemas/UserStats_MemoTypeStats' @@ -3653,6 +3640,12 @@ components: type: integer format: int32 description: The count of tags. + memoCreatedTimestamps: + type: array + items: + type: string + format: date-time + description: The creation timestamps of the user's memos. pinnedMemos: type: array items: diff --git a/proto/gen/store/instance_setting.pb.go b/proto/gen/store/instance_setting.pb.go index 8cf5ff605..e0f08e75f 100644 --- a/proto/gen/store/instance_setting.pb.go +++ b/proto/gen/store/instance_setting.pb.go @@ -751,8 +751,6 @@ func (x *StorageS3Config) GetUsePathStyle() bool { type InstanceMemoRelatedSetting struct { state protoimpl.MessageState `protogen:"open.v1"` - // display_with_update_time orders and displays memo with update time. - DisplayWithUpdateTime bool `protobuf:"varint,2,opt,name=display_with_update_time,json=displayWithUpdateTime,proto3" json:"display_with_update_time,omitempty"` // content_length_limit is the limit of content length. Unit is byte. ContentLengthLimit int32 `protobuf:"varint,3,opt,name=content_length_limit,json=contentLengthLimit,proto3" json:"content_length_limit,omitempty"` // enable_double_click_edit enables editing on double click. @@ -793,13 +791,6 @@ func (*InstanceMemoRelatedSetting) Descriptor() ([]byte, []int) { return file_store_instance_setting_proto_rawDescGZIP(), []int{6} } -func (x *InstanceMemoRelatedSetting) GetDisplayWithUpdateTime() bool { - if x != nil { - return x.DisplayWithUpdateTime - } - return false -} - func (x *InstanceMemoRelatedSetting) GetContentLengthLimit() int32 { if x != nil { return x.ContentLengthLimit @@ -1255,12 +1246,11 @@ const file_store_instance_setting_proto_rawDesc = "" + "\bendpoint\x18\x03 \x01(\tR\bendpoint\x12\x16\n" + "\x06region\x18\x04 \x01(\tR\x06region\x12\x16\n" + "\x06bucket\x18\x05 \x01(\tR\x06bucket\x12$\n" + - "\x0euse_path_style\x18\x06 \x01(\bR\fusePathStyle\"\xde\x01\n" + - "\x1aInstanceMemoRelatedSetting\x127\n" + - "\x18display_with_update_time\x18\x02 \x01(\bR\x15displayWithUpdateTime\x120\n" + + "\x0euse_path_style\x18\x06 \x01(\bR\fusePathStyle\"\xc5\x01\n" + + "\x1aInstanceMemoRelatedSetting\x120\n" + "\x14content_length_limit\x18\x03 \x01(\x05R\x12contentLengthLimit\x127\n" + "\x18enable_double_click_edit\x18\x04 \x01(\bR\x15enableDoubleClickEdit\x12\x1c\n" + - "\treactions\x18\a \x03(\tR\treactions\"w\n" + + "\treactions\x18\a \x03(\tR\treactionsJ\x04\b\x02\x10\x03R\x18display_with_update_time\"w\n" + "\x13InstanceTagMetadata\x12=\n" + "\x10background_color\x18\x01 \x01(\v2\x12.google.type.ColorR\x0fbackgroundColor\x12!\n" + "\fblur_content\x18\x02 \x01(\bR\vblurContent\"\xb0\x01\n" + diff --git a/proto/store/instance_setting.proto b/proto/store/instance_setting.proto index f1010b7ab..6d63e5182 100644 --- a/proto/store/instance_setting.proto +++ b/proto/store/instance_setting.proto @@ -103,8 +103,8 @@ message StorageS3Config { } message InstanceMemoRelatedSetting { - // display_with_update_time orders and displays memo with update time. - bool display_with_update_time = 2; + reserved 2; + reserved "display_with_update_time"; // content_length_limit is the limit of content length. Unit is byte. int32 content_length_limit = 3; // enable_double_click_edit enables editing on double click. diff --git a/server/router/api/v1/instance_service.go b/server/router/api/v1/instance_service.go index f4abf54f7..5d626efb7 100644 --- a/server/router/api/v1/instance_service.go +++ b/server/router/api/v1/instance_service.go @@ -325,7 +325,6 @@ func convertInstanceMemoRelatedSettingFromStore(setting *storepb.InstanceMemoRel return nil } return &v1pb.InstanceSetting_MemoRelatedSetting{ - DisplayWithUpdateTime: setting.DisplayWithUpdateTime, ContentLengthLimit: setting.ContentLengthLimit, EnableDoubleClickEdit: setting.EnableDoubleClickEdit, Reactions: setting.Reactions, @@ -337,7 +336,6 @@ func convertInstanceMemoRelatedSettingToStore(setting *v1pb.InstanceSetting_Memo return nil } return &storepb.InstanceMemoRelatedSetting{ - DisplayWithUpdateTime: setting.DisplayWithUpdateTime, ContentLengthLimit: setting.ContentLengthLimit, EnableDoubleClickEdit: setting.EnableDoubleClickEdit, Reactions: setting.Reactions, diff --git a/server/router/api/v1/memo_service.go b/server/router/api/v1/memo_service.go index 497be456c..27382970d 100644 --- a/server/router/api/v1/memo_service.go +++ b/server/router/api/v1/memo_service.go @@ -54,25 +54,7 @@ func (s *APIV1Service) CreateMemo(ctx context.Context, request *v1pb.CreateMemoR Visibility: convertVisibilityToStore(request.Memo.Visibility), } - instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting") - } - - // Handle display_time first: if provided, use it to set the appropriate timestamp - // based on the instance setting (similar to UpdateMemo logic) - // Note: explicit create_time/update_time below will override this if provided - if request.Memo.DisplayTime != nil && request.Memo.DisplayTime.IsValid() { - displayTs := request.Memo.DisplayTime.AsTime().Unix() - if instanceMemoRelatedSetting.DisplayWithUpdateTime { - create.UpdatedTs = displayTs - } else { - create.CreatedTs = displayTs - } - } - - // Set custom timestamps if provided in the request - // These take precedence over display_time + // Set custom timestamps if provided in the request. if request.Memo.CreateTime != nil && request.Memo.CreateTime.IsValid() { createdTs := request.Memo.CreateTime.AsTime().Unix() create.CreatedTs = createdTs @@ -196,7 +178,7 @@ func (s *APIV1Service) ListMemos(ctx context.Context, request *v1pb.ListMemosReq return nil, status.Errorf(codes.InvalidArgument, "invalid order_by: %v", err) } } else { - // Default ordering by display_time desc + // Default ordering by create_time desc. memoFind.OrderByTimeAsc = false } @@ -218,14 +200,6 @@ func (s *APIV1Service) ListMemos(ctx context.Context, request *v1pb.ListMemosReq } } - instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting") - } - if instanceMemoRelatedSetting.DisplayWithUpdateTime { - memoFind.OrderByUpdatedTs = true - } - var limit, offset int if request.PageToken != "" { var pageToken v1pb.PageToken @@ -312,15 +286,13 @@ func (s *APIV1Service) ListMemos(ctx context.Context, request *v1pb.ListMemosReq if err != nil { return nil, status.Errorf(codes.Internal, "failed to list memo creators: %v", err) } - conversionOptions := memoConversionOptions{displayWithUpdateTime: instanceMemoRelatedSetting.DisplayWithUpdateTime} - for _, memo := range memos { memoName := fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID) reactions := reactionMap[memoName] attachments := attachmentMap[memo.ID] relations := relationMap[memo.ID] - memoMessage, err := s.convertMemoFromStoreWithCreatorsAndOptions(ctx, memo, reactions, attachments, relations, creatorMap, conversionOptions) + memoMessage, err := s.convertMemoFromStoreWithCreators(ctx, memo, reactions, attachments, relations, creatorMap) if err != nil { if stderrors.Is(err, errMemoCreatorNotFound) { slog.Warn("Skipping memo with missing creator", @@ -479,16 +451,7 @@ func (s *APIV1Service) UpdateMemo(ctx context.Context, request *v1pb.UpdateMemoR } update.UpdatedTs = &updatedTs } else if path == "display_time" { - displayTs := request.Memo.DisplayTime.AsTime().Unix() - memoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting") - } - if memoRelatedSetting.DisplayWithUpdateTime { - update.UpdatedTs = &displayTs - } else { - update.CreatedTs = &displayTs - } + return nil, status.Errorf(codes.InvalidArgument, "display_time is not supported") } else if path == "location" { payload := memo.Payload payload.Location = convertLocationToStore(request.Memo.Location) @@ -817,12 +780,6 @@ func (s *APIV1Service) ListMemoComments(ctx context.Context, request *v1pb.ListM if err != nil { return nil, status.Errorf(codes.Internal, "failed to list memo creators: %v", err) } - instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx) - if err != nil { - return nil, status.Errorf(codes.Internal, "failed to get instance memo related setting") - } - conversionOptions := memoConversionOptions{displayWithUpdateTime: instanceMemoRelatedSetting.DisplayWithUpdateTime} - var memosResponse []*v1pb.Memo for _, m := range memos { memoName := memoIDToNameMap[m.ID] @@ -830,7 +787,7 @@ func (s *APIV1Service) ListMemoComments(ctx context.Context, request *v1pb.ListM attachments := attachmentMap[m.ID] relations := relationMap[m.ID] - memoMessage, err := s.convertMemoFromStoreWithCreatorsAndOptions(ctx, m, reactions, attachments, relations, creatorMap, conversionOptions) + memoMessage, err := s.convertMemoFromStoreWithCreators(ctx, m, reactions, attachments, relations, creatorMap) if err != nil { if stderrors.Is(err, errMemoCreatorNotFound) { slog.Warn("Skipping memo comment with missing creator", @@ -939,7 +896,7 @@ func (s *APIV1Service) getMemoContentSnippet(content string) (string, error) { // parseMemoOrderBy parses the order_by field and sets the appropriate ordering in memoFind. // Follows AIP-132: supports comma-separated list of fields with optional "desc" suffix. -// Example: "pinned desc, display_time desc" or "create_time asc". +// Example: "pinned desc, create_time desc" or "update_time asc". func (*APIV1Service) parseMemoOrderBy(orderBy string, memoFind *store.FindMemo) error { if strings.TrimSpace(orderBy) == "" { return errors.New("empty order_by") @@ -950,6 +907,7 @@ func (*APIV1Service) parseMemoOrderBy(orderBy string, memoFind *store.FindMemo) // Track if we've seen pinned field. hasPinned := false + hasExplicitTimeField := false for _, field := range fields { parts := strings.Fields(strings.TrimSpace(field)) @@ -971,16 +929,21 @@ func (*APIV1Service) parseMemoOrderBy(orderBy string, memoFind *store.FindMemo) hasPinned = true memoFind.OrderByPinned = true // Note: pinned is always DESC (true first) regardless of direction specified. - case "display_time", "create_time", "name": + case "create_time", "name": // Only set if this is the first time field we encounter. - if !memoFind.OrderByUpdatedTs { + if !hasExplicitTimeField { memoFind.OrderByTimeAsc = fieldDirection == "asc" } + hasExplicitTimeField = true case "update_time": - memoFind.OrderByUpdatedTs = true - memoFind.OrderByTimeAsc = fieldDirection == "asc" + // Only set if this is the first time field we encounter. + if !hasExplicitTimeField { + memoFind.OrderByUpdatedTs = true + memoFind.OrderByTimeAsc = fieldDirection == "asc" + } + hasExplicitTimeField = true default: - return errors.Errorf("unsupported order field: %s, supported fields are: pinned, display_time, create_time, update_time, name", fieldName) + return errors.Errorf("unsupported order field: %s, supported fields are: pinned, create_time, update_time, name", fieldName) } } diff --git a/server/router/api/v1/memo_service_converter.go b/server/router/api/v1/memo_service_converter.go index 936baff43..b949570e9 100644 --- a/server/router/api/v1/memo_service_converter.go +++ b/server/router/api/v1/memo_service_converter.go @@ -20,10 +20,6 @@ var ( errReactionCreatorNotFound = stderrors.New("reaction creator not found") ) -type memoConversionOptions struct { - displayWithUpdateTime bool -} - func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Memo, reactions []*store.Reaction, attachments []*store.Attachment, relations []*v1pb.MemoRelation) (*v1pb.Memo, error) { creatorMap, err := s.listUsersByID(ctx, []int32{memo.CreatorID}) if err != nil { @@ -33,42 +29,20 @@ func (s *APIV1Service) convertMemoFromStore(ctx context.Context, memo *store.Mem } func (s *APIV1Service) convertMemoFromStoreWithCreators(ctx context.Context, memo *store.Memo, reactions []*store.Reaction, attachments []*store.Attachment, relations []*v1pb.MemoRelation, creatorMap map[int32]*store.User) (*v1pb.Memo, error) { - instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx) - if err != nil { - return nil, errors.Wrap(err, "failed to get instance memo related setting") - } - return s.convertMemoFromStoreWithCreatorsAndOptions( - ctx, - memo, - reactions, - attachments, - relations, - creatorMap, - memoConversionOptions{displayWithUpdateTime: instanceMemoRelatedSetting.DisplayWithUpdateTime}, - ) -} - -func (s *APIV1Service) convertMemoFromStoreWithCreatorsAndOptions(ctx context.Context, memo *store.Memo, reactions []*store.Reaction, attachments []*store.Attachment, relations []*v1pb.MemoRelation, creatorMap map[int32]*store.User, options memoConversionOptions) (*v1pb.Memo, error) { - displayTs := memo.CreatedTs - if options.displayWithUpdateTime { - displayTs = memo.UpdatedTs - } - name := fmt.Sprintf("%s%s", MemoNamePrefix, memo.UID) creator := creatorMap[memo.CreatorID] if creator == nil { return nil, errMemoCreatorNotFound } memoMessage := &v1pb.Memo{ - Name: name, - State: convertStateFromStore(memo.RowStatus), - Creator: BuildUserName(creator.Username), - CreateTime: timestamppb.New(time.Unix(memo.CreatedTs, 0)), - UpdateTime: timestamppb.New(time.Unix(memo.UpdatedTs, 0)), - DisplayTime: timestamppb.New(time.Unix(displayTs, 0)), - Content: memo.Content, - Visibility: convertVisibilityFromStore(memo.Visibility), - Pinned: memo.Pinned, + Name: name, + State: convertStateFromStore(memo.RowStatus), + Creator: BuildUserName(creator.Username), + CreateTime: timestamppb.New(time.Unix(memo.CreatedTs, 0)), + UpdateTime: timestamppb.New(time.Unix(memo.UpdatedTs, 0)), + Content: memo.Content, + Visibility: convertVisibilityFromStore(memo.Visibility), + Pinned: memo.Pinned, } if memo.Payload != nil { memoMessage.Tags = memo.Payload.Tags diff --git a/server/router/api/v1/test/memo_service_test.go b/server/router/api/v1/test/memo_service_test.go index ed61e042d..dffff1ec5 100644 --- a/server/router/api/v1/test/memo_service_test.go +++ b/server/router/api/v1/test/memo_service_test.go @@ -254,6 +254,120 @@ func TestListMemos(t *testing.T) { require.Equal(t, "👍", userTwoReaction.ReactionType) } +func TestListMemosTimeOrderBy(t *testing.T) { + ctx := context.Background() + + ts := NewTestService(t) + defer ts.Cleanup() + + user, err := ts.CreateHostUser(ctx, "time-order-user") + require.NoError(t, err) + userCtx := ts.CreateUserContext(ctx, user.ID) + + memoEarlyCreateLateUpdate, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ + Memo: &apiv1.Memo{ + Content: "early create late update", + Visibility: apiv1.Visibility_PRIVATE, + CreateTime: timestamppb.New(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)), + UpdateTime: timestamppb.New(time.Date(2020, 1, 3, 0, 0, 0, 0, time.UTC)), + }, + }) + require.NoError(t, err) + memoMiddleCreateEarlyUpdate, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ + Memo: &apiv1.Memo{ + Content: "middle create early update", + Visibility: apiv1.Visibility_PRIVATE, + CreateTime: timestamppb.New(time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)), + UpdateTime: timestamppb.New(time.Date(2020, 1, 1, 0, 0, 0, 0, time.UTC)), + }, + }) + require.NoError(t, err) + memoLateCreateMiddleUpdate, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ + Memo: &apiv1.Memo{ + Content: "late create middle update", + Visibility: apiv1.Visibility_PRIVATE, + CreateTime: timestamppb.New(time.Date(2020, 1, 3, 0, 0, 0, 0, time.UTC)), + UpdateTime: timestamppb.New(time.Date(2020, 1, 2, 0, 0, 0, 0, time.UTC)), + }, + }) + require.NoError(t, err) + + tests := []struct { + name string + orderBy string + wantNames []string + }{ + { + name: "default create time", + orderBy: "", + wantNames: []string{ + memoLateCreateMiddleUpdate.Name, + memoMiddleCreateEarlyUpdate.Name, + memoEarlyCreateLateUpdate.Name, + }, + }, + { + name: "explicit create time", + orderBy: "create_time desc", + wantNames: []string{ + memoLateCreateMiddleUpdate.Name, + memoMiddleCreateEarlyUpdate.Name, + memoEarlyCreateLateUpdate.Name, + }, + }, + { + name: "explicit update time", + orderBy: "update_time desc", + wantNames: []string{ + memoEarlyCreateLateUpdate.Name, + memoLateCreateMiddleUpdate.Name, + memoMiddleCreateEarlyUpdate.Name, + }, + }, + { + name: "pinned with explicit create time", + orderBy: "pinned desc, create_time desc", + wantNames: []string{ + memoLateCreateMiddleUpdate.Name, + memoMiddleCreateEarlyUpdate.Name, + memoEarlyCreateLateUpdate.Name, + }, + }, + { + name: "explicit create time ascending", + orderBy: "create_time asc", + wantNames: []string{ + memoEarlyCreateLateUpdate.Name, + memoMiddleCreateEarlyUpdate.Name, + memoLateCreateMiddleUpdate.Name, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + resp, err := ts.Service.ListMemos(userCtx, &apiv1.ListMemosRequest{ + PageSize: 10, + OrderBy: test.orderBy, + }) + require.NoError(t, err) + require.Len(t, resp.Memos, len(test.wantNames)) + + gotNames := make([]string, 0, len(resp.Memos)) + for _, memo := range resp.Memos { + gotNames = append(gotNames, memo.Name) + } + require.Equal(t, test.wantNames, gotNames) + }) + } + + _, err = ts.Service.ListMemos(userCtx, &apiv1.ListMemosRequest{ + PageSize: 10, + OrderBy: "display_time desc", + }) + require.Error(t, err) +} + func TestListMemosSkipsReactionsWithMissingCreators(t *testing.T) { ctx := context.Background() @@ -431,7 +545,6 @@ func TestCreateMemoWithCustomTimestamps(t *testing.T) { // Define custom timestamps (January 1, 2020) customCreateTime := time.Date(2020, 1, 1, 12, 0, 0, 0, time.UTC) customUpdateTime := time.Date(2020, 1, 2, 12, 0, 0, 0, time.UTC) - customDisplayTime := time.Date(2020, 1, 3, 12, 0, 0, 0, time.UTC) // Test 1: Create a memo with custom create_time memoWithCreateTime, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ @@ -457,41 +570,21 @@ func TestCreateMemoWithCustomTimestamps(t *testing.T) { require.NotNil(t, memoWithUpdateTime) require.Equal(t, customUpdateTime.Unix(), memoWithUpdateTime.UpdateTime.AsTime().Unix(), "update_time should match the custom timestamp") - // Test 3: Create a memo with custom display_time - // Note: display_time is computed from either created_ts or updated_ts based on instance setting - // Since DisplayWithUpdateTime defaults to false, display_time maps to created_ts - memoWithDisplayTime, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ - Memo: &apiv1.Memo{ - Content: "This memo has a custom display time", - Visibility: apiv1.Visibility_PRIVATE, - DisplayTime: timestamppb.New(customDisplayTime), - }, - }) - require.NoError(t, err) - require.NotNil(t, memoWithDisplayTime) - // Since DisplayWithUpdateTime is false by default, display_time sets created_ts - require.Equal(t, customDisplayTime.Unix(), memoWithDisplayTime.DisplayTime.AsTime().Unix(), "display_time should match the custom timestamp") - require.Equal(t, customDisplayTime.Unix(), memoWithDisplayTime.CreateTime.AsTime().Unix(), "create_time should also match since display_time maps to created_ts") - - // Test 4: Create a memo with all custom timestamps - // When both display_time and create_time are provided, create_time takes precedence + // Test 3: Create a memo with all custom timestamps memoWithAllTimestamps, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ Memo: &apiv1.Memo{ - Content: "This memo has all custom timestamps", - Visibility: apiv1.Visibility_PRIVATE, - CreateTime: timestamppb.New(customCreateTime), - UpdateTime: timestamppb.New(customUpdateTime), - DisplayTime: timestamppb.New(customDisplayTime), + Content: "This memo has all custom timestamps", + Visibility: apiv1.Visibility_PRIVATE, + CreateTime: timestamppb.New(customCreateTime), + UpdateTime: timestamppb.New(customUpdateTime), }, }) require.NoError(t, err) require.NotNil(t, memoWithAllTimestamps) require.Equal(t, customCreateTime.Unix(), memoWithAllTimestamps.CreateTime.AsTime().Unix(), "create_time should match the custom timestamp") require.Equal(t, customUpdateTime.Unix(), memoWithAllTimestamps.UpdateTime.AsTime().Unix(), "update_time should match the custom timestamp") - // display_time is computed from created_ts when DisplayWithUpdateTime is false - require.Equal(t, customCreateTime.Unix(), memoWithAllTimestamps.DisplayTime.AsTime().Unix(), "display_time should be derived from create_time") - // Test 5: Create a comment (memo relation) with custom timestamps + // Test 4: Create a comment (memo relation) with custom timestamps parentMemo, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ Memo: &apiv1.Memo{ Content: "This is the parent memo", @@ -514,7 +607,7 @@ func TestCreateMemoWithCustomTimestamps(t *testing.T) { require.NotNil(t, comment) require.Equal(t, customCommentCreateTime.Unix(), comment.CreateTime.AsTime().Unix(), "comment create_time should match the custom timestamp") - // Test 6: Verify that memos without custom timestamps still get auto-generated ones + // Test 5: Verify that memos without custom timestamps still get auto-generated ones memoWithoutTimestamps, err := ts.Service.CreateMemo(userCtx, &apiv1.CreateMemoRequest{ Memo: &apiv1.Memo{ Content: "This memo has auto-generated timestamps", diff --git a/server/router/api/v1/user_service_stats.go b/server/router/api/v1/user_service_stats.go index c953d8b32..73670c294 100644 --- a/server/router/api/v1/user_service_stats.go +++ b/server/router/api/v1/user_service_stats.go @@ -5,7 +5,6 @@ import ( "fmt" "time" - "github.com/pkg/errors" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "google.golang.org/protobuf/types/known/timestamppb" @@ -55,11 +54,6 @@ func (s *APIV1Service) listUsernamesByID(ctx context.Context, userIDs []int32) ( } func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUserStatsRequest) (*v1pb.ListAllUserStatsResponse, error) { - instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx) - if err != nil { - return nil, errors.Wrap(err, "failed to get instance memo related setting") - } - normalStatus := store.Normal memoFind := &store.FindMemo{ // Exclude comments by default. @@ -105,7 +99,7 @@ func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUser userMemoStatMap[memo.CreatorID] = &v1pb.UserStats{ Name: "", TagCount: make(map[string]int32), - MemoDisplayTimestamps: []*timestamppb.Timestamp{}, + MemoCreatedTimestamps: []*timestamppb.Timestamp{}, PinnedMemos: []string{}, MemoTypeStats: &v1pb.UserStats_MemoTypeStats{ LinkCount: 0, @@ -118,12 +112,7 @@ func (s *APIV1Service) ListAllUserStats(ctx context.Context, _ *v1pb.ListAllUser stats := userMemoStatMap[memo.CreatorID] - // Add display timestamp - displayTs := memo.CreatedTs - if instanceMemoRelatedSetting.DisplayWithUpdateTime { - displayTs = memo.UpdatedTs - } - stats.MemoDisplayTimestamps = append(stats.MemoDisplayTimestamps, timestamppb.New(time.Unix(displayTs, 0))) + stats.MemoCreatedTimestamps = append(stats.MemoCreatedTimestamps, timestamppb.New(time.Unix(memo.CreatedTs, 0))) // Count memo stats stats.TotalMemoCount++ @@ -215,12 +204,7 @@ func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserSt memoFind.VisibilityList = []store.Visibility{store.Public, store.Protected} } - instanceMemoRelatedSetting, err := s.Store.GetInstanceMemoRelatedSetting(ctx) - if err != nil { - return nil, errors.Wrap(err, "failed to get instance memo related setting") - } - - displayTimestamps := []*timestamppb.Timestamp{} + createdTimestamps := []*timestamppb.Timestamp{} tagCount := make(map[string]int32) linkCount := int32(0) codeCount := int32(0) @@ -246,11 +230,7 @@ func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserSt totalMemoCount += int32(len(memos)) for _, memo := range memos { - displayTs := memo.CreatedTs - if instanceMemoRelatedSetting.DisplayWithUpdateTime { - displayTs = memo.UpdatedTs - } - displayTimestamps = append(displayTimestamps, timestamppb.New(time.Unix(displayTs, 0))) + createdTimestamps = append(createdTimestamps, timestamppb.New(time.Unix(memo.CreatedTs, 0))) // Count different memo types based on content. if memo.Payload != nil { for _, tag := range memo.Payload.Tags { @@ -281,7 +261,7 @@ func (s *APIV1Service) GetUserStats(ctx context.Context, request *v1pb.GetUserSt userStats := &v1pb.UserStats{ Name: fmt.Sprintf("%s/stats", BuildUserName(user.Username)), - MemoDisplayTimestamps: displayTimestamps, + MemoCreatedTimestamps: createdTimestamps, TagCount: tagCount, PinnedMemos: pinnedMemos, TotalMemoCount: totalMemoCount, diff --git a/web/src/components/MemoActionMenu/memoShareImagePreviewModel.ts b/web/src/components/MemoActionMenu/memoShareImagePreviewModel.ts index 369121401..5d5b2c981 100644 --- a/web/src/components/MemoActionMenu/memoShareImagePreviewModel.ts +++ b/web/src/components/MemoActionMenu/memoShareImagePreviewModel.ts @@ -35,7 +35,7 @@ export const buildMemoShareImagePreviewModel = ({ }: BuildMemoShareImagePreviewModelOptions): MemoShareImagePreviewModel => { const displayName = creator?.displayName || creator?.username || fallbackDisplayName; const avatarUrl = getMemoSharePreviewAvatarUrl(creator?.avatarUrl); - const displayTime = memo.displayTime ? timestampDate(memo.displayTime) : memo.createTime ? timestampDate(memo.createTime) : undefined; + const displayTime = memo.createTime ? timestampDate(memo.createTime) : undefined; const formattedDisplayTime = displayTime?.toLocaleString(locale, { dateStyle: "medium", timeStyle: "short", diff --git a/web/src/components/MemoCommentSection.tsx b/web/src/components/MemoCommentSection.tsx index e8f01b05e..76a70d8d7 100644 --- a/web/src/components/MemoCommentSection.tsx +++ b/web/src/components/MemoCommentSection.tsx @@ -67,7 +67,7 @@ const MemoCommentSection = ({ memo, comments, parentPage }: Props) => { )} {comments.map((comment) => ( -
+
))} diff --git a/web/src/components/MemoDisplaySettingMenu.tsx b/web/src/components/MemoDisplaySettingMenu.tsx index c1ec24632..7677f3ae9 100644 --- a/web/src/components/MemoDisplaySettingMenu.tsx +++ b/web/src/components/MemoDisplaySettingMenu.tsx @@ -11,8 +11,8 @@ interface Props { function MemoDisplaySettingMenu({ className }: Props) { const t = useTranslate(); - const { orderByTimeAsc, toggleSortOrder } = useView(); - const isApplying = orderByTimeAsc !== false; + const { orderByTimeAsc, timeBasis, setTimeBasis, toggleSortOrder } = useView(); + const isApplying = orderByTimeAsc !== false || timeBasis !== "create_time"; return ( @@ -22,7 +22,19 @@ function MemoDisplaySettingMenu({ className }: Props) {
- {t("memo.direction")} + {t("memo.shown-time")} + +
+
+ {t("memo.order")}
diff --git a/web/src/components/MemoMetadata/Relation/LinkMemoDialog.tsx b/web/src/components/MemoMetadata/Relation/LinkMemoDialog.tsx index 7721e842f..9fe2cc3ce 100644 --- a/web/src/components/MemoMetadata/Relation/LinkMemoDialog.tsx +++ b/web/src/components/MemoMetadata/Relation/LinkMemoDialog.tsx @@ -74,7 +74,7 @@ export const LinkMemoDialog = ({
{alreadyLinked && } - {memo.displayTime && timestampDate(memo.displayTime).toLocaleString()} + {memo.createTime && timestampDate(memo.createTime).toLocaleString()}
diff --git a/web/src/components/MemoView/MemoViewContext.tsx b/web/src/components/MemoView/MemoViewContext.tsx index 569934b11..a2604b835 100644 --- a/web/src/components/MemoView/MemoViewContext.tsx +++ b/web/src/components/MemoView/MemoViewContext.tsx @@ -1,6 +1,7 @@ import { timestampDate } from "@bufbuild/protobuf/wkt"; import { createContext, useContext } from "react"; import { useLocation } from "react-router-dom"; +import { useView } from "@/contexts/ViewContext"; import type { Memo } from "@/types/proto/api/v1/memo_service_pb"; import { MemoRelation_Type } from "@/types/proto/api/v1/memo_service_pb"; import type { User } from "@/types/proto/api/v1/user_service_pb"; @@ -37,12 +38,14 @@ export const computeCommentAmount = (memo: Memo): number => export const useMemoViewDerived = () => { const { memo, isArchived, readonly } = useMemoViewContext(); + const { timeBasis } = useView(); const location = useLocation(); const isInMemoDetailPage = location.pathname.startsWith(`/${memo.name}`) || location.pathname.startsWith("/memos/shares/"); const commentAmount = computeCommentAmount(memo); - const displayTime = memo.displayTime ? timestampDate(memo.displayTime) : undefined; + const displayTimestamp = timeBasis === "update_time" ? memo.updateTime : memo.createTime; + const displayTime = displayTimestamp ? timestampDate(displayTimestamp) : undefined; const relativeTimeFormat: "datetime" | "auto" = displayTime && Date.now() - displayTime.getTime() > RELATIVE_TIME_THRESHOLD_MS ? "datetime" : "auto"; @@ -51,6 +54,7 @@ export const useMemoViewDerived = () => { readonly, isInMemoDetailPage, commentAmount, + displayTime, relativeTimeFormat, }; }; diff --git a/web/src/components/MemoView/components/MemoHeader.tsx b/web/src/components/MemoView/components/MemoHeader.tsx index c91e308df..7fd2e8d07 100644 --- a/web/src/components/MemoView/components/MemoHeader.tsx +++ b/web/src/components/MemoView/components/MemoHeader.tsx @@ -1,4 +1,3 @@ -import { timestampDate } from "@bufbuild/protobuf/wkt"; import { BookmarkIcon } from "lucide-react"; import { useCallback, useState } from "react"; import { Link } from "react-router-dom"; @@ -23,7 +22,7 @@ const MemoHeader: React.FC = ({ showCreator, showVisibility, sh const [reactionSelectorOpen, setReactionSelectorOpen] = useState(false); const { memo, creator, currentUser, parentPage, isArchived, readonly, openEditor } = useMemoViewContext(); - const { relativeTimeFormat } = useMemoViewDerived(); + const { displayTime: memoDisplayTime, relativeTimeFormat } = useMemoViewDerived(); const navigateTo = useNavigateTo(); const handleGotoMemoDetailPage = useCallback(() => { @@ -33,13 +32,9 @@ const MemoHeader: React.FC = ({ showCreator, showVisibility, sh const { unpinMemo } = useMemoActions(memo); const displayTime = isArchived ? ( - (memo.displayTime ? timestampDate(memo.displayTime) : undefined)?.toLocaleString(i18n.language) + memoDisplayTime?.toLocaleString(i18n.language) ) : ( - + ); return ( diff --git a/web/src/components/PagedMemoList/PagedMemoList.tsx b/web/src/components/PagedMemoList/PagedMemoList.tsx index 47bab6649..3432da4c3 100644 --- a/web/src/components/PagedMemoList/PagedMemoList.tsx +++ b/web/src/components/PagedMemoList/PagedMemoList.tsx @@ -88,7 +88,7 @@ const PagedMemoList = (props: Props) => { const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading } = useInfiniteMemos( { state: props.state || State.NORMAL, - orderBy: props.orderBy || "display_time desc", + orderBy: props.orderBy || "create_time desc", filter: props.filter, pageSize: props.pageSize || DEFAULT_LIST_MEMOS_PAGE_SIZE, }, diff --git a/web/src/components/Settings/MemoRelatedSettings.tsx b/web/src/components/Settings/MemoRelatedSettings.tsx index 8c7d2620f..6bd27961c 100644 --- a/web/src/components/Settings/MemoRelatedSettings.tsx +++ b/web/src/components/Settings/MemoRelatedSettings.tsx @@ -72,13 +72,6 @@ const MemoRelatedSettings = () => { return ( - - updatePartialSetting({ displayWithUpdateTime: checked })} - /> - - { const { data, isLoading } = useInfiniteMemos( { state: State.NORMAL, - orderBy: "display_time desc", + orderBy: "create_time desc", pageSize: 1000, filter: creatorFilter, }, @@ -133,8 +133,8 @@ const UserMemoMap = ({ creator, className }: Props) => { Memo - {memo.displayTime && - timestampDate(memo.displayTime).toLocaleDateString(undefined, { + {memo.createTime && + timestampDate(memo.createTime).toLocaleDateString(undefined, { year: "numeric", month: "short", day: "numeric", diff --git a/web/src/contexts/ViewContext.tsx b/web/src/contexts/ViewContext.tsx index 3057d9efe..70bb3d1f7 100644 --- a/web/src/contexts/ViewContext.tsx +++ b/web/src/contexts/ViewContext.tsx @@ -1,8 +1,18 @@ import { createContext, type ReactNode, useContext, useState } from "react"; +export type MemoTimeBasis = "create_time" | "update_time"; + +interface ViewState { + orderByTimeAsc: boolean; + timeBasis?: MemoTimeBasis; + sortTimeField?: MemoTimeBasis; +} + interface ViewContextValue { orderByTimeAsc: boolean; + timeBasis: MemoTimeBasis; toggleSortOrder: () => void; + setTimeBasis: (field: MemoTimeBasis) => void; } const ViewContext = createContext(null); @@ -10,13 +20,16 @@ const ViewContext = createContext(null); const LOCAL_STORAGE_KEY = "memos-view-setting"; export function ViewProvider({ children }: { children: ReactNode }) { - const getInitialState = () => { + const getInitialState = (): ViewState => { try { const cached = localStorage.getItem(LOCAL_STORAGE_KEY); if (cached) { - const data = JSON.parse(cached); + const data = JSON.parse(cached) as Partial; + const cachedTimeBasis = data.timeBasis ?? data.sortTimeField; + const timeBasis = cachedTimeBasis === "create_time" || cachedTimeBasis === "update_time" ? cachedTimeBasis : undefined; return { orderByTimeAsc: Boolean(data.orderByTimeAsc ?? false), + timeBasis, }; } } catch (error) { @@ -26,8 +39,9 @@ export function ViewProvider({ children }: { children: ReactNode }) { }; const [viewState, setViewState] = useState(getInitialState); + const timeBasis = viewState.timeBasis ?? "create_time"; - const persistToStorage = (newState: typeof viewState) => { + const persistToStorage = (newState: ViewState) => { try { localStorage.setItem(LOCAL_STORAGE_KEY, JSON.stringify(newState)); } catch (error) { @@ -43,11 +57,21 @@ export function ViewProvider({ children }: { children: ReactNode }) { }); }; + const setTimeBasis = (field: MemoTimeBasis) => { + setViewState((prev) => { + const newState = { ...prev, timeBasis: field }; + persistToStorage(newState); + return newState; + }); + }; + return ( {children} diff --git a/web/src/hooks/useFilteredMemoStats.ts b/web/src/hooks/useFilteredMemoStats.ts index 3711f711b..8b8c90bf5 100644 --- a/web/src/hooks/useFilteredMemoStats.ts +++ b/web/src/hooks/useFilteredMemoStats.ts @@ -49,15 +49,15 @@ export const useFilteredMemoStats = (options: UseFilteredMemoStatsOptions = {}): } } const displayDates = (memosResponse?.memos ?? []) - .map((memo) => (memo.displayTime ? timestampDate(memo.displayTime) : undefined)) + .map((memo) => (memo.createTime ? timestampDate(memo.createTime) : undefined)) .filter((date): date is Date => date !== undefined) .map(toDateString); activityStats = countBy(displayDates); } else if (userName && userStats) { // home/profile: use backend per-user stats - if (userStats.memoDisplayTimestamps && userStats.memoDisplayTimestamps.length > 0) { + if (userStats.memoCreatedTimestamps && userStats.memoCreatedTimestamps.length > 0) { activityStats = countBy( - userStats.memoDisplayTimestamps + userStats.memoCreatedTimestamps .map((ts) => (ts ? timestampDate(ts) : undefined)) .filter((date): date is Date => date !== undefined) .map(toDateString), @@ -69,7 +69,7 @@ export const useFilteredMemoStats = (options: UseFilteredMemoStatsOptions = {}): } else if (memosResponse?.memos) { // archived/fallback: compute from cached memos const displayDates = memosResponse.memos - .map((memo) => (memo.displayTime ? timestampDate(memo.displayTime) : undefined)) + .map((memo) => (memo.createTime ? timestampDate(memo.createTime) : undefined)) .filter((date): date is Date => date !== undefined) .map(toDateString); activityStats = countBy(displayDates); diff --git a/web/src/hooks/useMemoFilters.ts b/web/src/hooks/useMemoFilters.ts index 76c60d07e..35149a3a2 100644 --- a/web/src/hooks/useMemoFilters.ts +++ b/web/src/hooks/useMemoFilters.ts @@ -1,6 +1,5 @@ import { useMemo } from "react"; import { useAuth } from "@/contexts/AuthContext"; -import { useInstance } from "@/contexts/InstanceContext"; import { useMemoFilterContext } from "@/contexts/MemoFilterContext"; import { buildMemoCreatorFilter } from "@/helpers/resource-names"; import { Visibility } from "@/types/proto/api/v1/memo_service_pb"; @@ -37,7 +36,6 @@ export const useMemoFilters = (options: UseMemoFiltersOptions = {}): string | un const { shortcuts } = useAuth(); const { filters, shortcut: currentShortcut } = useMemoFilterContext(); - const { memoRelatedSetting } = useInstance(); // Get selected shortcut if needed const selectedShortcut = useMemo(() => { @@ -79,14 +77,11 @@ export const useMemoFilters = (options: UseMemoFiltersOptions = {}): string | un } else if (filter.factor === "property.hasCode") { conditions.push(`has_code`); } else if (filter.factor === "displayTime") { - const displayWithUpdateTime = memoRelatedSetting?.displayWithUpdateTime ?? false; - const factor = displayWithUpdateTime ? "updated_ts" : "created_ts"; - const filterDate = new Date(filter.value); const filterUtcTimestamp = filterDate.getTime() + filterDate.getTimezoneOffset() * 60 * 1000; const timestampAfter = filterUtcTimestamp / 1000; - conditions.push(`${factor} >= ${timestampAfter} && ${factor} < ${timestampAfter + 60 * 60 * 24}`); + conditions.push(`created_ts >= ${timestampAfter} && created_ts < ${timestampAfter + 60 * 60 * 24}`); } } @@ -97,5 +92,5 @@ export const useMemoFilters = (options: UseMemoFiltersOptions = {}): string | un } return conditions.length > 0 ? conditions.join(" && ") : undefined; - }, [creatorName, includeShortcuts, includePinned, visibilities, selectedShortcut, filters, memoRelatedSetting]); + }, [creatorName, includeShortcuts, includePinned, visibilities, selectedShortcut, filters]); }; diff --git a/web/src/hooks/useMemoSorting.ts b/web/src/hooks/useMemoSorting.ts index a456a53cb..724a6c10c 100644 --- a/web/src/hooks/useMemoSorting.ts +++ b/web/src/hooks/useMemoSorting.ts @@ -1,9 +1,9 @@ import { timestampDate } from "@bufbuild/protobuf/wkt"; import dayjs from "dayjs"; import { useMemo } from "react"; -import { useView } from "@/contexts/ViewContext"; +import { type MemoTimeBasis, useView } from "@/contexts/ViewContext"; import { State } from "@/types/proto/api/v1/common_pb"; -import { Memo } from "@/types/proto/api/v1/memo_service_pb"; +import type { Memo } from "@/types/proto/api/v1/memo_service_pb"; export interface UseMemoSortingOptions { pinnedFirst?: boolean; @@ -15,15 +15,20 @@ export interface UseMemoSortingResult { orderBy: string; } +const getMemoSortTime = (memo: Memo, timeBasis: MemoTimeBasis): Date | undefined => { + const timestamp = timeBasis === "update_time" ? memo.updateTime : memo.createTime; + return timestamp ? timestampDate(timestamp) : undefined; +}; + export const useMemoSorting = (options: UseMemoSortingOptions = {}): UseMemoSortingResult => { const { pinnedFirst = false, state = State.NORMAL } = options; - const { orderByTimeAsc } = useView(); + const { orderByTimeAsc, timeBasis } = useView(); // Generate orderBy string for API const orderBy = useMemo(() => { - const timeOrder = orderByTimeAsc ? "display_time asc" : "display_time desc"; + const timeOrder = orderByTimeAsc ? `${timeBasis} asc` : `${timeBasis} desc`; return pinnedFirst ? `pinned desc, ${timeOrder}` : timeOrder; - }, [pinnedFirst, orderByTimeAsc]); + }, [pinnedFirst, orderByTimeAsc, timeBasis]); // Generate listSort function for client-side sorting const listSort = useMemo(() => { @@ -36,13 +41,13 @@ export const useMemoSorting = (options: UseMemoSortingOptions = {}): UseMemoSort return b.pinned ? 1 : -1; } - // Then sort by display time - const aTime = a.displayTime ? timestampDate(a.displayTime) : undefined; - const bTime = b.displayTime ? timestampDate(b.displayTime) : undefined; + // Then sort by the selected time field. + const aTime = getMemoSortTime(a, timeBasis); + const bTime = getMemoSortTime(b, timeBasis); return orderByTimeAsc ? dayjs(aTime).unix() - dayjs(bTime).unix() : dayjs(bTime).unix() - dayjs(aTime).unix(); }); }; - }, [pinnedFirst, state, orderByTimeAsc]); + }, [pinnedFirst, state, orderByTimeAsc, timeBasis]); return { listSort, orderBy }; }; diff --git a/web/src/locales/en.json b/web/src/locales/en.json index 24032523e..54facf362 100644 --- a/web/src/locales/en.json +++ b/web/src/locales/en.json @@ -247,9 +247,13 @@ "load-more": "Load more", "no-archived-memos": "No archived memos.", "no-memos": "No memos.", + "newest-first": "Newest first", + "oldest-first": "Oldest first", + "order": "Order", "order-by": "Order By", "outline": "Outline", "search-placeholder": "Search memos...", + "shown-time": "Shown time", "share": { "active-links": "Active share links", "copied": "Copied!", diff --git a/web/src/locales/zh-Hans.json b/web/src/locales/zh-Hans.json index fdbe54033..b27def4fc 100644 --- a/web/src/locales/zh-Hans.json +++ b/web/src/locales/zh-Hans.json @@ -209,8 +209,12 @@ "load-more": "加载更多", "no-archived-memos": "没有已归档备忘录。", "no-memos": "无备忘录", + "newest-first": "最新优先", + "oldest-first": "最早优先", + "order": "顺序", "order-by": "排序", "search-placeholder": "搜索备忘录", + "shown-time": "显示时间", "show-less": "显示较少", "show-more": "查看更多", "to-do": "待办", diff --git a/web/src/locales/zh-Hant.json b/web/src/locales/zh-Hant.json index 8f4ae0b94..ee892c232 100644 --- a/web/src/locales/zh-Hant.json +++ b/web/src/locales/zh-Hant.json @@ -206,8 +206,12 @@ "load-more": "載入更多", "no-archived-memos": "無已封存的備忘錄", "no-memos": "無備忘錄", + "newest-first": "最新優先", + "oldest-first": "最早優先", + "order": "順序", "order-by": "排序", "search-placeholder": "搜尋備忘錄", + "shown-time": "顯示時間", "show-less": "顯示較少", "show-more": "查看更多", "to-do": "待辦事項", diff --git a/web/src/pages/Home.tsx b/web/src/pages/Home.tsx index 43aa8d338..a8b824a8b 100644 --- a/web/src/pages/Home.tsx +++ b/web/src/pages/Home.tsx @@ -24,7 +24,7 @@ const Home = () => { return (
} + renderer={(memo: Memo) => } listSort={listSort} orderBy={orderBy} filter={memoFilter} diff --git a/web/src/pages/MemoDetail.tsx b/web/src/pages/MemoDetail.tsx index 6cd072b17..05266198c 100644 --- a/web/src/pages/MemoDetail.tsx +++ b/web/src/pages/MemoDetail.tsx @@ -100,7 +100,7 @@ const MemoDetail = () => {
)} { {activeTab === "memos" ? ( ( - + )} listSort={listSort} orderBy={orderBy} diff --git a/web/src/types/proto/api/v1/ai_service_pb.ts b/web/src/types/proto/api/v1/ai_service_pb.ts index 83503a1d1..059ff6a88 100644 --- a/web/src/types/proto/api/v1/ai_service_pb.ts +++ b/web/src/types/proto/api/v1/ai_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/ai_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -31,14 +31,14 @@ export type TranscribeRequest = Message<"memos.api.v1.TranscribeRequest"> & { * * @generated from field: memos.api.v1.TranscriptionConfig config = 2; */ - config?: TranscriptionConfig; + config?: TranscriptionConfig | undefined; /** * Required. Audio input. * * @generated from field: memos.api.v1.TranscriptionAudio audio = 3; */ - audio?: TranscriptionAudio; + audio?: TranscriptionAudio | undefined; }; /** diff --git a/web/src/types/proto/api/v1/attachment_service_pb.ts b/web/src/types/proto/api/v1/attachment_service_pb.ts index 9dadd2840..e7520f79f 100644 --- a/web/src/types/proto/api/v1/attachment_service_pb.ts +++ b/web/src/types/proto/api/v1/attachment_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/attachment_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -72,7 +72,7 @@ export type Attachment = Message<"memos.api.v1.Attachment"> & { * * @generated from field: google.protobuf.Timestamp create_time = 2; */ - createTime?: Timestamp; + createTime?: Timestamp | undefined; /** * The filename of the attachment. @@ -115,14 +115,14 @@ export type Attachment = Message<"memos.api.v1.Attachment"> & { * * @generated from field: optional string memo = 8; */ - memo?: string; + memo?: string | undefined; /** * Optional. Motion media metadata. * * @generated from field: memos.api.v1.MotionMedia motion_media = 9; */ - motionMedia?: MotionMedia; + motionMedia?: MotionMedia | undefined; }; /** @@ -141,7 +141,7 @@ export type CreateAttachmentRequest = Message<"memos.api.v1.CreateAttachmentRequ * * @generated from field: memos.api.v1.Attachment attachment = 1; */ - attachment?: Attachment; + attachment?: Attachment | undefined; /** * Optional. The attachment ID to use for this attachment. @@ -270,14 +270,14 @@ export type UpdateAttachmentRequest = Message<"memos.api.v1.UpdateAttachmentRequ * * @generated from field: memos.api.v1.Attachment attachment = 1; */ - attachment?: Attachment; + attachment?: Attachment | undefined; /** * Required. The list of fields to update. * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** diff --git a/web/src/types/proto/api/v1/auth_service_pb.ts b/web/src/types/proto/api/v1/auth_service_pb.ts index 972f3f6ac..4c8a0b400 100644 --- a/web/src/types/proto/api/v1/auth_service_pb.ts +++ b/web/src/types/proto/api/v1/auth_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/auth_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -40,7 +40,7 @@ export type GetCurrentUserResponse = Message<"memos.api.v1.GetCurrentUserRespons * * @generated from field: memos.api.v1.User user = 1; */ - user?: User; + user?: User | undefined; }; /** @@ -166,7 +166,7 @@ export type SignInResponse = Message<"memos.api.v1.SignInResponse"> & { * * @generated from field: memos.api.v1.User user = 1; */ - user?: User; + user?: User | undefined; /** * The short-lived access token for API requests. @@ -182,7 +182,7 @@ export type SignInResponse = Message<"memos.api.v1.SignInResponse"> & { * * @generated from field: google.protobuf.Timestamp access_token_expires_at = 3; */ - accessTokenExpiresAt?: Timestamp; + accessTokenExpiresAt?: Timestamp | undefined; }; /** @@ -234,7 +234,7 @@ export type RefreshTokenResponse = Message<"memos.api.v1.RefreshTokenResponse"> * * @generated from field: google.protobuf.Timestamp expires_at = 2; */ - expiresAt?: Timestamp; + expiresAt?: Timestamp | undefined; }; /** diff --git a/web/src/types/proto/api/v1/common_pb.ts b/web/src/types/proto/api/v1/common_pb.ts index 4d554fc7f..3e5f9d358 100644 --- a/web/src/types/proto/api/v1/common_pb.ts +++ b/web/src/types/proto/api/v1/common_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/common.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ diff --git a/web/src/types/proto/api/v1/idp_service_pb.ts b/web/src/types/proto/api/v1/idp_service_pb.ts index de4615c42..94bac9789 100644 --- a/web/src/types/proto/api/v1/idp_service_pb.ts +++ b/web/src/types/proto/api/v1/idp_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/idp_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -56,7 +56,7 @@ export type IdentityProvider = Message<"memos.api.v1.IdentityProvider"> & { * * @generated from field: memos.api.v1.IdentityProviderConfig config = 5; */ - config?: IdentityProviderConfig; + config?: IdentityProviderConfig | undefined; }; /** @@ -181,7 +181,7 @@ export type OAuth2Config = Message<"memos.api.v1.OAuth2Config"> & { /** * @generated from field: memos.api.v1.FieldMapping field_mapping = 7; */ - fieldMapping?: FieldMapping; + fieldMapping?: FieldMapping | undefined; }; /** @@ -252,7 +252,7 @@ export type CreateIdentityProviderRequest = Message<"memos.api.v1.CreateIdentity * * @generated from field: memos.api.v1.IdentityProvider identity_provider = 1; */ - identityProvider?: IdentityProvider; + identityProvider?: IdentityProvider | undefined; /** * Optional. The ID to use for the identity provider, which will become the final component of the resource name. @@ -279,7 +279,7 @@ export type UpdateIdentityProviderRequest = Message<"memos.api.v1.UpdateIdentity * * @generated from field: memos.api.v1.IdentityProvider identity_provider = 1; */ - identityProvider?: IdentityProvider; + identityProvider?: IdentityProvider | undefined; /** * Required. The update mask applies to the resource. Only the top level fields of @@ -287,7 +287,7 @@ export type UpdateIdentityProviderRequest = Message<"memos.api.v1.UpdateIdentity * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** diff --git a/web/src/types/proto/api/v1/instance_service_pb.ts b/web/src/types/proto/api/v1/instance_service_pb.ts index d3b29820c..224d88f65 100644 --- a/web/src/types/proto/api/v1/instance_service_pb.ts +++ b/web/src/types/proto/api/v1/instance_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/instance_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -20,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file api/v1/instance_service.proto. */ export const file_api_v1_instance_service: GenFile = /*@__PURE__*/ - fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxImkKD0luc3RhbmNlUHJvZmlsZRIPCgd2ZXJzaW9uGAIgASgJEgwKBGRlbW8YAyABKAgSFAoMaW5zdGFuY2VfdXJsGAYgASgJEiEKBWFkbWluGAcgASgLMhIubWVtb3MuYXBpLnYxLlVzZXIiGwoZR2V0SW5zdGFuY2VQcm9maWxlUmVxdWVzdCKjFAoPSW5zdGFuY2VTZXR0aW5nEhEKBG5hbWUYASABKAlCA+BBCBJHCg9nZW5lcmFsX3NldHRpbmcYAiABKAsyLC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkdlbmVyYWxTZXR0aW5nSAASRwoPc3RvcmFnZV9zZXR0aW5nGAMgASgLMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZ0gAElAKFG1lbW9fcmVsYXRlZF9zZXR0aW5nGAQgASgLMjAubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5NZW1vUmVsYXRlZFNldHRpbmdIABJBCgx0YWdzX3NldHRpbmcYBSABKAsyKS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRhZ3NTZXR0aW5nSAASUQoUbm90aWZpY2F0aW9uX3NldHRpbmcYBiABKAsyMS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLk5vdGlmaWNhdGlvblNldHRpbmdIABI9CgphaV9zZXR0aW5nGAcgASgLMicubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5BSVNldHRpbmdIABqHAwoOR2VuZXJhbFNldHRpbmcSIgoaZGlzYWxsb3dfdXNlcl9yZWdpc3RyYXRpb24YAiABKAgSHgoWZGlzYWxsb3dfcGFzc3dvcmRfYXV0aBgDIAEoCBIZChFhZGRpdGlvbmFsX3NjcmlwdBgEIAEoCRIYChBhZGRpdGlvbmFsX3N0eWxlGAUgASgJElIKDmN1c3RvbV9wcm9maWxlGAYgASgLMjoubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5HZW5lcmFsU2V0dGluZy5DdXN0b21Qcm9maWxlEh0KFXdlZWtfc3RhcnRfZGF5X29mZnNldBgHIAEoBRIgChhkaXNhbGxvd19jaGFuZ2VfdXNlcm5hbWUYCCABKAgSIAoYZGlzYWxsb3dfY2hhbmdlX25pY2tuYW1lGAkgASgIGkUKDUN1c3RvbVByb2ZpbGUSDQoFdGl0bGUYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSEAoIbG9nb191cmwYAyABKAkaugMKDlN0b3JhZ2VTZXR0aW5nEk4KDHN0b3JhZ2VfdHlwZRgBIAEoDjI4Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmcuU3RvcmFnZVR5cGUSGQoRZmlsZXBhdGhfdGVtcGxhdGUYAiABKAkSHAoUdXBsb2FkX3NpemVfbGltaXRfbWIYAyABKAMSSAoJczNfY29uZmlnGAQgASgLMjUubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZy5TM0NvbmZpZxqGAQoIUzNDb25maWcSFQoNYWNjZXNzX2tleV9pZBgBIAEoCRIZChFhY2Nlc3Nfa2V5X3NlY3JldBgCIAEoCRIQCghlbmRwb2ludBgDIAEoCRIOCgZyZWdpb24YBCABKAkSDgoGYnVja2V0GAUgASgJEhYKDnVzZV9wYXRoX3N0eWxlGAYgASgIIkwKC1N0b3JhZ2VUeXBlEhwKGFNUT1JBR0VfVFlQRV9VTlNQRUNJRklFRBAAEgwKCERBVEFCQVNFEAESCQoFTE9DQUwQAhIGCgJTMxADGokBChJNZW1vUmVsYXRlZFNldHRpbmcSIAoYZGlzcGxheV93aXRoX3VwZGF0ZV90aW1lGAIgASgIEhwKFGNvbnRlbnRfbGVuZ3RoX2xpbWl0GAMgASgFEiAKGGVuYWJsZV9kb3VibGVfY2xpY2tfZWRpdBgEIAEoCBIRCglyZWFjdGlvbnMYByADKAkaUQoLVGFnTWV0YWRhdGESLAoQYmFja2dyb3VuZF9jb2xvchgBIAEoCzISLmdvb2dsZS50eXBlLkNvbG9yEhQKDGJsdXJfY29udGVudBgCIAEoCBqoAQoLVGFnc1NldHRpbmcSQQoEdGFncxgBIAMoCzIzLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuVGFnc1NldHRpbmcuVGFnc0VudHJ5GlYKCVRhZ3NFbnRyeRILCgNrZXkYASABKAkSOAoFdmFsdWUYAiABKAsyKS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRhZ01ldGFkYXRhOgI4ARq1AgoTTm90aWZpY2F0aW9uU2V0dGluZxJNCgVlbWFpbBgBIAEoCzI+Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuTm90aWZpY2F0aW9uU2V0dGluZy5FbWFpbFNldHRpbmcazgEKDEVtYWlsU2V0dGluZxIPCgdlbmFibGVkGAEgASgIEhEKCXNtdHBfaG9zdBgCIAEoCRIRCglzbXRwX3BvcnQYAyABKAUSFQoNc210cF91c2VybmFtZRgEIAEoCRIVCg1zbXRwX3Bhc3N3b3JkGAUgASgJEhIKCmZyb21fZW1haWwYBiABKAkSEQoJZnJvbV9uYW1lGAcgASgJEhAKCHJlcGx5X3RvGAggASgJEg8KB3VzZV90bHMYCSABKAgSDwoHdXNlX3NzbBgKIAEoCBpOCglBSVNldHRpbmcSQQoJcHJvdmlkZXJzGAEgAygLMi4ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5BSVByb3ZpZGVyQ29uZmlnGsYBChBBSVByb3ZpZGVyQ29uZmlnEgoKAmlkGAEgASgJEg0KBXRpdGxlGAIgASgJEjoKBHR5cGUYAyABKA4yLC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkFJUHJvdmlkZXJUeXBlEhAKCGVuZHBvaW50GAQgASgJEhQKB2FwaV9rZXkYBSABKAlCA+BBBBIYCgthcGlfa2V5X3NldBgIIAEoCEID4EEDEhkKDGFwaV9rZXlfaGludBgJIAEoCUID4EEDImoKA0tleRITCg9LRVlfVU5TUEVDSUZJRUQQABILCgdHRU5FUkFMEAESCwoHU1RPUkFHRRACEhAKDE1FTU9fUkVMQVRFRBADEggKBFRBR1MQBBIQCgxOT1RJRklDQVRJT04QBRIGCgJBSRAGIkoKDkFJUHJvdmlkZXJUeXBlEiAKHEFJX1BST1ZJREVSX1RZUEVfVU5TUEVDSUZJRUQQABIKCgZPUEVOQUkQARIKCgZHRU1JTkkQAjph6kFeChxtZW1vcy5hcGkudjEvSW5zdGFuY2VTZXR0aW5nEhtpbnN0YW5jZS9zZXR0aW5ncy97c2V0dGluZ30qEGluc3RhbmNlU2V0dGluZ3MyD2luc3RhbmNlU2V0dGluZ0IHCgV2YWx1ZSJPChlHZXRJbnN0YW5jZVNldHRpbmdSZXF1ZXN0EjIKBG5hbWUYASABKAlCJOBBAvpBHgocbWVtb3MuYXBpLnYxL0luc3RhbmNlU2V0dGluZyKJAQocVXBkYXRlSW5zdGFuY2VTZXR0aW5nUmVxdWVzdBIzCgdzZXR0aW5nGAEgASgLMh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZ0ID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EEBMtsDCg9JbnN0YW5jZVNlcnZpY2USfgoSR2V0SW5zdGFuY2VQcm9maWxlEicubWVtb3MuYXBpLnYxLkdldEluc3RhbmNlUHJvZmlsZVJlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VQcm9maWxlIiCC0+STAhoSGC9hcGkvdjEvaW5zdGFuY2UvcHJvZmlsZRKPAQoSR2V0SW5zdGFuY2VTZXR0aW5nEicubWVtb3MuYXBpLnYxLkdldEluc3RhbmNlU2V0dGluZ1JlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nIjHaQQRuYW1lgtPkkwIkEiIvYXBpL3YxL3tuYW1lPWluc3RhbmNlL3NldHRpbmdzLyp9ErUBChVVcGRhdGVJbnN0YW5jZVNldHRpbmcSKi5tZW1vcy5hcGkudjEuVXBkYXRlSW5zdGFuY2VTZXR0aW5nUmVxdWVzdBodLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmciUdpBE3NldHRpbmcsdXBkYXRlX21hc2uC0+STAjU6B3NldHRpbmcyKi9hcGkvdjEve3NldHRpbmcubmFtZT1pbnN0YW5jZS9zZXR0aW5ncy8qfUKsAQoQY29tLm1lbW9zLmFwaS52MUIUSW5zdGFuY2VTZXJ2aWNlUHJvdG9QAVowZ2l0aHViLmNvbS91c2VtZW1vcy9tZW1vcy9wcm90by9nZW4vYXBpL3YxO2FwaXYxogIDTUFYqgIMTWVtb3MuQXBpLlYxygIMTWVtb3NcQXBpXFYx4gIYTWVtb3NcQXBpXFYxXEdQQk1ldGFkYXRh6gIOTWVtb3M6OkFwaTo6VjFiBnByb3RvMw", [file_api_v1_user_service, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_field_mask, file_google_type_color]); + fileDesc("Ch1hcGkvdjEvaW5zdGFuY2Vfc2VydmljZS5wcm90bxIMbWVtb3MuYXBpLnYxImkKD0luc3RhbmNlUHJvZmlsZRIPCgd2ZXJzaW9uGAIgASgJEgwKBGRlbW8YAyABKAgSFAoMaW5zdGFuY2VfdXJsGAYgASgJEiEKBWFkbWluGAcgASgLMhIubWVtb3MuYXBpLnYxLlVzZXIiGwoZR2V0SW5zdGFuY2VQcm9maWxlUmVxdWVzdCKhFAoPSW5zdGFuY2VTZXR0aW5nEhEKBG5hbWUYASABKAlCA+BBCBJHCg9nZW5lcmFsX3NldHRpbmcYAiABKAsyLC5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLkdlbmVyYWxTZXR0aW5nSAASRwoPc3RvcmFnZV9zZXR0aW5nGAMgASgLMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZ0gAElAKFG1lbW9fcmVsYXRlZF9zZXR0aW5nGAQgASgLMjAubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5NZW1vUmVsYXRlZFNldHRpbmdIABJBCgx0YWdzX3NldHRpbmcYBSABKAsyKS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRhZ3NTZXR0aW5nSAASUQoUbm90aWZpY2F0aW9uX3NldHRpbmcYBiABKAsyMS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLk5vdGlmaWNhdGlvblNldHRpbmdIABI9CgphaV9zZXR0aW5nGAcgASgLMicubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5BSVNldHRpbmdIABqHAwoOR2VuZXJhbFNldHRpbmcSIgoaZGlzYWxsb3dfdXNlcl9yZWdpc3RyYXRpb24YAiABKAgSHgoWZGlzYWxsb3dfcGFzc3dvcmRfYXV0aBgDIAEoCBIZChFhZGRpdGlvbmFsX3NjcmlwdBgEIAEoCRIYChBhZGRpdGlvbmFsX3N0eWxlGAUgASgJElIKDmN1c3RvbV9wcm9maWxlGAYgASgLMjoubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5HZW5lcmFsU2V0dGluZy5DdXN0b21Qcm9maWxlEh0KFXdlZWtfc3RhcnRfZGF5X29mZnNldBgHIAEoBRIgChhkaXNhbGxvd19jaGFuZ2VfdXNlcm5hbWUYCCABKAgSIAoYZGlzYWxsb3dfY2hhbmdlX25pY2tuYW1lGAkgASgIGkUKDUN1c3RvbVByb2ZpbGUSDQoFdGl0bGUYASABKAkSEwoLZGVzY3JpcHRpb24YAiABKAkSEAoIbG9nb191cmwYAyABKAkaugMKDlN0b3JhZ2VTZXR0aW5nEk4KDHN0b3JhZ2VfdHlwZRgBIAEoDjI4Lm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuU3RvcmFnZVNldHRpbmcuU3RvcmFnZVR5cGUSGQoRZmlsZXBhdGhfdGVtcGxhdGUYAiABKAkSHAoUdXBsb2FkX3NpemVfbGltaXRfbWIYAyABKAMSSAoJczNfY29uZmlnGAQgASgLMjUubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5TdG9yYWdlU2V0dGluZy5TM0NvbmZpZxqGAQoIUzNDb25maWcSFQoNYWNjZXNzX2tleV9pZBgBIAEoCRIZChFhY2Nlc3Nfa2V5X3NlY3JldBgCIAEoCRIQCghlbmRwb2ludBgDIAEoCRIOCgZyZWdpb24YBCABKAkSDgoGYnVja2V0GAUgASgJEhYKDnVzZV9wYXRoX3N0eWxlGAYgASgIIkwKC1N0b3JhZ2VUeXBlEhwKGFNUT1JBR0VfVFlQRV9VTlNQRUNJRklFRBAAEgwKCERBVEFCQVNFEAESCQoFTE9DQUwQAhIGCgJTMxADGocBChJNZW1vUmVsYXRlZFNldHRpbmcSHAoUY29udGVudF9sZW5ndGhfbGltaXQYAyABKAUSIAoYZW5hYmxlX2RvdWJsZV9jbGlja19lZGl0GAQgASgIEhEKCXJlYWN0aW9ucxgHIAMoCUoECAIQA1IYZGlzcGxheV93aXRoX3VwZGF0ZV90aW1lGlEKC1RhZ01ldGFkYXRhEiwKEGJhY2tncm91bmRfY29sb3IYASABKAsyEi5nb29nbGUudHlwZS5Db2xvchIUCgxibHVyX2NvbnRlbnQYAiABKAgaqAEKC1RhZ3NTZXR0aW5nEkEKBHRhZ3MYASADKAsyMy5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLlRhZ3NTZXR0aW5nLlRhZ3NFbnRyeRpWCglUYWdzRW50cnkSCwoDa2V5GAEgASgJEjgKBXZhbHVlGAIgASgLMikubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5UYWdNZXRhZGF0YToCOAEatQIKE05vdGlmaWNhdGlvblNldHRpbmcSTQoFZW1haWwYASABKAsyPi5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nLk5vdGlmaWNhdGlvblNldHRpbmcuRW1haWxTZXR0aW5nGs4BCgxFbWFpbFNldHRpbmcSDwoHZW5hYmxlZBgBIAEoCBIRCglzbXRwX2hvc3QYAiABKAkSEQoJc210cF9wb3J0GAMgASgFEhUKDXNtdHBfdXNlcm5hbWUYBCABKAkSFQoNc210cF9wYXNzd29yZBgFIAEoCRISCgpmcm9tX2VtYWlsGAYgASgJEhEKCWZyb21fbmFtZRgHIAEoCRIQCghyZXBseV90bxgIIAEoCRIPCgd1c2VfdGxzGAkgASgIEg8KB3VzZV9zc2wYCiABKAgaTgoJQUlTZXR0aW5nEkEKCXByb3ZpZGVycxgBIAMoCzIuLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmcuQUlQcm92aWRlckNvbmZpZxrGAQoQQUlQcm92aWRlckNvbmZpZxIKCgJpZBgBIAEoCRINCgV0aXRsZRgCIAEoCRI6CgR0eXBlGAMgASgOMiwubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZy5BSVByb3ZpZGVyVHlwZRIQCghlbmRwb2ludBgEIAEoCRIUCgdhcGlfa2V5GAUgASgJQgPgQQQSGAoLYXBpX2tleV9zZXQYCCABKAhCA+BBAxIZCgxhcGlfa2V5X2hpbnQYCSABKAlCA+BBAyJqCgNLZXkSEwoPS0VZX1VOU1BFQ0lGSUVEEAASCwoHR0VORVJBTBABEgsKB1NUT1JBR0UQAhIQCgxNRU1PX1JFTEFURUQQAxIICgRUQUdTEAQSEAoMTk9USUZJQ0FUSU9OEAUSBgoCQUkQBiJKCg5BSVByb3ZpZGVyVHlwZRIgChxBSV9QUk9WSURFUl9UWVBFX1VOU1BFQ0lGSUVEEAASCgoGT1BFTkFJEAESCgoGR0VNSU5JEAI6YepBXgocbWVtb3MuYXBpLnYxL0luc3RhbmNlU2V0dGluZxIbaW5zdGFuY2Uvc2V0dGluZ3Mve3NldHRpbmd9KhBpbnN0YW5jZVNldHRpbmdzMg9pbnN0YW5jZVNldHRpbmdCBwoFdmFsdWUiTwoZR2V0SW5zdGFuY2VTZXR0aW5nUmVxdWVzdBIyCgRuYW1lGAEgASgJQiTgQQL6QR4KHG1lbW9zLmFwaS52MS9JbnN0YW5jZVNldHRpbmciiQEKHFVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QSMwoHc2V0dGluZxgBIAEoCzIdLm1lbW9zLmFwaS52MS5JbnN0YW5jZVNldHRpbmdCA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBATLbAwoPSW5zdGFuY2VTZXJ2aWNlEn4KEkdldEluc3RhbmNlUHJvZmlsZRInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVByb2ZpbGVSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlUHJvZmlsZSIggtPkkwIaEhgvYXBpL3YxL2luc3RhbmNlL3Byb2ZpbGUSjwEKEkdldEluc3RhbmNlU2V0dGluZxInLm1lbW9zLmFwaS52MS5HZXRJbnN0YW5jZVNldHRpbmdSZXF1ZXN0Gh0ubWVtb3MuYXBpLnYxLkluc3RhbmNlU2V0dGluZyIx2kEEbmFtZYLT5JMCJBIiL2FwaS92MS97bmFtZT1pbnN0YW5jZS9zZXR0aW5ncy8qfRK1AQoVVXBkYXRlSW5zdGFuY2VTZXR0aW5nEioubWVtb3MuYXBpLnYxLlVwZGF0ZUluc3RhbmNlU2V0dGluZ1JlcXVlc3QaHS5tZW1vcy5hcGkudjEuSW5zdGFuY2VTZXR0aW5nIlHaQRNzZXR0aW5nLHVwZGF0ZV9tYXNrgtPkkwI1OgdzZXR0aW5nMiovYXBpL3YxL3tzZXR0aW5nLm5hbWU9aW5zdGFuY2Uvc2V0dGluZ3MvKn1CrAEKEGNvbS5tZW1vcy5hcGkudjFCFEluc3RhbmNlU2VydmljZVByb3RvUAFaMGdpdGh1Yi5jb20vdXNlbWVtb3MvbWVtb3MvcHJvdG8vZ2VuL2FwaS92MTthcGl2MaICA01BWKoCDE1lbW9zLkFwaS5WMcoCDE1lbW9zXEFwaVxWMeICGE1lbW9zXEFwaVxWMVxHUEJNZXRhZGF0YeoCDk1lbW9zOjpBcGk6OlYxYgZwcm90bzM", [file_api_v1_user_service, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_field_mask, file_google_type_color]); /** * Instance profile message containing basic instance information. @@ -55,7 +55,7 @@ export type InstanceProfile = Message<"memos.api.v1.InstanceProfile"> & { * * @generated from field: memos.api.v1.User admin = 7; */ - admin?: User; + admin?: User | undefined; }; /** @@ -182,7 +182,7 @@ export type InstanceSetting_GeneralSetting = Message<"memos.api.v1.InstanceSetti * * @generated from field: memos.api.v1.InstanceSetting.GeneralSetting.CustomProfile custom_profile = 6; */ - customProfile?: InstanceSetting_GeneralSetting_CustomProfile; + customProfile?: InstanceSetting_GeneralSetting_CustomProfile | undefined; /** * week_start_day_offset is the week start day offset from Sunday. @@ -277,7 +277,7 @@ export type InstanceSetting_StorageSetting = Message<"memos.api.v1.InstanceSetti * * @generated from field: memos.api.v1.InstanceSetting.StorageSetting.S3Config s3_config = 4; */ - s3Config?: InstanceSetting_StorageSetting_S3Config; + s3Config?: InstanceSetting_StorageSetting_S3Config | undefined; }; /** @@ -377,13 +377,6 @@ export const InstanceSetting_StorageSetting_StorageTypeSchema: GenEnum & { - /** - * display_with_update_time orders and displays memo with update time. - * - * @generated from field: bool display_with_update_time = 2; - */ - displayWithUpdateTime: boolean; - /** * content_length_limit is the limit of content length. Unit is byte. * @@ -425,7 +418,7 @@ export type InstanceSetting_TagMetadata = Message<"memos.api.v1.InstanceSetting. * * @generated from field: google.type.Color background_color = 1; */ - backgroundColor?: Color; + backgroundColor?: Color | undefined; /** * Whether memos with this tag should have their content blurred. @@ -475,7 +468,7 @@ export type InstanceSetting_NotificationSetting = Message<"memos.api.v1.Instance /** * @generated from field: memos.api.v1.InstanceSetting.NotificationSetting.EmailSetting email = 1; */ - email?: InstanceSetting_NotificationSetting_EmailSetting; + email?: InstanceSetting_NotificationSetting_EmailSetting | undefined; }; /** @@ -746,14 +739,14 @@ export type UpdateInstanceSettingRequest = Message<"memos.api.v1.UpdateInstanceS * * @generated from field: memos.api.v1.InstanceSetting setting = 1; */ - setting?: InstanceSetting; + setting?: InstanceSetting | undefined; /** * The list of fields to update. * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** diff --git a/web/src/types/proto/api/v1/memo_service_pb.ts b/web/src/types/proto/api/v1/memo_service_pb.ts index e4bf870d9..592d466c0 100644 --- a/web/src/types/proto/api/v1/memo_service_pb.ts +++ b/web/src/types/proto/api/v1/memo_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/memo_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -20,7 +20,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file api/v1/memo_service.proto. */ export const file_api_v1_memo_service: GenFile = /*@__PURE__*/ - fileDesc("ChlhcGkvdjEvbWVtb19zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEipwIKCFJlYWN0aW9uEhQKBG5hbWUYASABKAlCBuBBA+BBCBIqCgdjcmVhdG9yGAIgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEi0KCmNvbnRlbnRfaWQYAyABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SGgoNcmVhY3Rpb25fdHlwZRgEIAEoCUID4EECEjQKC2NyZWF0ZV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDOljqQVUKFW1lbW9zLmFwaS52MS9SZWFjdGlvbhIhbWVtb3Mve21lbW99L3JlYWN0aW9ucy97cmVhY3Rpb259GgRuYW1lKglyZWFjdGlvbnMyCHJlYWN0aW9uIo0HCgRNZW1vEhEKBG5hbWUYASABKAlCA+BBCBInCgVzdGF0ZRgCIAEoDjITLm1lbW9zLmFwaS52MS5TdGF0ZUID4EECEioKB2NyZWF0b3IYAyABKAlCGeBBA/pBEwoRbWVtb3MuYXBpLnYxL1VzZXISNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQESNAoLdXBkYXRlX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQESNQoMZGlzcGxheV90aW1lGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEBEhQKB2NvbnRlbnQYByABKAlCA+BBAhIxCgp2aXNpYmlsaXR5GAkgASgOMhgubWVtb3MuYXBpLnYxLlZpc2liaWxpdHlCA+BBAhIRCgR0YWdzGAogAygJQgPgQQMSEwoGcGlubmVkGAsgASgIQgPgQQESMgoLYXR0YWNobWVudHMYDCADKAsyGC5tZW1vcy5hcGkudjEuQXR0YWNobWVudEID4EEBEjIKCXJlbGF0aW9ucxgNIAMoCzIaLm1lbW9zLmFwaS52MS5NZW1vUmVsYXRpb25CA+BBARIuCglyZWFjdGlvbnMYDiADKAsyFi5tZW1vcy5hcGkudjEuUmVhY3Rpb25CA+BBAxIyCghwcm9wZXJ0eRgPIAEoCzIbLm1lbW9zLmFwaS52MS5NZW1vLlByb3BlcnR5QgPgQQMSLgoGcGFyZW50GBAgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9NZW1vSACIAQESFAoHc25pcHBldBgRIAEoCUID4EEDEjIKCGxvY2F0aW9uGBIgASgLMhYubWVtb3MuYXBpLnYxLkxvY2F0aW9uQgPgQQFIAYgBARpyCghQcm9wZXJ0eRIQCghoYXNfbGluaxgBIAEoCBIVCg1oYXNfdGFza19saXN0GAIgASgIEhAKCGhhc19jb2RlGAMgASgIEhwKFGhhc19pbmNvbXBsZXRlX3Rhc2tzGAQgASgIEg0KBXRpdGxlGAUgASgJOjfqQTQKEW1lbW9zLmFwaS52MS9NZW1vEgxtZW1vcy97bWVtb30aBG5hbWUqBW1lbW9zMgRtZW1vQgkKB19wYXJlbnRCCwoJX2xvY2F0aW9uIlMKCExvY2F0aW9uEhgKC3BsYWNlaG9sZGVyGAEgASgJQgPgQQESFQoIbGF0aXR1ZGUYAiABKAFCA+BBARIWCglsb25naXR1ZGUYAyABKAFCA+BBASJQChFDcmVhdGVNZW1vUmVxdWVzdBIlCgRtZW1vGAEgASgLMhIubWVtb3MuYXBpLnYxLk1lbW9CA+BBAhIUCgdtZW1vX2lkGAIgASgJQgPgQQEiswEKEExpc3RNZW1vc1JlcXVlc3QSFgoJcGFnZV9zaXplGAEgASgFQgPgQQESFwoKcGFnZV90b2tlbhgCIAEoCUID4EEBEicKBXN0YXRlGAMgASgOMhMubWVtb3MuYXBpLnYxLlN0YXRlQgPgQQESFQoIb3JkZXJfYnkYBCABKAlCA+BBARITCgZmaWx0ZXIYBSABKAlCA+BBARIZCgxzaG93X2RlbGV0ZWQYBiABKAhCA+BBASJPChFMaXN0TWVtb3NSZXNwb25zZRIhCgVtZW1vcxgBIAMoCzISLm1lbW9zLmFwaS52MS5NZW1vEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSI5Cg5HZXRNZW1vUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vInAKEVVwZGF0ZU1lbW9SZXF1ZXN0EiUKBG1lbW8YASABKAsyEi5tZW1vcy5hcGkudjEuTWVtb0ID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECIlAKEURlbGV0ZU1lbW9SZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SEgoFZm9yY2UYAiABKAhCA+BBASJ4ChlTZXRNZW1vQXR0YWNobWVudHNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SMgoLYXR0YWNobWVudHMYAiADKAsyGC5tZW1vcy5hcGkudjEuQXR0YWNobWVudEID4EECInYKGkxpc3RNZW1vQXR0YWNobWVudHNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBImUKG0xpc3RNZW1vQXR0YWNobWVudHNSZXNwb25zZRItCgthdHRhY2htZW50cxgBIAMoCzIYLm1lbW9zLmFwaS52MS5BdHRhY2htZW50EhcKD25leHRfcGFnZV90b2tlbhgCIAEoCSKzAgoMTWVtb1JlbGF0aW9uEjIKBG1lbW8YASABKAsyHy5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uLk1lbW9CA+BBAhI6CgxyZWxhdGVkX21lbW8YAiABKAsyHy5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uLk1lbW9CA+BBAhIyCgR0eXBlGAMgASgOMh8ubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbi5UeXBlQgPgQQIaRQoETWVtbxInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEhQKB3NuaXBwZXQYAiABKAlCA+BBAyI4CgRUeXBlEhQKEFRZUEVfVU5TUEVDSUZJRUQQABINCglSRUZFUkVOQ0UQARILCgdDT01NRU5UEAIidgoXU2V0TWVtb1JlbGF0aW9uc1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIyCglyZWxhdGlvbnMYAiADKAsyGi5tZW1vcy5hcGkudjEuTWVtb1JlbGF0aW9uQgPgQQIidAoYTGlzdE1lbW9SZWxhdGlvbnNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBImMKGUxpc3RNZW1vUmVsYXRpb25zUmVzcG9uc2USLQoJcmVsYXRpb25zGAEgAygLMhoubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkihgEKGENyZWF0ZU1lbW9Db21tZW50UmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEigKB2NvbW1lbnQYAiABKAsyEi5tZW1vcy5hcGkudjEuTWVtb0ID4EECEhcKCmNvbW1lbnRfaWQYAyABKAlCA+BBASKKAQoXTGlzdE1lbW9Db21tZW50c1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQESFQoIb3JkZXJfYnkYBCABKAlCA+BBASJqChhMaXN0TWVtb0NvbW1lbnRzUmVzcG9uc2USIQoFbWVtb3MYASADKAsyEi5tZW1vcy5hcGkudjEuTWVtbxIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkSEgoKdG90YWxfc2l6ZRgDIAEoBSJ0ChhMaXN0TWVtb1JlYWN0aW9uc1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEicwoZTGlzdE1lbW9SZWFjdGlvbnNSZXNwb25zZRIpCglyZWFjdGlvbnMYASADKAsyFi5tZW1vcy5hcGkudjEuUmVhY3Rpb24SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEhIKCnRvdGFsX3NpemUYAyABKAUicwoZVXBzZXJ0TWVtb1JlYWN0aW9uUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEi0KCHJlYWN0aW9uGAIgASgLMhYubWVtb3MuYXBpLnYxLlJlYWN0aW9uQgPgQQIiSAoZRGVsZXRlTWVtb1JlYWN0aW9uUmVxdWVzdBIrCgRuYW1lGAEgASgJQh3gQQL6QRcKFW1lbW9zLmFwaS52MS9SZWFjdGlvbiLoAQoJTWVtb1NoYXJlEhEKBG5hbWUYASABKAlCA+BBCBI0CgtjcmVhdGVfdGltZRgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI5CgtleHBpcmVfdGltZRgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAUgAiAEBOkfqQUQKFm1lbW9zLmFwaS52MS9NZW1vU2hhcmUSG21lbW9zL3ttZW1vfS9zaGFyZXMve3NoYXJlfSoGc2hhcmVzMgVzaGFyZUIOCgxfZXhwaXJlX3RpbWUidQoWQ3JlYXRlTWVtb1NoYXJlUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SMAoKbWVtb19zaGFyZRgCIAEoCzIXLm1lbW9zLmFwaS52MS5NZW1vU2hhcmVCA+BBAiJCChVMaXN0TWVtb1NoYXJlc1JlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vIkYKFkxpc3RNZW1vU2hhcmVzUmVzcG9uc2USLAoLbWVtb19zaGFyZXMYASADKAsyFy5tZW1vcy5hcGkudjEuTWVtb1NoYXJlIkYKFkRlbGV0ZU1lbW9TaGFyZVJlcXVlc3QSLAoEbmFtZRgBIAEoCUIe4EEC+kEYChZtZW1vcy5hcGkudjEvTWVtb1NoYXJlIi4KFUdldE1lbW9CeVNoYXJlUmVxdWVzdBIVCghzaGFyZV9pZBgBIAEoCUID4EECKlAKClZpc2liaWxpdHkSGgoWVklTSUJJTElUWV9VTlNQRUNJRklFRBAAEgsKB1BSSVZBVEUQARINCglQUk9URUNURUQQAhIKCgZQVUJMSUMQAzLuEgoLTWVtb1NlcnZpY2USZQoKQ3JlYXRlTWVtbxIfLm1lbW9zLmFwaS52MS5DcmVhdGVNZW1vUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5NZW1vIiLaQQRtZW1vgtPkkwIVOgRtZW1vIg0vYXBpL3YxL21lbW9zEmYKCUxpc3RNZW1vcxIeLm1lbW9zLmFwaS52MS5MaXN0TWVtb3NSZXF1ZXN0Gh8ubWVtb3MuYXBpLnYxLkxpc3RNZW1vc1Jlc3BvbnNlIhjaQQCC0+STAg8SDS9hcGkvdjEvbWVtb3MSYgoHR2V0TWVtbxIcLm1lbW9zLmFwaS52MS5HZXRNZW1vUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5NZW1vIiXaQQRuYW1lgtPkkwIYEhYvYXBpL3YxL3tuYW1lPW1lbW9zLyp9En8KClVwZGF0ZU1lbW8SHy5tZW1vcy5hcGkudjEuVXBkYXRlTWVtb1JlcXVlc3QaEi5tZW1vcy5hcGkudjEuTWVtbyI82kEQbWVtbyx1cGRhdGVfbWFza4LT5JMCIzoEbWVtbzIbL2FwaS92MS97bWVtby5uYW1lPW1lbW9zLyp9EmwKCkRlbGV0ZU1lbW8SHy5tZW1vcy5hcGkudjEuRGVsZXRlTWVtb1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiJdpBBG5hbWWC0+STAhgqFi9hcGkvdjEve25hbWU9bWVtb3MvKn0SiwEKElNldE1lbW9BdHRhY2htZW50cxInLm1lbW9zLmFwaS52MS5TZXRNZW1vQXR0YWNobWVudHNSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjTaQQRuYW1lgtPkkwInOgEqMiIvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L2F0dGFjaG1lbnRzEp0BChNMaXN0TWVtb0F0dGFjaG1lbnRzEigubWVtb3MuYXBpLnYxLkxpc3RNZW1vQXR0YWNobWVudHNSZXF1ZXN0GikubWVtb3MuYXBpLnYxLkxpc3RNZW1vQXR0YWNobWVudHNSZXNwb25zZSIx2kEEbmFtZYLT5JMCJBIiL2FwaS92MS97bmFtZT1tZW1vcy8qfS9hdHRhY2htZW50cxKFAQoQU2V0TWVtb1JlbGF0aW9ucxIlLm1lbW9zLmFwaS52MS5TZXRNZW1vUmVsYXRpb25zUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIy2kEEbmFtZYLT5JMCJToBKjIgL2FwaS92MS97bmFtZT1tZW1vcy8qfS9yZWxhdGlvbnMSlQEKEUxpc3RNZW1vUmVsYXRpb25zEiYubWVtb3MuYXBpLnYxLkxpc3RNZW1vUmVsYXRpb25zUmVxdWVzdBonLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlbGF0aW9uc1Jlc3BvbnNlIi/aQQRuYW1lgtPkkwIiEiAvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L3JlbGF0aW9ucxKQAQoRQ3JlYXRlTWVtb0NvbW1lbnQSJi5tZW1vcy5hcGkudjEuQ3JlYXRlTWVtb0NvbW1lbnRSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLk1lbW8iP9pBDG5hbWUsY29tbWVudILT5JMCKjoHY29tbWVudCIfL2FwaS92MS97bmFtZT1tZW1vcy8qfS9jb21tZW50cxKRAQoQTGlzdE1lbW9Db21tZW50cxIlLm1lbW9zLmFwaS52MS5MaXN0TWVtb0NvbW1lbnRzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0TWVtb0NvbW1lbnRzUmVzcG9uc2UiLtpBBG5hbWWC0+STAiESHy9hcGkvdjEve25hbWU9bWVtb3MvKn0vY29tbWVudHMSlQEKEUxpc3RNZW1vUmVhY3Rpb25zEiYubWVtb3MuYXBpLnYxLkxpc3RNZW1vUmVhY3Rpb25zUmVxdWVzdBonLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlYWN0aW9uc1Jlc3BvbnNlIi/aQQRuYW1lgtPkkwIiEiAvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L3JlYWN0aW9ucxKJAQoSVXBzZXJ0TWVtb1JlYWN0aW9uEicubWVtb3MuYXBpLnYxLlVwc2VydE1lbW9SZWFjdGlvblJlcXVlc3QaFi5tZW1vcy5hcGkudjEuUmVhY3Rpb24iMtpBBG5hbWWC0+STAiU6ASoiIC9hcGkvdjEve25hbWU9bWVtb3MvKn0vcmVhY3Rpb25zEogBChJEZWxldGVNZW1vUmVhY3Rpb24SJy5tZW1vcy5hcGkudjEuRGVsZXRlTWVtb1JlYWN0aW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIx2kEEbmFtZYLT5JMCJCoiL2FwaS92MS97bmFtZT1tZW1vcy8qL3JlYWN0aW9ucy8qfRKZAQoPQ3JlYXRlTWVtb1NoYXJlEiQubWVtb3MuYXBpLnYxLkNyZWF0ZU1lbW9TaGFyZVJlcXVlc3QaFy5tZW1vcy5hcGkudjEuTWVtb1NoYXJlIkfaQRFwYXJlbnQsbWVtb19zaGFyZYLT5JMCLToKbWVtb19zaGFyZSIfL2FwaS92MS97cGFyZW50PW1lbW9zLyp9L3NoYXJlcxKNAQoOTGlzdE1lbW9TaGFyZXMSIy5tZW1vcy5hcGkudjEuTGlzdE1lbW9TaGFyZXNSZXF1ZXN0GiQubWVtb3MuYXBpLnYxLkxpc3RNZW1vU2hhcmVzUmVzcG9uc2UiMNpBBnBhcmVudILT5JMCIRIfL2FwaS92MS97cGFyZW50PW1lbW9zLyp9L3NoYXJlcxJ/Cg9EZWxldGVNZW1vU2hhcmUSJC5tZW1vcy5hcGkudjEuRGVsZXRlTWVtb1NoYXJlUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIu2kEEbmFtZYLT5JMCISofL2FwaS92MS97bmFtZT1tZW1vcy8qL3NoYXJlcy8qfRJsCg5HZXRNZW1vQnlTaGFyZRIjLm1lbW9zLmFwaS52MS5HZXRNZW1vQnlTaGFyZVJlcXVlc3QaEi5tZW1vcy5hcGkudjEuTWVtbyIhgtPkkwIbEhkvYXBpL3YxL3NoYXJlcy97c2hhcmVfaWR9QqgBChBjb20ubWVtb3MuYXBpLnYxQhBNZW1vU2VydmljZVByb3RvUAFaMGdpdGh1Yi5jb20vdXNlbWVtb3MvbWVtb3MvcHJvdG8vZ2VuL2FwaS92MTthcGl2MaICA01BWKoCDE1lbW9zLkFwaS5WMcoCDE1lbW9zXEFwaVxWMeICGE1lbW9zXEFwaVxWMVxHUEJNZXRhZGF0YeoCDk1lbW9zOjpBcGk6OlYxYgZwcm90bzM", [file_api_v1_attachment_service, file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); + fileDesc("ChlhcGkvdjEvbWVtb19zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEipwIKCFJlYWN0aW9uEhQKBG5hbWUYASABKAlCBuBBA+BBCBIqCgdjcmVhdG9yGAIgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEi0KCmNvbnRlbnRfaWQYAyABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SGgoNcmVhY3Rpb25fdHlwZRgEIAEoCUID4EECEjQKC2NyZWF0ZV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDOljqQVUKFW1lbW9zLmFwaS52MS9SZWFjdGlvbhIhbWVtb3Mve21lbW99L3JlYWN0aW9ucy97cmVhY3Rpb259GgRuYW1lKglyZWFjdGlvbnMyCHJlYWN0aW9uIuoGCgRNZW1vEhEKBG5hbWUYASABKAlCA+BBCBInCgVzdGF0ZRgCIAEoDjITLm1lbW9zLmFwaS52MS5TdGF0ZUID4EECEioKB2NyZWF0b3IYAyABKAlCGeBBA/pBEwoRbWVtb3MuYXBpLnYxL1VzZXISNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQESNAoLdXBkYXRlX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQESFAoHY29udGVudBgHIAEoCUID4EECEjEKCnZpc2liaWxpdHkYCSABKA4yGC5tZW1vcy5hcGkudjEuVmlzaWJpbGl0eUID4EECEhEKBHRhZ3MYCiADKAlCA+BBAxITCgZwaW5uZWQYCyABKAhCA+BBARIyCgthdHRhY2htZW50cxgMIAMoCzIYLm1lbW9zLmFwaS52MS5BdHRhY2htZW50QgPgQQESMgoJcmVsYXRpb25zGA0gAygLMhoubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbkID4EEBEi4KCXJlYWN0aW9ucxgOIAMoCzIWLm1lbW9zLmFwaS52MS5SZWFjdGlvbkID4EEDEjIKCHByb3BlcnR5GA8gASgLMhsubWVtb3MuYXBpLnYxLk1lbW8uUHJvcGVydHlCA+BBAxIuCgZwYXJlbnQYECABKAlCGeBBA/pBEwoRbWVtb3MuYXBpLnYxL01lbW9IAIgBARIUCgdzbmlwcGV0GBEgASgJQgPgQQMSMgoIbG9jYXRpb24YEiABKAsyFi5tZW1vcy5hcGkudjEuTG9jYXRpb25CA+BBAUgBiAEBGnIKCFByb3BlcnR5EhAKCGhhc19saW5rGAEgASgIEhUKDWhhc190YXNrX2xpc3QYAiABKAgSEAoIaGFzX2NvZGUYAyABKAgSHAoUaGFzX2luY29tcGxldGVfdGFza3MYBCABKAgSDQoFdGl0bGUYBSABKAk6N+pBNAoRbWVtb3MuYXBpLnYxL01lbW8SDG1lbW9zL3ttZW1vfRoEbmFtZSoFbWVtb3MyBG1lbW9CCQoHX3BhcmVudEILCglfbG9jYXRpb25KBAgGEAdSDGRpc3BsYXlfdGltZSJTCghMb2NhdGlvbhIYCgtwbGFjZWhvbGRlchgBIAEoCUID4EEBEhUKCGxhdGl0dWRlGAIgASgBQgPgQQESFgoJbG9uZ2l0dWRlGAMgASgBQgPgQQEiUAoRQ3JlYXRlTWVtb1JlcXVlc3QSJQoEbWVtbxgBIAEoCzISLm1lbW9zLmFwaS52MS5NZW1vQgPgQQISFAoHbWVtb19pZBgCIAEoCUID4EEBIrMBChBMaXN0TWVtb3NSZXF1ZXN0EhYKCXBhZ2Vfc2l6ZRgBIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAiABKAlCA+BBARInCgVzdGF0ZRgDIAEoDjITLm1lbW9zLmFwaS52MS5TdGF0ZUID4EEBEhUKCG9yZGVyX2J5GAQgASgJQgPgQQESEwoGZmlsdGVyGAUgASgJQgPgQQESGQoMc2hvd19kZWxldGVkGAYgASgIQgPgQQEiTwoRTGlzdE1lbW9zUmVzcG9uc2USIQoFbWVtb3MYASADKAsyEi5tZW1vcy5hcGkudjEuTWVtbxIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkiOQoOR2V0TWVtb1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbyJwChFVcGRhdGVNZW1vUmVxdWVzdBIlCgRtZW1vGAEgASgLMhIubWVtb3MuYXBpLnYxLk1lbW9CA+BBAhI0Cgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBAiJQChFEZWxldGVNZW1vUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEhIKBWZvcmNlGAIgASgIQgPgQQEieAoZU2V0TWVtb0F0dGFjaG1lbnRzUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEjIKC2F0dGFjaG1lbnRzGAIgAygLMhgubWVtb3MuYXBpLnYxLkF0dGFjaG1lbnRCA+BBAiJ2ChpMaXN0TWVtb0F0dGFjaG1lbnRzUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBASJlChtMaXN0TWVtb0F0dGFjaG1lbnRzUmVzcG9uc2USLQoLYXR0YWNobWVudHMYASADKAsyGC5tZW1vcy5hcGkudjEuQXR0YWNobWVudBIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkiswIKDE1lbW9SZWxhdGlvbhIyCgRtZW1vGAEgASgLMh8ubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbi5NZW1vQgPgQQISOgoMcmVsYXRlZF9tZW1vGAIgASgLMh8ubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbi5NZW1vQgPgQQISMgoEdHlwZRgDIAEoDjIfLm1lbW9zLmFwaS52MS5NZW1vUmVsYXRpb24uVHlwZUID4EECGkUKBE1lbW8SJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIUCgdzbmlwcGV0GAIgASgJQgPgQQMiOAoEVHlwZRIUChBUWVBFX1VOU1BFQ0lGSUVEEAASDQoJUkVGRVJFTkNFEAESCwoHQ09NTUVOVBACInYKF1NldE1lbW9SZWxhdGlvbnNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SMgoJcmVsYXRpb25zGAIgAygLMhoubWVtb3MuYXBpLnYxLk1lbW9SZWxhdGlvbkID4EECInQKGExpc3RNZW1vUmVsYXRpb25zUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBASJjChlMaXN0TWVtb1JlbGF0aW9uc1Jlc3BvbnNlEi0KCXJlbGF0aW9ucxgBIAMoCzIaLm1lbW9zLmFwaS52MS5NZW1vUmVsYXRpb24SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJIoYBChhDcmVhdGVNZW1vQ29tbWVudFJlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxIoCgdjb21tZW50GAIgASgLMhIubWVtb3MuYXBpLnYxLk1lbW9CA+BBAhIXCgpjb21tZW50X2lkGAMgASgJQgPgQQEiigEKF0xpc3RNZW1vQ29tbWVudHNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBEhUKCG9yZGVyX2J5GAQgASgJQgPgQQEiagoYTGlzdE1lbW9Db21tZW50c1Jlc3BvbnNlEiEKBW1lbW9zGAEgAygLMhIubWVtb3MuYXBpLnYxLk1lbW8SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEhIKCnRvdGFsX3NpemUYAyABKAUidAoYTGlzdE1lbW9SZWFjdGlvbnNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL01lbW8SFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBInMKGUxpc3RNZW1vUmVhY3Rpb25zUmVzcG9uc2USKQoJcmVhY3Rpb25zGAEgAygLMhYubWVtb3MuYXBpLnYxLlJlYWN0aW9uEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFInMKGVVwc2VydE1lbW9SZWFjdGlvblJlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbxItCghyZWFjdGlvbhgCIAEoCzIWLm1lbW9zLmFwaS52MS5SZWFjdGlvbkID4EECIkgKGURlbGV0ZU1lbW9SZWFjdGlvblJlcXVlc3QSKwoEbmFtZRgBIAEoCUId4EEC+kEXChVtZW1vcy5hcGkudjEvUmVhY3Rpb24i6AEKCU1lbW9TaGFyZRIRCgRuYW1lGAEgASgJQgPgQQgSNAoLY3JlYXRlX3RpbWUYAiABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSOQoLZXhwaXJlX3RpbWUYAyABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQFIAIgBATpH6kFEChZtZW1vcy5hcGkudjEvTWVtb1NoYXJlEhttZW1vcy97bWVtb30vc2hhcmVzL3tzaGFyZX0qBnNoYXJlczIFc2hhcmVCDgoMX2V4cGlyZV90aW1lInUKFkNyZWF0ZU1lbW9TaGFyZVJlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9NZW1vEjAKCm1lbW9fc2hhcmUYAiABKAsyFy5tZW1vcy5hcGkudjEuTWVtb1NoYXJlQgPgQQIiQgoVTGlzdE1lbW9TaGFyZXNSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvTWVtbyJGChZMaXN0TWVtb1NoYXJlc1Jlc3BvbnNlEiwKC21lbW9fc2hhcmVzGAEgAygLMhcubWVtb3MuYXBpLnYxLk1lbW9TaGFyZSJGChZEZWxldGVNZW1vU2hhcmVSZXF1ZXN0EiwKBG5hbWUYASABKAlCHuBBAvpBGAoWbWVtb3MuYXBpLnYxL01lbW9TaGFyZSIuChVHZXRNZW1vQnlTaGFyZVJlcXVlc3QSFQoIc2hhcmVfaWQYASABKAlCA+BBAipQCgpWaXNpYmlsaXR5EhoKFlZJU0lCSUxJVFlfVU5TUEVDSUZJRUQQABILCgdQUklWQVRFEAESDQoJUFJPVEVDVEVEEAISCgoGUFVCTElDEAMy7hIKC01lbW9TZXJ2aWNlEmUKCkNyZWF0ZU1lbW8SHy5tZW1vcy5hcGkudjEuQ3JlYXRlTWVtb1JlcXVlc3QaEi5tZW1vcy5hcGkudjEuTWVtbyIi2kEEbWVtb4LT5JMCFToEbWVtbyINL2FwaS92MS9tZW1vcxJmCglMaXN0TWVtb3MSHi5tZW1vcy5hcGkudjEuTGlzdE1lbW9zUmVxdWVzdBofLm1lbW9zLmFwaS52MS5MaXN0TWVtb3NSZXNwb25zZSIY2kEAgtPkkwIPEg0vYXBpL3YxL21lbW9zEmIKB0dldE1lbW8SHC5tZW1vcy5hcGkudjEuR2V0TWVtb1JlcXVlc3QaEi5tZW1vcy5hcGkudjEuTWVtbyIl2kEEbmFtZYLT5JMCGBIWL2FwaS92MS97bmFtZT1tZW1vcy8qfRJ/CgpVcGRhdGVNZW1vEh8ubWVtb3MuYXBpLnYxLlVwZGF0ZU1lbW9SZXF1ZXN0GhIubWVtb3MuYXBpLnYxLk1lbW8iPNpBEG1lbW8sdXBkYXRlX21hc2uC0+STAiM6BG1lbW8yGy9hcGkvdjEve21lbW8ubmFtZT1tZW1vcy8qfRJsCgpEZWxldGVNZW1vEh8ubWVtb3MuYXBpLnYxLkRlbGV0ZU1lbW9SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IiXaQQRuYW1lgtPkkwIYKhYvYXBpL3YxL3tuYW1lPW1lbW9zLyp9EosBChJTZXRNZW1vQXR0YWNobWVudHMSJy5tZW1vcy5hcGkudjEuU2V0TWVtb0F0dGFjaG1lbnRzUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSI02kEEbmFtZYLT5JMCJzoBKjIiL2FwaS92MS97bmFtZT1tZW1vcy8qfS9hdHRhY2htZW50cxKdAQoTTGlzdE1lbW9BdHRhY2htZW50cxIoLm1lbW9zLmFwaS52MS5MaXN0TWVtb0F0dGFjaG1lbnRzUmVxdWVzdBopLm1lbW9zLmFwaS52MS5MaXN0TWVtb0F0dGFjaG1lbnRzUmVzcG9uc2UiMdpBBG5hbWWC0+STAiQSIi9hcGkvdjEve25hbWU9bWVtb3MvKn0vYXR0YWNobWVudHMShQEKEFNldE1lbW9SZWxhdGlvbnMSJS5tZW1vcy5hcGkudjEuU2V0TWVtb1JlbGF0aW9uc1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiMtpBBG5hbWWC0+STAiU6ASoyIC9hcGkvdjEve25hbWU9bWVtb3MvKn0vcmVsYXRpb25zEpUBChFMaXN0TWVtb1JlbGF0aW9ucxImLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlbGF0aW9uc1JlcXVlc3QaJy5tZW1vcy5hcGkudjEuTGlzdE1lbW9SZWxhdGlvbnNSZXNwb25zZSIv2kEEbmFtZYLT5JMCIhIgL2FwaS92MS97bmFtZT1tZW1vcy8qfS9yZWxhdGlvbnMSkAEKEUNyZWF0ZU1lbW9Db21tZW50EiYubWVtb3MuYXBpLnYxLkNyZWF0ZU1lbW9Db21tZW50UmVxdWVzdBoSLm1lbW9zLmFwaS52MS5NZW1vIj/aQQxuYW1lLGNvbW1lbnSC0+STAio6B2NvbW1lbnQiHy9hcGkvdjEve25hbWU9bWVtb3MvKn0vY29tbWVudHMSkQEKEExpc3RNZW1vQ29tbWVudHMSJS5tZW1vcy5hcGkudjEuTGlzdE1lbW9Db21tZW50c1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdE1lbW9Db21tZW50c1Jlc3BvbnNlIi7aQQRuYW1lgtPkkwIhEh8vYXBpL3YxL3tuYW1lPW1lbW9zLyp9L2NvbW1lbnRzEpUBChFMaXN0TWVtb1JlYWN0aW9ucxImLm1lbW9zLmFwaS52MS5MaXN0TWVtb1JlYWN0aW9uc1JlcXVlc3QaJy5tZW1vcy5hcGkudjEuTGlzdE1lbW9SZWFjdGlvbnNSZXNwb25zZSIv2kEEbmFtZYLT5JMCIhIgL2FwaS92MS97bmFtZT1tZW1vcy8qfS9yZWFjdGlvbnMSiQEKElVwc2VydE1lbW9SZWFjdGlvbhInLm1lbW9zLmFwaS52MS5VcHNlcnRNZW1vUmVhY3Rpb25SZXF1ZXN0GhYubWVtb3MuYXBpLnYxLlJlYWN0aW9uIjLaQQRuYW1lgtPkkwIlOgEqIiAvYXBpL3YxL3tuYW1lPW1lbW9zLyp9L3JlYWN0aW9ucxKIAQoSRGVsZXRlTWVtb1JlYWN0aW9uEicubWVtb3MuYXBpLnYxLkRlbGV0ZU1lbW9SZWFjdGlvblJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiMdpBBG5hbWWC0+STAiQqIi9hcGkvdjEve25hbWU9bWVtb3MvKi9yZWFjdGlvbnMvKn0SmQEKD0NyZWF0ZU1lbW9TaGFyZRIkLm1lbW9zLmFwaS52MS5DcmVhdGVNZW1vU2hhcmVSZXF1ZXN0GhcubWVtb3MuYXBpLnYxLk1lbW9TaGFyZSJH2kERcGFyZW50LG1lbW9fc2hhcmWC0+STAi06Cm1lbW9fc2hhcmUiHy9hcGkvdjEve3BhcmVudD1tZW1vcy8qfS9zaGFyZXMSjQEKDkxpc3RNZW1vU2hhcmVzEiMubWVtb3MuYXBpLnYxLkxpc3RNZW1vU2hhcmVzUmVxdWVzdBokLm1lbW9zLmFwaS52MS5MaXN0TWVtb1NoYXJlc1Jlc3BvbnNlIjDaQQZwYXJlbnSC0+STAiESHy9hcGkvdjEve3BhcmVudD1tZW1vcy8qfS9zaGFyZXMSfwoPRGVsZXRlTWVtb1NoYXJlEiQubWVtb3MuYXBpLnYxLkRlbGV0ZU1lbW9TaGFyZVJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiLtpBBG5hbWWC0+STAiEqHy9hcGkvdjEve25hbWU9bWVtb3MvKi9zaGFyZXMvKn0SbAoOR2V0TWVtb0J5U2hhcmUSIy5tZW1vcy5hcGkudjEuR2V0TWVtb0J5U2hhcmVSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLk1lbW8iIYLT5JMCGxIZL2FwaS92MS9zaGFyZXMve3NoYXJlX2lkfUKoAQoQY29tLm1lbW9zLmFwaS52MUIQTWVtb1NlcnZpY2VQcm90b1ABWjBnaXRodWIuY29tL3VzZW1lbW9zL21lbW9zL3Byb3RvL2dlbi9hcGkvdjE7YXBpdjGiAgNNQViqAgxNZW1vcy5BcGkuVjHKAgxNZW1vc1xBcGlcVjHiAhhNZW1vc1xBcGlcVjFcR1BCTWV0YWRhdGHqAg5NZW1vczo6QXBpOjpWMWIGcHJvdG8z", [file_api_v1_attachment_service, file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); /** * @generated from message memos.api.v1.Reaction @@ -63,7 +63,7 @@ export type Reaction = Message<"memos.api.v1.Reaction"> & { * * @generated from field: google.protobuf.Timestamp create_time = 5; */ - createTime?: Timestamp; + createTime?: Timestamp | undefined; }; /** @@ -106,7 +106,7 @@ export type Memo = Message<"memos.api.v1.Memo"> & { * * @generated from field: google.protobuf.Timestamp create_time = 4; */ - createTime?: Timestamp; + createTime?: Timestamp | undefined; /** * The last update timestamp. @@ -114,14 +114,7 @@ export type Memo = Message<"memos.api.v1.Memo"> & { * * @generated from field: google.protobuf.Timestamp update_time = 5; */ - updateTime?: Timestamp; - - /** - * The display timestamp of the memo. - * - * @generated from field: google.protobuf.Timestamp display_time = 6; - */ - displayTime?: Timestamp; + updateTime?: Timestamp | undefined; /** * Required. The content of the memo in Markdown format. @@ -177,7 +170,7 @@ export type Memo = Message<"memos.api.v1.Memo"> & { * * @generated from field: memos.api.v1.Memo.Property property = 15; */ - property?: Memo_Property; + property?: Memo_Property | undefined; /** * Output only. The name of the parent memo. @@ -185,7 +178,7 @@ export type Memo = Message<"memos.api.v1.Memo"> & { * * @generated from field: optional string parent = 16; */ - parent?: string; + parent?: string | undefined; /** * Output only. The snippet of the memo content. Plain text only. @@ -199,7 +192,7 @@ export type Memo = Message<"memos.api.v1.Memo"> & { * * @generated from field: optional memos.api.v1.Location location = 18; */ - location?: Location; + location?: Location | undefined; }; /** @@ -292,7 +285,7 @@ export type CreateMemoRequest = Message<"memos.api.v1.CreateMemoRequest"> & { * * @generated from field: memos.api.v1.Memo memo = 1; */ - memo?: Memo; + memo?: Memo | undefined; /** * Optional. The memo ID to use for this memo. @@ -342,10 +335,10 @@ export type ListMemosRequest = Message<"memos.api.v1.ListMemosRequest"> & { /** * Optional. The order to sort results by. - * Default to "display_time desc". + * Default to "create_time desc". * Supports comma-separated list of fields following AIP-132. - * Example: "pinned desc, display_time desc" or "create_time asc" - * Supported fields: pinned, display_time, create_time, update_time, name + * Example: "pinned desc, create_time desc" or "update_time asc" + * Supported fields: pinned, create_time, update_time, name * * @generated from field: string order_by = 4; */ @@ -432,14 +425,14 @@ export type UpdateMemoRequest = Message<"memos.api.v1.UpdateMemoRequest"> & { * * @generated from field: memos.api.v1.Memo memo = 1; */ - memo?: Memo; + memo?: Memo | undefined; /** * Required. The list of fields to update. * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** @@ -572,14 +565,14 @@ export type MemoRelation = Message<"memos.api.v1.MemoRelation"> & { * * @generated from field: memos.api.v1.MemoRelation.Memo memo = 1; */ - memo?: MemoRelation_Memo; + memo?: MemoRelation_Memo | undefined; /** * The related memo. * * @generated from field: memos.api.v1.MemoRelation.Memo related_memo = 2; */ - relatedMemo?: MemoRelation_Memo; + relatedMemo?: MemoRelation_Memo | undefined; /** * @generated from field: memos.api.v1.MemoRelation.Type type = 3; @@ -755,7 +748,7 @@ export type CreateMemoCommentRequest = Message<"memos.api.v1.CreateMemoCommentRe * * @generated from field: memos.api.v1.Memo comment = 2; */ - comment?: Memo; + comment?: Memo | undefined; /** * Optional. The comment ID to use. @@ -930,7 +923,7 @@ export type UpsertMemoReactionRequest = Message<"memos.api.v1.UpsertMemoReaction * * @generated from field: memos.api.v1.Reaction reaction = 2; */ - reaction?: Reaction; + reaction?: Reaction | undefined; }; /** @@ -979,7 +972,7 @@ export type MemoShare = Message<"memos.api.v1.MemoShare"> & { * * @generated from field: google.protobuf.Timestamp create_time = 2; */ - createTime?: Timestamp; + createTime?: Timestamp | undefined; /** * Optional. When set, the share link stops working after this time. @@ -987,7 +980,7 @@ export type MemoShare = Message<"memos.api.v1.MemoShare"> & { * * @generated from field: optional google.protobuf.Timestamp expire_time = 3; */ - expireTime?: Timestamp; + expireTime?: Timestamp | undefined; }; /** @@ -1014,7 +1007,7 @@ export type CreateMemoShareRequest = Message<"memos.api.v1.CreateMemoShareReques * * @generated from field: memos.api.v1.MemoShare memo_share = 2; */ - memoShare?: MemoShare; + memoShare?: MemoShare | undefined; }; /** diff --git a/web/src/types/proto/api/v1/shortcut_service_pb.ts b/web/src/types/proto/api/v1/shortcut_service_pb.ts index 8b87635b4..4121a4941 100644 --- a/web/src/types/proto/api/v1/shortcut_service_pb.ts +++ b/web/src/types/proto/api/v1/shortcut_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/shortcut_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -128,7 +128,7 @@ export type CreateShortcutRequest = Message<"memos.api.v1.CreateShortcutRequest" * * @generated from field: memos.api.v1.Shortcut shortcut = 2; */ - shortcut?: Shortcut; + shortcut?: Shortcut | undefined; /** * Optional. If set, validate the request, but do not actually create the shortcut. @@ -154,14 +154,14 @@ export type UpdateShortcutRequest = Message<"memos.api.v1.UpdateShortcutRequest" * * @generated from field: memos.api.v1.Shortcut shortcut = 1; */ - shortcut?: Shortcut; + shortcut?: Shortcut | undefined; /** * Optional. The list of fields to update. * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** diff --git a/web/src/types/proto/api/v1/user_service_pb.ts b/web/src/types/proto/api/v1/user_service_pb.ts index 4ea90f43f..f6625f7c9 100644 --- a/web/src/types/proto/api/v1/user_service_pb.ts +++ b/web/src/types/proto/api/v1/user_service_pb.ts @@ -1,4 +1,4 @@ -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file api/v1/user_service.proto (package memos.api.v1, syntax proto3) /* eslint-disable */ @@ -18,7 +18,7 @@ import type { Message } from "@bufbuild/protobuf"; * Describes the file api/v1/user_service.proto. */ export const file_api_v1_user_service: GenFile = /*@__PURE__*/ - fileDesc("ChlhcGkvdjEvdXNlcl9zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi1gMKBFVzZXISEQoEbmFtZRgBIAEoCUID4EEIEioKBHJvbGUYAiABKA4yFy5tZW1vcy5hcGkudjEuVXNlci5Sb2xlQgPgQQISFQoIdXNlcm5hbWUYAyABKAlCA+BBAhISCgVlbWFpbBgEIAEoCUID4EEBEhkKDGRpc3BsYXlfbmFtZRgFIAEoCUID4EEBEhcKCmF2YXRhcl91cmwYBiABKAlCA+BBARIYCgtkZXNjcmlwdGlvbhgHIAEoCUID4EEBEhUKCHBhc3N3b3JkGAggASgJQgPgQQQSJwoFc3RhdGUYCSABKA4yEy5tZW1vcy5hcGkudjEuU3RhdGVCA+BBAhI0CgtjcmVhdGVfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyIxCgRSb2xlEhQKEFJPTEVfVU5TUEVDSUZJRUQQABIJCgVBRE1JThACEggKBFVTRVIQAzo36kE0ChFtZW1vcy5hcGkudjEvVXNlchIMdXNlcnMve3VzZXJ9GgRuYW1lKgV1c2VyczIEdXNlciJzChBMaXN0VXNlcnNSZXF1ZXN0EhYKCXBhZ2Vfc2l6ZRgBIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAiABKAlCA+BBARITCgZmaWx0ZXIYAyABKAlCA+BBARIZCgxzaG93X2RlbGV0ZWQYBCABKAhCA+BBASJjChFMaXN0VXNlcnNSZXNwb25zZRIhCgV1c2VycxgBIAMoCzISLm1lbW9zLmFwaS52MS5Vc2VyEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIikKFEJhdGNoR2V0VXNlcnNSZXF1ZXN0EhEKCXVzZXJuYW1lcxgBIAMoCSI6ChVCYXRjaEdldFVzZXJzUmVzcG9uc2USIQoFdXNlcnMYASADKAsyEi5tZW1vcy5hcGkudjEuVXNlciJtCg5HZXRVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEjIKCXJlYWRfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBASKIAQoRQ3JlYXRlVXNlclJlcXVlc3QSKAoEdXNlchgBIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyQgbgQQLgQQQSFAoHdXNlcl9pZBgCIAEoCUID4EEBEhoKDXZhbGlkYXRlX29ubHkYAyABKAhCA+BBARIXCgpyZXF1ZXN0X2lkGAQgASgJQgPgQQEijAEKEVVwZGF0ZVVzZXJSZXF1ZXN0EiUKBHVzZXIYASABKAsyEi5tZW1vcy5hcGkudjEuVXNlckID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECEhoKDWFsbG93X21pc3NpbmcYAyABKAhCA+BBASJQChFEZWxldGVVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhIKBWZvcmNlGAIgASgIQgPgQQEi2AMKCVVzZXJTdGF0cxIRCgRuYW1lGAEgASgJQgPgQQgSOwoXbWVtb19kaXNwbGF5X3RpbWVzdGFtcHMYAiADKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wEj4KD21lbW9fdHlwZV9zdGF0cxgDIAEoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMuTWVtb1R5cGVTdGF0cxI4Cgl0YWdfY291bnQYBCADKAsyJS5tZW1vcy5hcGkudjEuVXNlclN0YXRzLlRhZ0NvdW50RW50cnkSFAoMcGlubmVkX21lbW9zGAUgAygJEhgKEHRvdGFsX21lbW9fY291bnQYBiABKAUaXwoNTWVtb1R5cGVTdGF0cxISCgpsaW5rX2NvdW50GAEgASgFEhIKCmNvZGVfY291bnQYAiABKAUSEgoKdG9kb19jb3VudBgDIAEoBRISCgp1bmRvX2NvdW50GAQgASgFGi8KDVRhZ0NvdW50RW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgFOgI4ATo/6kE8ChZtZW1vcy5hcGkudjEvVXNlclN0YXRzEgx1c2Vycy97dXNlcn0qCXVzZXJTdGF0czIJdXNlclN0YXRzIj4KE0dldFVzZXJTdGF0c1JlcXVlc3QSJwoEbmFtZRgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlciIZChdMaXN0QWxsVXNlclN0YXRzUmVxdWVzdCJCChhMaXN0QWxsVXNlclN0YXRzUmVzcG9uc2USJgoFc3RhdHMYASADKAsyFy5tZW1vcy5hcGkudjEuVXNlclN0YXRzIuQDCgtVc2VyU2V0dGluZxIRCgRuYW1lGAEgASgJQgPgQQgSQwoPZ2VuZXJhbF9zZXR0aW5nGAIgASgLMigubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nLkdlbmVyYWxTZXR0aW5nSAASRQoQd2ViaG9va3Nfc2V0dGluZxgFIAEoCzIpLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZy5XZWJob29rc1NldHRpbmdIABpXCg5HZW5lcmFsU2V0dGluZxITCgZsb2NhbGUYASABKAlCA+BBARIcCg9tZW1vX3Zpc2liaWxpdHkYAyABKAlCA+BBARISCgV0aGVtZRgEIAEoCUID4EEBGj4KD1dlYmhvb2tzU2V0dGluZxIrCgh3ZWJob29rcxgBIAMoCzIZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9vayI1CgNLZXkSEwoPS0VZX1VOU1BFQ0lGSUVEEAASCwoHR0VORVJBTBABEgwKCFdFQkhPT0tTEAQ6XepBWgoYbWVtb3MuYXBpLnYxL1VzZXJTZXR0aW5nEiN1c2Vycy97dXNlcm5hbWV9L3NldHRpbmdzL3tzZXR0aW5nfSoMdXNlclNldHRpbmdzMgt1c2VyU2V0dGluZ0IHCgV2YWx1ZSJHChVHZXRVc2VyU2V0dGluZ1JlcXVlc3QSLgoEbmFtZRgBIAEoCUIg4EEC+kEaChhtZW1vcy5hcGkudjEvVXNlclNldHRpbmcigQEKGFVwZGF0ZVVzZXJTZXR0aW5nUmVxdWVzdBIvCgdzZXR0aW5nGAEgASgLMhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQIidQoXTGlzdFVzZXJTZXR0aW5nc1JlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBASJ0ChhMaXN0VXNlclNldHRpbmdzUmVzcG9uc2USKwoIc2V0dGluZ3MYASADKAsyGS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmcSFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEhIKCnRvdGFsX3NpemUYAyABKAUi6gEKDkxpbmtlZElkZW50aXR5EhEKBG5hbWUYASABKAlCA+BBCBI3CghpZHBfbmFtZRgCIAEoCUIl4EED+kEfCh1tZW1vcy5hcGkudjEvSWRlbnRpdHlQcm92aWRlchIXCgpleHRlcm5fdWlkGAMgASgJQgPgQQM6c+pBcAobbWVtb3MuYXBpLnYxL0xpbmtlZElkZW50aXR5Ei91c2Vycy97dXNlcn0vbGlua2VkSWRlbnRpdGllcy97bGlua2VkX2lkZW50aXR5fSoQbGlua2VkSWRlbnRpdGllczIObGlua2VkSWRlbnRpdHkiSAobTGlzdExpbmtlZElkZW50aXRpZXNSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlciJXChxMaXN0TGlua2VkSWRlbnRpdGllc1Jlc3BvbnNlEjcKEWxpbmtlZF9pZGVudGl0aWVzGAEgAygLMhwubWVtb3MuYXBpLnYxLkxpbmtlZElkZW50aXR5IssBChtDcmVhdGVMaW5rZWRJZGVudGl0eVJlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEjcKCGlkcF9uYW1lGAIgASgJQiXgQQL6QR8KHW1lbW9zLmFwaS52MS9JZGVudGl0eVByb3ZpZGVyEhEKBGNvZGUYAyABKAlCA+BBAhIZCgxyZWRpcmVjdF91cmkYBCABKAlCA+BBAhIaCg1jb2RlX3ZlcmlmaWVyGAUgASgJQgPgQQEiTQoYR2V0TGlua2VkSWRlbnRpdHlSZXF1ZXN0EjEKBG5hbWUYASABKAlCI+BBAvpBHQobbWVtb3MuYXBpLnYxL0xpbmtlZElkZW50aXR5IlAKG0RlbGV0ZUxpbmtlZElkZW50aXR5UmVxdWVzdBIxCgRuYW1lGAEgASgJQiPgQQL6QR0KG21lbW9zLmFwaS52MS9MaW5rZWRJZGVudGl0eSLyAgoTUGVyc29uYWxBY2Nlc3NUb2tlbhIRCgRuYW1lGAEgASgJQgPgQQgSGAoLZGVzY3JpcHRpb24YAiABKAlCA+BBARIzCgpjcmVhdGVkX2F0GAMgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjMKCmV4cGlyZXNfYXQYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQESNQoMbGFzdF91c2VkX2F0GAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDOowB6kGIAQogbWVtb3MuYXBpLnYxL1BlcnNvbmFsQWNjZXNzVG9rZW4SOXVzZXJzL3t1c2VyfS9wZXJzb25hbEFjY2Vzc1Rva2Vucy97cGVyc29uYWxfYWNjZXNzX3Rva2VufSoUcGVyc29uYWxBY2Nlc3NUb2tlbnMyE3BlcnNvbmFsQWNjZXNzVG9rZW4ifQofTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBIpIBCiBMaXN0UGVyc29uYWxBY2Nlc3NUb2tlbnNSZXNwb25zZRJBChZwZXJzb25hbF9hY2Nlc3NfdG9rZW5zGAEgAygLMiEubWVtb3MuYXBpLnYxLlBlcnNvbmFsQWNjZXNzVG9rZW4SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJEhIKCnRvdGFsX3NpemUYAyABKAUihQEKIENyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIYCgtkZXNjcmlwdGlvbhgCIAEoCUID4EEBEhwKD2V4cGlyZXNfaW5fZGF5cxgDIAEoBUID4EEBInQKIUNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXNwb25zZRJAChVwZXJzb25hbF9hY2Nlc3NfdG9rZW4YASABKAsyIS5tZW1vcy5hcGkudjEuUGVyc29uYWxBY2Nlc3NUb2tlbhINCgV0b2tlbhgCIAEoCSJaCiBEZWxldGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVxdWVzdBI2CgRuYW1lGAEgASgJQijgQQL6QSIKIG1lbW9zLmFwaS52MS9QZXJzb25hbEFjY2Vzc1Rva2VuIqoBCgtVc2VyV2ViaG9vaxIMCgRuYW1lGAEgASgJEgsKA3VybBgCIAEoCRIUCgxkaXNwbGF5X25hbWUYAyABKAkSNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNAoLdXBkYXRlX3RpbWUYBSABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMiLgoXTGlzdFVzZXJXZWJob29rc1JlcXVlc3QSEwoGcGFyZW50GAEgASgJQgPgQQIiRwoYTGlzdFVzZXJXZWJob29rc1Jlc3BvbnNlEisKCHdlYmhvb2tzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rImAKGENyZWF0ZVVzZXJXZWJob29rUmVxdWVzdBITCgZwYXJlbnQYASABKAlCA+BBAhIvCgd3ZWJob29rGAIgASgLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rQgPgQQIifAoYVXBkYXRlVXNlcldlYmhvb2tSZXF1ZXN0Ei8KB3dlYmhvb2sYASABKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2tCA+BBAhIvCgt1cGRhdGVfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2siLQoYRGVsZXRlVXNlcldlYmhvb2tSZXF1ZXN0EhEKBG5hbWUYASABKAlCA+BBAiKiBwoQVXNlck5vdGlmaWNhdGlvbhIUCgRuYW1lGAEgASgJQgbgQQPgQQgSKQoGc2VuZGVyGAIgASgJQhngQQP6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEiwKC3NlbmRlcl91c2VyGAggASgLMhIubWVtb3MuYXBpLnYxLlVzZXJCA+BBAxI6CgZzdGF0dXMYAyABKA4yJS5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbi5TdGF0dXNCA+BBARI0CgtjcmVhdGVfdGltZRgEIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI2CgR0eXBlGAUgASgOMiMubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb24uVHlwZUID4EEDEk4KDG1lbW9fY29tbWVudBgGIAEoCzIxLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uLk1lbW9Db21tZW50UGF5bG9hZEID4EEDSAASTgoMbWVtb19tZW50aW9uGAcgASgLMjEubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb24uTWVtb01lbnRpb25QYXlsb2FkQgPgQQNIABpsChJNZW1vQ29tbWVudFBheWxvYWQSDAoEbWVtbxgBIAEoCRIUCgxyZWxhdGVkX21lbW8YAiABKAkSFAoMbWVtb19zbmlwcGV0GAMgASgJEhwKFHJlbGF0ZWRfbWVtb19zbmlwcGV0GAQgASgJGmwKEk1lbW9NZW50aW9uUGF5bG9hZBIMCgRtZW1vGAEgASgJEhQKDHJlbGF0ZWRfbWVtbxgCIAEoCRIUCgxtZW1vX3NuaXBwZXQYAyABKAkSHAoUcmVsYXRlZF9tZW1vX3NuaXBwZXQYBCABKAkiOgoGU3RhdHVzEhYKElNUQVRVU19VTlNQRUNJRklFRBAAEgoKBlVOUkVBRBABEgwKCEFSQ0hJVkVEEAIiQAoEVHlwZRIUChBUWVBFX1VOU1BFQ0lGSUVEEAASEAoMTUVNT19DT01NRU5UEAESEAoMTUVNT19NRU5USU9OEAI6cOpBbQodbWVtb3MuYXBpLnYxL1VzZXJOb3RpZmljYXRpb24SKXVzZXJzL3t1c2VyfS9ub3RpZmljYXRpb25zL3tub3RpZmljYXRpb259GgRuYW1lKg1ub3RpZmljYXRpb25zMgxub3RpZmljYXRpb25CCQoHcGF5bG9hZCKPAQocTGlzdFVzZXJOb3RpZmljYXRpb25zUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISFgoJcGFnZV9zaXplGAIgASgFQgPgQQESFwoKcGFnZV90b2tlbhgDIAEoCUID4EEBEhMKBmZpbHRlchgEIAEoCUID4EEBIm8KHUxpc3RVc2VyTm90aWZpY2F0aW9uc1Jlc3BvbnNlEjUKDW5vdGlmaWNhdGlvbnMYASADKAsyHi5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbhIXCg9uZXh0X3BhZ2VfdG9rZW4YAiABKAkikAEKHVVwZGF0ZVVzZXJOb3RpZmljYXRpb25SZXF1ZXN0EjkKDG5vdGlmaWNhdGlvbhgBIAEoCzIeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uQgPgQQISNAoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrQgPgQQIiVAodRGVsZXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QSMwoEbmFtZRgBIAEoCUIl4EEC+kEfCh1tZW1vcy5hcGkudjEvVXNlck5vdGlmaWNhdGlvbjKCHQoLVXNlclNlcnZpY2USYwoJTGlzdFVzZXJzEh4ubWVtb3MuYXBpLnYxLkxpc3RVc2Vyc1JlcXVlc3QaHy5tZW1vcy5hcGkudjEuTGlzdFVzZXJzUmVzcG9uc2UiFYLT5JMCDxINL2FwaS92MS91c2VycxJ7Cg1CYXRjaEdldFVzZXJzEiIubWVtb3MuYXBpLnYxLkJhdGNoR2V0VXNlcnNSZXF1ZXN0GiMubWVtb3MuYXBpLnYxLkJhdGNoR2V0VXNlcnNSZXNwb25zZSIhgtPkkwIbOgEqIhYvYXBpL3YxL3VzZXJzOmJhdGNoR2V0EmIKB0dldFVzZXISHC5tZW1vcy5hcGkudjEuR2V0VXNlclJlcXVlc3QaEi5tZW1vcy5hcGkudjEuVXNlciIl2kEEbmFtZYLT5JMCGBIWL2FwaS92MS97bmFtZT11c2Vycy8qfRJlCgpDcmVhdGVVc2VyEh8ubWVtb3MuYXBpLnYxLkNyZWF0ZVVzZXJSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLlVzZXIiItpBBHVzZXKC0+STAhU6BHVzZXIiDS9hcGkvdjEvdXNlcnMSfwoKVXBkYXRlVXNlchIfLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5Vc2VyIjzaQRB1c2VyLHVwZGF0ZV9tYXNrgtPkkwIjOgR1c2VyMhsvYXBpL3YxL3t1c2VyLm5hbWU9dXNlcnMvKn0SbAoKRGVsZXRlVXNlchIfLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIl2kEEbmFtZYLT5JMCGCoWL2FwaS92MS97bmFtZT11c2Vycy8qfRJ+ChBMaXN0QWxsVXNlclN0YXRzEiUubWVtb3MuYXBpLnYxLkxpc3RBbGxVc2VyU3RhdHNSZXF1ZXN0GiYubWVtb3MuYXBpLnYxLkxpc3RBbGxVc2VyU3RhdHNSZXNwb25zZSIbgtPkkwIVEhMvYXBpL3YxL3VzZXJzOnN0YXRzEnoKDEdldFVzZXJTdGF0cxIhLm1lbW9zLmFwaS52MS5HZXRVc2VyU3RhdHNSZXF1ZXN0GhcubWVtb3MuYXBpLnYxLlVzZXJTdGF0cyIu2kEEbmFtZYLT5JMCIRIfL2FwaS92MS97bmFtZT11c2Vycy8qfTpnZXRTdGF0cxKCAQoOR2V0VXNlclNldHRpbmcSIy5tZW1vcy5hcGkudjEuR2V0VXNlclNldHRpbmdSZXF1ZXN0GhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nIjDaQQRuYW1lgtPkkwIjEiEvYXBpL3YxL3tuYW1lPXVzZXJzLyovc2V0dGluZ3MvKn0SqAEKEVVwZGF0ZVVzZXJTZXR0aW5nEiYubWVtb3MuYXBpLnYxLlVwZGF0ZVVzZXJTZXR0aW5nUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZyJQ2kETc2V0dGluZyx1cGRhdGVfbWFza4LT5JMCNDoHc2V0dGluZzIpL2FwaS92MS97c2V0dGluZy5uYW1lPXVzZXJzLyovc2V0dGluZ3MvKn0SlQEKEExpc3RVc2VyU2V0dGluZ3MSJS5tZW1vcy5hcGkudjEuTGlzdFVzZXJTZXR0aW5nc1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdFVzZXJTZXR0aW5nc1Jlc3BvbnNlIjLaQQZwYXJlbnSC0+STAiMSIS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9zZXR0aW5ncxKpAQoUTGlzdExpbmtlZElkZW50aXRpZXMSKS5tZW1vcy5hcGkudjEuTGlzdExpbmtlZElkZW50aXRpZXNSZXF1ZXN0GioubWVtb3MuYXBpLnYxLkxpc3RMaW5rZWRJZGVudGl0aWVzUmVzcG9uc2UiOtpBBnBhcmVudILT5JMCKxIpL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L2xpbmtlZElkZW50aXRpZXMSpwEKFENyZWF0ZUxpbmtlZElkZW50aXR5EikubWVtb3MuYXBpLnYxLkNyZWF0ZUxpbmtlZElkZW50aXR5UmVxdWVzdBocLm1lbW9zLmFwaS52MS5MaW5rZWRJZGVudGl0eSJG2kEPcGFyZW50LGlkcF9uYW1lgtPkkwIuOgEqIikvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vbGlua2VkSWRlbnRpdGllcxKTAQoRR2V0TGlua2VkSWRlbnRpdHkSJi5tZW1vcy5hcGkudjEuR2V0TGlua2VkSWRlbnRpdHlSZXF1ZXN0GhwubWVtb3MuYXBpLnYxLkxpbmtlZElkZW50aXR5IjjaQQRuYW1lgtPkkwIrEikvYXBpL3YxL3tuYW1lPXVzZXJzLyovbGlua2VkSWRlbnRpdGllcy8qfRKTAQoURGVsZXRlTGlua2VkSWRlbnRpdHkSKS5tZW1vcy5hcGkudjEuRGVsZXRlTGlua2VkSWRlbnRpdHlSZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjjaQQRuYW1lgtPkkwIrKikvYXBpL3YxL3tuYW1lPXVzZXJzLyovbGlua2VkSWRlbnRpdGllcy8qfRK5AQoYTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zEi0ubWVtb3MuYXBpLnYxLkxpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1JlcXVlc3QaLi5tZW1vcy5hcGkudjEuTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zUmVzcG9uc2UiPtpBBnBhcmVudILT5JMCLxItL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3BlcnNvbmFsQWNjZXNzVG9rZW5zErYBChlDcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuEi4ubWVtb3MuYXBpLnYxLkNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0Gi8ubWVtb3MuYXBpLnYxLkNyZWF0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXNwb25zZSI4gtPkkwIyOgEqIi0vYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vcGVyc29uYWxBY2Nlc3NUb2tlbnMSoQEKGURlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW4SLi5tZW1vcy5hcGkudjEuRGVsZXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiPNpBBG5hbWWC0+STAi8qLS9hcGkvdjEve25hbWU9dXNlcnMvKi9wZXJzb25hbEFjY2Vzc1Rva2Vucy8qfRKVAQoQTGlzdFVzZXJXZWJob29rcxIlLm1lbW9zLmFwaS52MS5MaXN0VXNlcldlYmhvb2tzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0VXNlcldlYmhvb2tzUmVzcG9uc2UiMtpBBnBhcmVudILT5JMCIxIhL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3dlYmhvb2tzEpsBChFDcmVhdGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5DcmVhdGVVc2VyV2ViaG9va1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siQ9pBDnBhcmVudCx3ZWJob29rgtPkkwIsOgd3ZWJob29rIiEvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vd2ViaG9va3MSqAEKEVVwZGF0ZVVzZXJXZWJob29rEiYubWVtb3MuYXBpLnYxLlVwZGF0ZVVzZXJXZWJob29rUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9vayJQ2kETd2ViaG9vayx1cGRhdGVfbWFza4LT5JMCNDoHd2ViaG9vazIpL2FwaS92MS97d2ViaG9vay5uYW1lPXVzZXJzLyovd2ViaG9va3MvKn0ShQEKEURlbGV0ZVVzZXJXZWJob29rEiYubWVtb3MuYXBpLnYxLkRlbGV0ZVVzZXJXZWJob29rUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSIw2kEEbmFtZYLT5JMCIyohL2FwaS92MS97bmFtZT11c2Vycy8qL3dlYmhvb2tzLyp9EqkBChVMaXN0VXNlck5vdGlmaWNhdGlvbnMSKi5tZW1vcy5hcGkudjEuTGlzdFVzZXJOb3RpZmljYXRpb25zUmVxdWVzdBorLm1lbW9zLmFwaS52MS5MaXN0VXNlck5vdGlmaWNhdGlvbnNSZXNwb25zZSI32kEGcGFyZW50gtPkkwIoEiYvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vbm90aWZpY2F0aW9ucxLLAQoWVXBkYXRlVXNlck5vdGlmaWNhdGlvbhIrLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBoeLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uImTaQRhub3RpZmljYXRpb24sdXBkYXRlX21hc2uC0+STAkM6DG5vdGlmaWNhdGlvbjIzL2FwaS92MS97bm90aWZpY2F0aW9uLm5hbWU9dXNlcnMvKi9ub3RpZmljYXRpb25zLyp9EpQBChZEZWxldGVVc2VyTm90aWZpY2F0aW9uEisubWVtb3MuYXBpLnYxLkRlbGV0ZVVzZXJOb3RpZmljYXRpb25SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjXaQQRuYW1lgtPkkwIoKiYvYXBpL3YxL3tuYW1lPXVzZXJzLyovbm90aWZpY2F0aW9ucy8qfUKoAQoQY29tLm1lbW9zLmFwaS52MUIQVXNlclNlcnZpY2VQcm90b1ABWjBnaXRodWIuY29tL3VzZW1lbW9zL21lbW9zL3Byb3RvL2dlbi9hcGkvdjE7YXBpdjGiAgNNQViqAgxNZW1vcy5BcGkuVjHKAgxNZW1vc1xBcGlcVjHiAhhNZW1vc1xBcGlcVjFcR1BCTWV0YWRhdGHqAg5NZW1vczo6QXBpOjpWMWIGcHJvdG8z", [file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); + fileDesc("ChlhcGkvdjEvdXNlcl9zZXJ2aWNlLnByb3RvEgxtZW1vcy5hcGkudjEi1gMKBFVzZXISEQoEbmFtZRgBIAEoCUID4EEIEioKBHJvbGUYAiABKA4yFy5tZW1vcy5hcGkudjEuVXNlci5Sb2xlQgPgQQISFQoIdXNlcm5hbWUYAyABKAlCA+BBAhISCgVlbWFpbBgEIAEoCUID4EEBEhkKDGRpc3BsYXlfbmFtZRgFIAEoCUID4EEBEhcKCmF2YXRhcl91cmwYBiABKAlCA+BBARIYCgtkZXNjcmlwdGlvbhgHIAEoCUID4EEBEhUKCHBhc3N3b3JkGAggASgJQgPgQQQSJwoFc3RhdGUYCSABKA4yEy5tZW1vcy5hcGkudjEuU3RhdGVCA+BBAhI0CgtjcmVhdGVfdGltZRgKIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxI0Cgt1cGRhdGVfdGltZRgLIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAyIxCgRSb2xlEhQKEFJPTEVfVU5TUEVDSUZJRUQQABIJCgVBRE1JThACEggKBFVTRVIQAzo36kE0ChFtZW1vcy5hcGkudjEvVXNlchIMdXNlcnMve3VzZXJ9GgRuYW1lKgV1c2VyczIEdXNlciJzChBMaXN0VXNlcnNSZXF1ZXN0EhYKCXBhZ2Vfc2l6ZRgBIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAiABKAlCA+BBARITCgZmaWx0ZXIYAyABKAlCA+BBARIZCgxzaG93X2RlbGV0ZWQYBCABKAhCA+BBASJjChFMaXN0VXNlcnNSZXNwb25zZRIhCgV1c2VycxgBIAMoCzISLm1lbW9zLmFwaS52MS5Vc2VyEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIikKFEJhdGNoR2V0VXNlcnNSZXF1ZXN0EhEKCXVzZXJuYW1lcxgBIAMoCSI6ChVCYXRjaEdldFVzZXJzUmVzcG9uc2USIQoFdXNlcnMYASADKAsyEi5tZW1vcy5hcGkudjEuVXNlciJtCg5HZXRVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEjIKCXJlYWRfbWFzaxgCIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE1hc2tCA+BBASKIAQoRQ3JlYXRlVXNlclJlcXVlc3QSKAoEdXNlchgBIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyQgbgQQLgQQQSFAoHdXNlcl9pZBgCIAEoCUID4EEBEhoKDXZhbGlkYXRlX29ubHkYAyABKAhCA+BBARIXCgpyZXF1ZXN0X2lkGAQgASgJQgPgQQEijAEKEVVwZGF0ZVVzZXJSZXF1ZXN0EiUKBHVzZXIYASABKAsyEi5tZW1vcy5hcGkudjEuVXNlckID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECEhoKDWFsbG93X21pc3NpbmcYAyABKAhCA+BBASJQChFEZWxldGVVc2VyUmVxdWVzdBInCgRuYW1lGAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhIKBWZvcmNlGAIgASgIQgPgQQEi9wMKCVVzZXJTdGF0cxIRCgRuYW1lGAEgASgJQgPgQQgSPgoPbWVtb190eXBlX3N0YXRzGAMgASgLMiUubWVtb3MuYXBpLnYxLlVzZXJTdGF0cy5NZW1vVHlwZVN0YXRzEjgKCXRhZ19jb3VudBgEIAMoCzIlLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMuVGFnQ291bnRFbnRyeRI7ChdtZW1vX2NyZWF0ZWRfdGltZXN0YW1wcxgHIAMoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXASFAoMcGlubmVkX21lbW9zGAUgAygJEhgKEHRvdGFsX21lbW9fY291bnQYBiABKAUaXwoNTWVtb1R5cGVTdGF0cxISCgpsaW5rX2NvdW50GAEgASgFEhIKCmNvZGVfY291bnQYAiABKAUSEgoKdG9kb19jb3VudBgDIAEoBRISCgp1bmRvX2NvdW50GAQgASgFGi8KDVRhZ0NvdW50RW50cnkSCwoDa2V5GAEgASgJEg0KBXZhbHVlGAIgASgFOgI4ATo/6kE8ChZtZW1vcy5hcGkudjEvVXNlclN0YXRzEgx1c2Vycy97dXNlcn0qCXVzZXJTdGF0czIJdXNlclN0YXRzSgQIAhADUhdtZW1vX2Rpc3BsYXlfdGltZXN0YW1wcyI+ChNHZXRVc2VyU3RhdHNSZXF1ZXN0EicKBG5hbWUYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXIiGQoXTGlzdEFsbFVzZXJTdGF0c1JlcXVlc3QiQgoYTGlzdEFsbFVzZXJTdGF0c1Jlc3BvbnNlEiYKBXN0YXRzGAEgAygLMhcubWVtb3MuYXBpLnYxLlVzZXJTdGF0cyLkAwoLVXNlclNldHRpbmcSEQoEbmFtZRgBIAEoCUID4EEIEkMKD2dlbmVyYWxfc2V0dGluZxgCIAEoCzIoLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZy5HZW5lcmFsU2V0dGluZ0gAEkUKEHdlYmhvb2tzX3NldHRpbmcYBSABKAsyKS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmcuV2ViaG9va3NTZXR0aW5nSAAaVwoOR2VuZXJhbFNldHRpbmcSEwoGbG9jYWxlGAEgASgJQgPgQQESHAoPbWVtb192aXNpYmlsaXR5GAMgASgJQgPgQQESEgoFdGhlbWUYBCABKAlCA+BBARo+Cg9XZWJob29rc1NldHRpbmcSKwoId2ViaG9va3MYASADKAsyGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siNQoDS2V5EhMKD0tFWV9VTlNQRUNJRklFRBAAEgsKB0dFTkVSQUwQARIMCghXRUJIT09LUxAEOl3qQVoKGG1lbW9zLmFwaS52MS9Vc2VyU2V0dGluZxIjdXNlcnMve3VzZXJuYW1lfS9zZXR0aW5ncy97c2V0dGluZ30qDHVzZXJTZXR0aW5nczILdXNlclNldHRpbmdCBwoFdmFsdWUiRwoVR2V0VXNlclNldHRpbmdSZXF1ZXN0Ei4KBG5hbWUYASABKAlCIOBBAvpBGgoYbWVtb3MuYXBpLnYxL1VzZXJTZXR0aW5nIoEBChhVcGRhdGVVc2VyU2V0dGluZ1JlcXVlc3QSLwoHc2V0dGluZxgBIAEoCzIZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZ0ID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECInUKF0xpc3RVc2VyU2V0dGluZ3NSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchIWCglwYWdlX3NpemUYAiABKAVCA+BBARIXCgpwYWdlX3Rva2VuGAMgASgJQgPgQQEidAoYTGlzdFVzZXJTZXR0aW5nc1Jlc3BvbnNlEisKCHNldHRpbmdzGAEgAygLMhkubWVtb3MuYXBpLnYxLlVzZXJTZXR0aW5nEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIuoBCg5MaW5rZWRJZGVudGl0eRIRCgRuYW1lGAEgASgJQgPgQQgSNwoIaWRwX25hbWUYAiABKAlCJeBBA/pBHwodbWVtb3MuYXBpLnYxL0lkZW50aXR5UHJvdmlkZXISFwoKZXh0ZXJuX3VpZBgDIAEoCUID4EEDOnPqQXAKG21lbW9zLmFwaS52MS9MaW5rZWRJZGVudGl0eRIvdXNlcnMve3VzZXJ9L2xpbmtlZElkZW50aXRpZXMve2xpbmtlZF9pZGVudGl0eX0qEGxpbmtlZElkZW50aXRpZXMyDmxpbmtlZElkZW50aXR5IkgKG0xpc3RMaW5rZWRJZGVudGl0aWVzUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXIiVwocTGlzdExpbmtlZElkZW50aXRpZXNSZXNwb25zZRI3ChFsaW5rZWRfaWRlbnRpdGllcxgBIAMoCzIcLm1lbW9zLmFwaS52MS5MaW5rZWRJZGVudGl0eSLLAQobQ3JlYXRlTGlua2VkSWRlbnRpdHlSZXF1ZXN0EikKBnBhcmVudBgBIAEoCUIZ4EEC+kETChFtZW1vcy5hcGkudjEvVXNlchI3CghpZHBfbmFtZRgCIAEoCUIl4EEC+kEfCh1tZW1vcy5hcGkudjEvSWRlbnRpdHlQcm92aWRlchIRCgRjb2RlGAMgASgJQgPgQQISGQoMcmVkaXJlY3RfdXJpGAQgASgJQgPgQQISGgoNY29kZV92ZXJpZmllchgFIAEoCUID4EEBIk0KGEdldExpbmtlZElkZW50aXR5UmVxdWVzdBIxCgRuYW1lGAEgASgJQiPgQQL6QR0KG21lbW9zLmFwaS52MS9MaW5rZWRJZGVudGl0eSJQChtEZWxldGVMaW5rZWRJZGVudGl0eVJlcXVlc3QSMQoEbmFtZRgBIAEoCUIj4EEC+kEdChttZW1vcy5hcGkudjEvTGlua2VkSWRlbnRpdHki8gIKE1BlcnNvbmFsQWNjZXNzVG9rZW4SEQoEbmFtZRgBIAEoCUID4EEIEhgKC2Rlc2NyaXB0aW9uGAIgASgJQgPgQQESMwoKY3JlYXRlZF9hdBgDIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAxIzCgpleHBpcmVzX2F0GAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEBEjUKDGxhc3RfdXNlZF9hdBgFIAEoCzIaLmdvb2dsZS5wcm90b2J1Zi5UaW1lc3RhbXBCA+BBAzqMAepBiAEKIG1lbW9zLmFwaS52MS9QZXJzb25hbEFjY2Vzc1Rva2VuEjl1c2Vycy97dXNlcn0vcGVyc29uYWxBY2Nlc3NUb2tlbnMve3BlcnNvbmFsX2FjY2Vzc190b2tlbn0qFHBlcnNvbmFsQWNjZXNzVG9rZW5zMhNwZXJzb25hbEFjY2Vzc1Rva2VuIn0KH0xpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1JlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBASKSAQogTGlzdFBlcnNvbmFsQWNjZXNzVG9rZW5zUmVzcG9uc2USQQoWcGVyc29uYWxfYWNjZXNzX3Rva2VucxgBIAMoCzIhLm1lbW9zLmFwaS52MS5QZXJzb25hbEFjY2Vzc1Rva2VuEhcKD25leHRfcGFnZV90b2tlbhgCIAEoCRISCgp0b3RhbF9zaXplGAMgASgFIoUBCiBDcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVxdWVzdBIpCgZwYXJlbnQYASABKAlCGeBBAvpBEwoRbWVtb3MuYXBpLnYxL1VzZXISGAoLZGVzY3JpcHRpb24YAiABKAlCA+BBARIcCg9leHBpcmVzX2luX2RheXMYAyABKAVCA+BBASJ0CiFDcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVzcG9uc2USQAoVcGVyc29uYWxfYWNjZXNzX3Rva2VuGAEgASgLMiEubWVtb3MuYXBpLnYxLlBlcnNvbmFsQWNjZXNzVG9rZW4SDQoFdG9rZW4YAiABKAkiWgogRGVsZXRlUGVyc29uYWxBY2Nlc3NUb2tlblJlcXVlc3QSNgoEbmFtZRgBIAEoCUIo4EEC+kEiCiBtZW1vcy5hcGkudjEvUGVyc29uYWxBY2Nlc3NUb2tlbiKqAQoLVXNlcldlYmhvb2sSDAoEbmFtZRgBIAEoCRILCgN1cmwYAiABKAkSFAoMZGlzcGxheV9uYW1lGAMgASgJEjQKC2NyZWF0ZV90aW1lGAQgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDEjQKC3VwZGF0ZV90aW1lGAUgASgLMhouZ29vZ2xlLnByb3RvYnVmLlRpbWVzdGFtcEID4EEDIi4KF0xpc3RVc2VyV2ViaG9va3NSZXF1ZXN0EhMKBnBhcmVudBgBIAEoCUID4EECIkcKGExpc3RVc2VyV2ViaG9va3NSZXNwb25zZRIrCgh3ZWJob29rcxgBIAMoCzIZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9vayJgChhDcmVhdGVVc2VyV2ViaG9va1JlcXVlc3QSEwoGcGFyZW50GAEgASgJQgPgQQISLwoHd2ViaG9vaxgCIAEoCzIZLm1lbW9zLmFwaS52MS5Vc2VyV2ViaG9va0ID4EECInwKGFVwZGF0ZVVzZXJXZWJob29rUmVxdWVzdBIvCgd3ZWJob29rGAEgASgLMhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rQgPgQQISLwoLdXBkYXRlX21hc2sYAiABKAsyGi5nb29nbGUucHJvdG9idWYuRmllbGRNYXNrIi0KGERlbGV0ZVVzZXJXZWJob29rUmVxdWVzdBIRCgRuYW1lGAEgASgJQgPgQQIiogcKEFVzZXJOb3RpZmljYXRpb24SFAoEbmFtZRgBIAEoCUIG4EED4EEIEikKBnNlbmRlchgCIAEoCUIZ4EED+kETChFtZW1vcy5hcGkudjEvVXNlchIsCgtzZW5kZXJfdXNlchgIIAEoCzISLm1lbW9zLmFwaS52MS5Vc2VyQgPgQQMSOgoGc3RhdHVzGAMgASgOMiUubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb24uU3RhdHVzQgPgQQESNAoLY3JlYXRlX3RpbWUYBCABKAsyGi5nb29nbGUucHJvdG9idWYuVGltZXN0YW1wQgPgQQMSNgoEdHlwZRgFIAEoDjIjLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uLlR5cGVCA+BBAxJOCgxtZW1vX2NvbW1lbnQYBiABKAsyMS5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbi5NZW1vQ29tbWVudFBheWxvYWRCA+BBA0gAEk4KDG1lbW9fbWVudGlvbhgHIAEoCzIxLm1lbW9zLmFwaS52MS5Vc2VyTm90aWZpY2F0aW9uLk1lbW9NZW50aW9uUGF5bG9hZEID4EEDSAAabAoSTWVtb0NvbW1lbnRQYXlsb2FkEgwKBG1lbW8YASABKAkSFAoMcmVsYXRlZF9tZW1vGAIgASgJEhQKDG1lbW9fc25pcHBldBgDIAEoCRIcChRyZWxhdGVkX21lbW9fc25pcHBldBgEIAEoCRpsChJNZW1vTWVudGlvblBheWxvYWQSDAoEbWVtbxgBIAEoCRIUCgxyZWxhdGVkX21lbW8YAiABKAkSFAoMbWVtb19zbmlwcGV0GAMgASgJEhwKFHJlbGF0ZWRfbWVtb19zbmlwcGV0GAQgASgJIjoKBlN0YXR1cxIWChJTVEFUVVNfVU5TUEVDSUZJRUQQABIKCgZVTlJFQUQQARIMCghBUkNISVZFRBACIkAKBFR5cGUSFAoQVFlQRV9VTlNQRUNJRklFRBAAEhAKDE1FTU9fQ09NTUVOVBABEhAKDE1FTU9fTUVOVElPThACOnDqQW0KHW1lbW9zLmFwaS52MS9Vc2VyTm90aWZpY2F0aW9uEil1c2Vycy97dXNlcn0vbm90aWZpY2F0aW9ucy97bm90aWZpY2F0aW9ufRoEbmFtZSoNbm90aWZpY2F0aW9uczIMbm90aWZpY2F0aW9uQgkKB3BheWxvYWQijwEKHExpc3RVc2VyTm90aWZpY2F0aW9uc1JlcXVlc3QSKQoGcGFyZW50GAEgASgJQhngQQL6QRMKEW1lbW9zLmFwaS52MS9Vc2VyEhYKCXBhZ2Vfc2l6ZRgCIAEoBUID4EEBEhcKCnBhZ2VfdG9rZW4YAyABKAlCA+BBARITCgZmaWx0ZXIYBCABKAlCA+BBASJvCh1MaXN0VXNlck5vdGlmaWNhdGlvbnNSZXNwb25zZRI1Cg1ub3RpZmljYXRpb25zGAEgAygLMh4ubWVtb3MuYXBpLnYxLlVzZXJOb3RpZmljYXRpb24SFwoPbmV4dF9wYWdlX3Rva2VuGAIgASgJIpABCh1VcGRhdGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBI5Cgxub3RpZmljYXRpb24YASABKAsyHi5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbkID4EECEjQKC3VwZGF0ZV9tYXNrGAIgASgLMhouZ29vZ2xlLnByb3RvYnVmLkZpZWxkTWFza0ID4EECIlQKHURlbGV0ZVVzZXJOb3RpZmljYXRpb25SZXF1ZXN0EjMKBG5hbWUYASABKAlCJeBBAvpBHwodbWVtb3MuYXBpLnYxL1VzZXJOb3RpZmljYXRpb24ygh0KC1VzZXJTZXJ2aWNlEmMKCUxpc3RVc2VycxIeLm1lbW9zLmFwaS52MS5MaXN0VXNlcnNSZXF1ZXN0Gh8ubWVtb3MuYXBpLnYxLkxpc3RVc2Vyc1Jlc3BvbnNlIhWC0+STAg8SDS9hcGkvdjEvdXNlcnMSewoNQmF0Y2hHZXRVc2VycxIiLm1lbW9zLmFwaS52MS5CYXRjaEdldFVzZXJzUmVxdWVzdBojLm1lbW9zLmFwaS52MS5CYXRjaEdldFVzZXJzUmVzcG9uc2UiIYLT5JMCGzoBKiIWL2FwaS92MS91c2VyczpiYXRjaEdldBJiCgdHZXRVc2VyEhwubWVtb3MuYXBpLnYxLkdldFVzZXJSZXF1ZXN0GhIubWVtb3MuYXBpLnYxLlVzZXIiJdpBBG5hbWWC0+STAhgSFi9hcGkvdjEve25hbWU9dXNlcnMvKn0SZQoKQ3JlYXRlVXNlchIfLm1lbW9zLmFwaS52MS5DcmVhdGVVc2VyUmVxdWVzdBoSLm1lbW9zLmFwaS52MS5Vc2VyIiLaQQR1c2VygtPkkwIVOgR1c2VyIg0vYXBpL3YxL3VzZXJzEn8KClVwZGF0ZVVzZXISHy5tZW1vcy5hcGkudjEuVXBkYXRlVXNlclJlcXVlc3QaEi5tZW1vcy5hcGkudjEuVXNlciI82kEQdXNlcix1cGRhdGVfbWFza4LT5JMCIzoEdXNlcjIbL2FwaS92MS97dXNlci5uYW1lPXVzZXJzLyp9EmwKCkRlbGV0ZVVzZXISHy5tZW1vcy5hcGkudjEuRGVsZXRlVXNlclJlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiJdpBBG5hbWWC0+STAhgqFi9hcGkvdjEve25hbWU9dXNlcnMvKn0SfgoQTGlzdEFsbFVzZXJTdGF0cxIlLm1lbW9zLmFwaS52MS5MaXN0QWxsVXNlclN0YXRzUmVxdWVzdBomLm1lbW9zLmFwaS52MS5MaXN0QWxsVXNlclN0YXRzUmVzcG9uc2UiG4LT5JMCFRITL2FwaS92MS91c2VyczpzdGF0cxJ6CgxHZXRVc2VyU3RhdHMSIS5tZW1vcy5hcGkudjEuR2V0VXNlclN0YXRzUmVxdWVzdBoXLm1lbW9zLmFwaS52MS5Vc2VyU3RhdHMiLtpBBG5hbWWC0+STAiESHy9hcGkvdjEve25hbWU9dXNlcnMvKn06Z2V0U3RhdHMSggEKDkdldFVzZXJTZXR0aW5nEiMubWVtb3MuYXBpLnYxLkdldFVzZXJTZXR0aW5nUmVxdWVzdBoZLm1lbW9zLmFwaS52MS5Vc2VyU2V0dGluZyIw2kEEbmFtZYLT5JMCIxIhL2FwaS92MS97bmFtZT11c2Vycy8qL3NldHRpbmdzLyp9EqgBChFVcGRhdGVVc2VyU2V0dGluZxImLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyU2V0dGluZ1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlclNldHRpbmciUNpBE3NldHRpbmcsdXBkYXRlX21hc2uC0+STAjQ6B3NldHRpbmcyKS9hcGkvdjEve3NldHRpbmcubmFtZT11c2Vycy8qL3NldHRpbmdzLyp9EpUBChBMaXN0VXNlclNldHRpbmdzEiUubWVtb3MuYXBpLnYxLkxpc3RVc2VyU2V0dGluZ3NSZXF1ZXN0GiYubWVtb3MuYXBpLnYxLkxpc3RVc2VyU2V0dGluZ3NSZXNwb25zZSIy2kEGcGFyZW50gtPkkwIjEiEvYXBpL3YxL3twYXJlbnQ9dXNlcnMvKn0vc2V0dGluZ3MSqQEKFExpc3RMaW5rZWRJZGVudGl0aWVzEikubWVtb3MuYXBpLnYxLkxpc3RMaW5rZWRJZGVudGl0aWVzUmVxdWVzdBoqLm1lbW9zLmFwaS52MS5MaXN0TGlua2VkSWRlbnRpdGllc1Jlc3BvbnNlIjraQQZwYXJlbnSC0+STAisSKS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9saW5rZWRJZGVudGl0aWVzEqcBChRDcmVhdGVMaW5rZWRJZGVudGl0eRIpLm1lbW9zLmFwaS52MS5DcmVhdGVMaW5rZWRJZGVudGl0eVJlcXVlc3QaHC5tZW1vcy5hcGkudjEuTGlua2VkSWRlbnRpdHkiRtpBD3BhcmVudCxpZHBfbmFtZYLT5JMCLjoBKiIpL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L2xpbmtlZElkZW50aXRpZXMSkwEKEUdldExpbmtlZElkZW50aXR5EiYubWVtb3MuYXBpLnYxLkdldExpbmtlZElkZW50aXR5UmVxdWVzdBocLm1lbW9zLmFwaS52MS5MaW5rZWRJZGVudGl0eSI42kEEbmFtZYLT5JMCKxIpL2FwaS92MS97bmFtZT11c2Vycy8qL2xpbmtlZElkZW50aXRpZXMvKn0SkwEKFERlbGV0ZUxpbmtlZElkZW50aXR5EikubWVtb3MuYXBpLnYxLkRlbGV0ZUxpbmtlZElkZW50aXR5UmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSI42kEEbmFtZYLT5JMCKyopL2FwaS92MS97bmFtZT11c2Vycy8qL2xpbmtlZElkZW50aXRpZXMvKn0SuQEKGExpc3RQZXJzb25hbEFjY2Vzc1Rva2VucxItLm1lbW9zLmFwaS52MS5MaXN0UGVyc29uYWxBY2Nlc3NUb2tlbnNSZXF1ZXN0Gi4ubWVtb3MuYXBpLnYxLkxpc3RQZXJzb25hbEFjY2Vzc1Rva2Vuc1Jlc3BvbnNlIj7aQQZwYXJlbnSC0+STAi8SLS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS9wZXJzb25hbEFjY2Vzc1Rva2VucxK2AQoZQ3JlYXRlUGVyc29uYWxBY2Nlc3NUb2tlbhIuLm1lbW9zLmFwaS52MS5DcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVxdWVzdBovLm1lbW9zLmFwaS52MS5DcmVhdGVQZXJzb25hbEFjY2Vzc1Rva2VuUmVzcG9uc2UiOILT5JMCMjoBKiItL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3BlcnNvbmFsQWNjZXNzVG9rZW5zEqEBChlEZWxldGVQZXJzb25hbEFjY2Vzc1Rva2VuEi4ubWVtb3MuYXBpLnYxLkRlbGV0ZVBlcnNvbmFsQWNjZXNzVG9rZW5SZXF1ZXN0GhYuZ29vZ2xlLnByb3RvYnVmLkVtcHR5IjzaQQRuYW1lgtPkkwIvKi0vYXBpL3YxL3tuYW1lPXVzZXJzLyovcGVyc29uYWxBY2Nlc3NUb2tlbnMvKn0SlQEKEExpc3RVc2VyV2ViaG9va3MSJS5tZW1vcy5hcGkudjEuTGlzdFVzZXJXZWJob29rc1JlcXVlc3QaJi5tZW1vcy5hcGkudjEuTGlzdFVzZXJXZWJob29rc1Jlc3BvbnNlIjLaQQZwYXJlbnSC0+STAiMSIS9hcGkvdjEve3BhcmVudD11c2Vycy8qfS93ZWJob29rcxKbAQoRQ3JlYXRlVXNlcldlYmhvb2sSJi5tZW1vcy5hcGkudjEuQ3JlYXRlVXNlcldlYmhvb2tSZXF1ZXN0GhkubWVtb3MuYXBpLnYxLlVzZXJXZWJob29rIkPaQQ5wYXJlbnQsd2ViaG9va4LT5JMCLDoHd2ViaG9vayIhL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L3dlYmhvb2tzEqgBChFVcGRhdGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5VcGRhdGVVc2VyV2ViaG9va1JlcXVlc3QaGS5tZW1vcy5hcGkudjEuVXNlcldlYmhvb2siUNpBE3dlYmhvb2ssdXBkYXRlX21hc2uC0+STAjQ6B3dlYmhvb2syKS9hcGkvdjEve3dlYmhvb2submFtZT11c2Vycy8qL3dlYmhvb2tzLyp9EoUBChFEZWxldGVVc2VyV2ViaG9vaxImLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyV2ViaG9va1JlcXVlc3QaFi5nb29nbGUucHJvdG9idWYuRW1wdHkiMNpBBG5hbWWC0+STAiMqIS9hcGkvdjEve25hbWU9dXNlcnMvKi93ZWJob29rcy8qfRKpAQoVTGlzdFVzZXJOb3RpZmljYXRpb25zEioubWVtb3MuYXBpLnYxLkxpc3RVc2VyTm90aWZpY2F0aW9uc1JlcXVlc3QaKy5tZW1vcy5hcGkudjEuTGlzdFVzZXJOb3RpZmljYXRpb25zUmVzcG9uc2UiN9pBBnBhcmVudILT5JMCKBImL2FwaS92MS97cGFyZW50PXVzZXJzLyp9L25vdGlmaWNhdGlvbnMSywEKFlVwZGF0ZVVzZXJOb3RpZmljYXRpb24SKy5tZW1vcy5hcGkudjEuVXBkYXRlVXNlck5vdGlmaWNhdGlvblJlcXVlc3QaHi5tZW1vcy5hcGkudjEuVXNlck5vdGlmaWNhdGlvbiJk2kEYbm90aWZpY2F0aW9uLHVwZGF0ZV9tYXNrgtPkkwJDOgxub3RpZmljYXRpb24yMy9hcGkvdjEve25vdGlmaWNhdGlvbi5uYW1lPXVzZXJzLyovbm90aWZpY2F0aW9ucy8qfRKUAQoWRGVsZXRlVXNlck5vdGlmaWNhdGlvbhIrLm1lbW9zLmFwaS52MS5EZWxldGVVc2VyTm90aWZpY2F0aW9uUmVxdWVzdBoWLmdvb2dsZS5wcm90b2J1Zi5FbXB0eSI12kEEbmFtZYLT5JMCKComL2FwaS92MS97bmFtZT11c2Vycy8qL25vdGlmaWNhdGlvbnMvKn1CqAEKEGNvbS5tZW1vcy5hcGkudjFCEFVzZXJTZXJ2aWNlUHJvdG9QAVowZ2l0aHViLmNvbS91c2VtZW1vcy9tZW1vcy9wcm90by9nZW4vYXBpL3YxO2FwaXYxogIDTUFYqgIMTWVtb3MuQXBpLlYxygIMTWVtb3NcQXBpXFYx4gIYTWVtb3NcQXBpXFYxXEdQQk1ldGFkYXRh6gIOTWVtb3M6OkFwaTo6VjFiBnByb3RvMw", [file_api_v1_common, file_google_api_annotations, file_google_api_client, file_google_api_field_behavior, file_google_api_resource, file_google_protobuf_empty, file_google_protobuf_field_mask, file_google_protobuf_timestamp]); /** * @generated from message memos.api.v1.User @@ -93,14 +93,14 @@ export type User = Message<"memos.api.v1.User"> & { * * @generated from field: google.protobuf.Timestamp create_time = 10; */ - createTime?: Timestamp; + createTime?: Timestamp | undefined; /** * Output only. The last update timestamp. * * @generated from field: google.protobuf.Timestamp update_time = 11; */ - updateTime?: Timestamp; + updateTime?: Timestamp | undefined; }; /** @@ -275,7 +275,7 @@ export type GetUserRequest = Message<"memos.api.v1.GetUserRequest"> & { * * @generated from field: google.protobuf.FieldMask read_mask = 2; */ - readMask?: FieldMask; + readMask?: FieldMask | undefined; }; /** @@ -294,7 +294,7 @@ export type CreateUserRequest = Message<"memos.api.v1.CreateUserRequest"> & { * * @generated from field: memos.api.v1.User user = 1; */ - user?: User; + user?: User | undefined; /** * Optional. The user ID to use for this user. @@ -337,14 +337,14 @@ export type UpdateUserRequest = Message<"memos.api.v1.UpdateUserRequest"> & { * * @generated from field: memos.api.v1.User user = 1; */ - user?: User; + user?: User | undefined; /** * Required. The list of fields to update. * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; /** * Optional. If set to true, allows updating sensitive fields. @@ -402,19 +402,12 @@ export type UserStats = Message<"memos.api.v1.UserStats"> & { */ name: string; - /** - * The timestamps when the memos were displayed. - * - * @generated from field: repeated google.protobuf.Timestamp memo_display_timestamps = 2; - */ - memoDisplayTimestamps: Timestamp[]; - /** * The stats of memo types. * * @generated from field: memos.api.v1.UserStats.MemoTypeStats memo_type_stats = 3; */ - memoTypeStats?: UserStats_MemoTypeStats; + memoTypeStats?: UserStats_MemoTypeStats | undefined; /** * The count of tags. @@ -423,6 +416,13 @@ export type UserStats = Message<"memos.api.v1.UserStats"> & { */ tagCount: { [key: string]: number }; + /** + * The creation timestamps of the user's memos. + * + * @generated from field: repeated google.protobuf.Timestamp memo_created_timestamps = 7; + */ + memoCreatedTimestamps: Timestamp[]; + /** * The pinned memos of the user. * @@ -692,14 +692,14 @@ export type UpdateUserSettingRequest = Message<"memos.api.v1.UpdateUserSettingRe * * @generated from field: memos.api.v1.UserSetting setting = 1; */ - setting?: UserSetting; + setting?: UserSetting | undefined; /** * Required. The list of fields to update. * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** @@ -977,21 +977,21 @@ export type PersonalAccessToken = Message<"memos.api.v1.PersonalAccessToken"> & * * @generated from field: google.protobuf.Timestamp created_at = 3; */ - createdAt?: Timestamp; + createdAt?: Timestamp | undefined; /** * Optional. The expiration timestamp. * * @generated from field: google.protobuf.Timestamp expires_at = 4; */ - expiresAt?: Timestamp; + expiresAt?: Timestamp | undefined; /** * Output only. The last used timestamp. * * @generated from field: google.protobuf.Timestamp last_used_at = 5; */ - lastUsedAt?: Timestamp; + lastUsedAt?: Timestamp | undefined; }; /** @@ -1111,7 +1111,7 @@ export type CreatePersonalAccessTokenResponse = Message<"memos.api.v1.CreatePers * * @generated from field: memos.api.v1.PersonalAccessToken personal_access_token = 1; */ - personalAccessToken?: PersonalAccessToken; + personalAccessToken?: PersonalAccessToken | undefined; /** * The actual token value - only returned on creation. @@ -1182,14 +1182,14 @@ export type UserWebhook = Message<"memos.api.v1.UserWebhook"> & { * * @generated from field: google.protobuf.Timestamp create_time = 4; */ - createTime?: Timestamp; + createTime?: Timestamp | undefined; /** * The last update time of the webhook. * * @generated from field: google.protobuf.Timestamp update_time = 5; */ - updateTime?: Timestamp; + updateTime?: Timestamp | undefined; }; /** @@ -1255,7 +1255,7 @@ export type CreateUserWebhookRequest = Message<"memos.api.v1.CreateUserWebhookRe * * @generated from field: memos.api.v1.UserWebhook webhook = 2; */ - webhook?: UserWebhook; + webhook?: UserWebhook | undefined; }; /** @@ -1274,14 +1274,14 @@ export type UpdateUserWebhookRequest = Message<"memos.api.v1.UpdateUserWebhookRe * * @generated from field: memos.api.v1.UserWebhook webhook = 1; */ - webhook?: UserWebhook; + webhook?: UserWebhook | undefined; /** * The list of fields to update. * * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** @@ -1336,7 +1336,7 @@ export type UserNotification = Message<"memos.api.v1.UserNotification"> & { * * @generated from field: memos.api.v1.User sender_user = 8; */ - senderUser?: User; + senderUser?: User | undefined; /** * The status of the notification. @@ -1350,7 +1350,7 @@ export type UserNotification = Message<"memos.api.v1.UserNotification"> & { * * @generated from field: google.protobuf.Timestamp create_time = 4; */ - createTime?: Timestamp; + createTime?: Timestamp | undefined; /** * The type of the notification. @@ -1584,12 +1584,12 @@ export type UpdateUserNotificationRequest = Message<"memos.api.v1.UpdateUserNoti /** * @generated from field: memos.api.v1.UserNotification notification = 1; */ - notification?: UserNotification; + notification?: UserNotification | undefined; /** * @generated from field: google.protobuf.FieldMask update_mask = 2; */ - updateMask?: FieldMask; + updateMask?: FieldMask | undefined; }; /** diff --git a/web/src/types/proto/google/api/annotations_pb.ts b/web/src/types/proto/google/api/annotations_pb.ts index b6315b5e7..ede33445a 100644 --- a/web/src/types/proto/google/api/annotations_pb.ts +++ b/web/src/types/proto/google/api/annotations_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file google/api/annotations.proto (package google.api, syntax proto3) /* eslint-disable */ diff --git a/web/src/types/proto/google/api/client_pb.ts b/web/src/types/proto/google/api/client_pb.ts index 00f8f5d68..ba27b00b9 100644 --- a/web/src/types/proto/google/api/client_pb.ts +++ b/web/src/types/proto/google/api/client_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file google/api/client.proto (package google.api, syntax proto3) /* eslint-disable */ @@ -57,7 +57,7 @@ export type CommonLanguageSettings = Message<"google.api.CommonLanguageSettings" * * @generated from field: google.api.SelectiveGapicGeneration selective_gapic_generation = 3; */ - selectiveGapicGeneration?: SelectiveGapicGeneration; + selectiveGapicGeneration?: SelectiveGapicGeneration | undefined; }; /** @@ -102,56 +102,56 @@ export type ClientLibrarySettings = Message<"google.api.ClientLibrarySettings"> * * @generated from field: google.api.JavaSettings java_settings = 21; */ - javaSettings?: JavaSettings; + javaSettings?: JavaSettings | undefined; /** * Settings for C++ client libraries. * * @generated from field: google.api.CppSettings cpp_settings = 22; */ - cppSettings?: CppSettings; + cppSettings?: CppSettings | undefined; /** * Settings for PHP client libraries. * * @generated from field: google.api.PhpSettings php_settings = 23; */ - phpSettings?: PhpSettings; + phpSettings?: PhpSettings | undefined; /** * Settings for Python client libraries. * * @generated from field: google.api.PythonSettings python_settings = 24; */ - pythonSettings?: PythonSettings; + pythonSettings?: PythonSettings | undefined; /** * Settings for Node client libraries. * * @generated from field: google.api.NodeSettings node_settings = 25; */ - nodeSettings?: NodeSettings; + nodeSettings?: NodeSettings | undefined; /** * Settings for .NET client libraries. * * @generated from field: google.api.DotnetSettings dotnet_settings = 26; */ - dotnetSettings?: DotnetSettings; + dotnetSettings?: DotnetSettings | undefined; /** * Settings for Ruby client libraries. * * @generated from field: google.api.RubySettings ruby_settings = 27; */ - rubySettings?: RubySettings; + rubySettings?: RubySettings | undefined; /** * Settings for Go client libraries. * * @generated from field: google.api.GoSettings go_settings = 28; */ - goSettings?: GoSettings; + goSettings?: GoSettings | undefined; }; /** @@ -313,7 +313,7 @@ export type JavaSettings = Message<"google.api.JavaSettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 3; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; }; /** @@ -334,7 +334,7 @@ export type CppSettings = Message<"google.api.CppSettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 1; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; }; /** @@ -355,7 +355,7 @@ export type PhpSettings = Message<"google.api.PhpSettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 1; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; }; /** @@ -376,14 +376,14 @@ export type PythonSettings = Message<"google.api.PythonSettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 1; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; /** * Experimental features to be included during client library generation. * * @generated from field: google.api.PythonSettings.ExperimentalFeatures experimental_features = 2; */ - experimentalFeatures?: PythonSettings_ExperimentalFeatures; + experimentalFeatures?: PythonSettings_ExperimentalFeatures | undefined; }; /** @@ -450,7 +450,7 @@ export type NodeSettings = Message<"google.api.NodeSettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 1; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; }; /** @@ -471,7 +471,7 @@ export type DotnetSettings = Message<"google.api.DotnetSettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 1; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; /** * Map from original service names to renamed versions. @@ -542,7 +542,7 @@ export type RubySettings = Message<"google.api.RubySettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 1; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; }; /** @@ -563,7 +563,7 @@ export type GoSettings = Message<"google.api.GoSettings"> & { * * @generated from field: google.api.CommonLanguageSettings common = 1; */ - common?: CommonLanguageSettings; + common?: CommonLanguageSettings | undefined; /** * Map of service names to renamed services. Keys are the package relative @@ -626,7 +626,7 @@ export type MethodSettings = Message<"google.api.MethodSettings"> & { * * @generated from field: google.api.MethodSettings.LongRunning long_running = 2; */ - longRunning?: MethodSettings_LongRunning; + longRunning?: MethodSettings_LongRunning | undefined; /** * List of top-level fields of the request message, that should be @@ -669,7 +669,7 @@ export type MethodSettings_LongRunning = Message<"google.api.MethodSettings.Long * * @generated from field: google.protobuf.Duration initial_poll_delay = 1; */ - initialPollDelay?: Duration; + initialPollDelay?: Duration | undefined; /** * Multiplier to gradually increase delay between subsequent polls until it @@ -686,7 +686,7 @@ export type MethodSettings_LongRunning = Message<"google.api.MethodSettings.Long * * @generated from field: google.protobuf.Duration max_poll_delay = 3; */ - maxPollDelay?: Duration; + maxPollDelay?: Duration | undefined; /** * Total polling timeout. @@ -694,7 +694,7 @@ export type MethodSettings_LongRunning = Message<"google.api.MethodSettings.Long * * @generated from field: google.protobuf.Duration total_poll_timeout = 4; */ - totalPollTimeout?: Duration; + totalPollTimeout?: Duration | undefined; }; /** diff --git a/web/src/types/proto/google/api/field_behavior_pb.ts b/web/src/types/proto/google/api/field_behavior_pb.ts index 7103aafd5..369f4e21d 100644 --- a/web/src/types/proto/google/api/field_behavior_pb.ts +++ b/web/src/types/proto/google/api/field_behavior_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file google/api/field_behavior.proto (package google.api, syntax proto3) /* eslint-disable */ diff --git a/web/src/types/proto/google/api/http_pb.ts b/web/src/types/proto/google/api/http_pb.ts index 677a92a9a..b92dbcac4 100644 --- a/web/src/types/proto/google/api/http_pb.ts +++ b/web/src/types/proto/google/api/http_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file google/api/http.proto (package google.api, syntax proto3) /* eslint-disable */ diff --git a/web/src/types/proto/google/api/launch_stage_pb.ts b/web/src/types/proto/google/api/launch_stage_pb.ts index e1ce0acd8..1850442fc 100644 --- a/web/src/types/proto/google/api/launch_stage_pb.ts +++ b/web/src/types/proto/google/api/launch_stage_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file google/api/launch_stage.proto (package google.api, syntax proto3) /* eslint-disable */ diff --git a/web/src/types/proto/google/api/resource_pb.ts b/web/src/types/proto/google/api/resource_pb.ts index 4142fffd1..40bfa8e99 100644 --- a/web/src/types/proto/google/api/resource_pb.ts +++ b/web/src/types/proto/google/api/resource_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file google/api/resource.proto (package google.api, syntax proto3) /* eslint-disable */ diff --git a/web/src/types/proto/google/type/color_pb.ts b/web/src/types/proto/google/type/color_pb.ts index 03cb02c8d..d90cce54b 100644 --- a/web/src/types/proto/google/type/color_pb.ts +++ b/web/src/types/proto/google/type/color_pb.ts @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// @generated by protoc-gen-es v2.11.0 with parameter "target=ts" +// @generated by protoc-gen-es v2.12.0 with parameter "target=ts" // @generated from file google/type/color.proto (package google.type, syntax proto3) /* eslint-disable */ @@ -192,7 +192,7 @@ export type Color = Message<"google.type.Color"> & { * * @generated from field: google.protobuf.FloatValue alpha = 4; */ - alpha?: number; + alpha?: number | undefined; }; /**