From b52936826e1df8df7083df46e7f413c627504796 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 6 May 2024 18:20:16 -0400 Subject: [PATCH 01/51] fix(deps): update module golang.org/x/net to v0.25.0 (#2792) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index ad41b1c250dc..fc35eb4632d3 100644 --- a/go.mod +++ b/go.mod @@ -84,9 +84,9 @@ require ( go.mongodb.org/mongo-driver v1.15.0 go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 - golang.org/x/crypto v0.22.0 + golang.org/x/crypto v0.23.0 golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f - golang.org/x/net v0.24.0 + golang.org/x/net v0.25.0 golang.org/x/oauth2 v0.20.0 golang.org/x/sync v0.7.0 golang.org/x/text v0.15.0 @@ -273,8 +273,8 @@ require ( go.uber.org/multierr v1.11.0 // indirect go4.org v0.0.0-20200411211856-f5505b9728dd // indirect golang.org/x/mod v0.17.0 // indirect - golang.org/x/sys v0.19.0 // indirect - golang.org/x/term v0.19.0 // indirect + golang.org/x/sys v0.20.0 // indirect + golang.org/x/term v0.20.0 // indirect golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.20.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect diff --git a/go.sum b/go.sum index f8dcdd7c6a72..4d53f3ce79bf 100644 --- a/go.sum +++ b/go.sum @@ -895,6 +895,8 @@ golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= +golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= +golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -969,6 +971,8 @@ golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= +golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= +golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1046,6 +1050,8 @@ golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= +golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= @@ -1058,6 +1064,8 @@ golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= +golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= +golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= From 288003519a84afc9bdf2520306995f8522c07d1e Mon Sep 17 00:00:00 2001 From: Dustin Decker Date: Mon, 6 May 2024 19:43:10 -0400 Subject: [PATCH 02/51] Add webhook source protos (#2789) * add webhook source protos * update protos * update proto * update protos --- .../source_metadatapb/source_metadata.pb.go | 1020 ++++++++++------- .../source_metadata.pb.validate.go | 316 +++++ pkg/pb/sourcespb/sources.pb.go | 366 +++--- pkg/pb/sourcespb/sources.pb.validate.go | 186 +++ proto/source_metadata.proto | 17 + proto/sources.proto | 9 +- 6 files changed, 1370 insertions(+), 544 deletions(-) diff --git a/pkg/pb/source_metadatapb/source_metadata.pb.go b/pkg/pb/source_metadatapb/source_metadata.pb.go index a65f7ea3c3ee..b5d2c3c4c98a 100644 --- a/pkg/pb/source_metadatapb/source_metadata.pb.go +++ b/pkg/pb/source_metadatapb/source_metadata.pb.go @@ -9,6 +9,7 @@ package source_metadatapb import ( protoreflect "google.golang.org/protobuf/reflect/protoreflect" protoimpl "google.golang.org/protobuf/runtime/protoimpl" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" reflect "reflect" sync "sync" ) @@ -2804,6 +2805,136 @@ func (x *Postman) GetVariableType() string { return "" } +type Vector struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Timestamp *timestamppb.Timestamp `protobuf:"bytes,1,opt,name=timestamp,proto3" json:"timestamp,omitempty"` + SourceType string `protobuf:"bytes,2,opt,name=source_type,json=sourceType,proto3" json:"source_type,omitempty"` + Host string `protobuf:"bytes,3,opt,name=host,proto3" json:"host,omitempty"` +} + +func (x *Vector) Reset() { + *x = Vector{} + if protoimpl.UnsafeEnabled { + mi := &file_source_metadata_proto_msgTypes[29] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Vector) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Vector) ProtoMessage() {} + +func (x *Vector) ProtoReflect() protoreflect.Message { + mi := &file_source_metadata_proto_msgTypes[29] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Vector.ProtoReflect.Descriptor instead. +func (*Vector) Descriptor() ([]byte, []int) { + return file_source_metadata_proto_rawDescGZIP(), []int{29} +} + +func (x *Vector) GetTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.Timestamp + } + return nil +} + +func (x *Vector) GetSourceType() string { + if x != nil { + return x.SourceType + } + return "" +} + +func (x *Vector) GetHost() string { + if x != nil { + return x.Host + } + return "" +} + +type Webhook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // Types that are assignable to Data: + // + // *Webhook_Vector + Data isWebhook_Data `protobuf_oneof:"data"` +} + +func (x *Webhook) Reset() { + *x = Webhook{} + if protoimpl.UnsafeEnabled { + mi := &file_source_metadata_proto_msgTypes[30] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Webhook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Webhook) ProtoMessage() {} + +func (x *Webhook) ProtoReflect() protoreflect.Message { + mi := &file_source_metadata_proto_msgTypes[30] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Webhook.ProtoReflect.Descriptor instead. +func (*Webhook) Descriptor() ([]byte, []int) { + return file_source_metadata_proto_rawDescGZIP(), []int{30} +} + +func (m *Webhook) GetData() isWebhook_Data { + if m != nil { + return m.Data + } + return nil +} + +func (x *Webhook) GetVector() *Vector { + if x, ok := x.GetData().(*Webhook_Vector); ok { + return x.Vector + } + return nil +} + +type isWebhook_Data interface { + isWebhook_Data() +} + +type Webhook_Vector struct { + Vector *Vector `protobuf:"bytes,1,opt,name=vector,proto3,oneof"` +} + +func (*Webhook_Vector) isWebhook_Data() {} + type MetaData struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -2840,13 +2971,14 @@ type MetaData struct { // *MetaData_AzureRepos // *MetaData_TravisCI // *MetaData_Postman + // *MetaData_Webhook Data isMetaData_Data `protobuf_oneof:"data"` } func (x *MetaData) Reset() { *x = MetaData{} if protoimpl.UnsafeEnabled { - mi := &file_source_metadata_proto_msgTypes[29] + mi := &file_source_metadata_proto_msgTypes[31] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -2859,7 +2991,7 @@ func (x *MetaData) String() string { func (*MetaData) ProtoMessage() {} func (x *MetaData) ProtoReflect() protoreflect.Message { - mi := &file_source_metadata_proto_msgTypes[29] + mi := &file_source_metadata_proto_msgTypes[31] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -2872,7 +3004,7 @@ func (x *MetaData) ProtoReflect() protoreflect.Message { // Deprecated: Use MetaData.ProtoReflect.Descriptor instead. func (*MetaData) Descriptor() ([]byte, []int) { - return file_source_metadata_proto_rawDescGZIP(), []int{29} + return file_source_metadata_proto_rawDescGZIP(), []int{31} } func (m *MetaData) GetData() isMetaData_Data { @@ -3085,6 +3217,13 @@ func (x *MetaData) GetPostman() *Postman { return nil } +func (x *MetaData) GetWebhook() *Webhook { + if x, ok := x.GetData().(*MetaData_Webhook); ok { + return x.Webhook + } + return nil +} + type isMetaData_Data interface { isMetaData_Data() } @@ -3205,6 +3344,10 @@ type MetaData_Postman struct { Postman *Postman `protobuf:"bytes,29,opt,name=postman,proto3,oneof"` } +type MetaData_Webhook struct { + Webhook *Webhook `protobuf:"bytes,30,opt,name=webhook,proto3,oneof"` +} + func (*MetaData_Azure) isMetaData_Data() {} func (*MetaData_Bitbucket) isMetaData_Data() {} @@ -3263,117 +3406,310 @@ func (*MetaData_TravisCI) isMetaData_Data() {} func (*MetaData_Postman) isMetaData_Data() {} +func (*MetaData_Webhook) isMetaData_Data() {} + var File_source_metadata_proto protoreflect.FileDescriptor var file_source_metadata_proto_rawDesc = []byte{ 0x0a, 0x15, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x0f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x22, 0x7f, 0x0a, 0x05, 0x41, 0x7a, 0x75, 0x72, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x12, - 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, 0x12, - 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, - 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x86, 0x02, 0x0a, 0x09, 0x42, 0x69, - 0x74, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, - 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x77, - 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6e, 0x69, - 0x70, 0x70, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x73, - 0x6e, 0x69, 0x70, 0x70, 0x65, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, 0x6c, - 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, 0x16, - 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, - 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, - 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, - 0x6e, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, 0x65, - 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6f, - 0x72, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, - 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, - 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, - 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, - 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xcd, 0x01, 0x0a, 0x08, 0x43, 0x69, - 0x72, 0x63, 0x6c, 0x65, 0x43, 0x49, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x63, 0x73, 0x5f, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x63, 0x73, 0x54, 0x79, 0x70, - 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, - 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x21, 0x0a, - 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x65, 0x70, 0x12, - 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, - 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xb4, 0x01, 0x0a, 0x08, 0x54, 0x72, - 0x61, 0x76, 0x69, 0x73, 0x43, 0x49, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, - 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6a, 0x6f, 0x62, 0x4e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, - 0x69, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x22, 0xc8, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, - 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, - 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, - 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x5a, 0x0a, 0x06, 0x44, - 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, - 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0xa3, 0x01, 0x0a, 0x03, 0x45, 0x43, 0x52, 0x12, - 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, 0x61, - 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x12, - 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x72, - 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, 0x67, - 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x5e, 0x0a, - 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, - 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, - 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, - 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x99, 0x01, - 0x0a, 0x03, 0x47, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x7f, 0x0a, 0x05, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x65, 0x64, + 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x86, 0x02, 0x0a, 0x09, 0x42, + 0x69, 0x74, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1e, 0x0a, 0x0a, + 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, + 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x6e, + 0x69, 0x70, 0x70, 0x65, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, + 0x73, 0x6e, 0x69, 0x70, 0x70, 0x65, 0x74, 0x49, 0x64, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x74, + 0x6c, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 0x12, + 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, + 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, + 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, + 0x69, 0x6e, 0x65, 0x22, 0xa4, 0x01, 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x64, 0x6b, 0x69, 0x74, + 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6f, 0x72, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6f, 0x72, 0x67, 0x12, 0x1a, 0x0a, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x69, 0x70, 0x65, 0x6c, 0x69, 0x6e, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, + 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, + 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, + 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0xcd, 0x01, 0x0a, 0x08, 0x43, + 0x69, 0x72, 0x63, 0x6c, 0x65, 0x43, 0x49, 0x12, 0x19, 0x0a, 0x08, 0x76, 0x63, 0x73, 0x5f, 0x74, + 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x63, 0x73, 0x54, 0x79, + 0x70, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, + 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x21, + 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x53, 0x74, 0x65, 0x70, + 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xb4, 0x01, 0x0a, 0x08, 0x54, + 0x72, 0x61, 0x76, 0x69, 0x73, 0x43, 0x49, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, + 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, + 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x6a, 0x6f, 0x62, 0x5f, 0x6e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6a, 0x6f, 0x62, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x75, 0x62, + 0x6c, 0x69, 0x63, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, + 0x63, 0x22, 0xc8, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x66, 0x6c, 0x75, 0x65, 0x6e, 0x63, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x70, 0x61, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, + 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, + 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, + 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x22, 0x5a, 0x0a, 0x06, + 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x10, 0x0a, 0x03, 0x74, 0x61, 0x67, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x74, 0x61, 0x67, 0x22, 0xa3, 0x01, 0x0a, 0x03, 0x45, 0x43, 0x52, + 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6d, + 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x6d, 0x61, 0x67, 0x65, + 0x12, 0x1a, 0x0a, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x72, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, + 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x72, 0x65, + 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x5e, + 0x0a, 0x0a, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x12, 0x12, 0x0a, 0x04, + 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, + 0x6e, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x99, + 0x01, 0x0a, 0x03, 0x47, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, + 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, + 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, + 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, + 0x20, 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x89, 0x02, 0x0a, 0x06, 0x47, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, + 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, + 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, + 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, + 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, + 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, + 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x97, 0x02, 0x0a, 0x06, 0x47, 0x69, 0x74, 0x6c, 0x61, + 0x62, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, + 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, + 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, - 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, + 0x69, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x89, 0x02, 0x0a, 0x06, 0x47, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, + 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, + 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, + 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, + 0x22, 0xd8, 0x01, 0x0a, 0x03, 0x47, 0x43, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, + 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, + 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, + 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, + 0x64, 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, + 0x5f, 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, + 0x65, 0x64, 0x41, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, + 0x28, 0x09, 0x52, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, + 0x65, 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x04, + 0x4a, 0x69, 0x72, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x77, 0x0a, 0x03, 0x4e, 0x50, 0x4d, 0x12, 0x12, 0x0a, + 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, + 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, + 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, + 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, + 0x78, 0x0a, 0x04, 0x50, 0x79, 0x50, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, + 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, + 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, + 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, + 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x78, 0x0a, 0x02, 0x53, 0x33, 0x12, + 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, + 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x22, 0x97, 0x02, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, + 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, + 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, + 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x17, 0x0a, + 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, + 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, + 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, + 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, + 0x74, 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, + 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x96, 0x01, + 0x0a, 0x06, 0x47, 0x65, 0x72, 0x72, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, + 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, + 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, + 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, + 0x6a, 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x1a, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, + 0x6c, 0x65, 0x22, 0x81, 0x01, 0x0a, 0x07, 0x4a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x12, 0x21, + 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, + 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, + 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x90, 0x02, 0x0a, 0x05, 0x54, 0x65, 0x61, 0x6d, 0x73, + 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, + 0x21, 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, + 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, + 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x17, 0x0a, 0x07, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x41, 0x72, + 0x74, 0x69, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, + 0x6f, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x12, 0x0a, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, + 0x68, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xa8, 0x01, 0x0a, 0x06, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, + 0x12, 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, + 0x61, 0x70, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, + 0x70, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, 0x12, 0x1c, + 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, + 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, + 0x69, 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, + 0x22, 0x9f, 0x01, 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x06, + 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x48, 0x00, 0x52, 0x06, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, + 0x28, 0x0a, 0x03, 0x6e, 0x70, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4e, + 0x50, 0x4d, 0x48, 0x00, 0x52, 0x03, 0x6e, 0x70, 0x6d, 0x12, 0x2b, 0x0a, 0x04, 0x70, 0x79, 0x70, + 0x69, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x79, 0x50, 0x69, 0x48, 0x00, + 0x52, 0x04, 0x70, 0x79, 0x70, 0x69, 0x42, 0x0a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, + 0x74, 0x61, 0x22, 0xae, 0x01, 0x0a, 0x0a, 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x6f, 0x69, 0x6e, + 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, + 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, + 0x69, 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, + 0x65, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, + 0x52, 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x6f, 0x63, 0x69, 0x64, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x6f, 0x63, 0x69, 0x64, 0x12, 0x14, 0x0a, + 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, + 0x61, 0x69, 0x6c, 0x22, 0xbf, 0x01, 0x0a, 0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x44, 0x72, + 0x69, 0x76, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, + 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, + 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, + 0x16, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, + 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, + 0x6d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x42, + 0x79, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x70, 0x61, 0x74, 0x68, 0x22, 0xcb, 0x02, 0x0a, 0x0a, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, + 0x65, 0x70, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, @@ -3389,233 +3725,56 @@ var file_source_metadata_proto_rawDesc = []byte{ 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, 0x97, 0x02, 0x0a, 0x06, 0x47, 0x69, 0x74, 0x6c, 0x61, 0x62, - 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, - 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, - 0x74, 0x6f, 0x72, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, - 0x73, 0x69, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x03, 0x52, 0x09, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, - 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, - 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x70, 0x72, - 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6f, 0x77, 0x6e, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4f, 0x77, 0x6e, 0x65, 0x72, 0x22, - 0xd8, 0x01, 0x0a, 0x03, 0x47, 0x43, 0x53, 0x12, 0x16, 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, - 0x1a, 0x0a, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x66, 0x69, 0x6c, 0x65, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, - 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, - 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1d, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, - 0x5f, 0x61, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x64, 0x41, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, 0x64, 0x5f, - 0x61, 0x74, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x75, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x64, 0x41, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x18, 0x07, 0x20, 0x03, 0x28, - 0x09, 0x52, 0x04, 0x61, 0x63, 0x6c, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x6e, 0x74, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, - 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70, 0x65, 0x22, 0x98, 0x01, 0x0a, 0x04, 0x4a, - 0x69, 0x72, 0x61, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x69, 0x73, 0x73, 0x75, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, - 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x77, 0x0a, 0x03, 0x4e, 0x50, 0x4d, 0x12, 0x12, 0x0a, 0x04, - 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x07, 0x70, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, - 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, - 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x78, - 0x0a, 0x04, 0x50, 0x79, 0x50, 0x69, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x61, - 0x63, 0x6b, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x61, 0x63, - 0x6b, 0x61, 0x67, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, - 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x22, 0x78, 0x0a, 0x02, 0x53, 0x33, 0x12, 0x16, - 0x0a, 0x06, 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, - 0x62, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, - 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x22, 0x97, 0x02, 0x0a, 0x05, 0x53, 0x6c, 0x61, 0x63, 0x6b, 0x12, 0x1d, 0x0a, 0x0a, - 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x63, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, - 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x17, 0x0a, 0x07, - 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x75, - 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, - 0x79, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, - 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, - 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x22, 0x96, 0x01, 0x0a, - 0x06, 0x47, 0x65, 0x72, 0x72, 0x69, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, - 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, - 0x69, 0x6c, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, - 0x6a, 0x65, 0x63, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, - 0x65, 0x63, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x22, 0x1a, 0x0a, 0x04, 0x54, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, - 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, - 0x65, 0x22, 0x81, 0x01, 0x0a, 0x07, 0x4a, 0x65, 0x6e, 0x6b, 0x69, 0x6e, 0x73, 0x12, 0x21, 0x0a, - 0x0c, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x62, 0x75, 0x69, 0x6c, 0x64, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, - 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, - 0x73, 0x74, 0x61, 0x6d, 0x70, 0x22, 0x90, 0x02, 0x0a, 0x05, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x12, - 0x1d, 0x0a, 0x0a, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x49, 0x64, 0x12, 0x21, - 0x0a, 0x0c, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, - 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x12, 0x0a, 0x04, - 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x12, 0x1a, 0x0a, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x12, 0x1b, 0x0a, 0x09, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, - 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x74, 0x65, 0x61, 0x6d, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x17, 0x0a, 0x07, 0x74, 0x65, 0x61, 0x6d, 0x5f, 0x69, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x74, 0x65, 0x61, 0x6d, 0x49, 0x64, 0x22, 0x99, 0x01, 0x0a, 0x0b, 0x41, 0x72, 0x74, - 0x69, 0x66, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x12, 0x0a, 0x04, 0x72, 0x65, 0x70, 0x6f, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x72, 0x65, 0x70, 0x6f, 0x12, 0x12, 0x0a, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, - 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x22, 0xa8, 0x01, 0x0a, 0x06, 0x53, 0x79, 0x73, 0x6c, 0x6f, 0x67, 0x12, - 0x1a, 0x0a, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x08, 0x68, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, - 0x70, 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x70, - 0x70, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x6f, 0x63, 0x69, 0x64, 0x12, 0x1c, 0x0a, - 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x63, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x12, 0x1a, 0x0a, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x61, 0x63, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x22, - 0x9f, 0x01, 0x0a, 0x07, 0x46, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x72, 0x12, 0x31, 0x0a, 0x06, 0x67, - 0x69, 0x74, 0x68, 0x75, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x47, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x48, 0x00, 0x52, 0x06, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x12, 0x28, - 0x0a, 0x03, 0x6e, 0x70, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x4e, 0x50, - 0x4d, 0x48, 0x00, 0x52, 0x03, 0x6e, 0x70, 0x6d, 0x12, 0x2b, 0x0a, 0x04, 0x70, 0x79, 0x70, 0x69, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, - 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x79, 0x50, 0x69, 0x48, 0x00, 0x52, - 0x04, 0x70, 0x79, 0x70, 0x69, 0x42, 0x0a, 0x0a, 0x08, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0x22, 0xae, 0x01, 0x0a, 0x0a, 0x53, 0x68, 0x61, 0x72, 0x65, 0x50, 0x6f, 0x69, 0x6e, 0x74, - 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x06, 0x61, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, - 0x74, 0x6c, 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x03, 0x52, - 0x05, 0x76, 0x69, 0x65, 0x77, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x6f, 0x63, 0x69, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x64, 0x6f, 0x63, 0x69, 0x64, 0x12, 0x14, 0x0a, 0x05, - 0x65, 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, - 0x69, 0x6c, 0x22, 0xbf, 0x01, 0x0a, 0x0b, 0x47, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x44, 0x72, 0x69, - 0x76, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x6d, - 0x61, 0x69, 0x6c, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, 0x6c, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x16, - 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, - 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x12, 0x28, 0x0a, 0x10, 0x6c, 0x61, 0x73, 0x74, 0x5f, 0x6d, - 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x62, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x0e, 0x6c, 0x61, 0x73, 0x74, 0x4d, 0x6f, 0x64, 0x69, 0x66, 0x69, 0x65, 0x64, 0x42, 0x79, - 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x70, 0x61, 0x74, 0x68, 0x22, 0xcb, 0x02, 0x0a, 0x0a, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x52, 0x65, - 0x70, 0x6f, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x12, 0x1a, 0x0a, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x75, 0x73, 0x65, 0x72, 0x6e, - 0x61, 0x6d, 0x65, 0x12, 0x1e, 0x0a, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x72, 0x65, 0x70, 0x6f, 0x73, 0x69, 0x74, - 0x6f, 0x72, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x6f, 0x6d, 0x6d, 0x69, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, - 0x6d, 0x61, 0x69, 0x6c, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x6d, 0x61, 0x69, - 0x6c, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x69, 0x6c, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x66, 0x69, 0x6c, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, - 0x61, 0x6d, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x03, 0x52, 0x04, 0x6c, 0x69, 0x6e, 0x65, 0x12, 0x3b, 0x0a, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, - 0x69, 0x6c, 0x69, 0x74, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1b, 0x2e, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x69, - 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x0a, 0x76, 0x69, 0x73, 0x69, 0x62, 0x69, - 0x6c, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x18, - 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x22, - 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x22, 0x8d, 0x04, 0x0a, 0x07, 0x50, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x12, 0x12, - 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, 0x69, - 0x6e, 0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, - 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, - 0x73, 0x70, 0x61, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, - 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, - 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x5f, 0x69, 0x64, 0x18, 0x04, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x49, 0x64, 0x12, - 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x63, - 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, - 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0f, - 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, 0x21, - 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x61, 0x6d, - 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x0b, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, 0x1f, - 0x0a, 0x0b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, 0x12, - 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, 0x0a, - 0x0d, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0f, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x54, 0x79, - 0x70, 0x65, 0x22, 0x83, 0x0c, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, + 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x70, 0x72, 0x6f, 0x6a, 0x65, 0x63, 0x74, 0x12, + 0x22, 0x0a, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x6f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x22, 0x8d, 0x04, 0x0a, 0x07, 0x50, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x12, + 0x12, 0x0a, 0x04, 0x6c, 0x69, 0x6e, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6c, + 0x69, 0x6e, 0x6b, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, + 0x5f, 0x75, 0x75, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, + 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x55, 0x75, 0x69, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x77, 0x6f, + 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x0d, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x70, 0x61, 0x63, 0x65, 0x4e, 0x61, 0x6d, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x5f, 0x69, 0x64, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x49, 0x64, + 0x12, 0x23, 0x0a, 0x0d, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, + 0x63, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x25, + 0x0a, 0x0e, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, + 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x29, 0x0a, 0x10, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, + 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0f, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x49, 0x64, 0x12, + 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, + 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x49, 0x64, 0x12, + 0x1f, 0x0a, 0x0b, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x66, 0x6f, 0x6c, 0x64, 0x65, 0x72, 0x4e, 0x61, 0x6d, 0x65, + 0x12, 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, + 0x1d, 0x0a, 0x0a, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x0e, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x09, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x23, + 0x0a, 0x0d, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x0f, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x76, 0x61, 0x72, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x54, + 0x79, 0x70, 0x65, 0x22, 0x77, 0x0a, 0x06, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x38, 0x0a, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, 0x09, 0x74, 0x69, + 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1f, 0x0a, 0x0b, 0x73, 0x6f, 0x75, 0x72, 0x63, + 0x65, 0x5f, 0x74, 0x79, 0x70, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x73, 0x6f, + 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x68, 0x6f, 0x73, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x68, 0x6f, 0x73, 0x74, 0x22, 0x44, 0x0a, 0x07, + 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x31, 0x0a, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, + 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, + 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x48, 0x00, 0x52, 0x06, 0x76, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x22, 0xb9, 0x0c, 0x0a, 0x08, 0x4d, 0x65, 0x74, 0x61, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2e, 0x0a, 0x05, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x48, 0x00, 0x52, 0x05, 0x61, 0x7a, 0x75, 0x72, 0x65, 0x12, @@ -3711,16 +3870,19 @@ var file_source_metadata_proto_rawDesc = []byte{ 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x2e, 0x50, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, 0x48, 0x00, 0x52, 0x07, 0x70, 0x6f, 0x73, 0x74, 0x6d, 0x61, 0x6e, - 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x3e, 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, - 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x0a, 0x0a, 0x06, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, - 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, - 0x0a, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x10, 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x75, - 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x03, 0x42, 0x43, 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, - 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, 0x73, 0x65, - 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, 0x68, 0x6f, - 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x6f, 0x75, 0x72, - 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x70, 0x62, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x12, 0x34, 0x0a, 0x07, 0x77, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x18, 0x1e, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x18, 0x2e, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, + 0x61, 0x74, 0x61, 0x2e, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x48, 0x00, 0x52, 0x07, 0x77, + 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x42, 0x06, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x2a, 0x3e, + 0x0a, 0x0a, 0x56, 0x69, 0x73, 0x69, 0x62, 0x69, 0x6c, 0x69, 0x74, 0x79, 0x12, 0x0a, 0x0a, 0x06, + 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x10, 0x00, 0x12, 0x0b, 0x0a, 0x07, 0x70, 0x72, 0x69, 0x76, + 0x61, 0x74, 0x65, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x73, 0x68, 0x61, 0x72, 0x65, 0x64, 0x10, + 0x02, 0x12, 0x0b, 0x0a, 0x07, 0x75, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x03, 0x42, 0x43, + 0x5a, 0x41, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, + 0x66, 0x66, 0x6c, 0x65, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, + 0x66, 0x66, 0x6c, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, + 0x62, 0x2f, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, + 0x61, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3736,39 +3898,42 @@ func file_source_metadata_proto_rawDescGZIP() []byte { } var file_source_metadata_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_source_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 30) +var file_source_metadata_proto_msgTypes = make([]protoimpl.MessageInfo, 32) var file_source_metadata_proto_goTypes = []interface{}{ - (Visibility)(0), // 0: source_metadata.Visibility - (*Azure)(nil), // 1: source_metadata.Azure - (*Bitbucket)(nil), // 2: source_metadata.Bitbucket - (*Buildkite)(nil), // 3: source_metadata.Buildkite - (*CircleCI)(nil), // 4: source_metadata.CircleCI - (*TravisCI)(nil), // 5: source_metadata.TravisCI - (*Confluence)(nil), // 6: source_metadata.Confluence - (*Docker)(nil), // 7: source_metadata.Docker - (*ECR)(nil), // 8: source_metadata.ECR - (*Filesystem)(nil), // 9: source_metadata.Filesystem - (*Git)(nil), // 10: source_metadata.Git - (*Github)(nil), // 11: source_metadata.Github - (*Gitlab)(nil), // 12: source_metadata.Gitlab - (*GCS)(nil), // 13: source_metadata.GCS - (*Jira)(nil), // 14: source_metadata.Jira - (*NPM)(nil), // 15: source_metadata.NPM - (*PyPi)(nil), // 16: source_metadata.PyPi - (*S3)(nil), // 17: source_metadata.S3 - (*Slack)(nil), // 18: source_metadata.Slack - (*Gerrit)(nil), // 19: source_metadata.Gerrit - (*Test)(nil), // 20: source_metadata.Test - (*Jenkins)(nil), // 21: source_metadata.Jenkins - (*Teams)(nil), // 22: source_metadata.Teams - (*Artifactory)(nil), // 23: source_metadata.Artifactory - (*Syslog)(nil), // 24: source_metadata.Syslog - (*Forager)(nil), // 25: source_metadata.Forager - (*SharePoint)(nil), // 26: source_metadata.SharePoint - (*GoogleDrive)(nil), // 27: source_metadata.GoogleDrive - (*AzureRepos)(nil), // 28: source_metadata.AzureRepos - (*Postman)(nil), // 29: source_metadata.Postman - (*MetaData)(nil), // 30: source_metadata.MetaData + (Visibility)(0), // 0: source_metadata.Visibility + (*Azure)(nil), // 1: source_metadata.Azure + (*Bitbucket)(nil), // 2: source_metadata.Bitbucket + (*Buildkite)(nil), // 3: source_metadata.Buildkite + (*CircleCI)(nil), // 4: source_metadata.CircleCI + (*TravisCI)(nil), // 5: source_metadata.TravisCI + (*Confluence)(nil), // 6: source_metadata.Confluence + (*Docker)(nil), // 7: source_metadata.Docker + (*ECR)(nil), // 8: source_metadata.ECR + (*Filesystem)(nil), // 9: source_metadata.Filesystem + (*Git)(nil), // 10: source_metadata.Git + (*Github)(nil), // 11: source_metadata.Github + (*Gitlab)(nil), // 12: source_metadata.Gitlab + (*GCS)(nil), // 13: source_metadata.GCS + (*Jira)(nil), // 14: source_metadata.Jira + (*NPM)(nil), // 15: source_metadata.NPM + (*PyPi)(nil), // 16: source_metadata.PyPi + (*S3)(nil), // 17: source_metadata.S3 + (*Slack)(nil), // 18: source_metadata.Slack + (*Gerrit)(nil), // 19: source_metadata.Gerrit + (*Test)(nil), // 20: source_metadata.Test + (*Jenkins)(nil), // 21: source_metadata.Jenkins + (*Teams)(nil), // 22: source_metadata.Teams + (*Artifactory)(nil), // 23: source_metadata.Artifactory + (*Syslog)(nil), // 24: source_metadata.Syslog + (*Forager)(nil), // 25: source_metadata.Forager + (*SharePoint)(nil), // 26: source_metadata.SharePoint + (*GoogleDrive)(nil), // 27: source_metadata.GoogleDrive + (*AzureRepos)(nil), // 28: source_metadata.AzureRepos + (*Postman)(nil), // 29: source_metadata.Postman + (*Vector)(nil), // 30: source_metadata.Vector + (*Webhook)(nil), // 31: source_metadata.Webhook + (*MetaData)(nil), // 32: source_metadata.MetaData + (*timestamppb.Timestamp)(nil), // 33: google.protobuf.Timestamp } var file_source_metadata_proto_depIdxs = []int32{ 0, // 0: source_metadata.Github.visibility:type_name -> source_metadata.Visibility @@ -3777,40 +3942,43 @@ var file_source_metadata_proto_depIdxs = []int32{ 15, // 3: source_metadata.Forager.npm:type_name -> source_metadata.NPM 16, // 4: source_metadata.Forager.pypi:type_name -> source_metadata.PyPi 0, // 5: source_metadata.AzureRepos.visibility:type_name -> source_metadata.Visibility - 1, // 6: source_metadata.MetaData.azure:type_name -> source_metadata.Azure - 2, // 7: source_metadata.MetaData.bitbucket:type_name -> source_metadata.Bitbucket - 4, // 8: source_metadata.MetaData.circleci:type_name -> source_metadata.CircleCI - 6, // 9: source_metadata.MetaData.confluence:type_name -> source_metadata.Confluence - 7, // 10: source_metadata.MetaData.docker:type_name -> source_metadata.Docker - 8, // 11: source_metadata.MetaData.ecr:type_name -> source_metadata.ECR - 13, // 12: source_metadata.MetaData.gcs:type_name -> source_metadata.GCS - 11, // 13: source_metadata.MetaData.github:type_name -> source_metadata.Github - 12, // 14: source_metadata.MetaData.gitlab:type_name -> source_metadata.Gitlab - 14, // 15: source_metadata.MetaData.jira:type_name -> source_metadata.Jira - 15, // 16: source_metadata.MetaData.npm:type_name -> source_metadata.NPM - 16, // 17: source_metadata.MetaData.pypi:type_name -> source_metadata.PyPi - 17, // 18: source_metadata.MetaData.s3:type_name -> source_metadata.S3 - 18, // 19: source_metadata.MetaData.slack:type_name -> source_metadata.Slack - 9, // 20: source_metadata.MetaData.filesystem:type_name -> source_metadata.Filesystem - 10, // 21: source_metadata.MetaData.git:type_name -> source_metadata.Git - 20, // 22: source_metadata.MetaData.test:type_name -> source_metadata.Test - 3, // 23: source_metadata.MetaData.buildkite:type_name -> source_metadata.Buildkite - 19, // 24: source_metadata.MetaData.gerrit:type_name -> source_metadata.Gerrit - 21, // 25: source_metadata.MetaData.jenkins:type_name -> source_metadata.Jenkins - 22, // 26: source_metadata.MetaData.teams:type_name -> source_metadata.Teams - 23, // 27: source_metadata.MetaData.artifactory:type_name -> source_metadata.Artifactory - 24, // 28: source_metadata.MetaData.syslog:type_name -> source_metadata.Syslog - 25, // 29: source_metadata.MetaData.forager:type_name -> source_metadata.Forager - 26, // 30: source_metadata.MetaData.sharepoint:type_name -> source_metadata.SharePoint - 27, // 31: source_metadata.MetaData.googleDrive:type_name -> source_metadata.GoogleDrive - 28, // 32: source_metadata.MetaData.azureRepos:type_name -> source_metadata.AzureRepos - 5, // 33: source_metadata.MetaData.travisCI:type_name -> source_metadata.TravisCI - 29, // 34: source_metadata.MetaData.postman:type_name -> source_metadata.Postman - 35, // [35:35] is the sub-list for method output_type - 35, // [35:35] is the sub-list for method input_type - 35, // [35:35] is the sub-list for extension type_name - 35, // [35:35] is the sub-list for extension extendee - 0, // [0:35] is the sub-list for field type_name + 33, // 6: source_metadata.Vector.timestamp:type_name -> google.protobuf.Timestamp + 30, // 7: source_metadata.Webhook.vector:type_name -> source_metadata.Vector + 1, // 8: source_metadata.MetaData.azure:type_name -> source_metadata.Azure + 2, // 9: source_metadata.MetaData.bitbucket:type_name -> source_metadata.Bitbucket + 4, // 10: source_metadata.MetaData.circleci:type_name -> source_metadata.CircleCI + 6, // 11: source_metadata.MetaData.confluence:type_name -> source_metadata.Confluence + 7, // 12: source_metadata.MetaData.docker:type_name -> source_metadata.Docker + 8, // 13: source_metadata.MetaData.ecr:type_name -> source_metadata.ECR + 13, // 14: source_metadata.MetaData.gcs:type_name -> source_metadata.GCS + 11, // 15: source_metadata.MetaData.github:type_name -> source_metadata.Github + 12, // 16: source_metadata.MetaData.gitlab:type_name -> source_metadata.Gitlab + 14, // 17: source_metadata.MetaData.jira:type_name -> source_metadata.Jira + 15, // 18: source_metadata.MetaData.npm:type_name -> source_metadata.NPM + 16, // 19: source_metadata.MetaData.pypi:type_name -> source_metadata.PyPi + 17, // 20: source_metadata.MetaData.s3:type_name -> source_metadata.S3 + 18, // 21: source_metadata.MetaData.slack:type_name -> source_metadata.Slack + 9, // 22: source_metadata.MetaData.filesystem:type_name -> source_metadata.Filesystem + 10, // 23: source_metadata.MetaData.git:type_name -> source_metadata.Git + 20, // 24: source_metadata.MetaData.test:type_name -> source_metadata.Test + 3, // 25: source_metadata.MetaData.buildkite:type_name -> source_metadata.Buildkite + 19, // 26: source_metadata.MetaData.gerrit:type_name -> source_metadata.Gerrit + 21, // 27: source_metadata.MetaData.jenkins:type_name -> source_metadata.Jenkins + 22, // 28: source_metadata.MetaData.teams:type_name -> source_metadata.Teams + 23, // 29: source_metadata.MetaData.artifactory:type_name -> source_metadata.Artifactory + 24, // 30: source_metadata.MetaData.syslog:type_name -> source_metadata.Syslog + 25, // 31: source_metadata.MetaData.forager:type_name -> source_metadata.Forager + 26, // 32: source_metadata.MetaData.sharepoint:type_name -> source_metadata.SharePoint + 27, // 33: source_metadata.MetaData.googleDrive:type_name -> source_metadata.GoogleDrive + 28, // 34: source_metadata.MetaData.azureRepos:type_name -> source_metadata.AzureRepos + 5, // 35: source_metadata.MetaData.travisCI:type_name -> source_metadata.TravisCI + 29, // 36: source_metadata.MetaData.postman:type_name -> source_metadata.Postman + 31, // 37: source_metadata.MetaData.webhook:type_name -> source_metadata.Webhook + 38, // [38:38] is the sub-list for method output_type + 38, // [38:38] is the sub-list for method input_type + 38, // [38:38] is the sub-list for extension type_name + 38, // [38:38] is the sub-list for extension extendee + 0, // [0:38] is the sub-list for field type_name } func init() { file_source_metadata_proto_init() } @@ -4168,6 +4336,30 @@ func file_source_metadata_proto_init() { } } file_source_metadata_proto_msgTypes[29].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Vector); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_source_metadata_proto_msgTypes[30].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Webhook); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_source_metadata_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*MetaData); i { case 0: return &v.state @@ -4185,7 +4377,10 @@ func file_source_metadata_proto_init() { (*Forager_Npm)(nil), (*Forager_Pypi)(nil), } - file_source_metadata_proto_msgTypes[29].OneofWrappers = []interface{}{ + file_source_metadata_proto_msgTypes[30].OneofWrappers = []interface{}{ + (*Webhook_Vector)(nil), + } + file_source_metadata_proto_msgTypes[31].OneofWrappers = []interface{}{ (*MetaData_Azure)(nil), (*MetaData_Bitbucket)(nil), (*MetaData_Circleci)(nil), @@ -4215,6 +4410,7 @@ func file_source_metadata_proto_init() { (*MetaData_AzureRepos)(nil), (*MetaData_TravisCI)(nil), (*MetaData_Postman)(nil), + (*MetaData_Webhook)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -4222,7 +4418,7 @@ func file_source_metadata_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_source_metadata_proto_rawDesc, NumEnums: 1, - NumMessages: 30, + NumMessages: 32, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/pb/source_metadatapb/source_metadata.pb.validate.go b/pkg/pb/source_metadatapb/source_metadata.pb.validate.go index 20d090cd0535..452fee66f817 100644 --- a/pkg/pb/source_metadatapb/source_metadata.pb.validate.go +++ b/pkg/pb/source_metadatapb/source_metadata.pb.validate.go @@ -3399,6 +3399,281 @@ var _ interface { ErrorName() string } = PostmanValidationError{} +// Validate checks the field values on Vector with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Vector) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Vector with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in VectorMultiError, or nil if none found. +func (m *Vector) ValidateAll() error { + return m.validate(true) +} + +func (m *Vector) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if all { + switch v := interface{}(m.GetTimestamp()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, VectorValidationError{ + field: "Timestamp", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, VectorValidationError{ + field: "Timestamp", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetTimestamp()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return VectorValidationError{ + field: "Timestamp", + reason: "embedded message failed validation", + cause: err, + } + } + } + + // no validation rules for SourceType + + // no validation rules for Host + + if len(errors) > 0 { + return VectorMultiError(errors) + } + + return nil +} + +// VectorMultiError is an error wrapping multiple validation errors returned by +// Vector.ValidateAll() if the designated constraints aren't met. +type VectorMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m VectorMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m VectorMultiError) AllErrors() []error { return m } + +// VectorValidationError is the validation error returned by Vector.Validate if +// the designated constraints aren't met. +type VectorValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e VectorValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e VectorValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e VectorValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e VectorValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e VectorValidationError) ErrorName() string { return "VectorValidationError" } + +// Error satisfies the builtin error interface +func (e VectorValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sVector.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = VectorValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = VectorValidationError{} + +// Validate checks the field values on Webhook with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Webhook) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Webhook with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in WebhookMultiError, or nil if none found. +func (m *Webhook) ValidateAll() error { + return m.validate(true) +} + +func (m *Webhook) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + switch v := m.Data.(type) { + case *Webhook_Vector: + if v == nil { + err := WebhookValidationError{ + field: "Data", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetVector()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "Vector", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "Vector", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetVector()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookValidationError{ + field: "Vector", + reason: "embedded message failed validation", + cause: err, + } + } + } + + default: + _ = v // ensures v is used + } + + if len(errors) > 0 { + return WebhookMultiError(errors) + } + + return nil +} + +// WebhookMultiError is an error wrapping multiple validation errors returned +// by Webhook.ValidateAll() if the designated constraints aren't met. +type WebhookMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m WebhookMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m WebhookMultiError) AllErrors() []error { return m } + +// WebhookValidationError is the validation error returned by Webhook.Validate +// if the designated constraints aren't met. +type WebhookValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e WebhookValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e WebhookValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e WebhookValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e WebhookValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e WebhookValidationError) ErrorName() string { return "WebhookValidationError" } + +// Error satisfies the builtin error interface +func (e WebhookValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sWebhook.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = WebhookValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = WebhookValidationError{} + // Validate checks the field values on MetaData with the rules defined in the // proto definition for this message. If any rules are violated, the first // error encountered is returned, or nil if there are no violations. @@ -4611,6 +4886,47 @@ func (m *MetaData) validate(all bool) error { } } + case *MetaData_Webhook: + if v == nil { + err := MetaDataValidationError{ + field: "Data", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetWebhook()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, MetaDataValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, MetaDataValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetWebhook()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return MetaDataValidationError{ + field: "Webhook", + reason: "embedded message failed validation", + cause: err, + } + } + } + default: _ = v // ensures v is used } diff --git a/pkg/pb/sourcespb/sources.pb.go b/pkg/pb/sourcespb/sources.pb.go index 96a07b69634d..0ad638c86a96 100644 --- a/pkg/pb/sourcespb/sources.pb.go +++ b/pkg/pb/sourcespb/sources.pb.go @@ -62,6 +62,7 @@ const ( SourceType_SOURCE_TYPE_AZURE_REPOS SourceType = 31 SourceType_SOURCE_TYPE_TRAVISCI SourceType = 32 SourceType_SOURCE_TYPE_POSTMAN SourceType = 33 + SourceType_SOURCE_TYPE_WEBHOOK SourceType = 34 ) // Enum value maps for SourceType. @@ -101,6 +102,7 @@ var ( 31: "SOURCE_TYPE_AZURE_REPOS", 32: "SOURCE_TYPE_TRAVISCI", 33: "SOURCE_TYPE_POSTMAN", + 34: "SOURCE_TYPE_WEBHOOK", } SourceType_value = map[string]int32{ "SOURCE_TYPE_AZURE_STORAGE": 0, @@ -137,6 +139,7 @@ var ( "SOURCE_TYPE_AZURE_REPOS": 31, "SOURCE_TYPE_TRAVISCI": 32, "SOURCE_TYPE_POSTMAN": 33, + "SOURCE_TYPE_WEBHOOK": 34, } ) @@ -3682,6 +3685,81 @@ func (*Postman_Unauthenticated) isPostman_Credential() {} func (*Postman_Token) isPostman_Credential() {} +type Webhook struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ListenAddress string `protobuf:"bytes,1,opt,name=listen_address,json=listenAddress,proto3" json:"listen_address,omitempty"` + // Types that are assignable to Credential: + // + // *Webhook_Header + Credential isWebhook_Credential `protobuf_oneof:"credential"` +} + +func (x *Webhook) Reset() { + *x = Webhook{} + if protoimpl.UnsafeEnabled { + mi := &file_sources_proto_msgTypes[31] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *Webhook) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*Webhook) ProtoMessage() {} + +func (x *Webhook) ProtoReflect() protoreflect.Message { + mi := &file_sources_proto_msgTypes[31] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use Webhook.ProtoReflect.Descriptor instead. +func (*Webhook) Descriptor() ([]byte, []int) { + return file_sources_proto_rawDescGZIP(), []int{31} +} + +func (x *Webhook) GetListenAddress() string { + if x != nil { + return x.ListenAddress + } + return "" +} + +func (m *Webhook) GetCredential() isWebhook_Credential { + if m != nil { + return m.Credential + } + return nil +} + +func (x *Webhook) GetHeader() *credentialspb.Header { + if x, ok := x.GetCredential().(*Webhook_Header); ok { + return x.Header + } + return nil +} + +type isWebhook_Credential interface { + isWebhook_Credential() +} + +type Webhook_Header struct { + Header *credentialspb.Header `protobuf:"bytes,2,opt,name=header,proto3,oneof"` +} + +func (*Webhook_Header) isWebhook_Credential() {} + var File_sources_proto protoreflect.FileDescriptor var file_sources_proto_rawDesc = []byte{ @@ -4233,70 +4311,79 @@ var file_sources_proto_rawDesc = []byte{ 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x70, 0x61, 0x74, 0x68, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x09, 0x52, 0x10, 0x65, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x50, 0x61, 0x74, 0x68, 0x73, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, - 0x2a, 0xb7, 0x07, 0x0a, 0x0a, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, - 0x1d, 0x0a, 0x19, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, - 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x10, 0x00, 0x12, 0x19, - 0x0a, 0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x49, - 0x54, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, 0x45, 0x43, - 0x49, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x4c, 0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x12, - 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, - 0x4f, 0x43, 0x4b, 0x45, 0x52, 0x10, 0x04, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, 0x43, 0x52, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43, 0x53, 0x10, - 0x06, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x10, 0x07, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, - 0x47, 0x49, 0x54, 0x10, 0x08, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, - 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x4c, 0x41, 0x42, 0x10, 0x09, 0x12, 0x14, 0x0a, - 0x10, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x49, 0x52, - 0x41, 0x10, 0x0a, 0x12, 0x24, 0x0a, 0x20, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, - 0x50, 0x45, 0x5f, 0x4e, 0x50, 0x4d, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x44, 0x5f, 0x50, - 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0b, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x59, 0x50, 0x49, 0x5f, 0x55, 0x4e, - 0x41, 0x55, 0x54, 0x48, 0x44, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0c, - 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x53, 0x33, 0x10, 0x0d, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, - 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x43, 0x4b, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, - 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x0f, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x10, 0x10, 0x12, 0x14, 0x0a, 0x10, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, - 0x10, 0x11, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x53, 0x33, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x44, 0x10, 0x12, 0x12, - 0x2a, 0x0a, 0x26, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, - 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, - 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4f, 0x52, 0x47, 0x10, 0x13, 0x12, 0x19, 0x0a, 0x15, 0x53, - 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, - 0x4b, 0x49, 0x54, 0x45, 0x10, 0x14, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, - 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x45, 0x52, 0x52, 0x49, 0x54, 0x10, 0x15, 0x12, 0x17, - 0x0a, 0x13, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x45, - 0x4e, 0x4b, 0x49, 0x4e, 0x53, 0x10, 0x16, 0x12, 0x15, 0x0a, 0x11, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x41, 0x4d, 0x53, 0x10, 0x17, 0x12, 0x21, - 0x0a, 0x1d, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x46, - 0x52, 0x4f, 0x47, 0x5f, 0x41, 0x52, 0x54, 0x49, 0x46, 0x41, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x10, - 0x18, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x53, 0x59, 0x53, 0x4c, 0x4f, 0x47, 0x10, 0x19, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x4f, 0x55, - 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, - 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x4f, 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, 0x47, - 0x10, 0x1a, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x43, 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x4c, 0x54, 0x49, 0x4d, 0x45, - 0x10, 0x1b, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, - 0x45, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, 0x5f, 0x44, 0x52, 0x49, 0x56, 0x45, 0x10, 0x1c, - 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, - 0x53, 0x48, 0x41, 0x52, 0x45, 0x50, 0x4f, 0x49, 0x4e, 0x54, 0x10, 0x1d, 0x12, 0x1c, 0x0a, 0x18, - 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43, 0x53, 0x5f, - 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x44, 0x10, 0x1e, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x4f, - 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, - 0x52, 0x45, 0x50, 0x4f, 0x53, 0x10, 0x1f, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x55, 0x52, 0x43, - 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, 0x52, 0x41, 0x56, 0x49, 0x53, 0x43, 0x49, 0x10, - 0x20, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, - 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x4d, 0x41, 0x4e, 0x10, 0x21, 0x42, 0x3b, 0x5a, 0x39, 0x67, 0x69, - 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, - 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, - 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x73, 0x6f, - 0x75, 0x72, 0x63, 0x65, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x22, 0x76, 0x0a, 0x07, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x12, 0x2e, 0x0a, 0x0e, 0x6c, + 0x69, 0x73, 0x74, 0x65, 0x6e, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x68, 0x01, 0x52, 0x0d, 0x6c, 0x69, + 0x73, 0x74, 0x65, 0x6e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x2d, 0x0a, 0x06, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x13, 0x2e, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, + 0x48, 0x00, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x42, 0x0c, 0x0a, 0x0a, 0x63, 0x72, + 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x2a, 0xd0, 0x07, 0x0a, 0x0a, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x53, 0x54, 0x4f, + 0x52, 0x41, 0x47, 0x45, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x42, 0x49, 0x54, 0x42, 0x55, 0x43, 0x4b, 0x45, 0x54, 0x10, + 0x01, 0x12, 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x43, 0x49, 0x52, 0x43, 0x4c, 0x45, 0x43, 0x49, 0x10, 0x02, 0x12, 0x1a, 0x0a, 0x16, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x43, 0x4f, 0x4e, 0x46, 0x4c, + 0x55, 0x45, 0x4e, 0x43, 0x45, 0x10, 0x03, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x44, 0x4f, 0x43, 0x4b, 0x45, 0x52, 0x10, 0x04, 0x12, + 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x45, + 0x43, 0x52, 0x10, 0x05, 0x12, 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43, 0x53, 0x10, 0x06, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x10, + 0x07, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x47, 0x49, 0x54, 0x10, 0x08, 0x12, 0x16, 0x0a, + 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, + 0x4c, 0x41, 0x42, 0x10, 0x09, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, + 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x49, 0x52, 0x41, 0x10, 0x0a, 0x12, 0x24, 0x0a, 0x20, 0x53, + 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4e, 0x50, 0x4d, 0x5f, 0x55, + 0x4e, 0x41, 0x55, 0x54, 0x48, 0x44, 0x5f, 0x50, 0x41, 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, + 0x0b, 0x12, 0x25, 0x0a, 0x21, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x50, 0x59, 0x50, 0x49, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x44, 0x5f, 0x50, 0x41, + 0x43, 0x4b, 0x41, 0x47, 0x45, 0x53, 0x10, 0x0c, 0x12, 0x12, 0x0a, 0x0e, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x33, 0x10, 0x0d, 0x12, 0x15, 0x0a, 0x11, + 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x43, + 0x4b, 0x10, 0x0e, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x46, 0x49, 0x4c, 0x45, 0x53, 0x59, 0x53, 0x54, 0x45, 0x4d, 0x10, 0x0f, 0x12, + 0x13, 0x0a, 0x0f, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, + 0x49, 0x54, 0x10, 0x10, 0x12, 0x14, 0x0a, 0x10, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x54, 0x45, 0x53, 0x54, 0x10, 0x11, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x33, 0x5f, 0x55, 0x4e, 0x41, + 0x55, 0x54, 0x48, 0x45, 0x44, 0x10, 0x12, 0x12, 0x2a, 0x0a, 0x26, 0x53, 0x4f, 0x55, 0x52, 0x43, + 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x49, 0x54, 0x48, 0x55, 0x42, 0x5f, 0x55, 0x4e, + 0x41, 0x55, 0x54, 0x48, 0x45, 0x4e, 0x54, 0x49, 0x43, 0x41, 0x54, 0x45, 0x44, 0x5f, 0x4f, 0x52, + 0x47, 0x10, 0x13, 0x12, 0x19, 0x0a, 0x15, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, + 0x50, 0x45, 0x5f, 0x42, 0x55, 0x49, 0x4c, 0x44, 0x4b, 0x49, 0x54, 0x45, 0x10, 0x14, 0x12, 0x16, + 0x0a, 0x12, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x45, + 0x52, 0x52, 0x49, 0x54, 0x10, 0x15, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x45, 0x4e, 0x4b, 0x49, 0x4e, 0x53, 0x10, 0x16, 0x12, + 0x15, 0x0a, 0x11, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, + 0x45, 0x41, 0x4d, 0x53, 0x10, 0x17, 0x12, 0x21, 0x0a, 0x1d, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, + 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x4a, 0x46, 0x52, 0x4f, 0x47, 0x5f, 0x41, 0x52, 0x54, 0x49, + 0x46, 0x41, 0x43, 0x54, 0x4f, 0x52, 0x59, 0x10, 0x18, 0x12, 0x16, 0x0a, 0x12, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x59, 0x53, 0x4c, 0x4f, 0x47, 0x10, + 0x19, 0x12, 0x27, 0x0a, 0x23, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, + 0x5f, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x4d, 0x4f, + 0x4e, 0x49, 0x54, 0x4f, 0x52, 0x49, 0x4e, 0x47, 0x10, 0x1a, 0x12, 0x1e, 0x0a, 0x1a, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x4c, 0x41, 0x43, 0x4b, 0x5f, + 0x52, 0x45, 0x41, 0x4c, 0x54, 0x49, 0x4d, 0x45, 0x10, 0x1b, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x4f, + 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x47, 0x4f, 0x4f, 0x47, 0x4c, 0x45, + 0x5f, 0x44, 0x52, 0x49, 0x56, 0x45, 0x10, 0x1c, 0x12, 0x1a, 0x0a, 0x16, 0x53, 0x4f, 0x55, 0x52, + 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x53, 0x48, 0x41, 0x52, 0x45, 0x50, 0x4f, 0x49, + 0x4e, 0x54, 0x10, 0x1d, 0x12, 0x1c, 0x0a, 0x18, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, + 0x59, 0x50, 0x45, 0x5f, 0x47, 0x43, 0x53, 0x5f, 0x55, 0x4e, 0x41, 0x55, 0x54, 0x48, 0x45, 0x44, + 0x10, 0x1e, 0x12, 0x1b, 0x0a, 0x17, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x41, 0x5a, 0x55, 0x52, 0x45, 0x5f, 0x52, 0x45, 0x50, 0x4f, 0x53, 0x10, 0x1f, 0x12, + 0x18, 0x0a, 0x14, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x54, + 0x52, 0x41, 0x56, 0x49, 0x53, 0x43, 0x49, 0x10, 0x20, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x55, + 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x4d, 0x41, 0x4e, + 0x10, 0x21, 0x12, 0x17, 0x0a, 0x13, 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x5f, 0x54, 0x59, 0x50, + 0x45, 0x5f, 0x57, 0x45, 0x42, 0x48, 0x4f, 0x4f, 0x4b, 0x10, 0x22, 0x42, 0x3b, 0x5a, 0x39, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, + 0x65, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, 0x6c, + 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, 0x73, + 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -4312,7 +4399,7 @@ func file_sources_proto_rawDescGZIP() []byte { } var file_sources_proto_enumTypes = make([]protoimpl.EnumInfo, 2) -var file_sources_proto_msgTypes = make([]protoimpl.MessageInfo, 31) +var file_sources_proto_msgTypes = make([]protoimpl.MessageInfo, 32) var file_sources_proto_goTypes = []interface{}{ (SourceType)(0), // 0: sources.SourceType (Confluence_GetAllSpacesScope)(0), // 1: sources.Confluence.GetAllSpacesScope @@ -4347,74 +4434,76 @@ var file_sources_proto_goTypes = []interface{}{ (*Sharepoint)(nil), // 30: sources.Sharepoint (*AzureRepos)(nil), // 31: sources.AzureRepos (*Postman)(nil), // 32: sources.Postman - (*durationpb.Duration)(nil), // 33: google.protobuf.Duration - (*anypb.Any)(nil), // 34: google.protobuf.Any - (*credentialspb.BasicAuth)(nil), // 35: credentials.BasicAuth - (*credentialspb.Unauthenticated)(nil), // 36: credentials.Unauthenticated - (*credentialspb.Oauth2)(nil), // 37: credentials.Oauth2 - (*credentialspb.KeySecret)(nil), // 38: credentials.KeySecret - (*credentialspb.CloudEnvironment)(nil), // 39: credentials.CloudEnvironment - (*credentialspb.SSHAuth)(nil), // 40: credentials.SSHAuth - (*credentialspb.GitHubApp)(nil), // 41: credentials.GitHubApp - (*credentialspb.AWSSessionTokenSecret)(nil), // 42: credentials.AWSSessionTokenSecret - (*credentialspb.SlackTokens)(nil), // 43: credentials.SlackTokens - (*credentialspb.Header)(nil), // 44: credentials.Header - (*credentialspb.ClientCredentials)(nil), // 45: credentials.ClientCredentials - (*timestamppb.Timestamp)(nil), // 46: google.protobuf.Timestamp + (*Webhook)(nil), // 33: sources.Webhook + (*durationpb.Duration)(nil), // 34: google.protobuf.Duration + (*anypb.Any)(nil), // 35: google.protobuf.Any + (*credentialspb.BasicAuth)(nil), // 36: credentials.BasicAuth + (*credentialspb.Unauthenticated)(nil), // 37: credentials.Unauthenticated + (*credentialspb.Oauth2)(nil), // 38: credentials.Oauth2 + (*credentialspb.KeySecret)(nil), // 39: credentials.KeySecret + (*credentialspb.CloudEnvironment)(nil), // 40: credentials.CloudEnvironment + (*credentialspb.SSHAuth)(nil), // 41: credentials.SSHAuth + (*credentialspb.GitHubApp)(nil), // 42: credentials.GitHubApp + (*credentialspb.AWSSessionTokenSecret)(nil), // 43: credentials.AWSSessionTokenSecret + (*credentialspb.SlackTokens)(nil), // 44: credentials.SlackTokens + (*credentialspb.Header)(nil), // 45: credentials.Header + (*credentialspb.ClientCredentials)(nil), // 46: credentials.ClientCredentials + (*timestamppb.Timestamp)(nil), // 47: google.protobuf.Timestamp } var file_sources_proto_depIdxs = []int32{ - 33, // 0: sources.LocalSource.scan_interval:type_name -> google.protobuf.Duration - 34, // 1: sources.LocalSource.connection:type_name -> google.protobuf.Any - 35, // 2: sources.Artifactory.basic_auth:type_name -> credentials.BasicAuth - 36, // 3: sources.Artifactory.unauthenticated:type_name -> credentials.Unauthenticated - 35, // 4: sources.AzureStorage.basic_auth:type_name -> credentials.BasicAuth - 36, // 5: sources.AzureStorage.unauthenticated:type_name -> credentials.Unauthenticated - 37, // 6: sources.Bitbucket.oauth:type_name -> credentials.Oauth2 - 35, // 7: sources.Bitbucket.basic_auth:type_name -> credentials.BasicAuth - 36, // 8: sources.Confluence.unauthenticated:type_name -> credentials.Unauthenticated - 35, // 9: sources.Confluence.basic_auth:type_name -> credentials.BasicAuth + 34, // 0: sources.LocalSource.scan_interval:type_name -> google.protobuf.Duration + 35, // 1: sources.LocalSource.connection:type_name -> google.protobuf.Any + 36, // 2: sources.Artifactory.basic_auth:type_name -> credentials.BasicAuth + 37, // 3: sources.Artifactory.unauthenticated:type_name -> credentials.Unauthenticated + 36, // 4: sources.AzureStorage.basic_auth:type_name -> credentials.BasicAuth + 37, // 5: sources.AzureStorage.unauthenticated:type_name -> credentials.Unauthenticated + 38, // 6: sources.Bitbucket.oauth:type_name -> credentials.Oauth2 + 36, // 7: sources.Bitbucket.basic_auth:type_name -> credentials.BasicAuth + 37, // 8: sources.Confluence.unauthenticated:type_name -> credentials.Unauthenticated + 36, // 9: sources.Confluence.basic_auth:type_name -> credentials.BasicAuth 1, // 10: sources.Confluence.spaces_scope:type_name -> sources.Confluence.GetAllSpacesScope - 36, // 11: sources.Docker.unauthenticated:type_name -> credentials.Unauthenticated - 35, // 12: sources.Docker.basic_auth:type_name -> credentials.BasicAuth - 38, // 13: sources.ECR.access_key:type_name -> credentials.KeySecret - 36, // 14: sources.GCS.unauthenticated:type_name -> credentials.Unauthenticated - 39, // 15: sources.GCS.adc:type_name -> credentials.CloudEnvironment - 37, // 16: sources.GCS.oauth:type_name -> credentials.Oauth2 - 35, // 17: sources.Git.basic_auth:type_name -> credentials.BasicAuth - 36, // 18: sources.Git.unauthenticated:type_name -> credentials.Unauthenticated - 40, // 19: sources.Git.ssh_auth:type_name -> credentials.SSHAuth - 37, // 20: sources.GitLab.oauth:type_name -> credentials.Oauth2 - 35, // 21: sources.GitLab.basic_auth:type_name -> credentials.BasicAuth - 41, // 22: sources.GitHub.github_app:type_name -> credentials.GitHubApp - 36, // 23: sources.GitHub.unauthenticated:type_name -> credentials.Unauthenticated - 35, // 24: sources.GitHub.basic_auth:type_name -> credentials.BasicAuth - 35, // 25: sources.JIRA.basic_auth:type_name -> credentials.BasicAuth - 36, // 26: sources.JIRA.unauthenticated:type_name -> credentials.Unauthenticated - 37, // 27: sources.JIRA.oauth:type_name -> credentials.Oauth2 - 36, // 28: sources.NPMUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated - 36, // 29: sources.PyPIUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated - 38, // 30: sources.S3.access_key:type_name -> credentials.KeySecret - 36, // 31: sources.S3.unauthenticated:type_name -> credentials.Unauthenticated - 39, // 32: sources.S3.cloud_environment:type_name -> credentials.CloudEnvironment - 42, // 33: sources.S3.session_token:type_name -> credentials.AWSSessionTokenSecret - 43, // 34: sources.Slack.tokens:type_name -> credentials.SlackTokens - 35, // 35: sources.Gerrit.basic_auth:type_name -> credentials.BasicAuth - 36, // 36: sources.Gerrit.unauthenticated:type_name -> credentials.Unauthenticated - 35, // 37: sources.Jenkins.basic_auth:type_name -> credentials.BasicAuth - 44, // 38: sources.Jenkins.header:type_name -> credentials.Header - 45, // 39: sources.Teams.authenticated:type_name -> credentials.ClientCredentials - 37, // 40: sources.Teams.oauth:type_name -> credentials.Oauth2 - 36, // 41: sources.Forager.unauthenticated:type_name -> credentials.Unauthenticated - 46, // 42: sources.Forager.since:type_name -> google.protobuf.Timestamp - 43, // 43: sources.SlackRealtime.tokens:type_name -> credentials.SlackTokens - 37, // 44: sources.Sharepoint.oauth:type_name -> credentials.Oauth2 - 37, // 45: sources.AzureRepos.oauth:type_name -> credentials.Oauth2 - 36, // 46: sources.Postman.unauthenticated:type_name -> credentials.Unauthenticated - 47, // [47:47] is the sub-list for method output_type - 47, // [47:47] is the sub-list for method input_type - 47, // [47:47] is the sub-list for extension type_name - 47, // [47:47] is the sub-list for extension extendee - 0, // [0:47] is the sub-list for field type_name + 37, // 11: sources.Docker.unauthenticated:type_name -> credentials.Unauthenticated + 36, // 12: sources.Docker.basic_auth:type_name -> credentials.BasicAuth + 39, // 13: sources.ECR.access_key:type_name -> credentials.KeySecret + 37, // 14: sources.GCS.unauthenticated:type_name -> credentials.Unauthenticated + 40, // 15: sources.GCS.adc:type_name -> credentials.CloudEnvironment + 38, // 16: sources.GCS.oauth:type_name -> credentials.Oauth2 + 36, // 17: sources.Git.basic_auth:type_name -> credentials.BasicAuth + 37, // 18: sources.Git.unauthenticated:type_name -> credentials.Unauthenticated + 41, // 19: sources.Git.ssh_auth:type_name -> credentials.SSHAuth + 38, // 20: sources.GitLab.oauth:type_name -> credentials.Oauth2 + 36, // 21: sources.GitLab.basic_auth:type_name -> credentials.BasicAuth + 42, // 22: sources.GitHub.github_app:type_name -> credentials.GitHubApp + 37, // 23: sources.GitHub.unauthenticated:type_name -> credentials.Unauthenticated + 36, // 24: sources.GitHub.basic_auth:type_name -> credentials.BasicAuth + 36, // 25: sources.JIRA.basic_auth:type_name -> credentials.BasicAuth + 37, // 26: sources.JIRA.unauthenticated:type_name -> credentials.Unauthenticated + 38, // 27: sources.JIRA.oauth:type_name -> credentials.Oauth2 + 37, // 28: sources.NPMUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated + 37, // 29: sources.PyPIUnauthenticatedPackage.unauthenticated:type_name -> credentials.Unauthenticated + 39, // 30: sources.S3.access_key:type_name -> credentials.KeySecret + 37, // 31: sources.S3.unauthenticated:type_name -> credentials.Unauthenticated + 40, // 32: sources.S3.cloud_environment:type_name -> credentials.CloudEnvironment + 43, // 33: sources.S3.session_token:type_name -> credentials.AWSSessionTokenSecret + 44, // 34: sources.Slack.tokens:type_name -> credentials.SlackTokens + 36, // 35: sources.Gerrit.basic_auth:type_name -> credentials.BasicAuth + 37, // 36: sources.Gerrit.unauthenticated:type_name -> credentials.Unauthenticated + 36, // 37: sources.Jenkins.basic_auth:type_name -> credentials.BasicAuth + 45, // 38: sources.Jenkins.header:type_name -> credentials.Header + 46, // 39: sources.Teams.authenticated:type_name -> credentials.ClientCredentials + 38, // 40: sources.Teams.oauth:type_name -> credentials.Oauth2 + 37, // 41: sources.Forager.unauthenticated:type_name -> credentials.Unauthenticated + 47, // 42: sources.Forager.since:type_name -> google.protobuf.Timestamp + 44, // 43: sources.SlackRealtime.tokens:type_name -> credentials.SlackTokens + 38, // 44: sources.Sharepoint.oauth:type_name -> credentials.Oauth2 + 38, // 45: sources.AzureRepos.oauth:type_name -> credentials.Oauth2 + 37, // 46: sources.Postman.unauthenticated:type_name -> credentials.Unauthenticated + 45, // 47: sources.Webhook.header:type_name -> credentials.Header + 48, // [48:48] is the sub-list for method output_type + 48, // [48:48] is the sub-list for method input_type + 48, // [48:48] is the sub-list for extension type_name + 48, // [48:48] is the sub-list for extension extendee + 0, // [0:48] is the sub-list for field type_name } func init() { file_sources_proto_init() } @@ -4795,6 +4884,18 @@ func file_sources_proto_init() { return nil } } + file_sources_proto_msgTypes[31].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*Webhook); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } file_sources_proto_msgTypes[1].OneofWrappers = []interface{}{ (*Artifactory_BasicAuth)(nil), @@ -4914,13 +5015,16 @@ func file_sources_proto_init() { (*Postman_Unauthenticated)(nil), (*Postman_Token)(nil), } + file_sources_proto_msgTypes[31].OneofWrappers = []interface{}{ + (*Webhook_Header)(nil), + } type x struct{} out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_sources_proto_rawDesc, NumEnums: 2, - NumMessages: 31, + NumMessages: 32, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/pb/sourcespb/sources.pb.validate.go b/pkg/pb/sourcespb/sources.pb.validate.go index c89ecdfff6c3..b650ac95293e 100644 --- a/pkg/pb/sourcespb/sources.pb.validate.go +++ b/pkg/pb/sourcespb/sources.pb.validate.go @@ -5589,3 +5589,189 @@ var _ interface { Cause() error ErrorName() string } = PostmanValidationError{} + +// Validate checks the field values on Webhook with the rules defined in the +// proto definition for this message. If any rules are violated, the first +// error encountered is returned, or nil if there are no violations. +func (m *Webhook) Validate() error { + return m.validate(false) +} + +// ValidateAll checks the field values on Webhook with the rules defined in the +// proto definition for this message. If any rules are violated, the result is +// a list of violation errors wrapped in WebhookMultiError, or nil if none found. +func (m *Webhook) ValidateAll() error { + return m.validate(true) +} + +func (m *Webhook) validate(all bool) error { + if m == nil { + return nil + } + + var errors []error + + if err := m._validateHostname(m.GetListenAddress()); err != nil { + err = WebhookValidationError{ + field: "ListenAddress", + reason: "value must be a valid hostname", + cause: err, + } + if !all { + return err + } + errors = append(errors, err) + } + + switch v := m.Credential.(type) { + case *Webhook_Header: + if v == nil { + err := WebhookValidationError{ + field: "Credential", + reason: "oneof value cannot be a typed-nil", + } + if !all { + return err + } + errors = append(errors, err) + } + + if all { + switch v := interface{}(m.GetHeader()).(type) { + case interface{ ValidateAll() error }: + if err := v.ValidateAll(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "Header", + reason: "embedded message failed validation", + cause: err, + }) + } + case interface{ Validate() error }: + if err := v.Validate(); err != nil { + errors = append(errors, WebhookValidationError{ + field: "Header", + reason: "embedded message failed validation", + cause: err, + }) + } + } + } else if v, ok := interface{}(m.GetHeader()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return WebhookValidationError{ + field: "Header", + reason: "embedded message failed validation", + cause: err, + } + } + } + + default: + _ = v // ensures v is used + } + + if len(errors) > 0 { + return WebhookMultiError(errors) + } + + return nil +} + +func (m *Webhook) _validateHostname(host string) error { + s := strings.ToLower(strings.TrimSuffix(host, ".")) + + if len(host) > 253 { + return errors.New("hostname cannot exceed 253 characters") + } + + for _, part := range strings.Split(s, ".") { + if l := len(part); l == 0 || l > 63 { + return errors.New("hostname part must be non-empty and cannot exceed 63 characters") + } + + if part[0] == '-' { + return errors.New("hostname parts cannot begin with hyphens") + } + + if part[len(part)-1] == '-' { + return errors.New("hostname parts cannot end with hyphens") + } + + for _, r := range part { + if (r < 'a' || r > 'z') && (r < '0' || r > '9') && r != '-' { + return fmt.Errorf("hostname parts can only contain alphanumeric characters or hyphens, got %q", string(r)) + } + } + } + + return nil +} + +// WebhookMultiError is an error wrapping multiple validation errors returned +// by Webhook.ValidateAll() if the designated constraints aren't met. +type WebhookMultiError []error + +// Error returns a concatenation of all the error messages it wraps. +func (m WebhookMultiError) Error() string { + var msgs []string + for _, err := range m { + msgs = append(msgs, err.Error()) + } + return strings.Join(msgs, "; ") +} + +// AllErrors returns a list of validation violation errors. +func (m WebhookMultiError) AllErrors() []error { return m } + +// WebhookValidationError is the validation error returned by Webhook.Validate +// if the designated constraints aren't met. +type WebhookValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e WebhookValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e WebhookValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e WebhookValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e WebhookValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e WebhookValidationError) ErrorName() string { return "WebhookValidationError" } + +// Error satisfies the builtin error interface +func (e WebhookValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sWebhook.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = WebhookValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = WebhookValidationError{} diff --git a/proto/source_metadata.proto b/proto/source_metadata.proto index 11f2c78e51af..89437a2bb6ca 100644 --- a/proto/source_metadata.proto +++ b/proto/source_metadata.proto @@ -4,6 +4,8 @@ package source_metadata; option go_package = "github.com/trufflesecurity/trufflehog/v3/pkg/pb/source_metadatapb"; +import "google/protobuf/timestamp.proto"; + message Azure { string container = 1; string file = 2; @@ -298,6 +300,20 @@ message Postman { string variable_type = 15; } + + +message Vector { + google.protobuf.Timestamp timestamp = 1; + string source_type = 2; + string host = 3; +} + +message Webhook { + oneof data { + Vector vector = 1; + } +} + message MetaData { oneof data { Azure azure = 1; @@ -329,5 +345,6 @@ message MetaData { AzureRepos azureRepos = 27; TravisCI travisCI = 28; Postman postman = 29; + Webhook webhook = 30; } } diff --git a/proto/sources.proto b/proto/sources.proto index 8fe9de6e1616..4dd5dab8227d 100644 --- a/proto/sources.proto +++ b/proto/sources.proto @@ -46,6 +46,7 @@ enum SourceType { SOURCE_TYPE_AZURE_REPOS = 31; SOURCE_TYPE_TRAVISCI = 32; SOURCE_TYPE_POSTMAN = 33; + SOURCE_TYPE_WEBHOOK = 34; } message LocalSource { @@ -399,4 +400,10 @@ message Postman { repeated string collection_paths = 12; repeated string environment_paths = 13; } - \ No newline at end of file + +message Webhook { + string listen_address = 1 [(validate.rules).string.hostname = true]; + oneof credential { + credentials.Header header = 2; + } +} From a317897d6627d4bb249a2926f609facb4982ca1f Mon Sep 17 00:00:00 2001 From: Cody Rose Date: Tue, 7 May 2024 11:11:11 -0400 Subject: [PATCH 03/51] increase test chan size (#2797) This test has a race condition. This change makes it less likely to cause a test failure, and is a stopgap measure to de-flake the test while we investigate the underlying issue. --- pkg/sources/source_manager_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/sources/source_manager_test.go b/pkg/sources/source_manager_test.go index e7c59dbbdad7..9106b2b8c6d2 100644 --- a/pkg/sources/source_manager_test.go +++ b/pkg/sources/source_manager_test.go @@ -242,7 +242,7 @@ func TestSourceManagerNonFatalError(t *testing.T) { } func TestSourceManagerContextCancelled(t *testing.T) { - mgr := NewManager(WithBufferedOutput(8)) + mgr := NewManager(WithBufferedOutput(16)) source, err := buildDummy(&counterChunker{count: 100}) assert.NoError(t, err) From 799a190d46a9df0e9b425f9dac5c6404a1d04abb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 13:45:09 -0700 Subject: [PATCH 04/51] fix(deps): update module golang.org/x/exp to v0.0.0-20240506185415-9bf2ced13842 (#2795) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index fc35eb4632d3..e0e8fb00880a 100644 --- a/go.mod +++ b/go.mod @@ -85,7 +85,7 @@ require ( go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 golang.org/x/crypto v0.23.0 - golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f + golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 golang.org/x/net v0.25.0 golang.org/x/oauth2 v0.20.0 golang.org/x/sync v0.7.0 @@ -276,7 +276,7 @@ require ( golang.org/x/sys v0.20.0 // indirect golang.org/x/term v0.20.0 // indirect golang.org/x/time v0.5.0 // indirect - golang.org/x/tools v0.20.0 // indirect + golang.org/x/tools v0.21.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect diff --git a/go.sum b/go.sum index 4d53f3ce79bf..3a45a2b3706f 100644 --- a/go.sum +++ b/go.sum @@ -913,6 +913,8 @@ golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEw golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= +golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1122,6 +1124,8 @@ golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= +golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= +golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From 07b2ed7256f5130de502b4a1aa358a0d465bfd0e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 15:12:06 -0700 Subject: [PATCH 05/51] fix(deps): update module github.com/brianvoe/gofakeit/v7 to v7.0.3 (#2798) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index e0e8fb00880a..160b1b5eef79 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 - github.com/brianvoe/gofakeit/v7 v7.0.2 + github.com/brianvoe/gofakeit/v7 v7.0.3 github.com/charmbracelet/bubbles v0.18.0 github.com/charmbracelet/bubbletea v0.26.1 github.com/charmbracelet/glamour v0.7.0 diff --git a/go.sum b/go.sum index 3a45a2b3706f..19a0fde7446b 100644 --- a/go.sum +++ b/go.sum @@ -201,6 +201,8 @@ github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 h1:XWuWBRFEpqVrHepQob9yPS3Xg4 github.com/bradleyfalzon/ghinstallation/v2 v2.10.0/go.mod h1:qoGA4DxWPaYTgVCrmEspVSjlTu4WYAiSxMIhorMRXXc= github.com/brianvoe/gofakeit/v7 v7.0.2 h1:jzYT7Ge3RDHw7J1CM1kwu0OQywV9vbf2qSGxBS72TCY= github.com/brianvoe/gofakeit/v7 v7.0.2/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= +github.com/brianvoe/gofakeit/v7 v7.0.3 h1:tGCt+eYfhTMWE1ko5G2EO1f/yE44yNpIwUb4h32O0wo= +github.com/brianvoe/gofakeit/v7 v7.0.3/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= From 418da524c4b2044df9eac03fb4aebdc93991d4cc Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 15:12:23 -0700 Subject: [PATCH 06/51] fix(deps): update module github.com/aws/aws-sdk-go to v1.52.4 (#2794) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 160b1b5eef79..f06067ca395e 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/TheZeroSlave/zapsentry v1.23.0 github.com/adrg/strutil v0.3.1 github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/aws/aws-sdk-go v1.52.2 + github.com/aws/aws-sdk-go v1.52.4 github.com/aymanbagabas/go-osc52 v1.2.2 github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb diff --git a/go.sum b/go.sum index 19a0fde7446b..ad7070ad94b4 100644 --- a/go.sum +++ b/go.sum @@ -176,6 +176,8 @@ github.com/aws/aws-sdk-go v1.51.32 h1:A6mPui7QP4mwmovyzgtdedbRbNur1Iu0/El7hBWNHm github.com/aws/aws-sdk-go v1.51.32/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.52.2 h1:l4g9wBXRBlvCtScvv4iLZCzLCtR7BFJcXOnOGQ20orw= github.com/aws/aws-sdk-go v1.52.2/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.52.4 h1:9VsBVJ2TKf8xPP3+yIPGSYcEBIEymXsJzQoFgQuyvA0= +github.com/aws/aws-sdk-go v1.52.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo= From 7568804771f673f5d8d392ecbc52f27b55d25e75 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 15:36:06 -0700 Subject: [PATCH 07/51] fix(deps): update module google.golang.org/api to v0.178.0 (#2800) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index f06067ca395e..4ff386925591 100644 --- a/go.mod +++ b/go.mod @@ -90,7 +90,7 @@ require ( golang.org/x/oauth2 v0.20.0 golang.org/x/sync v0.7.0 golang.org/x/text v0.15.0 - google.golang.org/api v0.177.0 + google.golang.org/api v0.178.0 google.golang.org/protobuf v1.34.1 gopkg.in/h2non/gock.v1 v1.1.2 pgregory.net/rapid v1.1.0 diff --git a/go.sum b/go.sum index ad7070ad94b4..b7bb93567d06 100644 --- a/go.sum +++ b/go.sum @@ -1160,6 +1160,8 @@ google.golang.org/api v0.176.1 h1:DJSXnV6An+NhJ1J+GWtoF2nHEuqB1VNoTfnIbjNvwD4= google.golang.org/api v0.176.1/go.mod h1:j2MaSDYcvYV1lkZ1+SMW4IeF90SrEyFA+tluDYWRrFg= google.golang.org/api v0.177.0 h1:8a0p/BbPa65GlqGWtUKxot4p0TV8OGOfyTjtmkXNXmk= google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw= +google.golang.org/api v0.178.0 h1:yoW/QMI4bRVCHF+NWOTa4cL8MoWL3Jnuc7FlcFF91Ok= +google.golang.org/api v0.178.0/go.mod h1:84/k2v8DFpDRebpGcooklv/lais3MEfqpaBLA12gl2U= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= From 4c7e8da9fb8018bb66ef60c68c29d3f6adfd7544 Mon Sep 17 00:00:00 2001 From: Sam Chan <144381343+theproductone@users.noreply.github.com> Date: Tue, 7 May 2024 17:51:39 -0600 Subject: [PATCH 08/51] Moved up enterprise section and added additional integrations (#2803) --- README.md | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 0379bd8bf75e..c0c9bb1687ff 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,16 @@ **...and more** +To learn more about about TruffleHog and its features and capabilities, visit our [product page](https://trufflesecurity.com/trufflehog?gclid=CjwKCAjwouexBhAuEiwAtW_Zx5IW87JNj97Ci7heFnA5ar6-DuNzT2Y5nIl9DuZ-FOUqx0Qg3vb9nxoClcEQAvD_BwE). + + + +# :money_with_wings: TruffleHog Enterprise + +Are you interested in continuously monitoring **Git, Jira, Slack, Confluence, Microsoft Teams, Sharepoint, and more..** for credentials? We have an enterprise product that can help! Reach out here to learn more at + +We take the revenue from the enterprise product to fund more awesome open source projects that the whole community can benefit from. + # :loudspeaker: Join Our Community @@ -662,8 +672,3 @@ the stability of the public APIs at this time. Since v3.0, TruffleHog is released under a AGPL 3 license, included in [`LICENSE`](LICENSE). TruffleHog v3.0 uses none of the previous codebase, but care was taken to preserve backwards compatibility on the command line interface. The work previous to this release is still available licensed under GPL 2.0 in the history of this repository and the previous package releases and tags. A completed CLA is required for us to accept contributions going forward. -# :money_with_wings: Enterprise product - -Are you interested in continuously monitoring your Git, Jira, Slack, Confluence, etc.. for credentials? We have an enterprise product that can help. Reach out here to learn more - -We take the revenue from the enterprise product to fund more awesome open source projects that the whole community can benefit from. From 6c37313bc94e92735ca85f94512054ce8164ca9f Mon Sep 17 00:00:00 2001 From: Sam Chan <144381343+theproductone@users.noreply.github.com> Date: Tue, 7 May 2024 19:06:37 -0600 Subject: [PATCH 09/51] Updating Enterprise Readme Link from Contact to Product Info Page (#2804) * updated link * updated enterprise emoji --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index c0c9bb1687ff..6ba906dbed60 100644 --- a/README.md +++ b/README.md @@ -28,9 +28,9 @@ To learn more about about TruffleHog and its features and capabilities, visit ou -# :money_with_wings: TruffleHog Enterprise +# :globe_with_meridians: TruffleHog Enterprise -Are you interested in continuously monitoring **Git, Jira, Slack, Confluence, Microsoft Teams, Sharepoint, and more..** for credentials? We have an enterprise product that can help! Reach out here to learn more at +Are you interested in continuously monitoring **Git, Jira, Slack, Confluence, Microsoft Teams, Sharepoint, and more..** for credentials? We have an enterprise product that can help! Learn more at . We take the revenue from the enterprise product to fund more awesome open source projects that the whole community can benefit from. From 8ef15e9cdccd376339b1daebb2f59229109ce2e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 7 May 2024 20:23:52 -0700 Subject: [PATCH 10/51] chore(deps): update golangci/golangci-lint-action action to v6 (#2801) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/lint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index dc0d9a1fe333..d0af742d84f2 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -20,7 +20,7 @@ jobs: go-version: "1.22" - uses: actions/checkout@v4 - name: golangci-lint - uses: golangci/golangci-lint-action@v5 + uses: golangci/golangci-lint-action@v6 with: # Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version version: latest From c7b72b98677722afac24a2bafe84bd98074129b4 Mon Sep 17 00:00:00 2001 From: ahrav Date: Wed, 8 May 2024 13:58:50 -0700 Subject: [PATCH 11/51] address linter (#2783) --- main.go | 19 ++++++++++++------- pkg/engine/engine.go | 17 +++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/main.go b/main.go index e77cfe2b1bd2..f5d36d7b3795 100644 --- a/main.go +++ b/main.go @@ -342,13 +342,13 @@ func run(state overseer.State) { // Verify that all the user-provided detectors support the optional // detector features. { - if err, id := verifyDetectorsAreVersioner(includeDetectorSet); err != nil { + if id, err := verifyDetectorsAreVersioner(includeDetectorSet); err != nil { logFatal(err, "invalid include list detector configuration", "detector", id) } - if err, id := verifyDetectorsAreVersioner(excludeDetectorSet); err != nil { + if id, err := verifyDetectorsAreVersioner(excludeDetectorSet); err != nil { logFatal(err, "invalid exclude list detector configuration", "detector", id) } - if err, id := verifyDetectorsAreVersioner(detectorsWithCustomVerifierEndpoints); err != nil { + if id, err := verifyDetectorsAreVersioner(detectorsWithCustomVerifierEndpoints); err != nil { logFatal(err, "invalid verifier detector configuration", "detector", id) } // Extra check for endpoint customization. @@ -608,6 +608,8 @@ func run(state overseer.State) { if err := e.ScanPostman(ctx, cfg); err != nil { logFatal(err, "Failed to scan Postman.") } + default: + logFatal(fmt.Errorf("invalid command"), "Command not recognized.") } // Wait for all workers to finish. @@ -691,7 +693,10 @@ func commaSeparatedToSlice(s []string) []string { } func printAverageDetectorTime(e *engine.Engine) { - fmt.Fprintln(os.Stderr, "Average detector time is the measurement of average time spent on each detector when results are returned.") + fmt.Fprintln( + os.Stderr, + "Average detector time is the measurement of average time spent on each detector when results are returned.", + ) for detectorName, duration := range e.GetDetectorsMetrics() { fmt.Fprintf(os.Stderr, "%s: %s\n", detectorName, duration) } @@ -724,7 +729,7 @@ func getWithDetectorID[T any](d detectors.Detector, data map[config.DetectorID]T // verifyDetectorsAreVersioner checks all keys in a provided map to verify the // provided type is actually a Versioner. -func verifyDetectorsAreVersioner[T any](data map[config.DetectorID]T) (error, config.DetectorID) { +func verifyDetectorsAreVersioner[T any](data map[config.DetectorID]T) (config.DetectorID, error) { isVersioner := engine.DefaultDetectorTypesImplementing[detectors.Versioner]() for id := range data { if id.Version == 0 { @@ -736,7 +741,7 @@ func verifyDetectorsAreVersioner[T any](data map[config.DetectorID]T) (error, co continue } // Version provided on a non-Versioner detector. - return fmt.Errorf("version provided but detector does not have a version"), id + return id, fmt.Errorf("version provided but detector does not have a version") } - return nil, config.DetectorID{} + return config.DetectorID{}, nil } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 0a810c5e6980..7c1e2ca1bb60 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -30,7 +30,10 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/sources" ) -var overlapError = errors.New("More than one detector has found this result. For your safety, verification has been disabled. You can override this behavior by using the --allow-verification-overlap flag.") +var errOverlap = errors.New( + "More than one detector has found this result. For your safety, verification has been disabled." + + "You can override this behavior by using the --allow-verification-overlap flag.", +) // Metrics for the scan engine for external consumption. type Metrics struct { @@ -383,7 +386,9 @@ func (e *Engine) initialize(ctx context.Context, options ...Option) error { e.notifyVerifiedResults = true e.notifyUnknownResults = true e.notifyUnverifiedResults = true - e.verificationOverlapChunksChan = make(chan verificationOverlapChunk, defaultChannelBuffer*verificationOverlapChunksChanMultiplier) + e.verificationOverlapChunksChan = make( + chan verificationOverlapChunk, defaultChannelBuffer*verificationOverlapChunksChanMultiplier, + ) e.results = make(chan detectors.ResultWithMetadata, defaultChannelBuffer) e.dedupeCache = cache e.printer = new(output.PlainPrinter) @@ -405,8 +410,8 @@ func (e *Engine) initSourceManager(ctx context.Context) { const defaultOutputBufferSize = 64 opts := []func(*sources.SourceManager){ - sources.WithConcurrentSources(int(e.concurrency)), - sources.WithConcurrentUnits(int(e.concurrency)), + sources.WithConcurrentSources(e.concurrency), + sources.WithConcurrentUnits(e.concurrency), sources.WithSourceUnits(), sources.WithBufferedOutput(defaultOutputBufferSize), } @@ -528,7 +533,7 @@ func (e *Engine) startWorkers(ctx context.Context) { const notifierWorkerRatio = 4 maxNotifierWorkers := 1 if numWorkers := e.concurrency / notifierWorkerRatio; numWorkers > 0 { - maxNotifierWorkers = int(numWorkers) + maxNotifierWorkers = numWorkers } ctx.Logger().V(2).Info("starting notifier workers", "count", maxNotifierWorkers) for worker := 0; worker < maxNotifierWorkers; worker++ { @@ -745,7 +750,7 @@ func (e *Engine) verificationOverlapWorker(ctx context.Context) { if e.verificationOverlapTracker != nil { e.verificationOverlapTracker.increment() } - res.SetVerificationError(overlapError) + res.SetVerificationError(errOverlap) e.processResult(ctx, detectableChunk{ chunk: chunk.chunk, detector: detector, From 4712deed5b75d452e1270ec223605a6e82cfb5ad Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 13:36:37 -0700 Subject: [PATCH 12/51] fix(deps): update module github.com/xanzy/go-gitlab to v0.104.1 (#2784) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 4ff386925591..314b20bc03d3 100644 --- a/go.mod +++ b/go.mod @@ -80,7 +80,7 @@ require ( github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0 github.com/trufflesecurity/disk-buffer-reader v0.2.1 github.com/wasilibs/go-re2 v1.5.2 - github.com/xanzy/go-gitlab v0.103.0 + github.com/xanzy/go-gitlab v0.104.1 go.mongodb.org/mongo-driver v1.15.0 go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index b7bb93567d06..11cb8186ad8d 100644 --- a/go.sum +++ b/go.sum @@ -810,6 +810,8 @@ github.com/xanzy/go-gitlab v0.102.0 h1:ExHuJ1OTQ2yt25zBMMj0G96ChBirGYv8U7HyUiYkZ github.com/xanzy/go-gitlab v0.102.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/go-gitlab v0.103.0 h1:J9pTQoq0GsEFqzd6srCM1QfdfKAxSNz6mT6ntrpNF2w= github.com/xanzy/go-gitlab v0.103.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= +github.com/xanzy/go-gitlab v0.104.1 h1:g/liXIPJH0jsTwVuzTAUMiKdTf6Qup3u2XZq5Rp90Wc= +github.com/xanzy/go-gitlab v0.104.1/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= From 43d5a07924d990cbd9dbc48c1267b5eb1d45fc69 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 18:13:47 -0700 Subject: [PATCH 13/51] fix(deps): update module github.com/rabbitmq/amqp091-go to v1.10.0 (#2809) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 314b20bc03d3..b791647265db 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/paulbellamy/ratecounter v0.2.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.0 - github.com/rabbitmq/amqp091-go v1.9.0 + github.com/rabbitmq/amqp091-go v1.10.0 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 github.com/shuheiktgw/go-travis v0.3.1 github.com/snowflakedb/gosnowflake v1.8.0 diff --git a/go.sum b/go.sum index 11cb8186ad8d..ba78129521e8 100644 --- a/go.sum +++ b/go.sum @@ -705,6 +705,8 @@ github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo= github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= +github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= +github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= From 305e1fb99fc8797758c5beffd2f5965fa44ea66c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 18:14:07 -0700 Subject: [PATCH 14/51] fix(deps): update module github.com/snowflakedb/gosnowflake to v1.10.0 (#2810) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go.mod b/go.mod index b791647265db..a1e38a9e8e29 100644 --- a/go.mod +++ b/go.mod @@ -71,7 +71,7 @@ require ( github.com/rabbitmq/amqp091-go v1.10.0 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 github.com/shuheiktgw/go-travis v0.3.1 - github.com/snowflakedb/gosnowflake v1.8.0 + github.com/snowflakedb/gosnowflake v1.10.0 github.com/stretchr/testify v1.9.0 github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 github.com/testcontainers/testcontainers-go v0.30.0 From 98912a98f7371d8dc34c9d0da65181cfa9529422 Mon Sep 17 00:00:00 2001 From: Richard Gomez <32133502+rgmz@users.noreply.github.com> Date: Thu, 9 May 2024 21:17:14 -0400 Subject: [PATCH 15/51] test(common/http): fix panic (#2817) --- pkg/common/http_test.go | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/pkg/common/http_test.go b/pkg/common/http_test.go index 5b35eb8dfdac..cc1711b42599 100644 --- a/pkg/common/http_test.go +++ b/pkg/common/http_test.go @@ -24,6 +24,10 @@ func TestRetryableHTTPClientCheckRetry(t *testing.T) { name: "Retry on 500 status, give up after 3 retries", responseStatus: http.StatusInternalServerError, // Server error status checkRetry: func(ctx context.Context, resp *http.Response, err error) (bool, error) { + if err != nil { + t.Errorf("expected response with 500 status, got error: %v", err) + return false, err + } // The underlying transport will retry on 500 status. if resp.StatusCode == http.StatusInternalServerError { return true, nil @@ -45,6 +49,10 @@ func TestRetryableHTTPClientCheckRetry(t *testing.T) { name: "Retry on 429 status, give up after 3 retries", responseStatus: http.StatusTooManyRequests, checkRetry: func(ctx context.Context, resp *http.Response, err error) (bool, error) { + if err != nil { + t.Errorf("expected response with 429 status, got error: %v", err) + return false, err + } // The underlying transport will retry on 429 status. if resp.StatusCode == http.StatusTooManyRequests { return true, nil @@ -79,7 +87,7 @@ func TestRetryableHTTPClientCheckRetry(t *testing.T) { // Bad linter, there is no body to close. _, err = client.Do(req) //nolint:bodyclose - if err != nil && slices.Contains([]int{http.StatusInternalServerError, http.StatusTooManyRequests}, tc.responseStatus) { + if slices.Contains([]int{http.StatusInternalServerError, http.StatusTooManyRequests}, tc.responseStatus) { // The underlying transport will retry on 500 and 429 status. assert.Error(t, err) } From af4f9f5cdd8a9165842c6f188310cb30ae7b6a00 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 18:17:49 -0700 Subject: [PATCH 16/51] fix(deps): update module github.com/aws/aws-sdk-go to v1.52.6 (#2816) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index a1e38a9e8e29..c8aed886b0b6 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/TheZeroSlave/zapsentry v1.23.0 github.com/adrg/strutil v0.3.1 github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/aws/aws-sdk-go v1.52.4 + github.com/aws/aws-sdk-go v1.52.6 github.com/aymanbagabas/go-osc52 v1.2.2 github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb diff --git a/go.sum b/go.sum index ba78129521e8..ddd6c4202260 100644 --- a/go.sum +++ b/go.sum @@ -178,6 +178,8 @@ github.com/aws/aws-sdk-go v1.52.2 h1:l4g9wBXRBlvCtScvv4iLZCzLCtR7BFJcXOnOGQ20orw github.com/aws/aws-sdk-go v1.52.2/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.52.4 h1:9VsBVJ2TKf8xPP3+yIPGSYcEBIEymXsJzQoFgQuyvA0= github.com/aws/aws-sdk-go v1.52.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.52.6 h1:nw1AMg0wIj5tTnI89KaDe9G5aISqXm4KJEe1DfNbFvA= +github.com/aws/aws-sdk-go v1.52.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo= From d35754ffbec1018395cb02729bb7d6cf57bffdd5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 18:56:40 -0700 Subject: [PATCH 17/51] fix(deps): update module github.com/hashicorp/go-retryablehttp to v0.7.6 (#2819) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c8aed886b0b6..c8d5d89be233 100644 --- a/go.mod +++ b/go.mod @@ -49,7 +49,7 @@ require ( github.com/google/uuid v1.6.0 github.com/googleapis/gax-go/v2 v2.12.4 github.com/h2non/filetype v1.1.3 - github.com/hashicorp/go-retryablehttp v0.7.5 + github.com/hashicorp/go-retryablehttp v0.7.6 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/jlaffaye/ftp v0.2.0 github.com/joho/godotenv v1.5.1 diff --git a/go.sum b/go.sum index ddd6c4202260..6ce54333a571 100644 --- a/go.sum +++ b/go.sum @@ -501,6 +501,8 @@ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+l github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.6 h1:TwRYfx2z2C4cLbXmT8I5PgP/xmuqASDyiVuGYfs9GZM= +github.com/hashicorp/go-retryablehttp v0.7.6/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= From 41781ab116f1cf0a2f71db4087aa6af78eafd455 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 9 May 2024 18:57:16 -0700 Subject: [PATCH 18/51] fix(deps): update module github.com/charmbracelet/bubbletea to v0.26.2 (#2818) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c8d5d89be233..065465cb85c2 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 github.com/brianvoe/gofakeit/v7 v7.0.3 github.com/charmbracelet/bubbles v0.18.0 - github.com/charmbracelet/bubbletea v0.26.1 + github.com/charmbracelet/bubbletea v0.26.2 github.com/charmbracelet/glamour v0.7.0 github.com/charmbracelet/lipgloss v0.10.0 github.com/coinbase/waas-client-library-go v1.0.8 diff --git a/go.sum b/go.sum index 6ce54333a571..2993b6c6ce9b 100644 --- a/go.sum +++ b/go.sum @@ -219,6 +219,8 @@ github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= github.com/charmbracelet/bubbletea v0.26.1 h1:xujcQeF73rh4jwu3+zhfQsvV18x+7zIjlw7/CYbzGJ0= github.com/charmbracelet/bubbletea v0.26.1/go.mod h1:FzKr7sKoO8iFVcdIBM9J0sJOcQv5nDQaYwsee3kpbgo= +github.com/charmbracelet/bubbletea v0.26.2 h1:Eeb+n75Om9gQ+I6YpbCXQRKHt5Pn4vMwusQpwLiEgJQ= +github.com/charmbracelet/bubbletea v0.26.2/go.mod h1:6I0nZ3YHUrQj7YHIHlM8RySX4ZIthTliMY+W8X8b+Gs= github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng= github.com/charmbracelet/glamour v0.7.0/go.mod h1:jUMh5MeihljJPQbJ/wf4ldw2+yBP59+ctV36jASy7ps= github.com/charmbracelet/lipgloss v0.10.0 h1:KWeXFSexGcfahHX+54URiZGkBFazf70JNMtwg/AFW3s= From 0712df086b56e37dfeea7d3bbfa306d46b1d1c7d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 10 May 2024 07:21:54 -0700 Subject: [PATCH 19/51] fix(deps): update module github.com/prometheus/client_golang to v1.19.1 (#2821) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 065465cb85c2..1a4cfc0c372b 100644 --- a/go.mod +++ b/go.mod @@ -67,7 +67,7 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/paulbellamy/ratecounter v0.2.0 github.com/pkg/errors v0.9.1 - github.com/prometheus/client_golang v1.19.0 + github.com/prometheus/client_golang v1.19.1 github.com/rabbitmq/amqp091-go v1.10.0 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 github.com/shuheiktgw/go-travis v0.3.1 diff --git a/go.sum b/go.sum index 2993b6c6ce9b..282bcd2b6dc6 100644 --- a/go.sum +++ b/go.sum @@ -702,6 +702,8 @@ github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= From 9d4eb9516f4608f4e887a4f71997dae5b991a1d3 Mon Sep 17 00:00:00 2001 From: Dustin Decker Date: Fri, 10 May 2024 10:30:08 -0700 Subject: [PATCH 20/51] Update postman flags to be less confusing (#2755) * Update postman flags to be less confusing * Update readme * fmt --- README.md | 12 ++++++------ main.go | 53 ++++++++++++++++++++++++++++++++++++++++++----------- 2 files changed, 48 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 6ba906dbed60..28810537e167 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ --- -# :mag_right: _Now Scanning_ +# :mag*right: \_Now Scanning*
@@ -64,7 +64,7 @@ brew install trufflehog ### Docker: -*Ensure Docker engine is running before executing the following commands:* +_Ensure Docker engine is running before executing the following commands:_ ####     Unix @@ -261,10 +261,10 @@ trufflehog git file://. --since-commit main --branch feature-1 --only-verified - ## 12: Scan a Postman workspace -Use the `--workspace`, `--collection`, `--environment` flags multiple times to scan multiple targets. +Use the `--workspace-id`, `--collection-id`, `--environment` flags multiple times to scan multiple targets. ```bash -trufflehog postman --token= --workspace= +trufflehog postman --token= --workspace-id= ``` # :question: FAQ @@ -497,7 +497,7 @@ If you'd like to specify specific `base` and `head` refs, you can use the `base` ```yaml stages: - security - + security-secrets: stage: security allow_failure: false @@ -626,7 +626,7 @@ class Verifier(BaseHTTPRequestHandler): self.log_message("%s", request) # check the match, you'll need to implement validateToken, which takes an array of ID's and Secrets - if not validateTokens(request['HogTokenDetector']['hogID'], request['HogTokenDetector']['hogSecret']): + if not validateTokens(request['HogTokenDetector']['hogID'], request['HogTokenDetector']['hogSecret']): self.send_response(200) self.end_headers() else: diff --git a/main.go b/main.go index f5d36d7b3795..a538e7bdc5ff 100644 --- a/main.go +++ b/main.go @@ -155,14 +155,25 @@ var ( travisCiScanToken = travisCiScan.Flag("token", "TravisCI token. Can also be provided with environment variable").Envar("TRAVISCI_TOKEN").Required().String() // Postman is hidden for now until we get more feedback from the community. - postmanScan = cli.Command("postman", "Scan Postman") - postmanToken = postmanScan.Flag("token", "Postman token. Can also be provided with environment variable").Envar("POSTMAN_TOKEN").String() - postmanWorkspaces = postmanScan.Flag("workspace", "Postman workspace to scan. You can repeat this flag.").Strings() - postmanCollections = postmanScan.Flag("collection", "Postman collection to scan. You can repeat this flag.").Strings() - postmanEnvironments = postmanScan.Flag("environment", "Postman environment to scan. You can repeat this flag.").Strings() - postmanIncludeCollections = postmanScan.Flag("include-collections", "Collections to include in scan. You can repeat this flag.").Strings() + postmanScan = cli.Command("postman", "Scan Postman") + postmanToken = postmanScan.Flag("token", "Postman token. Can also be provided with environment variable").Envar("POSTMAN_TOKEN").String() + + postmanWorkspaces = postmanScan.Flag("workspace", "Postman workspace to scan. You can repeat this flag. Deprecated flag.").Hidden().Strings() + postmanWorkspaceIDs = postmanScan.Flag("workspace-id", "Postman workspace ID to scan. You can repeat this flag.").Strings() + + postmanCollections = postmanScan.Flag("collection", "Postman collection to scan. You can repeat this flag. Deprecated flag.").Hidden().Strings() + postmanCollectionIDs = postmanScan.Flag("collection-id", "Postman collection ID to scan. You can repeat this flag.").Strings() + + postmanEnvironments = postmanScan.Flag("environment", "Postman environment to scan. You can repeat this flag.").Strings() + + postmanIncludeCollections = postmanScan.Flag("include-collections", "Collections to include in scan. You can repeat this flag. Deprecated flag.").Hidden().Strings() + postmanIncludeCollectionIDs = postmanScan.Flag("include-collection-id", "Collection ID to include in scan. You can repeat this flag.").Strings() + postmanIncludeEnvironments = postmanScan.Flag("include-environments", "Environments to include in scan. You can repeat this flag.").Strings() - postmanExcludeCollections = postmanScan.Flag("exclude-collections", "Collections to exclude from scan. You can repeat this flag.").Strings() + + postmanExcludeCollections = postmanScan.Flag("exclude-collections", "Collections to exclude from scan. You can repeat this flag. Deprecated flag.").Hidden().Strings() + postmanExcludeCollectionIDs = postmanScan.Flag("exclude-collection-id", "Collection ID to exclude from scan. You can repeat this flag.").Strings() + postmanExcludeEnvironments = postmanScan.Flag("exclude-environments", "Environments to exclude from scan. You can repeat this flag.").Strings() postmanWorkspacePaths = postmanScan.Flag("workspace-paths", "Path to Postman workspaces.").Strings() postmanCollectionPaths = postmanScan.Flag("collection-paths", "Path to Postman collections.").Strings() @@ -592,14 +603,34 @@ func run(state overseer.State) { logFatal(err, "Failed to scan Docker.") } case postmanScan.FullCommand(): + // handle deprecated flag + workspaceIDs := make([]string, 0, len(*postmanWorkspaceIDs)+len(*postmanWorkspaces)) + workspaceIDs = append(workspaceIDs, *postmanWorkspaceIDs...) + workspaceIDs = append(workspaceIDs, *postmanWorkspaces...) + + // handle deprecated flag + collectionIDs := make([]string, 0, len(*postmanCollectionIDs)+len(*postmanCollections)) + collectionIDs = append(collectionIDs, *postmanCollectionIDs...) + collectionIDs = append(collectionIDs, *postmanCollections...) + + // handle deprecated flag + includeCollectionIDs := make([]string, 0, len(*postmanIncludeCollectionIDs)+len(*postmanIncludeCollections)) + includeCollectionIDs = append(includeCollectionIDs, *postmanIncludeCollectionIDs...) + includeCollectionIDs = append(includeCollectionIDs, *postmanIncludeCollections...) + + // handle deprecated flag + excludeCollectionIDs := make([]string, 0, len(*postmanExcludeCollectionIDs)+len(*postmanExcludeCollections)) + excludeCollectionIDs = append(excludeCollectionIDs, *postmanExcludeCollectionIDs...) + excludeCollectionIDs = append(excludeCollectionIDs, *postmanExcludeCollections...) + cfg := sources.PostmanConfig{ Token: *postmanToken, - Workspaces: *postmanWorkspaces, - Collections: *postmanCollections, + Workspaces: workspaceIDs, + Collections: collectionIDs, Environments: *postmanEnvironments, - IncludeCollections: *postmanIncludeCollections, + IncludeCollections: includeCollectionIDs, IncludeEnvironments: *postmanIncludeEnvironments, - ExcludeCollections: *postmanExcludeCollections, + ExcludeCollections: excludeCollectionIDs, ExcludeEnvironments: *postmanExcludeEnvironments, CollectionPaths: *postmanCollectionPaths, WorkspacePaths: *postmanWorkspacePaths, From 570cec756567111a08ca4cfa651b7810588bd2ec Mon Sep 17 00:00:00 2001 From: ahrav Date: Fri, 10 May 2024 11:36:06 -0700 Subject: [PATCH 21/51] [refactor] - Refactor Archive Handling Logic (#2703) * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Adjust check for rpm/deb archive type * add additional deb mime type * update comment * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Adjust check for rpm/deb archive type * add additional deb mime type * update comment * go mod tidy * update go mod * go mod tidy * add comment * update max depth check to > * go mod tidy * rename * [refactor] - Refactor Archive Handling Logic - Part 4: Non-Archive Data Handling and Cleanup (#2704) * Handle non-archive data within the DefaultHandler * make structs and methods private * Remove non-archive data handling within sources * Handle non-archive data within the DefaultHandler * rebase * Remove non-archive data handling within sources * add gzip * move diskbuffered rereader setup into handler pkg * remove DiskBuffereReader creation logic within sources * move rewind closer * reduce log verbosity * make defaultBufferSize a const * use correct reader * address comments * update test * [feat] - Add Prometheus Metrics for File Handlers (#2705) * add metrics for file handling * add metrics for errors * add metrics for file handling * add metrics for errors * fix tests * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * fix err assignment * add metrics for file handling * add metrics for errors * fix tests * rebase * add metrics for errors * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * fix err assignment * rebase * remove * update metric to ms * update comments * address comments * reduce indentations * add metrics for archive depth * [bug] - Enhanced Archive Handling to Address Interface Constraints (#2710) * add metrics for file handling * add metrics for errors * add metrics for file handling * add metrics for errors * fix tests * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * Address incompatible reader to openArchive * remove nil check * fix err assignment * wrap compReader with DiskbufferReader * add metrics for file handling * add metrics for errors * fix tests * rebase * add metrics for errors * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * fix err assignment * rebase * remove * update metric to ms * update comments * address comments * reduce indentations * replace diskbuffereader with bufferedfilereader * updtes * add metric back * [bug] - Fix bug and simplify git cat-file command execution and output handling (#2719) * add metrics for file handling * add metrics for errors * add metrics for file handling * add metrics for errors * fix tests * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * Address incompatible reader to openArchive * remove nil check * fix err assignment * Allow git cat-file blob to complete before trying to handle the file * wrap compReader with DiskbufferReader * Allow git cat-file blob to complete before trying to handle the file * updates * revert stuff * update test * remove * add metrics for file handling * add metrics for errors * fix tests * rebase * add metrics for errors * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * fix err assignment * rebase * remove * update metric to ms * update comments * address comments * reduce indentations * inline --- go.mod | 10 +- go.sum | 225 +------ pkg/handlers/ar.go | 80 +++ pkg/handlers/ar_test.go | 32 + pkg/handlers/archive.go | 554 ------------------ pkg/handlers/archive_test.go | 493 ---------------- pkg/handlers/default.go | 282 +++++++++ pkg/handlers/default_test.go | 124 ++++ pkg/handlers/handlers.go | 241 ++++++-- pkg/handlers/handlers_test.go | 214 +++++++ pkg/handlers/metrics.go | 183 ++++++ pkg/handlers/rpm.go | 87 +++ pkg/handlers/rpm_test.go | 32 + pkg/handlers/testdata/example.zip.gz | Bin 0 -> 185 bytes .../testdata/nested-compressed-archive.tar.gz | Bin 0 -> 391 bytes pkg/handlers/testdata/nested-dirs.zip | Bin 0 -> 2318 bytes pkg/sources/filesystem/filesystem.go | 48 +- pkg/sources/gcs/gcs.go | 48 +- pkg/sources/git/git.go | 62 +- pkg/sources/s3/s3.go | 36 +- 20 files changed, 1248 insertions(+), 1503 deletions(-) create mode 100644 pkg/handlers/ar.go create mode 100644 pkg/handlers/ar_test.go delete mode 100644 pkg/handlers/archive.go delete mode 100644 pkg/handlers/archive_test.go create mode 100644 pkg/handlers/default.go create mode 100644 pkg/handlers/default_test.go create mode 100644 pkg/handlers/handlers_test.go create mode 100644 pkg/handlers/metrics.go create mode 100644 pkg/handlers/rpm.go create mode 100644 pkg/handlers/rpm_test.go create mode 100644 pkg/handlers/testdata/example.zip.gz create mode 100644 pkg/handlers/testdata/nested-compressed-archive.tar.gz create mode 100644 pkg/handlers/testdata/nested-dirs.zip diff --git a/go.mod b/go.mod index 1a4cfc0c372b..43e02836576f 100644 --- a/go.mod +++ b/go.mod @@ -48,7 +48,6 @@ require ( github.com/google/go-github/v61 v61.0.0 github.com/google/uuid v1.6.0 github.com/googleapis/gax-go/v2 v2.12.4 - github.com/h2non/filetype v1.1.3 github.com/hashicorp/go-retryablehttp v0.7.6 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/jlaffaye/ftp v0.2.0 @@ -69,6 +68,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.1 github.com/rabbitmq/amqp091-go v1.10.0 + github.com/sassoftware/go-rpmutils v0.3.0 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 github.com/shuheiktgw/go-travis v0.3.1 github.com/snowflakedb/gosnowflake v1.10.0 @@ -93,6 +93,7 @@ require ( google.golang.org/api v0.178.0 google.golang.org/protobuf v1.34.1 gopkg.in/h2non/gock.v1 v1.1.2 + pault.ag/go/debian v0.16.0 pgregory.net/rapid v1.1.0 sigs.k8s.io/yaml v1.4.0 ) @@ -101,7 +102,6 @@ require ( cloud.google.com/go v0.112.2 // indirect cloud.google.com/go/auth v0.3.0 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect - cloud.google.com/go/compute v1.25.1 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v1.1.7 // indirect cloud.google.com/go/longrunning v0.5.6 // indirect @@ -118,6 +118,7 @@ require ( github.com/Azure/go-autorest/logger v0.2.1 // indirect github.com/Azure/go-autorest/tracing v0.6.0 // indirect github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 // indirect + github.com/DataDog/zstd v1.5.5 // indirect github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c // indirect github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect @@ -137,7 +138,6 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 // indirect github.com/containerd/containerd v1.7.12 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect @@ -198,6 +198,7 @@ require ( github.com/josharian/intern v1.0.0 // indirect github.com/jpillora/s3 v1.1.4 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect + github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d // indirect github.com/klauspost/compress v1.17.4 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect @@ -258,6 +259,7 @@ require ( github.com/xdg-go/scram v1.1.2 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect + github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/yuin/goldmark v1.5.4 // indirect github.com/yuin/goldmark-emoji v1.0.2 // indirect @@ -278,7 +280,6 @@ require ( golang.org/x/time v0.5.0 // indirect golang.org/x/tools v0.21.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect - google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect @@ -286,4 +287,5 @@ require ( gopkg.in/square/go-jose.v2 v2.6.0 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect + pault.ag/go/topsort v0.1.1 // indirect ) diff --git a/go.sum b/go.sum index 282bcd2b6dc6..fb63fca994de 100644 --- a/go.sum +++ b/go.sum @@ -7,43 +7,23 @@ cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTj cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= -cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= -cloud.google.com/go/auth v0.2.0 h1:y6oTcpMSbOcXbwYgUUrvI+mrQ2xbrcdpPgtVbCGTLTk= -cloud.google.com/go/auth v0.2.0/go.mod h1:+yb+oy3/P0geX6DLKlqiGHARGR6EX2GRtYCzWOCQSbU= -cloud.google.com/go/auth v0.2.2 h1:gmxNJs4YZYcw6YvKRtVBaF2fyUE6UrWPyzU8jHvYfmI= -cloud.google.com/go/auth v0.2.2/go.mod h1:2bDNJWtWziDT3Pu1URxHHbkHE/BbOCuyUiKIGcNvafo= cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs= cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w= -cloud.google.com/go/auth/oauth2adapt v0.2.0 h1:FR8zevgQwu+8CqiOT5r6xCmJa3pJC/wdXEEPF1OkNhA= -cloud.google.com/go/auth/oauth2adapt v0.2.0/go.mod h1:AfqujpDAlTfLfeCIl/HJZZlIxD8+nJoZ5e0x1IxGq5k= -cloud.google.com/go/auth/oauth2adapt v0.2.1 h1:VSPmMmUlT8CkIZ2PzD9AlLN+R3+D1clXMWHHa6vG/Ag= -cloud.google.com/go/auth/oauth2adapt v0.2.1/go.mod h1:tOdK/k+D2e4GEwfBRA48dKNQiDsqIXxLh7VU319eV0g= cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= -cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= -cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= -cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= -cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= -cloud.google.com/go/longrunning v0.5.5 h1:GOE6pZFdSrTb4KAiKnXsJBtlE6mEyaW44oKyMILWnOg= -cloud.google.com/go/longrunning v0.5.5/go.mod h1:WV2LAxD8/rg5Z1cNW6FJ/ZpX4E4VnDnoTk0yawPBB7s= cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXmjuEaE= cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/secretmanager v1.12.0 h1:e5pIo/QEgiFiHPVJPxM5jbtUr4O/u5h2zLHYtkFQr24= -cloud.google.com/go/secretmanager v1.12.0/go.mod h1:Y1Gne3Ag+fZ2TDTiJc8ZJCMFbi7k1rYT4Rw30GXfvlk= cloud.google.com/go/secretmanager v1.13.0 h1:nQ/Ca2Gzm/OEP8tr1hiFdHRi5wAnAmsm9qTjwkivyrQ= cloud.google.com/go/secretmanager v1.13.0/go.mod h1:yWdfNmM2sLIiyv6RM6VqWKeBV7CdS0SO3ybxJJRhBEs= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= @@ -100,6 +80,8 @@ github.com/BobuSumisu/aho-corasick v1.0.3/go.mod h1:hm4jLcvZKI2vRF2WDU1N4p/jpWtp github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/zstd v1.5.5 h1:oWf5W7GtOLgp6bciQYDmhHHjdhYkALu6S/5Ni9ZgSvQ= +github.com/DataDog/zstd v1.5.5/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c h1:RGWPOewvKIROun94nF7v2cua9qP+thov/7M50KEoeSU= github.com/JohnCGriffin/overflow v0.0.0-20211019200055-46fa312c352c/go.mod h1:X0CRv0ky0k6m906ixxpzmDRLvX58TFUKS2eePweuyxk= github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= @@ -109,8 +91,6 @@ github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7 github.com/Microsoft/hcsshim v0.11.4/go.mod h1:smjE4dvqPX9Zldna+t5FG3rnoHhaB7QYxPRqGcpAD9w= github.com/ProtonMail/go-crypto v1.0.0 h1:LRuvITjQWX+WIfr930YHG2HNfjR1uOfyf5vE0kC2U78= github.com/ProtonMail/go-crypto v1.0.0/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/TheZeroSlave/zapsentry v1.22.1 h1:NB7JW4SDlWCdEZ+7qqbjfS3hkvuJuTRAvHh4RRKo4BY= -github.com/TheZeroSlave/zapsentry v1.22.1/go.mod h1:D1YMfSuu6xnkhwFXxrronesmsiyDhIqo+86I3Ok+r64= github.com/TheZeroSlave/zapsentry v1.23.0 h1:TKyzfEL7LRlRr+7AvkukVLZ+jZPC++ebCUv7ZJHl1AU= github.com/TheZeroSlave/zapsentry v1.23.0/go.mod h1:3DRFLu4gIpnCTD4V9HMCBSaqYP8gYU7mZickrs2/rIY= github.com/adrg/strutil v0.3.1 h1:OLvSS7CSJO8lBii4YmBt8jiK9QOtB9CzCzwl4Ic/Fz4= @@ -125,8 +105,7 @@ github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74 h1:Kk6a4nehpJ3UuJRqlA3JxYxBZEqCeOmATOvrbT4p9RA= -github.com/alexbrainman/sspi v0.0.0-20210105120005-909beea2cc74/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= +github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa h1:LHTHcTQiSGT7VVbI0o4wBRNQIgn917usHWOd6VAffYI= github.com/alexbrainman/sspi v0.0.0-20231016080023-1a75b4708caa/go.mod h1:cEWa1LVoE5KvSD9ONXsZrj0z6KqySlCCNKHlLzbqAt4= github.com/andybalholm/brotli v1.0.6 h1:Yf9fFpf49Zrxb9NlQaluyE92/+X7UVHlhMNJN2sxfOI= github.com/andybalholm/brotli v1.0.6/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= @@ -138,46 +117,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aws/aws-sdk-go v1.51.14 h1:qedX6zZEO1a+5kra+D4ythOYR3TgaROC0hTPxhTFh8I= -github.com/aws/aws-sdk-go v1.51.14/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.16 h1:vnWKK8KjbftEkuPX8bRj3WHsLy1uhotn0eXptpvrxJI= -github.com/aws/aws-sdk-go v1.51.16/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.17 h1:Cfa40lCdjv9OxC3X1Ks3a6O1Tu3gOANSyKHOSw/zuWU= -github.com/aws/aws-sdk-go v1.51.17/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.18 h1:JKrk49ZlBTyKa4+droU7U/hk0QG84v91xaA58O0LPdo= -github.com/aws/aws-sdk-go v1.51.18/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.19 h1:jp/Vx/mUpXttthvvo/4/Nn/3+zumirIlAFkp1Irf1kM= -github.com/aws/aws-sdk-go v1.51.19/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.20 h1:ziM90ujYHKKkoTZL+Wg2LwjbQecL+l298GGJeG4ktZs= -github.com/aws/aws-sdk-go v1.51.20/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.21 h1:UrT6JC9R9PkYYXDZBV0qDKTualMr+bfK2eboTknMgbs= -github.com/aws/aws-sdk-go v1.51.21/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.22 h1:VL2p2JgC32myt7DMEcbe1devdtgGSgMNvZpkcdvlxq4= -github.com/aws/aws-sdk-go v1.51.22/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.23 h1:/3TEdsEE/aHmdKGw2NrOp7Sdea76zfffGkTTSXTsDxY= -github.com/aws/aws-sdk-go v1.51.23/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.24 h1:nwL5MaommPkwb7Ixk24eWkdx5HY4of1gD10kFFVAl6A= -github.com/aws/aws-sdk-go v1.51.24/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.25 h1:DjTT8mtmsachhV6yrXR8+yhnG6120dazr720nopRsls= -github.com/aws/aws-sdk-go v1.51.25/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.26 h1:fYud+95lh9B89fAlRtgYpY8CcJF4T7JrWkLMq4GGCOo= -github.com/aws/aws-sdk-go v1.51.26/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.27 h1:ZprksHovT4rFfNBHB+Bc/0p4PTntAnTlZP39DMA/Qp8= -github.com/aws/aws-sdk-go v1.51.27/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.28 h1:x3CV5xjnL4EbVLaPXulBOxqiq2dkc9o6+50xxT3tvXY= -github.com/aws/aws-sdk-go v1.51.28/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.29 h1:18I5kjEcbyJOH4l2EjQyJJG6v3uPjrzwG0uiSD3vJEM= -github.com/aws/aws-sdk-go v1.51.29/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.30 h1:RVFkjn9P0JMwnuZCVH0TlV5k9zepHzlbc4943eZMhGw= -github.com/aws/aws-sdk-go v1.51.30/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.31 h1:4TM+sNc+Dzs7wY1sJ0+J8i60c6rkgnKP1pvPx8ghsSY= -github.com/aws/aws-sdk-go v1.51.31/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.51.32 h1:A6mPui7QP4mwmovyzgtdedbRbNur1Iu0/El7hBWNHms= -github.com/aws/aws-sdk-go v1.51.32/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.52.2 h1:l4g9wBXRBlvCtScvv4iLZCzLCtR7BFJcXOnOGQ20orw= -github.com/aws/aws-sdk-go v1.52.2/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.52.4 h1:9VsBVJ2TKf8xPP3+yIPGSYcEBIEymXsJzQoFgQuyvA0= -github.com/aws/aws-sdk-go v1.52.4/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.52.6 h1:nw1AMg0wIj5tTnI89KaDe9G5aISqXm4KJEe1DfNbFvA= github.com/aws/aws-sdk-go v1.52.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= @@ -203,8 +142,6 @@ github.com/bodgit/windows v1.0.1 h1:tF7K6KOluPYygXa3Z2594zxlkbKPAOvqr97etrGNIz4= github.com/bodgit/windows v1.0.1/go.mod h1:a6JLwrB4KrTR5hBpp8FI9/9W9jJfeQ2h4XDXU74ZCdM= github.com/bradleyfalzon/ghinstallation/v2 v2.10.0 h1:XWuWBRFEpqVrHepQob9yPS3Xg4K3Wr9QCx4fu8HbUNg= github.com/bradleyfalzon/ghinstallation/v2 v2.10.0/go.mod h1:qoGA4DxWPaYTgVCrmEspVSjlTu4WYAiSxMIhorMRXXc= -github.com/brianvoe/gofakeit/v7 v7.0.2 h1:jzYT7Ge3RDHw7J1CM1kwu0OQywV9vbf2qSGxBS72TCY= -github.com/brianvoe/gofakeit/v7 v7.0.2/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/brianvoe/gofakeit/v7 v7.0.3 h1:tGCt+eYfhTMWE1ko5G2EO1f/yE44yNpIwUb4h32O0wo= github.com/brianvoe/gofakeit/v7 v7.0.3/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= @@ -215,10 +152,6 @@ github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charmbracelet/bubbles v0.18.0 h1:PYv1A036luoBGroX6VWjQIE9Syf2Wby2oOl/39KLfy0= github.com/charmbracelet/bubbles v0.18.0/go.mod h1:08qhZhtIwzgrtBjAcJnij1t1H0ZRjwHyGsy6AL11PSw= -github.com/charmbracelet/bubbletea v0.25.0 h1:bAfwk7jRz7FKFl9RzlIULPkStffg5k6pNt5dywy4TcM= -github.com/charmbracelet/bubbletea v0.25.0/go.mod h1:EN3QDR1T5ZdWmdfDzYcqOCAps45+QIJbLOBxmVNWNNg= -github.com/charmbracelet/bubbletea v0.26.1 h1:xujcQeF73rh4jwu3+zhfQsvV18x+7zIjlw7/CYbzGJ0= -github.com/charmbracelet/bubbletea v0.26.1/go.mod h1:FzKr7sKoO8iFVcdIBM9J0sJOcQv5nDQaYwsee3kpbgo= github.com/charmbracelet/bubbletea v0.26.2 h1:Eeb+n75Om9gQ+I6YpbCXQRKHt5Pn4vMwusQpwLiEgJQ= github.com/charmbracelet/bubbletea v0.26.2/go.mod h1:6I0nZ3YHUrQj7YHIHlM8RySX4ZIthTliMY+W8X8b+Gs= github.com/charmbracelet/glamour v0.7.0 h1:2BtKGZ4iVJCDfMF229EzbeR1QRKLWztO9dMtjmqZSng= @@ -241,27 +174,20 @@ github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBS github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coinbase/waas-client-library-go v1.0.8 h1:AdbTmBQpsSUx947GZd5/68BhNBw1CSwTfE2PcnVy3Ao= github.com/coinbase/waas-client-library-go v1.0.8/go.mod h1:RVKozprfdfMiK92ATZUWHRs0EFGHQj4rbEJjzzZzI1I= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY= -github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNAHhJogcZtrNHdKrA99/FCCRjE3HD36o= -github.com/couchbase/gocb/v2 v2.8.0 h1:KoG44zWrP4QgK724D7D2rXHgRlztwkAPFQVApJCJaB4= -github.com/couchbase/gocb/v2 v2.8.0/go.mod h1:GL6M8F4eB5ZuoTYh2RzwCUheVVi4EADdCQ3yc52kqUI= github.com/couchbase/gocb/v2 v2.8.1 h1:syeJEVy36IvUy4wyzK/74M4wc4OJ2eWZ1d6yWG31Qno= github.com/couchbase/gocb/v2 v2.8.1/go.mod h1:xI7kkiz4IhdrhBAAEcKC6R2oqVXxpMIV/ZkmxB+PWgM= -github.com/couchbase/gocbcore/v10 v10.4.0 h1:ItBAQdxl5I9CBkt/XqlRB/Ni4Ej2k2OK1ClB2HHipVE= -github.com/couchbase/gocbcore/v10 v10.4.0/go.mod h1:lYQIIk+tzoMcwtwU5GzPbDdqEkwkH3isI2rkSpfL0oM= github.com/couchbase/gocbcore/v10 v10.4.1 h1:2vZjYRTbSCp1HEcL3iFQv+r4HwiI13VhdnbTku+E/+M= github.com/couchbase/gocbcore/v10 v10.4.1/go.mod h1:rulbgUK70EuyRUiLQ0LhQAfSI/Rl+jWws8tTbHzvB6M= github.com/couchbase/gocbcoreps v0.1.2 h1:wlGyyMnkWpCNOlTtfy8UG+8XZsFtqTJtPXz63+QKC58= github.com/couchbase/gocbcoreps v0.1.2/go.mod h1:33hSdOKnrUVaBqw4+RiqW+2JoD8ylkbvqm89Wg81uXk= github.com/couchbase/goprotostellar v1.0.2 h1:yoPbAL9sCtcyZ5e/DcU5PRMOEFaJrF9awXYu3VPfGls= github.com/couchbase/goprotostellar v1.0.2/go.mod h1:5/yqVnZlW2/NSbAWu1hPJCFBEwjxgpe0PFFOlRixnp4= -github.com/couchbaselabs/gocaves/client v0.0.0-20230307083111-cc3960c624b1/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259 h1:2TXy68EGEzIMHOx9UvczR5ApVecwCfQZ0LjkmwMI6g4= github.com/couchbaselabs/gocaves/client v0.0.0-20230404095311-05e3ba4f0259/go.mod h1:AVekAZwIY2stsJOMWLAS/0uA/+qdp7pjO8EHnl61QkY= github.com/couchbaselabs/gocbconnstr/v2 v2.0.0-20230515165046-68b522a21131 h1:2EAfFswAfgYn3a05DVcegiw6DgMgn1Mv5eGz6IHt1Cw= @@ -348,10 +274,6 @@ github.com/go-git/go-git/v5 v5.12.0/go.mod h1:FTM9VKtnI2m65hNI/TenDDDnUf2Q9FHnXY github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-ldap/ldap/v3 v3.4.6 h1:ert95MdbiG7aWo/oPYp9btL3KJlMPKnP58r09rI8T+A= -github.com/go-ldap/ldap/v3 v3.4.6/go.mod h1:IGMQANNtxpsOzj7uUAMjpGBaOVTC4DYyIy8VsTdxmtc= -github.com/go-ldap/ldap/v3 v3.4.7 h1:3Hbd7mIB1qjd3Ra59fI3JYea/t5kykFu2CVHBca9koE= -github.com/go-ldap/ldap/v3 v3.4.7/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk= github.com/go-ldap/ldap/v3 v3.4.8 h1:loKJyspcRezt2Q3ZRMq2p/0v8iOurlmeXDPw6fikSvQ= github.com/go-ldap/ldap/v3 v3.4.8/go.mod h1:qS3Sjlu76eHfHGpUdWkAXQTw4beih+cHsco2jXlIXrk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= @@ -419,8 +341,6 @@ github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvq github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -436,7 +356,6 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= @@ -463,16 +382,12 @@ github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm4 github.com/google/s2a-go v0.1.7 h1:60BLSyTrOV4/haCDW4zb1guZItoSq8foHCXrAnjBo/o= github.com/google/s2a-go v0.1.7/go.mod h1:50CgR4k1jNlWBu4UfS4AcfhVe1r6pdZPygJ3R8F0Qdw= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfFxPRy3Bf7vr3h0cechB90XaQs= github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.12.3 h1:5/zPPDvw8Q1SuXjrqrZslrqT7dL/uJT2CQii/cLCKqA= -github.com/googleapis/gax-go/v2 v2.12.3/go.mod h1:AKloxT6GtNbaLm8QTNSidHUVsHYcBHwWRvkNFJUQcS4= github.com/googleapis/gax-go/v2 v2.12.4 h1:9gWcmF85Wvq4ryPFvGFaOgPIs1AQX0d0bcbGw4Z96qg= github.com/googleapis/gax-go/v2 v2.12.4/go.mod h1:KYEYLorsnIGDi/rPC8b5TdlB9kbKoFubselGIoBMCwI= github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY= @@ -488,8 +403,6 @@ github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rH github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= -github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= -github.com/h2non/filetype v1.1.3/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542 h1:2VTzZjLZBgl62/EtslCrtky5vbi9dd7HrQPQIx6wqiw= github.com/h2non/parth v0.0.0-20190131123155-b4df798d6542/go.mod h1:Ow0tF8D4Kplbc8s8sSb3V2oUCygFHVp8gC3Dn6U4MNI= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= @@ -497,15 +410,14 @@ github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= -github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-retryablehttp v0.7.6 h1:TwRYfx2z2C4cLbXmT8I5PgP/xmuqASDyiVuGYfs9GZM= github.com/hashicorp/go-retryablehttp v0.7.6/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -524,11 +436,17 @@ github.com/jackc/pgx/v5 v5.5.4 h1:Xp2aQS8uXButQdnCMWNmvx6UysWQQC+u1EoizjguY+8= github.com/jackc/pgx/v5 v5.5.4/go.mod h1:ez9gk+OAat140fv9ErkZDYFWmXLfV+++K0uAOiwgm1A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= +github.com/jcmturner/aescts/v2 v2.0.0 h1:9YKLH6ey7H4eDBXW8khjYslgyqG2xZikXP0EQFKrle8= github.com/jcmturner/aescts/v2 v2.0.0/go.mod h1:AiaICIRyfYg35RUkr8yESTqvSy7csK90qZ5xfvvsoNs= +github.com/jcmturner/dnsutils/v2 v2.0.0 h1:lltnkeZGL0wILNvrNiVCR6Ro5PGU/SeBvVO/8c/iPbo= github.com/jcmturner/dnsutils/v2 v2.0.0/go.mod h1:b0TnjGOvI/n42bZa+hmXL+kFJZsFT7G4t3HTlQ184QM= +github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVETg= github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= +github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= +github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= +github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jlaffaye/ftp v0.2.0 h1:lXNvW7cBu7R/68bknOX3MrRIIqZ61zELs1P2RAiA3lg= github.com/jlaffaye/ftp v0.2.0/go.mod h1:is2Ds5qkhceAPy2xD6RLI6hmp/qysSoymZ+Z2uTnspI= @@ -550,6 +468,8 @@ github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4 github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d h1:RnWZeH8N8KXfbwMTex/KKMYMj0FJRCF6tQubUuQ02GM= +github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d/go.mod h1:phT/jsRPBAEqjAibu1BurrabCBNTYiVI+zbmyCZJY6Q= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= @@ -582,8 +502,6 @@ github.com/launchdarkly/go-semver v1.0.2 h1:sYVRnuKyvxlmQCnCUyDkAhtmzSFRoX6rG2Xa github.com/launchdarkly/go-semver v1.0.2/go.mod h1:xFmMwXba5Mb+3h72Z+VeSs9ahCvKo2QFUTHRNHVqR28= github.com/launchdarkly/go-server-sdk-evaluation/v3 v3.0.0 h1:nQbR1xCpkdU9Z71FI28bWTi5LrmtSVURy0UFcBVD5ZU= github.com/launchdarkly/go-server-sdk-evaluation/v3 v3.0.0/go.mod h1:cwk7/7SzNB2wZbCZS7w2K66klMLBe3NFM3/qd3xnsRc= -github.com/launchdarkly/go-server-sdk/v7 v7.3.0 h1:blc8npHPjhXGs2NU68YSKby6Xkxp16aDSObLt3W5Qww= -github.com/launchdarkly/go-server-sdk/v7 v7.3.0/go.mod h1:EY2ag+p9HnNXiG4pJ+y7QG2gqCYEoYD+NJgwkhmUUqk= github.com/launchdarkly/go-server-sdk/v7 v7.4.0 h1:GaxFHjLuJzPTnadrQ2FcwSgW2Q1q2ZK/JtxpN5Q6vus= github.com/launchdarkly/go-server-sdk/v7 v7.4.0/go.mod h1:EY2ag+p9HnNXiG4pJ+y7QG2gqCYEoYD+NJgwkhmUUqk= github.com/launchdarkly/go-test-helpers/v2 v2.2.0 h1:L3kGILP/6ewikhzhdNkHy1b5y4zs50LueWenVF0sBbs= @@ -622,8 +540,6 @@ github.com/mholt/archiver/v4 v4.0.0-alpha.8 h1:tRGQuDVPh66WCOelqe6LIGh0gwmfwxUrS github.com/mholt/archiver/v4 v4.0.0-alpha.8/go.mod h1:5f7FUYGXdJWUjESffJaYR4R60VhnHxb2X3T1teMyv5A= github.com/microcosm-cc/bluemonday v1.0.25 h1:4NEwSfiJ+Wva0VxN5B8OwMicaJvD8r9tlJWm9rtloEg= github.com/microcosm-cc/bluemonday v1.0.25/go.mod h1:ZIOjCQp1OrzBBPIJmfX4qDYFuhU02nx4bn030ixfHLE= -github.com/microsoft/go-mssqldb v1.7.0 h1:sgMPW0HA6Ihd37Yx0MzHyKD726C2kY/8KJsQtXHNaAs= -github.com/microsoft/go-mssqldb v1.7.0/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/microsoft/go-mssqldb v1.7.1 h1:KU/g8aWeM3Hx7IMOFpiwYiUkU+9zeISb4+tx3ScVfsM= github.com/microsoft/go-mssqldb v1.7.1/go.mod h1:kOvZKUdrhhFQmxLZqbwUV0rHkNkZpthMITIb2Ko1IoA= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= @@ -644,8 +560,6 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= -github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70 h1:kMlmsLSbjkikxQJ1IPwaM+7LJ9ltFu/fi8CRzvSnQmA= -github.com/muesli/ansi v0.0.0-20211031195517-c9f0611b6c70/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 h1:ZK8zHtRHOkbHy6Mmr5D264iyp3TiX5OmNcI5cIARiQI= github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6/go.mod h1:CJlz5H+gyd6CUWT45Oy4q24RdLyn7Md9Vj2/ldJBSIo= github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= @@ -700,8 +614,6 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE= -github.com/prometheus/client_golang v1.19.0 h1:ygXvpU1AoN1MhdzckN+PyD9QJOSD4x7kmXYlnfbA6JU= -github.com/prometheus/client_golang v1.19.0/go.mod h1:ZRM9uEAypZakd+q/x7+gmsvXdURP+DABIEIjnmDdp+k= github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -711,8 +623,6 @@ github.com/prometheus/common v0.48.0 h1:QO8U2CdOzSn1BBsmXJXduaaW+dY/5QLjfB8svtSz github.com/prometheus/common v0.48.0/go.mod h1:0/KsvlIEfPQCQ5I2iNSAWKPZziNCvRs5EC6ILDTlAPc= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/rabbitmq/amqp091-go v1.9.0 h1:qrQtyzB4H8BQgEuJwhmVQqVHB9O4+MNDJCCAcpc3Aoo= -github.com/rabbitmq/amqp091-go v1.9.0/go.mod h1:+jPrT9iY2eLjRaMSRHUhc3z14E/l85kv/f+6luSD3pc= github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= @@ -726,6 +636,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/sassoftware/go-rpmutils v0.3.0 h1:tE4TZ8KcOXay5iIP64P291s6Qxd9MQCYhI7DU+f3gFA= +github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcucCa0DsCzE9RMfwMo= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= @@ -770,20 +682,12 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 h1:34icjjmqJ2HPjrSuJYEkdZ+0ItmGQAQ75cRHIiftIyE= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= -github.com/testcontainers/testcontainers-go v0.29.1 h1:z8kxdFlovA2y97RWx98v/TQ+tR+SXZm6p35M+xB92zk= -github.com/testcontainers/testcontainers-go v0.29.1/go.mod h1:SnKnKQav8UcgtKqjp/AD8bE1MqZm+3TDb/B8crE3XnI= github.com/testcontainers/testcontainers-go v0.30.0 h1:jmn/XS22q4YRrcMwWg0pAwlClzs/abopbsBzrepyc4E= github.com/testcontainers/testcontainers-go v0.30.0/go.mod h1:K+kHNGiM5zjklKjgTtcrEetF3uhWbMUyqAQoyoh8Pf0= -github.com/testcontainers/testcontainers-go/modules/mssql v0.29.1 h1:N5GqwKhyoytElzELjR9KCdiAvvy+6GpJ7ibtvdyY/o4= -github.com/testcontainers/testcontainers-go/modules/mssql v0.29.1/go.mod h1:Hc7lzst9KkM+JMMrv4OjQOE7GUEDzzjBXVfq04iBE6E= github.com/testcontainers/testcontainers-go/modules/mssql v0.30.0 h1:jvDa5EImFyFNv6LLbd3qdcq1TXBY2LzOUZ0GbVbsI7I= github.com/testcontainers/testcontainers-go/modules/mssql v0.30.0/go.mod h1:BYBQszX47xz69xeTg5hX62ndgwxdfAIs6w/94Pk1Z1M= -github.com/testcontainers/testcontainers-go/modules/mysql v0.29.1 h1:SnJtZNcskgxOMyVAT7M+MQjpveP59nwKzlBw2ItX+C8= -github.com/testcontainers/testcontainers-go/modules/mysql v0.29.1/go.mod h1:VhA5dV+O19sx3Y9u9bfO+fbJfP3E7RiMq0nDMEGjslw= github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0 h1:wrePvxfU/2HFALKyBqpNs6VoPPvThzHy9aN+PCxse9g= github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0/go.mod h1:Srnlf7wwA7s6K4sKKhjAoBHJcKorRINR/i5dCA4ZyGk= -github.com/testcontainers/testcontainers-go/modules/postgres v0.29.1 h1:hTn3MzhR9w4btwfzr/NborGCaeNZG0MPBpufeDj10KA= -github.com/testcontainers/testcontainers-go/modules/postgres v0.29.1/go.mod h1:YsWyy+pHDgvGdi0axGOx6CGXWsE6eqSaApyd1FYYSSc= github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0 h1:D3HFqpZS90iRGAN7M85DFiuhPfvYvFNnx8urQ6mPAvo= github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0/go.mod h1:e1sKxwUOkqzvaqdHl/oV9mUtFmkDPTfBGp0po2tnWQU= github.com/tetratelabs/wazero v1.7.0 h1:jg5qPydno59wqjpGrHph81lbtHzTrWzwwtD4cD88+hQ= @@ -806,20 +710,12 @@ github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0o github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= -github.com/wasilibs/go-re2 v1.5.1 h1:a+Gb1mx6Q7MmU4d+3BCnnN28U2/cnADmY1oRRanQi10= -github.com/wasilibs/go-re2 v1.5.1/go.mod h1:UqqxQ1O99boQUm1r61H/IYGiGQOS/P88K7hU5nLNkEg= github.com/wasilibs/go-re2 v1.5.2 h1:fDO2TJrRzRrv3jD0gzOvmZ2UM4Yt9YXOEdLrlNc/Ies= github.com/wasilibs/go-re2 v1.5.2/go.mod h1:UqqxQ1O99boQUm1r61H/IYGiGQOS/P88K7hU5nLNkEg= github.com/wasilibs/nottinygc v0.4.0 h1:h1TJMihMC4neN6Zq+WKpLxgd9xCFMw7O9ETLwY2exJQ= github.com/wasilibs/nottinygc v0.4.0/go.mod h1:oDcIotskuYNMpqMF23l7Z8uzD4TC0WXHK8jetlB3HIo= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM= -github.com/xanzy/go-gitlab v0.101.0 h1:qRgvX8DNE19zRugB6rnnZMZ5ubhITSKPLNWEyc6UIPg= -github.com/xanzy/go-gitlab v0.101.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= -github.com/xanzy/go-gitlab v0.102.0 h1:ExHuJ1OTQ2yt25zBMMj0G96ChBirGYv8U7HyUiYkZ+4= -github.com/xanzy/go-gitlab v0.102.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= -github.com/xanzy/go-gitlab v0.103.0 h1:J9pTQoq0GsEFqzd6srCM1QfdfKAxSNz6mT6ntrpNF2w= -github.com/xanzy/go-gitlab v0.103.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/go-gitlab v0.104.1 h1:g/liXIPJH0jsTwVuzTAUMiKdTf6Qup3u2XZq5Rp90Wc= github.com/xanzy/go-gitlab v0.104.1/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= @@ -832,6 +728,8 @@ github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6 github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofmx9yWTog9BfvIu0q41lo= +github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -851,8 +749,6 @@ github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= go.einride.tech/aip v0.60.0 h1:h6bgabZ5BCfAptbGex8jbh3VvPBRLa6xq+pQ1CAjHYw= go.einride.tech/aip v0.60.0/go.mod h1:SdLbSbgSU60Xkb4TMkmsZEQPHeEWx0ikBoq5QnqZvdg= -go.mongodb.org/mongo-driver v1.14.0 h1:P98w8egYRjYe3XDjxhYJagTokP/H6HzlsnojRgZRd80= -go.mongodb.org/mongo-driver v1.14.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.mongodb.org/mongo-driver v1.15.0 h1:rJCKC8eEliewXjZGf0ddURtl7tTVy1TK3bfl0gkUSLc= go.mongodb.org/mongo-driver v1.15.0/go.mod h1:Vzb0Mk/pa7e6cWw85R4F/endUC3u0U9jGcNU603k65c= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= @@ -873,15 +769,14 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0 h1:IeMey go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.19.0/go.mod h1:oVdCUtjq9MK9BlS7TtucsQwUcXcymNiEDjgDD2jMtZU= go.opentelemetry.io/otel/metric v1.24.0 h1:6EhoGWWK28x1fbpA4tYTOWBkPefTDQnb8WSGXlc88kI= go.opentelemetry.io/otel/metric v1.24.0/go.mod h1:VYhLe1rFfxuTXLgj4CBiyz+9WYBA8pNGJgDcSFRKBco= -go.opentelemetry.io/otel/sdk v1.22.0 h1:6coWHw9xw7EfClIC/+O31R8IY3/+EiRFHevmHafB2Gw= -go.opentelemetry.io/otel/sdk v1.22.0/go.mod h1:iu7luyVGYovrRpe2fmj3CVKouQNdTOkxtLzPvPz1DOc= +go.opentelemetry.io/otel/sdk v1.24.0 h1:YMPPDNymmQN3ZgczicBY3B6sf9n62Dlj9pWD3ucgoDw= +go.opentelemetry.io/otel/sdk v1.24.0/go.mod h1:KVrIYw6tEubO9E96HQpcmpTKDVn9gdv35HoYiQWGDFg= go.opentelemetry.io/otel/trace v1.24.0 h1:CsKnnL4dUAr/0llH9FKuc698G04IrpWV0MQA/Y1YELI= go.opentelemetry.io/otel/trace v1.24.0/go.mod h1:HPc3Xr/cOApsBI154IU0OI0HJexz+aw5uPdbs3UCjNU= go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/mock v0.4.0 h1:VcM4ZOtdbR4f6VXfiOpwpVJDL6lCReaZ6mw31wqh7KU= @@ -905,12 +800,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= -golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA= golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= -golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30= -golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -921,14 +812,6 @@ golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8 h1:aAcj0Da7eBAtrTp03QXWvm88pSyOt+UgdZw2BFZ+lEw= -golang.org/x/exp v0.0.0-20240325151524-a685a6edb6d8/go.mod h1:CQ1k9gNrJ50XIzaKCRR2hssIjF07kZFEiieALBM/ARQ= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0 h1:985EYyeCOxTpcgOTJpflJUwOeEz0CQOdPt73OzpE9F8= -golang.org/x/exp v0.0.0-20240404231335-c0f41cb1a7a0/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8 h1:ESSUROHIBHg7USnszlcdmjBEwdMj9VUvU+OPk4yl2mc= -golang.org/x/exp v0.0.0-20240409090435-93d18d7e34b8/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f h1:99ci1mjWVBWwJiEKYY6jWa4d2nTQVIEhZIptnrVb1XY= -golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f/go.mod h1:/lliqkxwWAhPjf5oSOIJup2XcqJaw8RGS6k3TGEc7GI= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM= golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= @@ -952,8 +835,6 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.16.0 h1:QX4fJ0Rr5cPQCF7O9lh9Se4pmwfwskqZfq5moyldzic= -golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -985,10 +866,7 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= -golang.org/x/net v0.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc= golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= -golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w= -golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -996,10 +874,6 @@ golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.18.0 h1:09qnuIAgzdx1XplqJvW6CQqMCtGZykZWcXzPMPUusvI= -golang.org/x/oauth2 v0.18.0/go.mod h1:Wf7knwG0MPoWIMMBgFlEaSUDaKskp0dCfrlJRJXbBi8= -golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= golang.org/x/oauth2 v0.20.0 h1:4mQdhULixXKP1rwYBW0vAijoXnkTG0BLCDRzfe1idMo= golang.org/x/oauth2 v0.20.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1011,8 +885,6 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= -golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -1054,20 +926,15 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4= golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= @@ -1076,12 +943,8 @@ golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= -golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= -golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8= golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= -golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q= -golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1096,8 +959,6 @@ golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= @@ -1136,10 +997,6 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.19.0 h1:tfGCXNR1OsFG+sVdLAitlpjAvD/I6dHDKnYrpEZUHkw= -golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= -golang.org/x/tools v0.20.0 h1:hz/CVckiOxybQvFw6h7b/q80NTr9IUQb4s1IIzW7KNY= -golang.org/x/tools v0.20.0/go.mod h1:WvitBU7JJf6A4jOdg4S1tviW9bhUxkgeCui/0JHctQg= golang.org/x/tools v0.21.0 h1:qc0xYgIbsSDt9EyWz05J5wfa7LOVW0YTLOXrqdLAWIw= golang.org/x/tools v0.21.0/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -1158,20 +1015,6 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.172.0 h1:/1OcMZGPmW1rX2LCu2CmGUD1KXK1+pfzxotxyRUCCdk= -google.golang.org/api v0.172.0/go.mod h1:+fJZq6QXWfa9pXhnIzsjx4yI22d4aI9ZpLb58gvXjis= -google.golang.org/api v0.173.0 h1:fz6B7GWYWLS/HfruiTsRYVKQQApJ6vasTYWAK6+Qo8g= -google.golang.org/api v0.173.0/go.mod h1:ins7pTzjeBPQ3SdC/plzki6d/dQWwAWy8qVZ4Vgkzl8= -google.golang.org/api v0.174.0 h1:zB1BWl7ocxfTea2aQ9mgdzXjnfPySllpPOskdnO+q34= -google.golang.org/api v0.174.0/go.mod h1:aC7tB6j0HR1Nl0ni5ghpx6iLasmAX78Zkh/wgxAAjLg= -google.golang.org/api v0.175.0 h1:9bMDh10V9cBuU8N45Wlc3cKkItfqMRV0Fi8UscLEtbY= -google.golang.org/api v0.175.0/go.mod h1:Rra+ltKu14pps/4xTycZfobMgLpbosoaaL7c+SEMrO8= -google.golang.org/api v0.176.0 h1:dHj1/yv5Dm/eQTXiP9hNCRT3xzJHWXeNdRq29XbMxoE= -google.golang.org/api v0.176.0/go.mod h1:Rra+ltKu14pps/4xTycZfobMgLpbosoaaL7c+SEMrO8= -google.golang.org/api v0.176.1 h1:DJSXnV6An+NhJ1J+GWtoF2nHEuqB1VNoTfnIbjNvwD4= -google.golang.org/api v0.176.1/go.mod h1:j2MaSDYcvYV1lkZ1+SMW4IeF90SrEyFA+tluDYWRrFg= -google.golang.org/api v0.177.0 h1:8a0p/BbPa65GlqGWtUKxot4p0TV8OGOfyTjtmkXNXmk= -google.golang.org/api v0.177.0/go.mod h1:srbhue4MLjkjbkux5p3dw/ocYOSZTaIEvf7bCOnFQDw= google.golang.org/api v0.178.0 h1:yoW/QMI4bRVCHF+NWOTa4cL8MoWL3Jnuc7FlcFF91Ok= google.golang.org/api v0.178.0/go.mod h1:84/k2v8DFpDRebpGcooklv/lais3MEfqpaBLA12gl2U= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1179,8 +1022,6 @@ google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= -google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -1196,22 +1037,10 @@ google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9 h1:9+tzLLstTlPTRyJTh+ah5wIMsBW5c4tQwGTN3thOW9Y= -google.golang.org/genproto v0.0.0-20240213162025-012b6fc9bca9/go.mod h1:mqHbVIp48Muh7Ywss/AD6I5kNVKZMmAa/QEW58Gxp2s= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= -google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= -google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c h1:kaI7oewGK5YnVwj+Y+EJBO/YN1ht8iTL9XkFHtVZLsc= -google.golang.org/genproto/googleapis/api v0.0.0-20240314234333-6e1732d8331c/go.mod h1:VQW3tUculP/D4B+xVCo+VgSq8As6wA9ZjHl//pmk+6s= google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 h1:DTJM0R8LECCgFeUwApvcEJHz85HLagW8uRENYxHh1ww= google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237 h1:NnYq6UN9ReLM9/Y01KWNOWyI5xQ9kbIms5GGJVwS/Yc= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240318140521-94a12d6c2237/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa h1:RBgMaUMP+6soRkik4VoN8ojR2nex2TqZwjSSogic+eo= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240325203815-454cdb8f5daa/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be h1:LG9vZxsWGOmUKieR8wPAUR3u3MpnYFQZROPIMaXh7/A= -google.golang.org/genproto/googleapis/rpc v0.0.0-20240415180920-8c6c420018be/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1224,10 +1053,6 @@ google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8 google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.62.1 h1:B4n+nfKzOICUXMgyrNd19h/I9oH0L1pizfk1d4zSgTk= -google.golang.org/grpc v1.62.1/go.mod h1:IWTG0VlJLCh1SkC58F7np9ka9mx/WNkjl4PGJaiq+QE= -google.golang.org/grpc v1.63.0 h1:WjKe+dnvABXyPJMD7KDNLxtoGk5tgk+YFWN6cBWjZE8= -google.golang.org/grpc v1.63.0/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -1239,12 +1064,6 @@ google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2 google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= -google.golang.org/protobuf v1.34.0 h1:Qo/qEd2RZPCf2nKuorzksSknv0d3ERwp1vFG38gSmH4= -google.golang.org/protobuf v1.34.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1281,6 +1100,10 @@ honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +pault.ag/go/debian v0.16.0 h1:fivXn/IO9rn2nzTGndflDhOkNU703Axs/StWihOeU2g= +pault.ag/go/debian v0.16.0/go.mod h1:JFl0XWRCv9hWBrB5MDDZjA5GSEs1X3zcFK/9kCNIUmE= +pault.ag/go/topsort v0.1.1 h1:L0QnhUly6LmTv0e3DEzbN2q6/FGgAcQvaEw65S53Bg4= +pault.ag/go/topsort v0.1.1/go.mod h1:r1kc/L0/FZ3HhjezBIPaNVhkqv8L0UJ9bxRuHRVZ0q4= pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= diff --git a/pkg/handlers/ar.go b/pkg/handlers/ar.go new file mode 100644 index 000000000000..70ad4e785956 --- /dev/null +++ b/pkg/handlers/ar.go @@ -0,0 +1,80 @@ +package handlers + +import ( + "errors" + "fmt" + "io" + "time" + + "pault.ag/go/debian/deb" + + logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" +) + +// arHandler specializes defaultHandler to handle AR archive formats. By embedding defaultHandler, +// arHandler inherits and can further customize the common handling behavior such as skipping binaries. +type arHandler struct{ *defaultHandler } + +// newARHandler creates an arHandler. +func newARHandler() *arHandler { + return &arHandler{defaultHandler: newDefaultHandler(arHandlerType)} +} + +// HandleFile processes AR formatted files. This function needs to be implemented to extract or +// manage data from AR files according to specific requirements. +func (h *arHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (chan []byte, error) { + archiveChan := make(chan []byte, defaultBufferSize) + + go func() { + ctx, cancel := logContext.WithTimeout(ctx, maxTimeout) + defer cancel() + defer close(archiveChan) + + // Update the metrics for the file processing. + start := time.Now() + var err error + defer h.measureLatencyAndHandleErrors(start, err) + + var arReader *deb.Ar + arReader, err = deb.LoadAr(input) + if err != nil { + ctx.Logger().Error(err, "error reading AR") + return + } + + if err = h.processARFiles(ctx, arReader, archiveChan); err != nil { + ctx.Logger().Error(err, "error processing AR files") + } + }() + + return archiveChan, nil +} + +func (h *arHandler) processARFiles(ctx logContext.Context, reader *deb.Ar, archiveChan chan []byte) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + arEntry, err := reader.Next() + if err != nil { + if errors.Is(err, io.EOF) { + ctx.Logger().V(3).Info("AR archive fully processed") + return nil + } + return fmt.Errorf("error reading AR payload: %w", err) + } + + fileSize := arEntry.Size + fileCtx := logContext.WithValues(ctx, "filename", arEntry.Name, "size", fileSize) + + if err := h.handleNonArchiveContent(fileCtx, arEntry.Data, archiveChan); err != nil { + fileCtx.Logger().Error(err, "error handling archive content in AR") + h.metrics.incErrors() + } + + h.metrics.incFilesProcessed() + h.metrics.observeFileSize(fileSize) + } + } +} diff --git a/pkg/handlers/ar_test.go b/pkg/handlers/ar_test.go new file mode 100644 index 000000000000..c3d250616b7b --- /dev/null +++ b/pkg/handlers/ar_test.go @@ -0,0 +1,32 @@ +package handlers + +import ( + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/trufflesecurity/trufflehog/v3/pkg/context" +) + +func TestHandleARFile(t *testing.T) { + file, err := os.Open("testdata/test.deb") + assert.Nil(t, err) + defer file.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + handler := newARHandler() + archiveChan, err := handler.HandleFile(context.AddLogger(ctx), file) + assert.NoError(t, err) + + wantChunkCount := 102 + count := 0 + for range archiveChan { + count++ + } + + assert.Equal(t, wantChunkCount, count) +} diff --git a/pkg/handlers/archive.go b/pkg/handlers/archive.go deleted file mode 100644 index d42b44b9063f..000000000000 --- a/pkg/handlers/archive.go +++ /dev/null @@ -1,554 +0,0 @@ -package handlers - -import ( - "bufio" - "bytes" - "context" - "errors" - "fmt" - "io" - "os" - "os/exec" - "path/filepath" - "strings" - "time" - - "github.com/gabriel-vasile/mimetype" - "github.com/h2non/filetype" - "github.com/mholt/archiver/v4" - - "github.com/trufflesecurity/trufflehog/v3/pkg/common" - logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" - "github.com/trufflesecurity/trufflehog/v3/pkg/sources" -) - -type ctxKey int - -const ( - depthKey ctxKey = iota - - errMaxArchiveDepthReached = "max archive depth reached" -) - -var ( - maxDepth = 5 - maxSize = 250 * 1024 * 1024 // 20MB - maxTimeout = time.Duration(30) * time.Second - - defaultBufferSize = 512 -) - -// Ensure the Archive satisfies the interfaces at compile time. -var _ SpecializedHandler = (*Archive)(nil) - -// Archive is a handler for extracting and decompressing archives. -type Archive struct { - size int - currentDepth int - skipBinaries bool - skipArchives bool -} - -// New creates a new Archive handler with the provided options. -func (a *Archive) New(opts ...Option) { - for _, opt := range opts { - opt(a) - } -} - -// SetArchiveMaxSize sets the maximum size of the archive. -func SetArchiveMaxSize(size int) { - maxSize = size -} - -// SetArchiveMaxDepth sets the maximum depth of the archive. -func SetArchiveMaxDepth(depth int) { - maxDepth = depth -} - -// SetArchiveMaxTimeout sets the maximum timeout for the archive handler. -func SetArchiveMaxTimeout(timeout time.Duration) { - maxTimeout = timeout -} - -// FromFile extracts the files from an archive. -func (a *Archive) FromFile(originalCtx logContext.Context, data io.Reader) chan []byte { - if a.skipArchives { - return nil - } - - archiveChan := make(chan []byte, defaultBufferSize) - go func() { - ctx, cancel := logContext.WithTimeout(originalCtx, maxTimeout) - logger := logContext.AddLogger(ctx).Logger() - defer cancel() - defer close(archiveChan) - err := a.openArchive(ctx, 0, data, archiveChan) - if err != nil { - if errors.Is(err, archiver.ErrNoMatch) { - return - } - logger.Error(err, "error unarchiving chunk.") - } - }() - return archiveChan -} - -// openArchive takes a reader and extracts the contents up to the maximum depth. -func (a *Archive) openArchive(ctx logContext.Context, depth int, reader io.Reader, archiveChan chan []byte) error { - if common.IsDone(ctx) { - return ctx.Err() - } - - if depth >= maxDepth { - return fmt.Errorf(errMaxArchiveDepthReached) - } - - format, arReader, err := archiver.Identify("", reader) - if errors.Is(err, archiver.ErrNoMatch) && depth > 0 { - return a.handleNonArchiveContent(ctx, arReader, archiveChan) - } - - if err != nil { - return err - } - - switch archive := format.(type) { - case archiver.Decompressor: - // Decompress tha archive and feed the decompressed data back into the archive handler to extract any nested archives. - compReader, err := archive.OpenReader(arReader) - if err != nil { - return err - } - - defer compReader.Close() - - return a.openArchive(ctx, depth+1, compReader, archiveChan) - case archiver.Extractor: - return archive.Extract(logContext.WithValue(ctx, depthKey, depth+1), arReader, nil, a.extractorHandler(archiveChan)) - default: - return fmt.Errorf("unknown archive type: %s", format.Name()) - } -} - -const mimeTypeBufferSize = 512 - -func (a *Archive) handleNonArchiveContent(ctx logContext.Context, reader io.Reader, archiveChan chan []byte) error { - bufReader := bufio.NewReaderSize(reader, mimeTypeBufferSize) - // A buffer of 512 bytes is used since many file formats store their magic numbers within the first 512 bytes. - // If fewer bytes are read, MIME type detection may still succeed. - buffer, err := bufReader.Peek(mimeTypeBufferSize) - if err != nil && !errors.Is(err, io.EOF) { - return fmt.Errorf("unable to read file for MIME type detection: %w", err) - } - - mime := mimetype.Detect(buffer) - mimeT := mimeType(mime.String()) - - if common.SkipFile(mime.Extension()) { - ctx.Logger().V(5).Info("skipping file", "ext", mimeT) - return nil - } - - if a.skipBinaries { - if common.IsBinary(mime.Extension()) || mimeT == machOType || mimeT == octetStream { - ctx.Logger().V(5).Info("skipping binary file", "ext", mimeT) - return nil - } - } - - chunkReader := sources.NewChunkReader() - chunkResChan := chunkReader(ctx, bufReader) - for data := range chunkResChan { - if err := data.Error(); err != nil { - ctx.Logger().Error(err, "error reading chunk") - continue - } - if err := common.CancellableWrite(ctx, archiveChan, data.Bytes()); err != nil { - return err - } - } - return nil -} - -// IsFiletype returns true if the provided reader is an archive. -func (a *Archive) IsFiletype(_ logContext.Context, reader io.Reader) (io.Reader, bool) { - format, readerB, err := archiver.Identify("", reader) - if err != nil { - return readerB, false - } - switch format.(type) { - case archiver.Extractor: - return readerB, true - case archiver.Decompressor: - return readerB, true - default: - return readerB, false - } -} - -// extractorHandler is applied to each file in an archiver.Extractor file. -func (a *Archive) extractorHandler(archiveChan chan []byte) func(context.Context, archiver.File) error { - return func(ctx context.Context, f archiver.File) error { - lCtx := logContext.AddLogger(ctx) - lCtx.Logger().V(5).Info("Handling extracted file.", "filename", f.Name()) - - if common.IsDone(ctx) { - return ctx.Err() - } - - depth := 0 - if ctxDepth, ok := ctx.Value(depthKey).(int); ok { - depth = ctxDepth - } - - fReader, err := f.Open() - if err != nil { - return err - } - defer fReader.Close() - - if common.SkipFile(f.Name()) { - lCtx.Logger().V(5).Info("skipping file", "filename", f.Name()) - return nil - } - - if a.skipBinaries && common.IsBinary(f.Name()) { - lCtx.Logger().V(5).Info("skipping binary file", "filename", f.Name()) - return nil - } - - return a.openArchive(lCtx, depth, fReader, archiveChan) - } -} - -// ReadToMax reads up to the max size. -func (a *Archive) ReadToMax(ctx logContext.Context, reader io.Reader) (data []byte, err error) { - // Archiver v4 is in alpha and using an experimental version of - // rardecode. There is a bug somewhere with rar decoder format 29 - // that can lead to a panic. An issue is open in rardecode repo - // https://github.com/nwaples/rardecode/issues/30. - defer func() { - if r := recover(); r != nil { - // Return an error from ReadToMax. - if e, ok := r.(error); ok { - err = e - } else { - err = fmt.Errorf("panic occurred: %v", r) - } - ctx.Logger().Error(err, "Panic occurred when reading archive") - } - }() - - if common.IsDone(ctx) { - return nil, ctx.Err() - } - - var fileContent bytes.Buffer - // Create a limited reader to ensure we don't read more than the max size. - lr := io.LimitReader(reader, int64(maxSize)) - - // Using io.CopyBuffer for performance advantages. Though buf is mandatory - // for the method, due to the internal implementation of io.CopyBuffer, when - // *bytes.Buffer implements io.WriterTo or io.ReaderFrom, the provided buf - // is simply ignored. Thus, we can pass nil for the buf parameter. - _, err = io.CopyBuffer(&fileContent, lr, nil) - if err != nil && !errors.Is(err, io.EOF) { - return nil, err - } - - if fileContent.Len() == maxSize { - ctx.Logger().V(2).Info("Max archive size reached.") - } - - return fileContent.Bytes(), nil -} - -type mimeType string - -const ( - arMimeType mimeType = "application/x-unix-archive" - rpmMimeType mimeType = "application/x-rpm" - machOType mimeType = "application/x-mach-binary" - octetStream mimeType = "application/octet-stream" -) - -// mimeTools maps MIME types to the necessary command-line tools to handle them. -// This centralizes the tool requirements for different file types. -var mimeTools = map[mimeType][]string{ - arMimeType: {"ar"}, - rpmMimeType: {"rpm2cpio", "cpio"}, -} - -// extractToolCache stores the availability of extraction tools, eliminating the need for repeated filesystem lookups. -var extractToolCache map[string]bool - -func init() { - // Preload the extractToolCache with the availability status of each required tool. - extractToolCache = make(map[string]bool) - for _, tools := range mimeTools { - for _, tool := range tools { - _, err := exec.LookPath(tool) - extractToolCache[tool] = err == nil - } - } -} - -func ensureToolsForMimeType(mimeType mimeType) error { - tools, exists := mimeTools[mimeType] - if !exists { - return fmt.Errorf("unsupported mime type: %s", mimeType) - } - - for _, tool := range tools { - if installed := extractToolCache[tool]; !installed { - return fmt.Errorf("required tool %s is not installed", tool) - } - } - return nil -} - -// HandleSpecialized takes a file path and an io.Reader representing the input file, -// and processes it based on its extension, such as handling Debian (.deb) and RPM (.rpm) packages. -// It returns an io.Reader that can be used to read the processed content of the file, -// and an error if any issues occurred during processing. -// If the file is specialized, the returned boolean is true with no error. -// The caller is responsible for closing the returned reader. -func (a *Archive) HandleSpecialized(ctx logContext.Context, reader io.Reader) (io.Reader, bool, error) { - mimeType, reader, err := determineMimeType(reader) - if err != nil { - return nil, false, err - } - - switch mimeType { - case arMimeType: // includes .deb files - if err := ensureToolsForMimeType(mimeType); err != nil { - return nil, false, err - } - reader, err = a.extractDebContent(ctx, reader) - case rpmMimeType: - if err := ensureToolsForMimeType(mimeType); err != nil { - return nil, false, err - } - reader, err = a.extractRpmContent(ctx, reader) - default: - return reader, false, nil - } - - if err != nil { - return nil, false, fmt.Errorf("unable to extract file with MIME type %s: %w", mimeType, err) - } - return reader, true, nil -} - -// extractDebContent takes a .deb file as an io.Reader, extracts its contents -// into a temporary directory, and returns a Reader for the extracted data archive. -// It handles the extraction process by using the 'ar' command and manages temporary -// files and directories for the operation. -// The caller is responsible for closing the returned reader. -func (a *Archive) extractDebContent(ctx logContext.Context, file io.Reader) (io.ReadCloser, error) { - if a.currentDepth >= maxDepth { - return nil, fmt.Errorf(errMaxArchiveDepthReached) - } - - tmpEnv, err := a.createTempEnv(ctx, file) - if err != nil { - return nil, err - } - defer os.Remove(tmpEnv.tempFileName) - defer os.RemoveAll(tmpEnv.extractPath) - - cmd := exec.Command("ar", "x", tmpEnv.tempFile.Name()) - cmd.Dir = tmpEnv.extractPath - if err := executeCommand(cmd); err != nil { - return nil, err - } - - handler := func(ctx logContext.Context, env tempEnv, file string) (string, error) { - if strings.HasPrefix(file, "data.tar.") { - return file, nil - } - return a.handleNestedFileMIME(ctx, env, file) - } - - dataArchiveName, err := a.handleExtractedFiles(ctx, tmpEnv, handler) - if err != nil { - return nil, err - } - - return openDataArchive(tmpEnv.extractPath, dataArchiveName) -} - -// extractRpmContent takes an .rpm file as an io.Reader, extracts its contents -// into a temporary directory, and returns a Reader for the extracted data archive. -// It handles the extraction process by using the 'rpm2cpio' and 'cpio' commands and manages temporary -// files and directories for the operation. -// The caller is responsible for closing the returned reader. -func (a *Archive) extractRpmContent(ctx logContext.Context, file io.Reader) (io.ReadCloser, error) { - if a.currentDepth >= maxDepth { - return nil, fmt.Errorf("max archive depth reached") - } - - tmpEnv, err := a.createTempEnv(ctx, file) - if err != nil { - return nil, err - } - defer os.Remove(tmpEnv.tempFileName) - defer os.RemoveAll(tmpEnv.extractPath) - - // Use rpm2cpio to convert the RPM file to a cpio archive and then extract it using cpio command. - cmd := exec.Command("sh", "-c", "rpm2cpio "+tmpEnv.tempFile.Name()+" | cpio -id") - cmd.Dir = tmpEnv.extractPath - if err := executeCommand(cmd); err != nil { - return nil, err - } - - handler := func(ctx logContext.Context, env tempEnv, file string) (string, error) { - if strings.HasSuffix(file, ".tar.gz") { - return file, nil - } - return a.handleNestedFileMIME(ctx, env, file) - } - - dataArchiveName, err := a.handleExtractedFiles(ctx, tmpEnv, handler) - if err != nil { - return nil, err - } - - return openDataArchive(tmpEnv.extractPath, dataArchiveName) -} - -func (a *Archive) handleNestedFileMIME(ctx logContext.Context, tempEnv tempEnv, fileName string) (string, error) { - nestedFile, err := os.Open(filepath.Join(tempEnv.extractPath, fileName)) - if err != nil { - return "", err - } - defer nestedFile.Close() - - mimeType, reader, err := determineMimeType(nestedFile) - if err != nil { - return "", fmt.Errorf("unable to determine MIME type of nested filename: %s, %w", nestedFile.Name(), err) - } - - switch mimeType { - case arMimeType, rpmMimeType: - _, _, err = a.HandleSpecialized(ctx, reader) - default: - return "", nil - } - - if err != nil { - return "", fmt.Errorf("unable to extract file with MIME type %s: %w", mimeType, err) - } - - return fileName, nil -} - -// determineMimeType reads from the provided reader to detect the MIME type. -// It returns the detected MIME type and a new reader that includes the read portion. -func determineMimeType(reader io.Reader) (mimeType, io.Reader, error) { - // A buffer of 512 bytes is used since many file formats store their magic numbers within the first 512 bytes. - // If fewer bytes are read, MIME type detection may still succeed. - buffer := make([]byte, 512) - n, err := reader.Read(buffer) - if err != nil && !errors.Is(err, io.EOF) { - return "", nil, fmt.Errorf("unable to read file for MIME type detection: %w", err) - } - - // Create a new reader that starts with the buffer we just read - // and continues with the rest of the original reader. - reader = io.MultiReader(bytes.NewReader(buffer[:n]), reader) - - kind, err := filetype.Match(buffer) - if err != nil { - return "", nil, fmt.Errorf("unable to determine file type: %w", err) - } - - return mimeType(kind.MIME.Value), reader, nil -} - -// handleExtractedFiles processes each file in the extracted directory using a provided handler function. -// The function iterates through the files, applying the handleFile function to each, and returns the name -// of the data archive it finds. This centralizes the logic for handling specialized files such as .deb and .rpm -// by using the appropriate handling function passed as an argument. This design allows for flexibility and reuse -// of this function across various extraction processes in the package. -func (a *Archive) handleExtractedFiles(ctx logContext.Context, env tempEnv, handleFile func(logContext.Context, tempEnv, string) (string, error)) (string, error) { - extractedFiles, err := os.ReadDir(env.extractPath) - if err != nil { - return "", fmt.Errorf("unable to read extracted directory: %w", err) - } - - var dataArchiveName string - for _, file := range extractedFiles { - filename := file.Name() - filePath := filepath.Join(env.extractPath, filename) - fileInfo, err := os.Stat(filePath) - if err != nil { - return "", fmt.Errorf("unable to get file info for filename %s: %w", filename, err) - } - if fileInfo.IsDir() { - continue - } - - name, err := handleFile(ctx, env, filename) - if err != nil { - return "", err - } - if name != "" { - dataArchiveName = name - break - } - } - - return dataArchiveName, nil -} - -type tempEnv struct { - tempFile *os.File - tempFileName string - extractPath string -} - -// createTempEnv creates a temporary file and a temporary directory for extracting archives. -// The caller is responsible for removing these temporary resources -// (both the file and directory) when they are no longer needed. -func (a *Archive) createTempEnv(ctx logContext.Context, file io.Reader) (tempEnv, error) { - tempFile, err := os.CreateTemp("", "tmp") - if err != nil { - return tempEnv{}, fmt.Errorf("unable to create temporary file: %w", err) - } - - extractPath, err := os.MkdirTemp("", "tmp_archive") - if err != nil { - return tempEnv{}, fmt.Errorf("unable to create temporary directory: %w", err) - } - - b, err := a.ReadToMax(ctx, file) - if err != nil { - return tempEnv{}, err - } - - if _, err = tempFile.Write(b); err != nil { - return tempEnv{}, fmt.Errorf("unable to write to temporary file: %w", err) - } - - return tempEnv{tempFile: tempFile, tempFileName: tempFile.Name(), extractPath: extractPath}, nil -} - -func executeCommand(cmd *exec.Cmd) error { - var stderr bytes.Buffer - cmd.Stderr = &stderr - if err := cmd.Run(); err != nil { - return fmt.Errorf("unable to execute command %v: %w; error: %s", cmd.String(), err, stderr.String()) - } - return nil -} - -func openDataArchive(extractPath string, dataArchiveName string) (io.ReadCloser, error) { - dataArchivePath := filepath.Join(extractPath, dataArchiveName) - dataFile, err := os.Open(dataArchivePath) - if err != nil { - return nil, fmt.Errorf("unable to open file: %w", err) - } - return dataFile, nil -} diff --git a/pkg/handlers/archive_test.go b/pkg/handlers/archive_test.go deleted file mode 100644 index de2ed3fbf1ae..000000000000 --- a/pkg/handlers/archive_test.go +++ /dev/null @@ -1,493 +0,0 @@ -package handlers - -import ( - "archive/tar" - "bytes" - "context" - "encoding/binary" - "io" - "math/rand" - "net/http" - "os" - "regexp" - "strings" - "testing" - "time" - - "github.com/h2non/filetype" - "github.com/stretchr/testify/assert" - diskbufferreader "github.com/trufflesecurity/disk-buffer-reader" - - logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" - "github.com/trufflesecurity/trufflehog/v3/pkg/sources" -) - -func TestArchiveHandler(t *testing.T) { - tests := map[string]struct { - archiveURL string - expectedChunks int - matchString string - }{ - "gzip-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one-zip.gz", - 1, - "AKIAYVP4CIPPH5TNP3SW", - }, - "gzip-nested": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/double-zip.gz", - 1, - "AKIAYVP4CIPPH5TNP3SW", - }, - "gzip-too-deep": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six-zip.gz", - 0, - "", - }, - "tar-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one.tar", - 1, - "AKIAYVP4CIPPH5TNP3SW", - }, - "tar-nested": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/two.tar", - 1, - "AKIAYVP4CIPPH5TNP3SW", - }, - "tar-too-deep": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six.tar", - 0, - "", - }, - "targz-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/tar-archive.tar.gz", - 1, - "AKIAYVP4CIPPH5TNP3SW", - }, - "gzip-large": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/FifteenMB.gz", - 1543, - "AKIAYVP4CIPPH5TNP3SW", - }, - "zip-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/aws-canary-creds.zip", - 1, - "AKIAYVP4CIPPH5TNP3SW", - }, - } - - for name, testCase := range tests { - t.Run(name, func(t *testing.T) { - resp, err := http.Get(testCase.archiveURL) - if err != nil || resp.StatusCode != http.StatusOK { - t.Error(err) - } - defer resp.Body.Close() - - archive := Archive{} - archive.New() - - newReader, err := diskbufferreader.New(resp.Body) - if err != nil { - t.Errorf("error creating reusable reader: %s", err) - } - archiveChan := archive.FromFile(logContext.Background(), newReader) - - count := 0 - re := regexp.MustCompile(testCase.matchString) - matched := false - for chunk := range archiveChan { - count++ - if re.Match(chunk) { - matched = true - } - } - if !matched && len(testCase.matchString) > 0 { - t.Errorf("%s: Expected string not found in archive.", name) - } - if count != testCase.expectedChunks { - t.Errorf("%s: Unexpected number of chunks. Got %d, expected: %d", name, count, testCase.expectedChunks) - } - }) - } -} - -func TestHandleFile(t *testing.T) { - reporter := sources.ChanReporter{Ch: make(chan *sources.Chunk, 2)} - - // Context cancels the operation. - canceledCtx, cancel := logContext.WithCancel(logContext.Background()) - cancel() - reader, err := diskbufferreader.New(strings.NewReader("file")) - assert.NoError(t, err) - assert.False(t, HandleFile(canceledCtx, reader, &sources.Chunk{}, reporter)) - - // Only one chunk is sent on the channel. - // TODO: Embed a zip without making an HTTP request. - resp, err := http.Get("https://raw.githubusercontent.com/bill-rich/bad-secrets/master/aws-canary-creds.zip") - assert.NoError(t, err) - defer resp.Body.Close() - archive := Archive{} - archive.New() - reader, err = diskbufferreader.New(resp.Body) - assert.NoError(t, err) - - assert.Equal(t, 0, len(reporter.Ch)) - assert.True(t, HandleFile(logContext.Background(), reader, &sources.Chunk{}, reporter)) - assert.Equal(t, 1, len(reporter.Ch)) -} - -func BenchmarkHandleFile(b *testing.B) { - file, err := os.Open("testdata/test.tgz") - assert.Nil(b, err) - defer file.Close() - - archive := Archive{} - archive.New() - - b.ResetTimer() - for i := 0; i < b.N; i++ { - sourceChan := make(chan *sources.Chunk, 1) - reader, err := diskbufferreader.New(file) - assert.NoError(b, err) - - b.StartTimer() - - go func() { - defer close(sourceChan) - HandleFile(logContext.Background(), reader, &sources.Chunk{}, sources.ChanReporter{Ch: sourceChan}) - }() - - for range sourceChan { - } - - b.StopTimer() - } -} - -func TestHandleFileSkipBinaries(t *testing.T) { - filename := createBinaryArchive(t) - defer os.Remove(filename) - - file, err := os.Open(filename) - assert.NoError(t, err) - - reader, err := diskbufferreader.New(file) - assert.NoError(t, err) - - ctx, cancel := logContext.WithTimeout(logContext.Background(), 5*time.Second) - defer cancel() - sourceChan := make(chan *sources.Chunk, 1) - - go func() { - defer close(sourceChan) - HandleFile(ctx, reader, &sources.Chunk{}, sources.ChanReporter{Ch: sourceChan}, WithSkipBinaries(true)) - }() - - count := 0 - for range sourceChan { - count++ - } - // The binary archive should not be scanned. - assert.Equal(t, 0, count) -} - -func createBinaryArchive(t *testing.T) string { - t.Helper() - - f, err := os.CreateTemp("", "testbinary") - assert.NoError(t, err) - defer os.Remove(f.Name()) - - r := rand.New(rand.NewSource(time.Now().UnixNano())) - - randomBytes := make([]byte, 1024) - _, err = r.Read(randomBytes) - assert.NoError(t, err) - - _, err = f.Write(randomBytes) - assert.NoError(t, err) - - // Create and write some structured binary data (e.g., integers, floats) - for i := 0; i < 10; i++ { - err = binary.Write(f, binary.LittleEndian, int32(rand.Intn(1000))) - assert.NoError(t, err) - err = binary.Write(f, binary.LittleEndian, rand.Float64()) - assert.NoError(t, err) - } - - tarFile, err := os.Create("example.tar") - if err != nil { - t.Fatal(err) - } - defer tarFile.Close() - - // Create a new tar archive. - tarWriter := tar.NewWriter(tarFile) - defer tarWriter.Close() - - fileInfo, err := f.Stat() - assert.NoError(t, err) - - header, err := tar.FileInfoHeader(fileInfo, "") - assert.NoError(t, err) - - err = tarWriter.WriteHeader(header) - assert.NoError(t, err) - - fileContent, err := os.ReadFile(f.Name()) - assert.NoError(t, err) - - _, err = tarWriter.Write(fileContent) - assert.NoError(t, err) - - return tarFile.Name() -} - -func TestReadToMax(t *testing.T) { - tests := []struct { - name string - input []byte - expected []byte - }{ - { - name: "read full content within maxSize", - input: []byte("abcdefg"), - expected: []byte("abcdefg"), - }, - { - name: "read content larger than maxSize", - input: make([]byte, maxSize+10), // this creates a byte slice 10 bytes larger than maxSize - expected: make([]byte, maxSize), - }, - { - name: "empty input", - input: []byte(""), - expected: []byte(""), - }, - } - - a := &Archive{} - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - reader := bytes.NewReader(tt.input) - output, err := a.ReadToMax(logContext.Background(), reader) - assert.Nil(t, err) - - assert.Equal(t, tt.expected, output) - }) - } -} - -func BenchmarkReadToMax(b *testing.B) { - data := bytes.Repeat([]byte("a"), 1024*1000) // 1MB of data. - reader := bytes.NewReader(data) - a := &Archive{} - - b.ResetTimer() - for i := 0; i < b.N; i++ { - b.StartTimer() - _, _ = a.ReadToMax(logContext.Background(), reader) - b.StopTimer() - - _, _ = reader.Seek(0, 0) // Reset the reader position. - a.size = 0 // Reset archive size. - } -} - -func TestExtractDebContent(t *testing.T) { - // Open the sample .deb file from the testdata folder. - file, err := os.Open("testdata/test.deb") - assert.Nil(t, err) - defer file.Close() - - ctx := logContext.AddLogger(context.Background()) - a := &Archive{} - - reader, err := a.extractDebContent(ctx, file) - assert.Nil(t, err) - - content, err := io.ReadAll(reader) - assert.Nil(t, err) - expectedLength := 1015582 - assert.Equal(t, expectedLength, len(string(content))) -} - -func TestSkipArchive(t *testing.T) { - file, err := os.Open("testdata/test.tgz") - assert.Nil(t, err) - defer file.Close() - - reader, err := diskbufferreader.New(file) - assert.NoError(t, err) - - ctx := logContext.Background() - - chunkCh := make(chan *sources.Chunk) - go func() { - defer close(chunkCh) - ok := HandleFile(ctx, reader, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}, WithSkipArchives(true)) - assert.False(t, ok) - }() - - wantCount := 0 - count := 0 - for range chunkCh { - count++ - } - assert.Equal(t, wantCount, count) -} - -func TestExtractTarContent(t *testing.T) { - file, err := os.Open("testdata/test.tgz") - assert.Nil(t, err) - defer file.Close() - - reader, err := diskbufferreader.New(file) - assert.NoError(t, err) - - ctx := logContext.Background() - - chunkCh := make(chan *sources.Chunk) - go func() { - defer close(chunkCh) - ok := HandleFile(ctx, reader, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) - assert.True(t, ok) - }() - - wantCount := 4 - count := 0 - for range chunkCh { - count++ - } - assert.Equal(t, wantCount, count) -} - -func TestExtractRPMContent(t *testing.T) { - // Open the sample .rpm file from the testdata folder. - file, err := os.Open("testdata/test.rpm") - assert.Nil(t, err) - defer file.Close() - - ctx := logContext.AddLogger(context.Background()) - a := &Archive{} - - reader, err := a.extractRpmContent(ctx, file) - assert.Nil(t, err) - - content, err := io.ReadAll(reader) - assert.Nil(t, err) - expectedLength := 1822720 - assert.Equal(t, expectedLength, len(string(content))) -} - -func TestOpenInvalidArchive(t *testing.T) { - reader := strings.NewReader("invalid archive") - - ctx := logContext.AddLogger(context.Background()) - a := &Archive{} - - archiveChan := make(chan []byte) - - err := a.openArchive(ctx, 0, reader, archiveChan) - assert.Error(t, err) -} - -func TestNestedDirArchive(t *testing.T) { - file, err := os.Open("testdata/dir-archive.zip") - assert.Nil(t, err) - defer file.Close() - - reader, err := diskbufferreader.New(file) - assert.NoError(t, err) - - ctx, cancel := logContext.WithTimeout(logContext.Background(), 5*time.Second) - defer cancel() - sourceChan := make(chan *sources.Chunk, 1) - - go func() { - defer close(sourceChan) - HandleFile(ctx, reader, &sources.Chunk{}, sources.ChanReporter{Ch: sourceChan}) - }() - - count := 0 - want := 4 - for range sourceChan { - count++ - } - assert.Equal(t, want, count) -} - -func TestDetermineMimeType(t *testing.T) { - filetype.AddMatcher(filetype.NewType("txt", "text/plain"), func(buf []byte) bool { - return strings.HasPrefix(string(buf), "text:") - }) - - pngBytes := []byte("\x89PNG\r\n\x1a\n") - jpegBytes := []byte{0xFF, 0xD8, 0xFF} - textBytes := []byte("text: This is a plain text") - rpmBytes := []byte("\xed\xab\xee\xdb") - - tests := []struct { - name string - input io.Reader - expected mimeType - shouldFail bool - }{ - { - name: "PNG file", - input: bytes.NewReader(pngBytes), - expected: mimeType("image/png"), - shouldFail: false, - }, - { - name: "JPEG file", - input: bytes.NewReader(jpegBytes), - expected: mimeType("image/jpeg"), - shouldFail: false, - }, - { - name: "Text file", - input: bytes.NewReader(textBytes), - expected: mimeType("text/plain"), - shouldFail: false, - }, - { - name: "RPM file", - input: bytes.NewReader(rpmBytes), - expected: rpmMimeType, - shouldFail: false, - }, - { - name: "Truncated JPEG file", - input: io.LimitReader(bytes.NewReader(jpegBytes), 2), - expected: mimeType("unknown"), - shouldFail: true, - }, - { - name: "Empty reader", - input: bytes.NewReader([]byte{}), - shouldFail: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - originalData, _ := io.ReadAll(io.TeeReader(tt.input, &bytes.Buffer{})) - tt.input = bytes.NewReader(originalData) // Reset the reader - - mime, reader, err := determineMimeType(tt.input) - if err != nil && !tt.shouldFail { - t.Fatalf("unexpected error: %v", err) - } - - if !tt.shouldFail { - assert.Equal(t, tt.expected, mime) - } - - // Ensure the reader still contains all the original data. - data, _ := io.ReadAll(reader) - assert.Equal(t, originalData, data) - }) - } -} diff --git a/pkg/handlers/default.go b/pkg/handlers/default.go new file mode 100644 index 000000000000..6b73fe03671a --- /dev/null +++ b/pkg/handlers/default.go @@ -0,0 +1,282 @@ +package handlers + +import ( + "bufio" + "context" + "errors" + "fmt" + "io" + "time" + + "github.com/gabriel-vasile/mimetype" + "github.com/mholt/archiver/v4" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" + logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" + "github.com/trufflesecurity/trufflehog/v3/pkg/readers" + "github.com/trufflesecurity/trufflehog/v3/pkg/sources" +) + +type ctxKey int + +const ( + depthKey ctxKey = iota + defaultBufferSize = 512 +) + +var ( + maxDepth = 5 + maxSize = 250 * 1024 * 1024 // 250 MB + maxTimeout = time.Duration(30) * time.Second +) + +// SetArchiveMaxSize sets the maximum size of the archive. +func SetArchiveMaxSize(size int) { maxSize = size } + +// SetArchiveMaxDepth sets the maximum depth of the archive. +func SetArchiveMaxDepth(depth int) { maxDepth = depth } + +// SetArchiveMaxTimeout sets the maximum timeout for the archive handler. +func SetArchiveMaxTimeout(timeout time.Duration) { maxTimeout = timeout } + +// defaultHandler provides a base implementation for file handlers, encapsulating common behaviors +// needed across different handlers. This handler is embedded in other specialized handlers to ensure +// consistent application of these common behaviors and to simplify the extension of handler functionalities. +type defaultHandler struct{ metrics *metrics } + +// newDefaultHandler creates a defaultHandler with metrics configured based on the provided handlerType. +// The handlerType parameter is used to initialize the metrics instance with the appropriate handler type, +// ensuring that the metrics recorded within the defaultHandler methods are correctly attributed to the +// specific handler that invoked them. This allows for accurate metrics attribution when the defaultHandler +// is embedded in specialized handlers like arHandler or rpmHandler. +func newDefaultHandler(handlerType handlerType) *defaultHandler { + return &defaultHandler{metrics: newHandlerMetrics(handlerType)} +} + +// HandleFile processes the input as either an archive or non-archive based on its content, +// utilizing a single output channel. It first tries to identify the input as an archive. If it is an archive, +// it processes it accordingly; otherwise, it handles the input as non-archive content. +// The function returns a channel that will receive the extracted data bytes and an error if the initial setup fails. +func (h *defaultHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (chan []byte, error) { + // Shared channel for both archive and non-archive content. + dataChan := make(chan []byte, defaultBufferSize) + + _, arReader, err := archiver.Identify("", input) + if err != nil { + if errors.Is(err, archiver.ErrNoMatch) { + // Not an archive, handle as non-archive content in a separate goroutine. + ctx.Logger().V(3).Info("File not recognized as an archive, handling as non-archive content.") + go func() { + defer close(dataChan) + + // Update the metrics for the file processing. + start := time.Now() + var err error + defer func() { + h.measureLatencyAndHandleErrors(start, err) + h.metrics.incFilesProcessed() + }() + + if err = h.handleNonArchiveContent(ctx, arReader, dataChan); err != nil { + ctx.Logger().Error(err, "error handling non-archive content.") + } + }() + + return dataChan, nil + } + + h.metrics.incErrors() + return nil, err + } + + go func() { + ctx, cancel := logContext.WithTimeout(ctx, maxTimeout) + defer cancel() + defer close(dataChan) + + // Update the metrics for the file processing. + start := time.Now() + var err error + defer h.measureLatencyAndHandleErrors(start, err) + + if err = h.openArchive(ctx, 0, arReader, dataChan); err != nil { + ctx.Logger().Error(err, "error unarchiving chunk.") + } + }() + return dataChan, nil +} + +// measureLatencyAndHandleErrors measures the latency of the file processing and updates the metrics accordingly. +// It also records errors and timeouts in the metrics. +func (h *defaultHandler) measureLatencyAndHandleErrors(start time.Time, err error) { + if err == nil { + h.metrics.observeHandleFileLatency(time.Since(start).Milliseconds()) + return + } + + h.metrics.incErrors() + if errors.Is(err, context.DeadlineExceeded) { + h.metrics.incFileProcessingTimeouts() + } +} + +var ErrMaxDepthReached = errors.New("max archive depth reached") + +// openArchive recursively extracts content from an archive up to a maximum depth, handling nested archives if necessary. +// It takes a reader from which it attempts to identify and process the archive format. Depending on the archive type, +// it either decompresses or extracts the contents directly, sending data to the provided channel. +// Returns an error if the archive cannot be processed due to issues like exceeding maximum depth or unsupported formats. +func (h *defaultHandler) openArchive(ctx logContext.Context, depth int, reader io.Reader, archiveChan chan []byte) error { + if common.IsDone(ctx) { + return ctx.Err() + } + + if depth > maxDepth { + h.metrics.incMaxArchiveDepthCount() + return ErrMaxDepthReached + } + + format, arReader, err := archiver.Identify("", reader) + switch { + case err == nil: + // Continue with the rest of the code. + case errors.Is(err, archiver.ErrNoMatch): + if depth > 0 { + // If openArchive is called on an already extracted/decompressed file and the depth is greater than 0, + // it means we are at least 1 layer deep in the archive. In this case, we should handle the content + // as non-archive data by calling handleNonArchiveContent. + return h.handleNonArchiveContent(ctx, arReader, archiveChan) + } + // If openArchive is called on the root (depth == 0) and we can't identify the format, + // it means we can't handle the content at all. Return the archiver.ErrNoMatch error. + return err + default: + // Some other error occurred. + return fmt.Errorf("error identifying archive: %w", err) + } + + switch archive := format.(type) { + case archiver.Decompressor: + // Decompress tha archive and feed the decompressed data back into the archive handler to extract any nested archives. + compReader, err := archive.OpenReader(arReader) + if err != nil { + return fmt.Errorf("error opening decompressor with format %q: %w", format.Name(), err) + } + defer compReader.Close() + + h.metrics.incFilesProcessed() + + rdr, err := readers.NewBufferedFileReader(compReader) + if err != nil { + return fmt.Errorf("error creating random access reader: %w", err) + } + defer rdr.Close() + + return h.openArchive(ctx, depth+1, rdr, archiveChan) + case archiver.Extractor: + err := archive.Extract(logContext.WithValue(ctx, depthKey, depth+1), arReader, nil, h.extractorHandler(archiveChan)) + if err != nil { + return fmt.Errorf("error extracting archive with format: %s: %w", format.Name(), err) + } + return nil + default: + return fmt.Errorf("unknown archive type: %s", format.Name()) + } +} + +// extractorHandler creates a closure that handles individual files extracted by an archiver. +// It logs the extraction, checks for cancellation, and decides whether to skip the file based on its name or type, +// particularly for binary files if configured to skip. If the file is not skipped, it recursively calls openArchive +// to handle nested archives or to continue processing based on the file's content and depth in the archive structure. +func (h *defaultHandler) extractorHandler(archiveChan chan []byte) func(context.Context, archiver.File) error { + return func(ctx context.Context, file archiver.File) error { + lCtx := logContext.WithValues( + logContext.AddLogger(ctx), + "filename", file.Name(), + "size", file.Size(), + ) + lCtx.Logger().V(5).Info("Handling extracted file.") + + if file.IsDir() || file.LinkTarget != "" { + lCtx.Logger().V(5).Info("skipping directory or symlink") + return nil + } + + if common.IsDone(ctx) { + return ctx.Err() + } + + depth := 0 + if ctxDepth, ok := ctx.Value(depthKey).(int); ok { + depth = ctxDepth + } + + fileSize := file.Size() + if int(fileSize) > maxSize { + lCtx.Logger().V(3).Info("skipping file due to size") + return nil + } + + if common.SkipFile(file.Name()) || common.IsBinary(file.Name()) { + lCtx.Logger().V(5).Info("skipping file") + h.metrics.incFilesSkipped() + return nil + } + + fReader, err := file.Open() + if err != nil { + return fmt.Errorf("error opening file %q: %w", file.Name(), err) + } + defer fReader.Close() + + rdr, err := readers.NewBufferedFileReader(fReader) + if err != nil { + return fmt.Errorf("error creating random access reader: %w", err) + } + defer rdr.Close() + + h.metrics.incFilesProcessed() + h.metrics.observeFileSize(fileSize) + + return h.openArchive(lCtx, depth, rdr, archiveChan) + } +} + +// handleNonArchiveContent processes files that do not contain nested archives, serving as the final stage in the +// extraction/decompression process. It reads the content to detect its MIME type and decides whether to skip based +// on the type, particularly for binary files. It manages reading file chunks and writing them to the archive channel, +// effectively collecting the final bytes for further processing. This function is a key component in ensuring that all +// file content, regardless of being an archive or not, is handled appropriately. +func (h *defaultHandler) handleNonArchiveContent(ctx logContext.Context, reader io.Reader, archiveChan chan []byte) error { + bufReader := bufio.NewReaderSize(reader, defaultBufferSize) + // A buffer of 512 bytes is used since many file formats store their magic numbers within the first 512 bytes. + // If fewer bytes are read, MIME type detection may still succeed. + buffer, err := bufReader.Peek(defaultBufferSize) + if err != nil && !errors.Is(err, io.EOF) { + return fmt.Errorf("unable to read file for MIME type detection: %w", err) + } + + mime := mimetype.Detect(buffer) + mimeT := mimeType(mime.String()) + + if common.SkipFile(mime.Extension()) || common.IsBinary(mime.Extension()) { + ctx.Logger().V(5).Info("skipping file", "ext", mimeT) + h.metrics.incFilesSkipped() + return nil + } + + chunkReader := sources.NewChunkReader() + for data := range chunkReader(ctx, bufReader) { + if err := data.Error(); err != nil { + ctx.Logger().Error(err, "error reading chunk") + h.metrics.incErrors() + continue + } + + if err := common.CancellableWrite(ctx, archiveChan, data.Bytes()); err != nil { + return err + } + h.metrics.incBytesProcessed(len(data.Bytes())) + } + return nil +} diff --git a/pkg/handlers/default_test.go b/pkg/handlers/default_test.go new file mode 100644 index 000000000000..accec82edb9c --- /dev/null +++ b/pkg/handlers/default_test.go @@ -0,0 +1,124 @@ +package handlers + +import ( + "context" + "net/http" + "regexp" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + diskbufferreader "github.com/trufflesecurity/disk-buffer-reader" + + logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" +) + +func TestArchiveHandler(t *testing.T) { + tests := map[string]struct { + archiveURL string + expectedChunks int + matchString string + expectErr bool + }{ + "gzip-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one-zip.gz", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "gzip-nested": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/double-zip.gz", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "gzip-too-deep": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six-zip.gz", + 0, + "", + true, + }, + "tar-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one.tar", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "tar-nested": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/two.tar", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "tar-too-deep": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six.tar", + 0, + "", + true, + }, + "targz-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/tar-archive.tar.gz", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "gzip-large": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/FifteenMB.gz", + 1543, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "zip-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/aws-canary-creds.zip", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + } + + for name, testCase := range tests { + t.Run(name, func(t *testing.T) { + resp, err := http.Get(testCase.archiveURL) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + defer resp.Body.Close() + + handler := newDefaultHandler(defaultHandlerType) + + newReader, err := diskbufferreader.New(resp.Body) + if err != nil { + t.Errorf("error creating reusable reader: %s", err) + } + archiveChan, err := handler.HandleFile(logContext.Background(), newReader) + if testCase.expectErr { + assert.NoError(t, err) + return + } + + count := 0 + re := regexp.MustCompile(testCase.matchString) + matched := false + for chunk := range archiveChan { + count++ + if re.Match(chunk) { + matched = true + } + } + + assert.True(t, matched) + assert.Equal(t, testCase.expectedChunks, count) + }) + } +} + +func TestOpenInvalidArchive(t *testing.T) { + reader := strings.NewReader("invalid archive") + + ctx := logContext.AddLogger(context.Background()) + handler := defaultHandler{} + + archiveChan := make(chan []byte) + + err := handler.openArchive(ctx, 0, reader, archiveChan) + assert.Error(t, err) +} diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index 43fcf8941704..0cc70b4705d8 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -1,115 +1,226 @@ package handlers import ( + "fmt" "io" - diskbufferreader "github.com/trufflesecurity/disk-buffer-reader" + "github.com/gabriel-vasile/mimetype" logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" + "github.com/trufflesecurity/trufflehog/v3/pkg/readers" "github.com/trufflesecurity/trufflehog/v3/pkg/sources" ) -func DefaultHandlers() []Handler { - return []Handler{ - &Archive{}, - } +// readSeekCloser is an interface that combines the functionality of io.ReadSeekCloser and io.ReaderAt. +// It supports reading data, seeking within an open resource, and closing the resource once operations are complete. +// Additionally, it allows reading from a specific offset within the resource without altering its current position, +// enabling efficient and flexible data access patterns. This interface is particularly useful for handling files +// or other data streams where random access and sequential processing are required. +type readSeekCloser interface { + io.ReadSeekCloser + io.ReaderAt } -// SpecializedHandler defines the interface for handlers that can process specialized archives. -// It includes a method to handle specialized archives and determine if the file is of a special type. -type SpecializedHandler interface { - // HandleSpecialized examines the provided file reader within the context and determines if it is a specialized archive. - // It returns a reader with any necessary modifications, a boolean indicating if the file was specialized, - // and an error if something went wrong during processing. - HandleSpecialized(logContext.Context, io.Reader) (io.Reader, bool, error) +// FileHandler represents a handler for files. +// It has a single method, HandleFile, which takes a context and a readSeekCloser as input, +// and returns a channel of byte slices and an error. +// The readSeekCloser extends io.ReadSeekCloser with io.ReaderAt capabilities, +// allowing handlers to perform random and direct access on the file content efficiently. +type FileHandler interface { + HandleFile(ctx logContext.Context, reader readSeekCloser) (chan []byte, error) } -// Option is a function type that applies a configuration to a Handler. -type Option func(Handler) +// fileHandlingConfig encapsulates configuration settings that control the behavior of file processing. +type fileHandlingConfig struct{ skipArchives bool } -// WithSkipBinaries returns a Option that configures whether to skip binary files. -func WithSkipBinaries(skip bool) Option { - return func(h Handler) { - if a, ok := h.(*Archive); ok { - a.skipBinaries = skip - } +// newFileHandlingConfig creates a default fileHandlingConfig with default settings. +// Optional functional parameters can customize the configuration. +func newFileHandlingConfig(options ...func(*fileHandlingConfig)) *fileHandlingConfig { + config := new(fileHandlingConfig) + for _, option := range options { + option(config) } + + return config } -// WithSkipArchives returns a Option that configures whether to skip archive files. -func WithSkipArchives(skip bool) Option { - return func(h Handler) { - if a, ok := h.(*Archive); ok { - a.skipArchives = skip - } - } +// WithSkipArchives sets the skipArchives field of the fileHandlingConfig. +// If skip is true, the FileHandler will skip archive files. +func WithSkipArchives(skip bool) func(*fileHandlingConfig) { + return func(c *fileHandlingConfig) { c.skipArchives = skip } } -type Handler interface { - FromFile(logContext.Context, io.Reader) chan []byte - IsFiletype(logContext.Context, io.Reader) (io.Reader, bool) - New(...Option) +type handlerType string + +const ( + defaultHandlerType handlerType = "default" + arHandlerType handlerType = "ar" + rpmHandlerType handlerType = "rpm" +) + +type mimeType string + +const ( + sevenZMime mimeType = "application/x-7z-compressed" + bzip2Mime mimeType = "application/x-bzip2" + rarCompressedMime mimeType = "application/x-rar-compressed" + rarMime mimeType = "application/x-rar" + tarMime mimeType = "application/x-tar" + zipMime mimeType = "application/zip" + gxzipMime mimeType = "application/x-gzip" + gzipMime mimeType = "application/gzip" + gunzipMime mimeType = "application/x-gunzip" + gzippedMime mimeType = "application/gzipped" + gzipCompressedMime mimeType = "application/x-gzip-compressed" + gzipDocumentMime mimeType = "gzip/document" + xzMime mimeType = "application/x-xz" + msCabCompressedMime mimeType = "application/vnd.ms-cab-compressed" + rpmMime mimeType = "application/x-rpm" + fitsMime mimeType = "application/fits" + xarMime mimeType = "application/x-xar" + warcMime mimeType = "application/warc" + cpioMime mimeType = "application/cpio" + unixArMime mimeType = "application/x-unix-archive" + arMime mimeType = "application/x-archive" + debMime mimeType = "application/vnd.debian.binary-package" + lzipMime mimeType = "application/lzip" + lzipXMime mimeType = "application/x-lzip" +) + +var knownArchiveMimeTypes = map[mimeType]struct{}{ + sevenZMime: {}, + bzip2Mime: {}, + gzipMime: {}, + gxzipMime: {}, + rarCompressedMime: {}, + rarMime: {}, + tarMime: {}, + zipMime: {}, + gunzipMime: {}, + gzippedMime: {}, + gzipCompressedMime: {}, + gzipDocumentMime: {}, + xzMime: {}, + msCabCompressedMime: {}, + rpmMime: {}, + fitsMime: {}, + xarMime: {}, + warcMime: {}, + cpioMime: {}, + unixArMime: {}, + arMime: {}, + debMime: {}, + lzipMime: {}, + lzipXMime: {}, } -// HandleFile processes a given file by selecting an appropriate handler from DefaultHandlers. -// It first checks if the handler implements SpecializedHandler for any special processing, -// then falls back to regular file type handling. If successful, it reads the file in chunks, -// packages them in the provided chunk skeleton, and reports them to the chunk reporter. -// The function returns true if processing was successful and false otherwise. -// Context is used for cancellation, and the caller is responsible for canceling it if needed. -func HandleFile(ctx logContext.Context, reReader *diskbufferreader.DiskBufferReader, chunkSkel *sources.Chunk, reporter sources.ChunkReporter, opts ...Option) bool { - for _, h := range DefaultHandlers() { - h.New(opts...) - - if handled := processHandler(ctx, h, reReader, chunkSkel, reporter); handled { - return true - } +// getHandlerForType dynamically selects and configures a FileHandler based on the provided MIME type. +// This method uses specialized handlers for specific archive types and RPM packages: +// - arHandler is used for 'arMime', 'unixArMime', and 'debMime' which include Unix archives and Debian packages. +// - rpmHandler is used for 'rpmMime' and 'cpioMime', handling RPM and CPIO archives. +// For all other MIME types, which typically include common archive formats like .zip, .tar, .gz, etc., +// a defaultHandler is used, leveraging the archiver library to manage these formats. +// The chosen handler is then configured with provided options, adapting it to specific operational needs. +// Returns the configured handler or an error if the handler type does not match the expected type. +func getHandlerForType(mimeT mimeType) (FileHandler, error) { + var handler FileHandler + switch mimeT { + case arMime, unixArMime, debMime: + handler = newARHandler() + case rpmMime, cpioMime: + handler = newRPMHandler() + default: + handler = newDefaultHandler(defaultHandlerType) } - return false + return handler, nil } -func processHandler(ctx logContext.Context, h Handler, reReader *diskbufferreader.DiskBufferReader, chunkSkel *sources.Chunk, reporter sources.ChunkReporter) bool { - if specialHandler, ok := h.(SpecializedHandler); ok { - file, isSpecial, err := specialHandler.HandleSpecialized(ctx, reReader) - if isSpecial { - return handleChunks(ctx, h.FromFile(ctx, file), chunkSkel, reporter) - } - if err != nil { - ctx.Logger().Error(err, "error handling file") - } +// HandleFile orchestrates the complete file handling process for a given file. +// It determines the MIME type of the file, selects the appropriate handler based on this type, and processes the file. +// This function initializes the handling process and delegates to the specific handler to manage file +// extraction or processing. Errors at any stage (MIME type determination, handler retrieval, +// seeking, or file handling) result in an error return value. +// Successful handling passes the file content through a channel to be chunked and reported. +// +// The function takes an io.Reader as input and wraps it with a diskbufferreader.DiskBufferReader to support +// seeking and to provide an io.ReaderAt interface. This is necessary for certain file handlers that require +// random access to the file content. +// +// If the skipArchives option is set to true and the detected MIME type is a known archive type, +// the function will skip processing the file and return nil. +func HandleFile( + ctx logContext.Context, + reader io.Reader, + chunkSkel *sources.Chunk, + reporter sources.ChunkReporter, + options ...func(*fileHandlingConfig), +) error { + config := newFileHandlingConfig(options...) + + rdr, err := readers.NewBufferedFileReader(reader) + if err != nil { + return fmt.Errorf("error creating random access reader: %w", err) + } + defer rdr.Close() + + mimeT, err := mimetype.DetectReader(rdr) + if err != nil { + return fmt.Errorf("error detecting MIME type: %w", err) + } + + mime := mimeType(mimeT.String()) + if _, ok := knownArchiveMimeTypes[mime]; ok && config.skipArchives { + ctx.Logger().V(5).Info("skipping archive file", "mime", mimeT.String()) + return nil + } + + // Reset the reader to the start of the file since the MIME type detection may have read some bytes. + if _, err := rdr.Seek(0, io.SeekStart); err != nil { + return fmt.Errorf("error seeking to start of file: %w", err) } - if _, err := reReader.Seek(0, io.SeekStart); err != nil { - ctx.Logger().Error(err, "error seeking to start of file") - return false + handler, err := getHandlerForType(mime) + if err != nil { + return fmt.Errorf("error getting handler for type: %w", err) } - if _, isType := h.IsFiletype(ctx, reReader); !isType { - return false + archiveChan, err := handler.HandleFile(ctx, rdr) // Delegate to the specific handler to process the file. + if err != nil { + return fmt.Errorf("error handling file: %w", err) } - return handleChunks(ctx, h.FromFile(ctx, reReader), chunkSkel, reporter) + return handleChunks(ctx, archiveChan, chunkSkel, reporter) } -func handleChunks(ctx logContext.Context, handlerChan chan []byte, chunkSkel *sources.Chunk, reporter sources.ChunkReporter) bool { +// handleChunks reads data from the handlerChan and uses it to fill chunks according to a predefined skeleton (chunkSkel). +// Each filled chunk is reported using the provided reporter. This function manages the lifecycle of the channel, +// handling the termination condition when the channel closes and ensuring the cancellation of the operation if the context +// is done. It returns true if all chunks are processed successfully, otherwise returns false on errors or cancellation. +func handleChunks( + ctx logContext.Context, + handlerChan chan []byte, + chunkSkel *sources.Chunk, + reporter sources.ChunkReporter, +) error { if handlerChan == nil { - return false + return fmt.Errorf("handler channel is nil") } for { select { case data, open := <-handlerChan: if !open { - return true + ctx.Logger().V(5).Info("handler channel closed, all chunks processed") + return nil } chunk := *chunkSkel chunk.Data = data if err := reporter.ChunkOk(ctx, chunk); err != nil { - return false + return fmt.Errorf("error reporting chunk: %w", err) } case <-ctx.Done(): - return false + return ctx.Err() } } } diff --git a/pkg/handlers/handlers_test.go b/pkg/handlers/handlers_test.go new file mode 100644 index 000000000000..d4c6430332e1 --- /dev/null +++ b/pkg/handlers/handlers_test.go @@ -0,0 +1,214 @@ +package handlers + +import ( + "io" + "net/http" + "os" + "strings" + "testing" + "time" + + "github.com/stretchr/testify/assert" + diskbufferreader "github.com/trufflesecurity/disk-buffer-reader" + + "github.com/trufflesecurity/trufflehog/v3/pkg/context" + "github.com/trufflesecurity/trufflehog/v3/pkg/sources" +) + +func TestHandleFileCancelledContext(t *testing.T) { + reporter := sources.ChanReporter{Ch: make(chan *sources.Chunk, 2)} + + canceledCtx, cancel := context.WithCancel(context.Background()) + cancel() + reader, err := diskbufferreader.New(strings.NewReader("file")) + assert.NoError(t, err) + assert.Error(t, HandleFile(canceledCtx, reader, &sources.Chunk{}, reporter)) +} + +func TestHandleFile(t *testing.T) { + reporter := sources.ChanReporter{Ch: make(chan *sources.Chunk, 2)} + + // Only one chunk is sent on the channel. + // TODO: Embed a zip without making an HTTP request. + resp, err := http.Get("https://raw.githubusercontent.com/bill-rich/bad-secrets/master/aws-canary-creds.zip") + assert.NoError(t, err) + defer resp.Body.Close() + + assert.Equal(t, 0, len(reporter.Ch)) + assert.NoError(t, HandleFile(context.Background(), resp.Body, &sources.Chunk{}, reporter)) + assert.Equal(t, 1, len(reporter.Ch)) +} + +func BenchmarkHandleFile(b *testing.B) { + file, err := os.Open("testdata/test.tgz") + assert.Nil(b, err) + defer file.Close() + + b.ResetTimer() + for i := 0; i < b.N; i++ { + sourceChan := make(chan *sources.Chunk, 1) + + b.StartTimer() + go func() { + defer close(sourceChan) + err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: sourceChan}) + assert.NoError(b, err) + }() + + for range sourceChan { + } + b.StopTimer() + + _, err = file.Seek(0, io.SeekStart) + assert.NoError(b, err) + } +} + +func TestSkipArchive(t *testing.T) { + file, err := os.Open("testdata/test.tgz") + assert.Nil(t, err) + defer file.Close() + + chunkCh := make(chan *sources.Chunk) + go func() { + defer close(chunkCh) + err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}, WithSkipArchives(true)) + assert.NoError(t, err) + }() + + wantCount := 0 + count := 0 + for range chunkCh { + count++ + } + assert.Equal(t, wantCount, count) +} + +func TestHandleNestedArchives(t *testing.T) { + file, err := os.Open("testdata/nested-dirs.zip") + assert.Nil(t, err) + defer file.Close() + + chunkCh := make(chan *sources.Chunk) + go func() { + defer close(chunkCh) + err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + assert.NoError(t, err) + }() + + wantCount := 8 + count := 0 + for range chunkCh { + count++ + } + assert.Equal(t, wantCount, count) +} + +func TestHandleCompressedZip(t *testing.T) { + file, err := os.Open("testdata/example.zip.gz") + assert.Nil(t, err) + defer file.Close() + + chunkCh := make(chan *sources.Chunk) + go func() { + defer close(chunkCh) + err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + assert.NoError(t, err) + }() + + wantCount := 2 + count := 0 + for range chunkCh { + count++ + } + assert.Equal(t, wantCount, count) +} + +func TestHandleNestedCompressedArchive(t *testing.T) { + file, err := os.Open("testdata/nested-compressed-archive.tar.gz") + assert.Nil(t, err) + defer file.Close() + + chunkCh := make(chan *sources.Chunk) + go func() { + defer close(chunkCh) + err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + assert.NoError(t, err) + }() + + wantCount := 4 + count := 0 + for range chunkCh { + count++ + } + assert.Equal(t, wantCount, count) +} + +func TestExtractTarContent(t *testing.T) { + file, err := os.Open("testdata/test.tgz") + assert.Nil(t, err) + defer file.Close() + + chunkCh := make(chan *sources.Chunk) + go func() { + defer close(chunkCh) + err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + assert.NoError(t, err) + }() + + wantCount := 4 + count := 0 + for range chunkCh { + count++ + } + assert.Equal(t, wantCount, count) +} + +func TestNestedDirArchive(t *testing.T) { + file, err := os.Open("testdata/dir-archive.zip") + assert.Nil(t, err) + defer file.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + sourceChan := make(chan *sources.Chunk, 1) + + go func() { + defer close(sourceChan) + err := HandleFile(ctx, file, &sources.Chunk{}, sources.ChanReporter{Ch: sourceChan}) + assert.NoError(t, err) + }() + + count := 0 + want := 4 + for range sourceChan { + count++ + } + assert.Equal(t, want, count) +} + +func TestHandleFileRPM(t *testing.T) { + wantChunkCount := 179 + reporter := sources.ChanReporter{Ch: make(chan *sources.Chunk, wantChunkCount)} + + file, err := os.Open("testdata/test.rpm") + assert.Nil(t, err) + defer file.Close() + + assert.Equal(t, 0, len(reporter.Ch)) + assert.NoError(t, HandleFile(context.Background(), file, &sources.Chunk{}, reporter)) + assert.Equal(t, wantChunkCount, len(reporter.Ch)) +} + +func TestHandleFileAR(t *testing.T) { + wantChunkCount := 102 + reporter := sources.ChanReporter{Ch: make(chan *sources.Chunk, wantChunkCount)} + + file, err := os.Open("testdata/test.deb") + assert.Nil(t, err) + defer file.Close() + + assert.Equal(t, 0, len(reporter.Ch)) + assert.NoError(t, HandleFile(context.Background(), file, &sources.Chunk{}, reporter)) + assert.Equal(t, wantChunkCount, len(reporter.Ch)) +} diff --git a/pkg/handlers/metrics.go b/pkg/handlers/metrics.go new file mode 100644 index 000000000000..941d8d2e0590 --- /dev/null +++ b/pkg/handlers/metrics.go @@ -0,0 +1,183 @@ +package handlers + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" +) + +type metrics struct { + handlerType handlerType + handleFileLatency *prometheus.HistogramVec + bytesProcessed *prometheus.CounterVec + filesProcessed *prometheus.CounterVec + errorsEncountered *prometheus.CounterVec + filesSkipped *prometheus.CounterVec + maxArchiveDepthCount *prometheus.CounterVec + fileSize *prometheus.HistogramVec + fileProcessingTimeouts *prometheus.CounterVec +} + +var ( + handleFileLatency = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_file_latency_milliseconds", + Help: "Latency of the HandleFile method", + Buckets: prometheus.ExponentialBuckets(1, 5, 6), + }, + []string{"handler_type"}, + ) + bytesProcessed = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_bytes_processed_total", + Help: "Total number of bytes processed", + }, + []string{"handler_type"}, + ) + filesProcessed = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_files_processed_total", + Help: "Total number of files processed", + }, + []string{"handler_type"}, + ) + errorsEncountered = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_errors_encountered_total", + Help: "Total number of errors encountered", + }, + []string{"handler_type"}, + ) + filesSkipped = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_files_skipped_total", + Help: "Total number of files skipped", + }, + []string{"handler_type"}, + ) + maxArchiveDepthCount = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_max_archive_depth_reached_total", + Help: "Total number of times the maximum archive depth was reached", + }, + []string{"handler_type"}, + ) + fileSize = promauto.NewHistogramVec( + prometheus.HistogramOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_file_size_bytes", + Help: "Sizes of files handled by the handler", + Buckets: prometheus.ExponentialBuckets(1, 2, 4), + }, + []string{"handler_type"}, + ) + fileProcessingTimeouts = promauto.NewCounterVec( + prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "handlers_file_processing_timeouts_total", + Help: "Total number of file processing timeouts encountered", + }, + []string{"handler_type"}, + ) +) + +// newHandlerMetrics creates a new metrics instance configured with Prometheus metrics specific to a file handler. +// The function takes a handlerType parameter, which represents the type of the handler (e.g., "default", "ar", "rpm"). +// The handlerType is used as a label for each metric, allowing for differentiation and aggregation of metrics +// based on the handler type. +// +// The function initializes and returns a pointer to a metrics struct that contains the following Prometheus metrics: +// +// - handleFileLatency: a HistogramVec metric that measures the latency of the HandleFile method. +// It uses exponential buckets with a base of 1 and a factor of 5, up to 6 buckets. +// The metric is labeled with the handlerType. +// +// - bytesProcessed: a CounterVec metric that tracks the total number of bytes processed by the handler. +// It is labeled with the handlerType. +// +// - filesProcessed: a CounterVec metric that tracks the total number of files processed by the handler. +// It is labeled with the handlerType. +// +// - errorsEncountered: a CounterVec metric that tracks the total number of errors encountered by the handler. +// It is labeled with the handlerType. +// +// - filesSkipped: a CounterVec metric that tracks the total number of files skipped by the handler. +// It is labeled with the handlerType. +// +// - maxArchiveDepthCount: a CounterVec metric that tracks the total number of times the maximum archive depth was reached. +// It is labeled with the handlerType. +// +// - fileSize: a HistogramVec metric that measures the sizes of files handled by the handler. +// It uses exponential buckets with a base of 1 and a factor of 2, up to 4 buckets. +// It is labeled with the handlerType. +// +// - fileProcessingTimeouts: a CounterVec metric that tracks the total number of file processing timeouts +// encountered by the handler. +// It is labeled with the handlerType. +// +// The metrics are created with a common namespace and subsystem defined in the common package. +// This helps to organize and group related metrics together. +// +// By initializing the metrics with the handlerType label, the function enables accurate attribution and aggregation +// of metrics based on the specific handler type. This allows for fine-grained monitoring and analysis of +// file handler performance. +func newHandlerMetrics(t handlerType) *metrics { + return &metrics{ + handlerType: t, + handleFileLatency: handleFileLatency, + bytesProcessed: bytesProcessed, + filesProcessed: filesProcessed, + errorsEncountered: errorsEncountered, + filesSkipped: filesSkipped, + maxArchiveDepthCount: maxArchiveDepthCount, + fileSize: fileSize, + fileProcessingTimeouts: fileProcessingTimeouts, + } +} + +func (m *metrics) observeHandleFileLatency(duration int64) { + m.handleFileLatency.WithLabelValues(string(m.handlerType)).Observe(float64(duration)) +} + +func (m *metrics) incBytesProcessed(bytes int) { + m.bytesProcessed.WithLabelValues(string(m.handlerType)).Add(float64(bytes)) +} + +func (m *metrics) incFilesProcessed() { + m.filesProcessed.WithLabelValues(string(m.handlerType)).Inc() +} + +func (m *metrics) incErrors() { + m.errorsEncountered.WithLabelValues(string(m.handlerType)).Inc() +} + +func (m *metrics) incFilesSkipped() { + m.filesSkipped.WithLabelValues(string(m.handlerType)).Inc() +} + +func (m *metrics) incMaxArchiveDepthCount() { + m.maxArchiveDepthCount.WithLabelValues(string(m.handlerType)).Inc() +} + +func (m *metrics) observeFileSize(size int64) { + m.fileSize.WithLabelValues(string(m.handlerType)).Observe(float64(size)) +} + +func (m *metrics) incFileProcessingTimeouts() { + m.fileProcessingTimeouts.WithLabelValues(string(m.handlerType)).Inc() +} diff --git a/pkg/handlers/rpm.go b/pkg/handlers/rpm.go new file mode 100644 index 000000000000..be799768b047 --- /dev/null +++ b/pkg/handlers/rpm.go @@ -0,0 +1,87 @@ +package handlers + +import ( + "errors" + "fmt" + "io" + "time" + + "github.com/sassoftware/go-rpmutils" + + logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" +) + +// rpmHandler specializes defaultHandler to manage RPM package files. It leverages shared behaviors +// from defaultHandler and introduces additional logic specific to RPM packages. +type rpmHandler struct{ *defaultHandler } + +// newRPMHandler creates an rpmHandler. +func newRPMHandler() *rpmHandler { + return &rpmHandler{defaultHandler: newDefaultHandler(rpmHandlerType)} +} + +// HandleFile processes RPM formatted files. Further implementation is required to appropriately +// handle RPM specific archive operations. +func (h *rpmHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (chan []byte, error) { + archiveChan := make(chan []byte, defaultBufferSize) + + go func() { + ctx, cancel := logContext.WithTimeout(ctx, maxTimeout) + defer cancel() + defer close(archiveChan) + + // Update the metrics for the file processing. + start := time.Now() + var err error + defer h.measureLatencyAndHandleErrors(start, err) + + var rpm *rpmutils.Rpm + rpm, err = rpmutils.ReadRpm(input) + if err != nil { + ctx.Logger().Error(err, "error reading RPM") + return + } + + var reader rpmutils.PayloadReader + reader, err = rpm.PayloadReaderExtended() + if err != nil { + ctx.Logger().Error(err, "error getting RPM payload reader") + return + } + + if err = h.processRPMFiles(ctx, reader, archiveChan); err != nil { + ctx.Logger().Error(err, "error processing RPM files") + } + }() + + return archiveChan, nil +} + +func (h *rpmHandler) processRPMFiles(ctx logContext.Context, reader rpmutils.PayloadReader, archiveChan chan []byte) error { + for { + select { + case <-ctx.Done(): + return ctx.Err() + default: + fileInfo, err := reader.Next() + if err != nil { + if errors.Is(err, io.EOF) { + ctx.Logger().V(3).Info("RPM payload archive fully processed") + return nil + } + return fmt.Errorf("error reading RPM payload: %w", err) + } + + fileSize := fileInfo.Size() + fileCtx := logContext.WithValues(ctx, "filename", fileInfo.Name, "size", fileSize) + + if err := h.handleNonArchiveContent(fileCtx, reader, archiveChan); err != nil { + fileCtx.Logger().Error(err, "error handling archive content in RPM") + h.metrics.incErrors() + } + + h.metrics.incFilesProcessed() + h.metrics.observeFileSize(fileSize) + } + } +} diff --git a/pkg/handlers/rpm_test.go b/pkg/handlers/rpm_test.go new file mode 100644 index 000000000000..d5e2e7b34e29 --- /dev/null +++ b/pkg/handlers/rpm_test.go @@ -0,0 +1,32 @@ +package handlers + +import ( + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + + "github.com/trufflesecurity/trufflehog/v3/pkg/context" +) + +func TestHandleRPMFile(t *testing.T) { + file, err := os.Open("testdata/test.rpm") + assert.Nil(t, err) + defer file.Close() + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + + handler := newRPMHandler() + archiveChan, err := handler.HandleFile(context.AddLogger(ctx), file) + assert.NoError(t, err) + + wantChunkCount := 179 + count := 0 + for range archiveChan { + count++ + } + + assert.Equal(t, wantChunkCount, count) +} diff --git a/pkg/handlers/testdata/example.zip.gz b/pkg/handlers/testdata/example.zip.gz new file mode 100644 index 0000000000000000000000000000000000000000..863318791b71cbe49e1e90f80bc438f47017ab7c GIT binary patch literal 185 zcmV;q07m~GiwFqiZXjj=17&z&ZE$R5E_!Kj01NPDX5nH0f!Tc%BW}elHk1akL7108 zhM^?2xFjtzC)G%=q@pA=gp+~!X`VtF2$xoHGcdAzWn^Gr5dkU=$;d2L0HVaa{F02+ zA_b5}1&~fXt^gDp;&wFO5(TnF(QGgz+6Gj!8JXmmak*atEDkh)VM!y1h2|Sph+Sy* npc{$mU}Phckc>3MZzL-lNE;InE(6m0z=i+-BpGxadI10cP*+C@ literal 0 HcmV?d00001 diff --git a/pkg/handlers/testdata/nested-compressed-archive.tar.gz b/pkg/handlers/testdata/nested-compressed-archive.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..30440d1a954a436de5d5d0043f003f4f814782a4 GIT binary patch literal 391 zcmV;20eJo&iwFR~E+A$A1M|$wOD%HAEJ{r-$uFwZtI8~3pgJ%xFfcPQQ2^2AW~N}; zzzD(z0Yei5V+BJKGee*#kT6m(Ff=nXG+|IMpuSTuL1}SGViC|Oi5W$SWqK*4B_)Yi z)d7{IrQtCL;ui%tJw!l&H!}+tn8lSjF#=hJpFxJf6D4)%hlX%6Fq`Noq?rS8X$3a} zBg{&g>HfvO!n^(;&CZoKz#dl8O?ziDsB4x|HVTRw|?CqDb0MQ?Ist2p$*{&4&6*&tElUYlV@QTIhCpi=ndF#pg}(%pCBX335kzCe1}nri zjF><*6g4g&h62?xENS$_G!!Xjh%+5E3Xo0TfZcRsQcOn;d1TYY8L^sfh~IQpHjoJ{ zK$s5{tYai0rwmV!Us{q{lm-kqP`J^^4g%#rkOMFO&5g_rfaSlbp}FyB`A-kv4~l;U lPy$d$&d)1J%`4#=XeW(=Q7{Td!6={u008M6Qzifo000ecm&pJC literal 0 HcmV?d00001 diff --git a/pkg/handlers/testdata/nested-dirs.zip b/pkg/handlers/testdata/nested-dirs.zip new file mode 100644 index 0000000000000000000000000000000000000000..763a1999eae25c6b6818c12edcc507921d6a7632 GIT binary patch literal 2318 zcmb`I&q~8U5XPq_m0A%MT3SRTcoxN0^rVtf1pk4Eq8^K>7-$=*5v&KH;#ufPJm^Ue z9t00QfKMR4hKNT`f;f|;x|=m7rrok_Db4TO`DSNkWl@sjKr5*?HmxttTMPzaxi+Vl ziu+^hYh55Mj3_%BxDO7yAtJv=0OSPzcZDNNKb&9GT9I^S(nUe{Nct&W;}$ Date: Sat, 11 May 2024 07:05:59 -0700 Subject: [PATCH 22/51] fix(deps): update testcontainers-go monorepo to v0.31.0 (#2823) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 10 +++++----- go.sum | 10 ++++++++++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 43e02836576f..c5f1b27dae42 100644 --- a/go.mod +++ b/go.mod @@ -74,10 +74,10 @@ require ( github.com/snowflakedb/gosnowflake v1.10.0 github.com/stretchr/testify v1.9.0 github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 - github.com/testcontainers/testcontainers-go v0.30.0 - github.com/testcontainers/testcontainers-go/modules/mssql v0.30.0 - github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0 - github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0 + github.com/testcontainers/testcontainers-go v0.31.0 + github.com/testcontainers/testcontainers-go/modules/mssql v0.31.0 + github.com/testcontainers/testcontainers-go/modules/mysql v0.31.0 + github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 github.com/trufflesecurity/disk-buffer-reader v0.2.1 github.com/wasilibs/go-re2 v1.5.2 github.com/xanzy/go-gitlab v0.104.1 @@ -138,7 +138,7 @@ require ( github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/cloudflare/circl v1.3.7 // indirect - github.com/containerd/containerd v1.7.12 // indirect + github.com/containerd/containerd v1.7.15 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect github.com/couchbase/gocbcore/v10 v10.4.1 // indirect diff --git a/go.sum b/go.sum index fb63fca994de..4331951cba47 100644 --- a/go.sum +++ b/go.sum @@ -176,6 +176,8 @@ github.com/coinbase/waas-client-library-go v1.0.8 h1:AdbTmBQpsSUx947GZd5/68BhNBw github.com/coinbase/waas-client-library-go v1.0.8/go.mod h1:RVKozprfdfMiK92ATZUWHRs0EFGHQj4rbEJjzzZzI1I= github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= +github.com/containerd/containerd v1.7.15 h1:afEHXdil9iAm03BmhjzKyXnnEBtjaLJefdU7DV0IFes= +github.com/containerd/containerd v1.7.15/go.mod h1:ISzRRTMF8EXNpJlTzyr2XMhN+j9K302C21/+cr3kUnY= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k= @@ -684,12 +686,20 @@ github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 h1:34icjjmqJ2HP github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= github.com/testcontainers/testcontainers-go v0.30.0 h1:jmn/XS22q4YRrcMwWg0pAwlClzs/abopbsBzrepyc4E= github.com/testcontainers/testcontainers-go v0.30.0/go.mod h1:K+kHNGiM5zjklKjgTtcrEetF3uhWbMUyqAQoyoh8Pf0= +github.com/testcontainers/testcontainers-go v0.31.0 h1:W0VwIhcEVhRflwL9as3dhY6jXjVCA27AkmbnZ+UTh3U= +github.com/testcontainers/testcontainers-go v0.31.0/go.mod h1:D2lAoA0zUFiSY+eAflqK5mcUx/A5hrrORaEQrd0SefI= github.com/testcontainers/testcontainers-go/modules/mssql v0.30.0 h1:jvDa5EImFyFNv6LLbd3qdcq1TXBY2LzOUZ0GbVbsI7I= github.com/testcontainers/testcontainers-go/modules/mssql v0.30.0/go.mod h1:BYBQszX47xz69xeTg5hX62ndgwxdfAIs6w/94Pk1Z1M= +github.com/testcontainers/testcontainers-go/modules/mssql v0.31.0 h1:X4MRxswzZJov/X5a5FYGzNmMRAKlnErE+5euMoMJGzM= +github.com/testcontainers/testcontainers-go/modules/mssql v0.31.0/go.mod h1:GsGFz4tcxka1meZdBBHdqZCYdpHQaa/pORXW/ELWZV0= github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0 h1:wrePvxfU/2HFALKyBqpNs6VoPPvThzHy9aN+PCxse9g= github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0/go.mod h1:Srnlf7wwA7s6K4sKKhjAoBHJcKorRINR/i5dCA4ZyGk= +github.com/testcontainers/testcontainers-go/modules/mysql v0.31.0 h1:790+S8ewZYCbG+o8IiFlZ8ZZ33XbNO6zV9qhU6xhlRk= +github.com/testcontainers/testcontainers-go/modules/mysql v0.31.0/go.mod h1:REFmO+lSG9S6uSBEwIMZCxeI36uhScjTwChYADeO3JA= github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0 h1:D3HFqpZS90iRGAN7M85DFiuhPfvYvFNnx8urQ6mPAvo= github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0/go.mod h1:e1sKxwUOkqzvaqdHl/oV9mUtFmkDPTfBGp0po2tnWQU= +github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 h1:isAwFS3KNKRbJMbWv+wolWqOFUECmjYZ+sIRZCIBc/E= +github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0/go.mod h1:ZNYY8vumNCEG9YI59A9d6/YaMY49uwRhmeU563EzFGw= github.com/tetratelabs/wazero v1.7.0 h1:jg5qPydno59wqjpGrHph81lbtHzTrWzwwtD4cD88+hQ= github.com/tetratelabs/wazero v1.7.0/go.mod h1:ytl6Zuh20R/eROuyDaGPkp82O9C/DJfXAwJfQ3X6/7Y= github.com/therootcompany/xz v1.0.1 h1:CmOtsn1CbtmyYiusbfmhmkpAAETj0wBIH6kCYaX+xzw= From 82f450b00ff749c6cb4086a15f2a0ec5c7a36a8d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 07:06:21 -0700 Subject: [PATCH 23/51] fix(deps): update module github.com/xanzy/go-gitlab to v0.105.0 (#2824) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index c5f1b27dae42..d12960678163 100644 --- a/go.mod +++ b/go.mod @@ -80,7 +80,7 @@ require ( github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 github.com/trufflesecurity/disk-buffer-reader v0.2.1 github.com/wasilibs/go-re2 v1.5.2 - github.com/xanzy/go-gitlab v0.104.1 + github.com/xanzy/go-gitlab v0.105.0 go.mongodb.org/mongo-driver v1.15.0 go.uber.org/mock v0.4.0 go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index 4331951cba47..db67550a843a 100644 --- a/go.sum +++ b/go.sum @@ -728,6 +728,8 @@ github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlV github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM= github.com/xanzy/go-gitlab v0.104.1 h1:g/liXIPJH0jsTwVuzTAUMiKdTf6Qup3u2XZq5Rp90Wc= github.com/xanzy/go-gitlab v0.104.1/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= +github.com/xanzy/go-gitlab v0.105.0 h1:3nyLq0ESez0crcaM19o5S//SvezOQguuIHZ3wgX64hM= +github.com/xanzy/go-gitlab v0.105.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= From a2b79fb12804a741feb7e22cfdd57c0fc9dbca9c Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 07:06:47 -0700 Subject: [PATCH 24/51] fix(deps): update module google.golang.org/api to v0.180.0 (#2822) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 4 ++-- go.sum | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index d12960678163..319fcdec5c54 100644 --- a/go.mod +++ b/go.mod @@ -90,7 +90,7 @@ require ( golang.org/x/oauth2 v0.20.0 golang.org/x/sync v0.7.0 golang.org/x/text v0.15.0 - google.golang.org/api v0.178.0 + google.golang.org/api v0.180.0 google.golang.org/protobuf v1.34.1 gopkg.in/h2non/gock.v1 v1.1.2 pault.ag/go/debian v0.16.0 @@ -100,7 +100,7 @@ require ( require ( cloud.google.com/go v0.112.2 // indirect - cloud.google.com/go/auth v0.3.0 // indirect + cloud.google.com/go/auth v0.4.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect cloud.google.com/go/iam v1.1.7 // indirect diff --git a/go.sum b/go.sum index db67550a843a..5a11f7234308 100644 --- a/go.sum +++ b/go.sum @@ -11,6 +11,8 @@ cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs= cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w= +cloud.google.com/go/auth v0.4.1 h1:Z7YNIhlWRtrnKlZke7z3GMqzvuYzdc2z98F9D1NV5Hg= +cloud.google.com/go/auth v0.4.1/go.mod h1:QVBuVEKpCn4Zp58hzRGvL0tjRGU0YqdRTdCHM1IHnro= cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= cloud.google.com/go/auth/oauth2adapt v0.2.2/go.mod h1:wcYjgpZI9+Yu7LyYBg4pqSiaRkfEK3GQcpb7C/uyF1Q= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -1029,6 +1031,8 @@ google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= google.golang.org/api v0.178.0 h1:yoW/QMI4bRVCHF+NWOTa4cL8MoWL3Jnuc7FlcFF91Ok= google.golang.org/api v0.178.0/go.mod h1:84/k2v8DFpDRebpGcooklv/lais3MEfqpaBLA12gl2U= +google.golang.org/api v0.180.0 h1:M2D87Yo0rGBPWpo1orwfCLehUUL6E7/TYe5gvMQWDh4= +google.golang.org/api v0.180.0/go.mod h1:51AiyoEg1MJPSZ9zvklA8VnRILPXxn1iVen9v25XHAE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= From 7fd36f86cd04a0808f3832a7766f11f7d8212859 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sat, 11 May 2024 07:18:13 -0700 Subject: [PATCH 25/51] fix(deps): update module github.com/sassoftware/go-rpmutils to v0.4.0 (#2831) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 319fcdec5c54..384265b66899 100644 --- a/go.mod +++ b/go.mod @@ -68,7 +68,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.19.1 github.com/rabbitmq/amqp091-go v1.10.0 - github.com/sassoftware/go-rpmutils v0.3.0 + github.com/sassoftware/go-rpmutils v0.4.0 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 github.com/shuheiktgw/go-travis v0.3.1 github.com/snowflakedb/gosnowflake v1.10.0 @@ -137,7 +137,7 @@ require ( github.com/bodgit/windows v1.0.1 // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect - github.com/cloudflare/circl v1.3.7 // indirect + github.com/cloudflare/circl v1.3.8 // indirect github.com/containerd/containerd v1.7.15 // indirect github.com/containerd/log v0.1.0 // indirect github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect @@ -199,7 +199,7 @@ require ( github.com/jpillora/s3 v1.1.4 // indirect github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d // indirect - github.com/klauspost/compress v1.17.4 // indirect + github.com/klauspost/compress v1.17.8 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/klauspost/pgzip v1.2.5 // indirect github.com/launchdarkly/ccache v1.1.0 // indirect @@ -252,7 +252,7 @@ require ( github.com/therootcompany/xz v1.0.1 // indirect github.com/tklauser/go-sysconf v0.3.12 // indirect github.com/tklauser/numcpus v0.6.1 // indirect - github.com/ulikunitz/xz v0.5.11 // indirect + github.com/ulikunitz/xz v0.5.12 // indirect github.com/vbatts/tar-split v0.11.3 // indirect github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect diff --git a/go.sum b/go.sum index 5a11f7234308..5d41b0c53dec 100644 --- a/go.sum +++ b/go.sum @@ -173,6 +173,8 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= +github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI= +github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coinbase/waas-client-library-go v1.0.8 h1:AdbTmBQpsSUx947GZd5/68BhNBw1CSwTfE2PcnVy3Ao= github.com/coinbase/waas-client-library-go v1.0.8/go.mod h1:RVKozprfdfMiK92ATZUWHRs0EFGHQj4rbEJjzzZzI1I= @@ -477,6 +479,8 @@ github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d/go.mod h1:phT/jsRPBAEqjAi github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= +github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= +github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg= github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= @@ -642,6 +646,8 @@ github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wr github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= github.com/sassoftware/go-rpmutils v0.3.0 h1:tE4TZ8KcOXay5iIP64P291s6Qxd9MQCYhI7DU+f3gFA= github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcucCa0DsCzE9RMfwMo= +github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg= +github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= @@ -719,6 +725,8 @@ github.com/trufflesecurity/overseer v1.2.7/go.mod h1:nT9w37AiO1Nop2VhVhNfzAFaPjt github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= +github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RVck= github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY= From 64be16c940401047368ecb17724e1721548da8fa Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 12 May 2024 12:37:05 -0700 Subject: [PATCH 26/51] fix(deps): update module github.com/google/go-github/v61 to v62 (#2832) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 1 + go.sum | 1 + 2 files changed, 2 insertions(+) diff --git a/go.mod b/go.mod index 384265b66899..aa44f9b8553a 100644 --- a/go.mod +++ b/go.mod @@ -46,6 +46,7 @@ require ( github.com/google/go-cmp v0.6.0 github.com/google/go-containerregistry v0.19.1 github.com/google/go-github/v61 v61.0.0 + github.com/google/go-github/v62 v62.0.0 github.com/google/uuid v1.6.0 github.com/googleapis/gax-go/v2 v2.12.4 github.com/hashicorp/go-retryablehttp v0.7.6 diff --git a/go.sum b/go.sum index 5d41b0c53dec..3cc520c20443 100644 --- a/go.sum +++ b/go.sum @@ -372,6 +372,7 @@ github.com/google/go-github/v60 v60.0.0 h1:oLG98PsLauFvvu4D/YPxq374jhSxFYdzQGNCy github.com/google/go-github/v60 v60.0.0/go.mod h1:ByhX2dP9XT9o/ll2yXAu2VD8l5eNVg8hD4Cr0S/LmQk= github.com/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= +github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= From f527da9ecc6ff9941e8ebdf449ee8ffc26096d61 Mon Sep 17 00:00:00 2001 From: Abdul Basit Date: Mon, 13 May 2024 19:09:35 +0500 Subject: [PATCH 27/51] Update results's extra data for Twilio (#2807) * Response structure added for service api of Twilio. added two response fields in extra data: 1) friendly_name 2) account_sid * mark credentials verified for non-fatal errors. also check for atleast one service in response before extracting metadata. --- pkg/detectors/twilio/twilio.go | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/pkg/detectors/twilio/twilio.go b/pkg/detectors/twilio/twilio.go index d761dc33356e..fa32247010a5 100644 --- a/pkg/detectors/twilio/twilio.go +++ b/pkg/detectors/twilio/twilio.go @@ -2,10 +2,12 @@ package twilio import ( "context" + "encoding/json" "fmt" - regexp "github.com/wasilibs/go-re2" "net/http" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" @@ -25,6 +27,16 @@ var ( keyPat = regexp.MustCompile(`\b[0-9a-f]{32}\b`) ) +type serviceResponse struct { + Services []service `json:"services"` +} + +type service struct { + FriendlyName string `json:"friendly_name"` // friendly name of a service + SID string `json:"sid"` // object id of service + AccountSID string `json:"account_sid"` // account sid +} + // Keywords are used for efficiently pre-filtering chunks. // Use identifiers in the secret preferably, or the provider name. func (s Scanner) Keywords() []string { @@ -73,10 +85,16 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result req.SetBasicAuth(sid, key) res, err := client.Do(req) if err == nil { - res.Body.Close() // The request body is unused. + defer res.Body.Close() if res.StatusCode >= 200 && res.StatusCode < 300 { s1.Verified = true + var serviceResponse serviceResponse + if err := json.NewDecoder(res.Body).Decode(&serviceResponse); err == nil && len(serviceResponse.Services) > 0 { // no error in parsing and have atleast one service + service := serviceResponse.Services[0] + s1.ExtraData["friendly_name"] = service.FriendlyName + s1.ExtraData["account_sid"] = service.AccountSID + } } else if res.StatusCode == 401 || res.StatusCode == 403 { // The secret is determinately not verified (nothing to do) } else { From 333c4f52961bf1d06d04a82fbdea35a796d102db Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 08:08:47 -0700 Subject: [PATCH 28/51] fix(deps): update module github.com/aws/aws-sdk-go to v1.53.0 (#2830) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index aa44f9b8553a..60bab08e99f1 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/TheZeroSlave/zapsentry v1.23.0 github.com/adrg/strutil v0.3.1 github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/aws/aws-sdk-go v1.52.6 + github.com/aws/aws-sdk-go v1.53.0 github.com/aymanbagabas/go-osc52 v1.2.2 github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb diff --git a/go.sum b/go.sum index 3cc520c20443..54965ff1184f 100644 --- a/go.sum +++ b/go.sum @@ -121,6 +121,8 @@ github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= github.com/aws/aws-sdk-go v1.52.6 h1:nw1AMg0wIj5tTnI89KaDe9G5aISqXm4KJEe1DfNbFvA= github.com/aws/aws-sdk-go v1.52.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.0 h1:MMo1x1ggPPxDfHMXJnQudTbGXYlD4UigUAud1DJxPVo= +github.com/aws/aws-sdk-go v1.53.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo= From 9873c144ee59d626c5587b0b80d033943a3ca23e Mon Sep 17 00:00:00 2001 From: ahrav Date: Mon, 13 May 2024 14:13:23 -0700 Subject: [PATCH 29/51] [chore] - Update GitlabV2 detector (#2840) * replace keyword and replace prefix * address comment --- pkg/detectors/gitlab/v2/gitlab_v2.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/pkg/detectors/gitlab/v2/gitlab_v2.go b/pkg/detectors/gitlab/v2/gitlab_v2.go index 2cd0fd8d1426..d0d413c60ea5 100644 --- a/pkg/detectors/gitlab/v2/gitlab_v2.go +++ b/pkg/detectors/gitlab/v2/gitlab_v2.go @@ -28,14 +28,12 @@ func (Scanner) DefaultEndpoint() string { return "https://gitlab.com" } var ( defaultClient = common.SaneHttpClient() - keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"gitlab"}) + `\b(glpat-[a-zA-Z0-9\-=_]{20,22})\b`) + keyPat = regexp.MustCompile(`\b(glpat-[a-zA-Z0-9\-=_]{20,22})\b`) ) // Keywords are used for efficiently pre-filtering chunks. // Use identifiers in the secret preferably, or the provider name. -func (s Scanner) Keywords() []string { - return []string{"gitlab"} -} +func (s Scanner) Keywords() []string { return []string{"glpat-"} } // FromData will find and optionally verify Gitlab secrets in a given set of bytes. func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { From c13b1e53bf287ce145def9bde98b72ea4194fd9b Mon Sep 17 00:00:00 2001 From: Sam Chan <144381343+theproductone@users.noreply.github.com> Date: Mon, 13 May 2024 15:36:23 -0600 Subject: [PATCH 30/51] Fixed the Now Scanning emoji (#2842) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 28810537e167..e7425cd8e343 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ --- -# :mag*right: \_Now Scanning* +# :mag_right: *Now Scanning*
From daec737ccea1a3c365834cb495c1c3ff9f3a8ed2 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 14:45:25 -0700 Subject: [PATCH 31/51] fix(deps): update module github.com/fatih/color to v1.17.0 (#2837) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 60bab08e99f1..50200079c6ca 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,7 @@ require ( github.com/couchbase/gocb/v2 v2.8.1 github.com/crewjam/rfc5424 v0.1.0 github.com/envoyproxy/protoc-gen-validate v1.0.4 - github.com/fatih/color v1.16.0 + github.com/fatih/color v1.17.0 github.com/felixge/fgprof v0.9.4 github.com/gabriel-vasile/mimetype v1.4.3 github.com/getsentry/sentry-go v0.27.0 diff --git a/go.sum b/go.sum index 54965ff1184f..5238283510a0 100644 --- a/go.sum +++ b/go.sum @@ -251,6 +251,8 @@ github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6 github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88= github.com/felixge/fgprof v0.9.4/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= From 09e465b44572b4dca3cc7adc31c5c9330e45fa81 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 14:45:42 -0700 Subject: [PATCH 32/51] fix(deps): update module github.com/aws/aws-sdk-go to v1.53.1 (#2841) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index 50200079c6ca..6ca45d16ff8f 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/TheZeroSlave/zapsentry v1.23.0 github.com/adrg/strutil v0.3.1 github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/aws/aws-sdk-go v1.53.0 + github.com/aws/aws-sdk-go v1.53.1 github.com/aymanbagabas/go-osc52 v1.2.2 github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb diff --git a/go.sum b/go.sum index 5238283510a0..723120a61743 100644 --- a/go.sum +++ b/go.sum @@ -123,6 +123,8 @@ github.com/aws/aws-sdk-go v1.52.6 h1:nw1AMg0wIj5tTnI89KaDe9G5aISqXm4KJEe1DfNbFvA github.com/aws/aws-sdk-go v1.52.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.53.0 h1:MMo1x1ggPPxDfHMXJnQudTbGXYlD4UigUAud1DJxPVo= github.com/aws/aws-sdk-go v1.53.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.1 h1:15/i0m9rE8r1q3P4ooHCfZTJtkxwG2Dwqp9JhPaVbs0= +github.com/aws/aws-sdk-go v1.53.1/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo= From 806c06406a983c584f5e8bbd5bc7cfd7b79afddf Mon Sep 17 00:00:00 2001 From: Zachary Rice Date: Mon, 13 May 2024 16:53:08 -0500 Subject: [PATCH 33/51] Bump up performance test threshold to 50% (#2839) --- .github/workflows/performance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 76fef62882f5..78190d4483d2 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -85,7 +85,7 @@ jobs: run: | echo "head ($GITHUB_SHA) avg time (n=5): $HEAD_TIME" echo "$PREVIOUS_TAG avg time (n=5): $PREVIOUS_TIME" - if [ $(echo "$HEAD_TIME > $PREVIOUS_TIME * 1.1" | bc) -eq 1 ] + if [ $(echo "$HEAD_TIME > $PREVIOUS_TIME * 1.5" | bc) -eq 1 ] then echo "HEAD run time is at least 10% slower than PREVIOUS run time" exit 1 From a00587673a2189ecbfd33076d87ff0164cd41ed0 Mon Sep 17 00:00:00 2001 From: Richard Gomez <32133502+rgmz@users.noreply.github.com> Date: Mon, 13 May 2024 21:44:37 -0400 Subject: [PATCH 34/51] feat(sendgrid): update detector (#2833) --- pkg/detectors/sendgrid/sendgrid.go | 103 ++++++++++++++++++----------- 1 file changed, 65 insertions(+), 38 deletions(-) diff --git a/pkg/detectors/sendgrid/sendgrid.go b/pkg/detectors/sendgrid/sendgrid.go index e00cb2a2e748..936004a047e0 100644 --- a/pkg/detectors/sendgrid/sendgrid.go +++ b/pkg/detectors/sendgrid/sendgrid.go @@ -2,11 +2,14 @@ package sendgrid import ( "context" + "encoding/json" "fmt" - regexp "github.com/wasilibs/go-re2" + "io" "net/http" "strings" + regexp "github.com/wasilibs/go-re2" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" @@ -23,7 +26,7 @@ var _ detectors.Detector = (*Scanner)(nil) var ( defaultClient = common.SaneHttpClient() - keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"sendgrid"}) + `(SG\.[\w\-_]{20,24}\.[\w\-_]{39,50})\b`) + keyPat = regexp.MustCompile(`\bSG\.[\w\-]{20,24}\.[\w\-]{39,50}\b`) ) // Keywords are used for efficiently pre-filtering chunks. @@ -36,53 +39,27 @@ func (s Scanner) Keywords() []string { func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { dataStr := string(data) - matches := keyPat.FindAllStringSubmatch(dataStr, -1) - - for _, match := range matches { - if len(match) != 2 { - continue - } - resMatch := strings.TrimSpace(match[1]) + uniqueMatches := make(map[string]struct{}) + for _, match := range keyPat.FindAllStringSubmatch(dataStr, -1) { + uniqueMatches[match[0]] = struct{}{} + } + for token := range uniqueMatches { s1 := detectors.Result{ DetectorType: detectorspb.DetectorType_SendGrid, - Raw: []byte(resMatch), - } - s1.ExtraData = map[string]string{ - "rotation_guide": "https://howtorotate.com/docs/tutorials/sendgrid/", + Raw: []byte(token), } if verify { - // there are a few endpoints we can check, but templates seems the least sensitive. - // 403 will be issued if the scope is wrong but the key is correct - baseURL := "https://api.sendgrid.com/v3/templates" - client := s.client if client == nil { client = defaultClient } - // test `read_user` scope - req, err := http.NewRequestWithContext(ctx, "GET", baseURL, nil) - if err != nil { - continue - } - req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", resMatch)) - req.Header.Add("Content-Type", "application/json") - res, err := client.Do(req) - if err == nil { - res.Body.Close() // The request body is unused. - - // 200 means good key and has `templates` scope - // 403 means good key but not the right scope - // 401 is bad key - if res.StatusCode == http.StatusOK || res.StatusCode == http.StatusForbidden { - s1.Verified = true - } else if res.StatusCode != http.StatusUnauthorized { - err = fmt.Errorf("unexpected HTTP response status %d", res.StatusCode) - s1.SetVerificationError(err, resMatch) - } - } + verified, extraData, verificationErr := verifyToken(ctx, client, token) + s1.Verified = verified + s1.ExtraData = extraData + s1.SetVerificationError(verificationErr) } results = append(results, s1) @@ -91,6 +68,56 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result return } +func verifyToken(ctx context.Context, client *http.Client, token string) (bool, map[string]string, error) { + // Check the scopes assigned to the api key. + // https://docs.sendgrid.com/api-reference/api-key-permissions/retrieve-a-list-of-scopes-for-which-this-user-has-access + req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://api.sendgrid.com/v3/scopes", nil) + if err != nil { + return false, nil, err + } + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) + req.Header.Set("Content-Type", "application/json") + res, err := client.Do(req) + if err != nil { + return false, nil, err + } + defer func() { + _, _ = io.Copy(io.Discard, res.Body) + _ = res.Body.Close() + }() + + switch res.StatusCode { + case http.StatusOK: + extraData := map[string]string{ + "rotation_guide": "https://howtorotate.com/docs/tutorials/sendgrid/", + } + + var scopesRes scopesResponse + if err := json.NewDecoder(res.Body).Decode(&scopesRes); err != nil { + return false, nil, err + } + + if len(scopesRes.Scopes) > 0 { + extraData["scopes"] = strings.Join(scopesRes.Scopes, ",") + } + + return true, extraData, nil + case http.StatusUnauthorized: + // 401 means the key is definitively invalid. + return false, nil, nil + case http.StatusForbidden: + // 403 means good key but not the right scope + return true, nil, nil + default: + return false, nil, fmt.Errorf("unexpected HTTP response status %d", res.StatusCode) + } +} + +type scopesResponse struct { + Scopes []string `json:"scopes"` +} + func (s Scanner) Type() detectorspb.DetectorType { return detectorspb.DetectorType_SendGrid } From f1e419f8fe3421b02f8a8a4e1292c892a364944e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 18:45:01 -0700 Subject: [PATCH 35/51] fix(deps): update module cloud.google.com/go/storage to v1.41.0 (#2843) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 8 ++++---- go.sum | 8 ++++++++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/go.mod b/go.mod index 6ca45d16ff8f..aba026bd30f4 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ replace github.com/snowflakedb/gosnowflake => github.com/trufflesecurity/gosnowf require ( cloud.google.com/go/secretmanager v1.13.0 - cloud.google.com/go/storage v1.40.0 + cloud.google.com/go/storage v1.41.0 github.com/Azure/go-autorest/autorest/azure/auth v0.5.12 github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 github.com/BobuSumisu/aho-corasick v1.0.3 @@ -104,8 +104,8 @@ require ( cloud.google.com/go/auth v0.4.1 // indirect cloud.google.com/go/auth/oauth2adapt v0.2.2 // indirect cloud.google.com/go/compute/metadata v0.3.0 // indirect - cloud.google.com/go/iam v1.1.7 // indirect - cloud.google.com/go/longrunning v0.5.6 // indirect + cloud.google.com/go/iam v1.1.8 // indirect + cloud.google.com/go/longrunning v0.5.7 // indirect dario.cat/mergo v1.0.0 // indirect filippo.io/edwards25519 v1.1.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect @@ -282,7 +282,7 @@ require ( golang.org/x/tools v0.21.0 // indirect golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 // indirect google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 // indirect google.golang.org/grpc v1.63.2 // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect diff --git a/go.sum b/go.sum index 723120a61743..722b05d55681 100644 --- a/go.sum +++ b/go.sum @@ -22,8 +22,12 @@ cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1h cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= +cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= +cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXmjuEaE= cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= +cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU= +cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/secretmanager v1.13.0 h1:nQ/Ca2Gzm/OEP8tr1hiFdHRi5wAnAmsm9qTjwkivyrQ= @@ -32,6 +36,8 @@ cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiy cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.40.0 h1:VEpDQV5CJxFmJ6ueWNsKxcr1QAYOXEgxDa+sBbJahPw= cloud.google.com/go/storage v1.40.0/go.mod h1:Rrj7/hKlG87BLqDJYtwR0fbPld8uJPbQ2ucUMY7Ir0g= +cloud.google.com/go/storage v1.41.0 h1:RusiwatSu6lHeEXe3kglxakAmAbfV+rhtPqA6i8RBx0= +cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -1072,6 +1078,8 @@ google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWh google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 h1:DTJM0R8LECCgFeUwApvcEJHz85HLagW8uRENYxHh1ww= google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw= +google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae h1:AH34z6WAGVNkllnKs5raNq3yRq93VnjBG6rpfub/jYk= +google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae/go.mod h1:FfiGhwUm6CJviekPrc0oJ+7h29e+DmWU6UtjX0ZvI7Y= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= From f82cf8d76d7f54b12cc0a982f21926eae467923c Mon Sep 17 00:00:00 2001 From: ahrav Date: Tue, 14 May 2024 06:55:36 -0700 Subject: [PATCH 36/51] [bug] - Fix case-sensitivity issue in PrefixRegex function (#2811) * correctly remove case insensitivity for the capture group * update --- pkg/detectors/detectors.go | 7 +++--- pkg/detectors/detectors_test.go | 38 ++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/pkg/detectors/detectors.go b/pkg/detectors/detectors.go index c316af87d6f6..f71c61b51d9c 100644 --- a/pkg/detectors/detectors.go +++ b/pkg/detectors/detectors.go @@ -3,13 +3,12 @@ package detectors import ( "context" "crypto/rand" + "errors" "math/big" "net/url" "strings" "unicode" - "errors" - "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/source_metadatapb" "github.com/trufflesecurity/trufflehog/v3/pkg/pb/sourcespb" @@ -154,10 +153,10 @@ func CleanResults(results []Result) []Result { } // PrefixRegex ensures that at least one of the given keywords is within -// 20 characters of the capturing group that follows. +// 40 characters of the capturing group that follows. // This can help prevent false positives. func PrefixRegex(keywords []string) string { - pre := `(?i)(?:` + pre := `(?i:` middle := strings.Join(keywords, "|") post := `)(?:.|[\n\r]){0,40}?` return pre + middle + post diff --git a/pkg/detectors/detectors_test.go b/pkg/detectors/detectors_test.go index 0e4d8a9369f7..9c6a850e87d3 100644 --- a/pkg/detectors/detectors_test.go +++ b/pkg/detectors/detectors_test.go @@ -3,7 +3,11 @@ package detectors -import "testing" +import ( + "testing" + + regexp "github.com/wasilibs/go-re2" +) func TestPrefixRegex(t *testing.T) { tests := []struct { @@ -31,6 +35,38 @@ func TestPrefixRegex(t *testing.T) { } } +func TestPrefixRegexKeywords(t *testing.T) { + keywords := []string{"keyword1", "keyword2", "keyword3"} + + testCases := []struct { + input string + expected bool + }{ + {"keyword1 1234c4aabceeff4444442131444aab44", true}, + {"keyword1 1234567890ABCDEF1234567890ABBBCA", false}, + {"KEYWORD1 1234567890abcdef1234567890ababcd", true}, + {"KEYWORD1 1234567890ABCDEF1234567890ABdaba", false}, + {"keyword2 1234567890abcdef1234567890abeeff", true}, + {"keyword2 1234567890ABCDEF1234567890ABadbd", false}, + {"KEYWORD2 1234567890abcdef1234567890ababca", true}, + {"KEYWORD2 1234567890ABCDEF1234567890ABBBBs", false}, + {"keyword3 1234567890abcdef1234567890abccea", true}, + {"KEYWORD3 1234567890abcdef1234567890abaabb", true}, + {"keyword4 1234567890abcdef1234567890abzzzz", false}, + {"keyword3 1234567890ABCDEF1234567890AB", false}, + {"keyword4 1234567890ABCDEF1234567890AB", false}, + } + + keyPat := regexp.MustCompile(PrefixRegex(keywords) + `\b([0-9a-f]{32})\b`) + + for _, tc := range testCases { + match := keyPat.MatchString(tc.input) + if match != tc.expected { + t.Errorf("Input: %s, Expected: %v, Got: %v", tc.input, tc.expected, match) + } + } +} + func BenchmarkPrefixRegex(b *testing.B) { kws := []string{"securitytrails"} for i := 0; i < b.N; i++ { From 8d1fa4236008c1bea8bd9cd673e38bd39bbc5113 Mon Sep 17 00:00:00 2001 From: Zachary Rice Date: Tue, 14 May 2024 11:57:01 -0500 Subject: [PATCH 37/51] switch to filesystem and specific tag when performance testing (#2846) * switch to filesystem and specific tag when performance testing * good ol gha debugging * Update performance.yml --- .github/workflows/performance.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/performance.yml b/.github/workflows/performance.yml index 78190d4483d2..7ea9e283a80a 100644 --- a/.github/workflows/performance.yml +++ b/.github/workflows/performance.yml @@ -26,13 +26,15 @@ jobs: go build -o current . repo_tmp=$(mktemp -d) git clone https://github.com/trufflesecurity/trufflehog.git $repo_tmp + cd $repo_tmp + git checkout v3.75.1 user_time_sum=0 for i in {1..5} do tmpfile=$(mktemp) - /usr/bin/time -o $tmpfile $GITHUB_WORKSPACE/current git "file://$repo_tmp" --no-verification --no-update > out.txt + /usr/bin/time -o $tmpfile $GITHUB_WORKSPACE/current filesystem "$repo_tmp" --no-verification --no-update > out.txt cat $tmpfile time_output=$(cat $tmpfile) rm $tmpfile @@ -62,13 +64,15 @@ jobs: go build -o previous . repo_tmp=$(mktemp -d) git clone https://github.com/trufflesecurity/trufflehog.git $repo_tmp + cd $repo_tmp + git checkout v3.75.1 user_time_sum=0 for i in {1..5} do tmpfile=$(mktemp) - /usr/bin/time -o $tmpfile $GITHUB_WORKSPACE/previous git "file://$repo_tmp" --no-verification --no-update > out.txt + /usr/bin/time -o $tmpfile $GITHUB_WORKSPACE/previous filesystem "$repo_tmp" --no-verification --no-update > out.txt cat $tmpfile time_output=$(cat $tmpfile) rm $tmpfile From 4882d230e048af82589de06fe3eaedb28e2be577 Mon Sep 17 00:00:00 2001 From: Cody Rose Date: Tue, 14 May 2024 13:15:06 -0400 Subject: [PATCH 38/51] Use fake detectors in versioned detectors test (#2847) This automated test used to run with the real GitLab detectors because they were versioned. However, the test doesn't need real detectors to actually validate the functionality in question, and relying on real detectors means that we're susceptible to token expiration, which we recently discovered when it happened. The test has been updated to use fake detectors (which means it can run correctly in the community suite as well now.) --- pkg/engine/engine_test.go | 59 +++++++++++++++++++++++++++++---------- 1 file changed, 45 insertions(+), 14 deletions(-) diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 88d340c2b353..506e319a101a 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -1,6 +1,7 @@ package engine import ( + aCtx "context" "fmt" "net/http" "net/http/httptest" @@ -10,8 +11,8 @@ import ( "time" "github.com/stretchr/testify/assert" + "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" - "github.com/trufflesecurity/trufflehog/v3/pkg/common" "github.com/trufflesecurity/trufflehog/v3/pkg/config" "github.com/trufflesecurity/trufflehog/v3/pkg/context" "github.com/trufflesecurity/trufflehog/v3/pkg/custom_detectors" @@ -24,6 +25,44 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/sources" ) +const fakeDetectorKeyword = "fakedetector" + +type fakeDetectorV1 struct{} +type fakeDetectorV2 struct{} + +var _ detectors.Detector = (*fakeDetectorV1)(nil) +var _ detectors.Versioner = (*fakeDetectorV1)(nil) +var _ detectors.Detector = (*fakeDetectorV2)(nil) +var _ detectors.Versioner = (*fakeDetectorV2)(nil) + +func (f fakeDetectorV1) FromData(_ aCtx.Context, _ bool, _ []byte) ([]detectors.Result, error) { + return []detectors.Result{ + { + DetectorType: detectorspb.DetectorType(-1), + Verified: true, + Raw: []byte("fake secret v1"), + }, + }, nil +} + +func (f fakeDetectorV1) Keywords() []string { return []string{fakeDetectorKeyword} } +func (f fakeDetectorV1) Type() detectorspb.DetectorType { return detectorspb.DetectorType(-1) } +func (f fakeDetectorV1) Version() int { return 1 } + +func (f fakeDetectorV2) FromData(_ aCtx.Context, _ bool, _ []byte) ([]detectors.Result, error) { + return []detectors.Result{ + { + DetectorType: detectorspb.DetectorType(-1), + Verified: true, + Raw: []byte("fake secret v2"), + }, + }, nil +} + +func (f fakeDetectorV2) Keywords() []string { return []string{fakeDetectorKeyword} } +func (f fakeDetectorV2) Type() detectorspb.DetectorType { return detectorspb.DetectorType(-1) } +func (f fakeDetectorV2) Version() int { return 2 } + func TestFragmentLineOffset(t *testing.T) { tests := []struct { name string @@ -227,38 +266,30 @@ func TestEngine_DuplicateSecrets(t *testing.T) { func TestEngine_VersionedDetectorsVerifiedSecrets(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) defer cancel() - testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors4") - if err != nil { - t.Log("Failed to get secrets, likely running community-tests") - return - } - assert.NoError(t, err) - secretV2 := testSecrets.MustGetField("GITLABV2") - secretV1 := testSecrets.MustGetField("GITLAB") tmpFile, err := os.CreateTemp("", "testfile") assert.Nil(t, err) defer tmpFile.Close() defer os.Remove(tmpFile.Name()) - _, err = tmpFile.WriteString(fmt.Sprintf("You can find a gitlab secrets %s and another gitlab secret %s within", secretV2, secretV1)) - assert.Nil(t, err) + _, err = tmpFile.WriteString(fmt.Sprintf("test data using keyword %s", fakeDetectorKeyword)) + assert.NoError(t, err) e, err := Start(ctx, WithConcurrency(1), WithDecoders(decoders.DefaultDecoders()...), - WithDetectors(DefaultDetectors()...), + WithDetectors(&fakeDetectorV1{}, &fakeDetectorV2{}), WithVerify(true), WithPrinter(new(discardPrinter)), ) - assert.Nil(t, err) + assert.NoError(t, err) cfg := sources.FilesystemConfig{Paths: []string{tmpFile.Name()}} if err := e.ScanFileSystem(ctx, cfg); err != nil { return } - assert.Nil(t, e.Finish(ctx)) + assert.NoError(t, e.Finish(ctx)) want := uint64(2) assert.Equal(t, want, e.GetMetrics().VerifiedSecretsFound) } From 6df147de58902c4ae48cf234e8a61ec7d5db11d7 Mon Sep 17 00:00:00 2001 From: ahrav Date: Tue, 14 May 2024 11:30:11 -0700 Subject: [PATCH 39/51] [feat] - Support bearer auth for docker scans (#2848) * Support bearer auth for docker scans * updates * use no auth by default if no other auth method is provided --- main.go | 18 ++++++------------ pkg/engine/docker.go | 27 ++++++++++++++++++++++++--- pkg/sources/sources.go | 10 ++++++++++ 3 files changed, 40 insertions(+), 15 deletions(-) diff --git a/main.go b/main.go index a538e7bdc5ff..ab4d76494757 100644 --- a/main.go +++ b/main.go @@ -18,7 +18,6 @@ import ( "github.com/go-logr/logr" "github.com/jpillora/overseer" "github.com/mattn/go-isatty" - "google.golang.org/protobuf/types/known/anypb" "github.com/trufflesecurity/trufflehog/v3/pkg/cleantemp" "github.com/trufflesecurity/trufflehog/v3/pkg/common" @@ -30,7 +29,6 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/handlers" "github.com/trufflesecurity/trufflehog/v3/pkg/log" "github.com/trufflesecurity/trufflehog/v3/pkg/output" - "github.com/trufflesecurity/trufflehog/v3/pkg/pb/sourcespb" "github.com/trufflesecurity/trufflehog/v3/pkg/sources" "github.com/trufflesecurity/trufflehog/v3/pkg/tui" "github.com/trufflesecurity/trufflehog/v3/pkg/updater" @@ -150,6 +148,7 @@ var ( dockerScan = cli.Command("docker", "Scan Docker Image") dockerScanImages = dockerScan.Flag("image", "Docker image to scan. Use the file:// prefix to point to a local tarball, otherwise a image registry is assumed.").Required().Strings() + dockerScanToken = dockerScan.Flag("token", "Docker bearer token. Can also be provided with environment variable").Envar("DOCKER_TOKEN").String() travisCiScan = cli.Command("travisci", "Scan TravisCI") travisCiScanToken = travisCiScan.Flag("token", "TravisCI token. Can also be provided with environment variable").Envar("TRAVISCI_TOKEN").Required().String() @@ -589,17 +588,12 @@ func run(state overseer.State) { logFatal(err, "Failed to scan GCS.") } case dockerScan.FullCommand(): - dockerConn := sourcespb.Docker{ - Images: *dockerScanImages, - Credential: &sourcespb.Docker_DockerKeychain{ - DockerKeychain: true, - }, + cfg := sources.DockerConfig{ + BearerToken: *dockerScanToken, + Images: *dockerScanImages, + UseDockerKeychain: *dockerScanToken == "", } - anyConn, err := anypb.New(&dockerConn) - if err != nil { - logFatal(err, "Failed to marshal Docker connection") - } - if err := e.ScanDocker(ctx, anyConn); err != nil { + if err := e.ScanDocker(ctx, cfg); err != nil { logFatal(err, "Failed to scan Docker.") } case postmanScan.FullCommand(): diff --git a/pkg/engine/docker.go b/pkg/engine/docker.go index 38ffcc73ea34..49e8af3ca8a4 100644 --- a/pkg/engine/docker.go +++ b/pkg/engine/docker.go @@ -3,21 +3,42 @@ package engine import ( "runtime" + "google.golang.org/protobuf/proto" "google.golang.org/protobuf/types/known/anypb" "github.com/trufflesecurity/trufflehog/v3/pkg/context" + "github.com/trufflesecurity/trufflehog/v3/pkg/pb/sourcespb" + "github.com/trufflesecurity/trufflehog/v3/pkg/sources" "github.com/trufflesecurity/trufflehog/v3/pkg/sources/docker" ) // ScanDocker scans a given docker connection. -func (e *Engine) ScanDocker(ctx context.Context, conn *anypb.Any) error { +func (e *Engine) ScanDocker(ctx context.Context, c sources.DockerConfig) error { + connection := &sourcespb.Docker{Images: c.Images} + + switch { + case c.UseDockerKeychain: + connection.Credential = &sourcespb.Docker_DockerKeychain{DockerKeychain: true} + case len(c.BearerToken) > 0: + connection.Credential = &sourcespb.Docker_BearerToken{BearerToken: c.BearerToken} + default: + connection.Credential = &sourcespb.Docker_Unauthenticated{} + } + + var conn anypb.Any + err := anypb.MarshalFrom(&conn, connection, proto.MarshalOptions{}) + if err != nil { + ctx.Logger().Error(err, "failed to marshal gitlab connection") + return err + } + sourceName := "trufflehog - docker" sourceID, jobID, _ := e.sourceManager.GetIDs(ctx, sourceName, docker.SourceType) dockerSource := &docker.Source{} - if err := dockerSource.Init(ctx, sourceName, jobID, sourceID, true, conn, runtime.NumCPU()); err != nil { + if err := dockerSource.Init(ctx, sourceName, jobID, sourceID, true, &conn, runtime.NumCPU()); err != nil { return err } - _, err := e.sourceManager.Run(ctx, sourceName, dockerSource) + _, err = e.sourceManager.Run(ctx, sourceName, dockerSource) return err } diff --git a/pkg/sources/sources.go b/pkg/sources/sources.go index ffd8e0962943..be60d9a008a2 100644 --- a/pkg/sources/sources.go +++ b/pkg/sources/sources.go @@ -144,6 +144,16 @@ type SourceUnit interface { Display() string } +// DockerConfig defines the optional configuration for a Docker source. +type DockerConfig struct { + // Images is the list of images to scan. + Images []string + // BearerToken is the token to use to authenticate with the source. + BearerToken string + // UseDockerKeychain determines whether to use the Docker keychain. + UseDockerKeychain bool +} + // GCSConfig defines the optional configuration for a GCS source. type GCSConfig struct { // CloudCred determines whether to use cloud credentials. From 0d8c3335ed9321c2e198206f9279a31c8f2e3b67 Mon Sep 17 00:00:00 2001 From: Alexandre GUIOT--VALENTIN Date: Tue, 14 May 2024 20:33:54 +0200 Subject: [PATCH 40/51] Add "Intra42" detector (#2835) * Add basic intra42 detector (lacks verification) * Improve keywords/prefixes for intra42 detector * Un-lint pkg/pb/detectorspb/detectors.pb.go to avoid bloating PR * Add client_id match and secret verification * Improve PrefixRegex * Add missing entry in DetectorType_name in detectors.pb.go * Add Intra42 to proto/detectors.proto * Remove PrefixRegex * Keep only identifiers as keywords * Factorize regex (a-f0-9) --- pkg/detectors/intra42/intra42.go | 117 ++++++++++++++ pkg/detectors/intra42/intra42_test.go | 223 ++++++++++++++++++++++++++ pkg/engine/defaults.go | 2 + pkg/pb/detectorspb/detectors.pb.go | 3 + proto/detectors.proto | 1 + 5 files changed, 346 insertions(+) create mode 100644 pkg/detectors/intra42/intra42.go create mode 100644 pkg/detectors/intra42/intra42_test.go diff --git a/pkg/detectors/intra42/intra42.go b/pkg/detectors/intra42/intra42.go new file mode 100644 index 000000000000..6aa1a5a2514c --- /dev/null +++ b/pkg/detectors/intra42/intra42.go @@ -0,0 +1,117 @@ +package intra42 + +import ( + "context" + "fmt" + "net/http" + "net/url" + "strconv" + "strings" + + regexp "github.com/wasilibs/go-re2" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" + "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" +) + +type Scanner struct { + client *http.Client +} + +// Ensure the Scanner satisfies the interface at compile time +var _ detectors.Detector = (*Scanner)(nil) + +const verifyURL = "https://api.intra.42.fr/oauth/token" + +var ( + defaultClient = common.SaneHttpClient() + + // Make sure that your group is surrounded in boundary characters such as below to reduce false positives + keyPat = regexp.MustCompile(`\b(s-s4t2(?:ud|af)-[a-f0-9]{64})\b`) + idPat = regexp.MustCompile(`\b(u-s4t2(?:ud|af)-[a-f0-9]{64})\b`) +) + +// Keywords are used for efficiently pre-filtering chunks. +// Use identifiers in the secret preferably, or the provider name. +func (s Scanner) Keywords() []string { + return []string{"s-s4t2ud-", "s-s4t2af-"} +} + +// FromData will find and optionally verify Intra42 secrets in a given set of bytes. +func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { + dataStr := string(data) + + matches := keyPat.FindAllStringSubmatch(dataStr, -1) + idMatches := idPat.FindAllStringSubmatch(dataStr, -1) + + for _, match := range matches { + if len(match) != 2 { + continue + } + resMatch := strings.TrimSpace(match[1]) + + for _, idMatch := range idMatches { + if len(idMatch) != 2 { + continue + } + resIdMatch := strings.TrimSpace(idMatch[1]) + + s1 := detectors.Result{ + DetectorType: detectorspb.DetectorType_Intra42, + Raw: []byte(resMatch), + } + + if verify { + client := s.getClient() + isVerified, verificationErr := verifyIntra42(ctx, client, resMatch, resIdMatch) + s1.Verified = isVerified + s1.SetVerificationError(verificationErr, resMatch) + } + + results = append(results, s1) + } + } + return results, nil +} + +func (s Scanner) getClient() *http.Client { + if s.client != nil { + return s.client + } + return defaultClient +} + +func verifyIntra42(ctx context.Context, client *http.Client, resMatch string, resIdMatch string) (bool, error) { + data := url.Values{} + data.Set("client_id", resIdMatch) + data.Set("client_secret", resMatch) + data.Set("grant_type", "client_credentials") + encodedData := data.Encode() + + req, err := http.NewRequestWithContext(ctx, http.MethodPost, verifyURL, strings.NewReader(encodedData)) + if err != nil { + return false, err + } + + req.Header.Add("Content-Type", "application/x-www-form-urlencoded") + req.Header.Add("Content-Length", strconv.Itoa(len(data.Encode()))) + res, err := client.Do(req) + if err != nil { + return false, err + } + defer res.Body.Close() + + switch res.StatusCode { + case http.StatusOK: + return true, nil + case http.StatusUnauthorized: + return false, nil + default: + return false, fmt.Errorf("unexpected http response status %d", res.StatusCode) + } +} + +func (s Scanner) Type() detectorspb.DetectorType { + return detectorspb.DetectorType_Intra42 +} diff --git a/pkg/detectors/intra42/intra42_test.go b/pkg/detectors/intra42/intra42_test.go new file mode 100644 index 000000000000..b89950ee5755 --- /dev/null +++ b/pkg/detectors/intra42/intra42_test.go @@ -0,0 +1,223 @@ +//go:build detectors +// +build detectors + +package intra42 + +import ( + "context" + "fmt" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/trufflesecurity/trufflehog/v3/pkg/common" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" + "github.com/trufflesecurity/trufflehog/v3/pkg/engine/ahocorasick" + "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" +) + +func TestIntra42_Pattern(t *testing.T) { + d := Scanner{} + ahoCorasickCore := ahocorasick.NewAhoCorasickCore([]detectors.Detector{d}) + tests := []struct { + name string + input string + want []string + }{ + { + name: "typical pattern", + input: ` +intra_client_id = 'u-s4t2ud-d91c558a2ba6b47f60f690efc20a33d28c252d5bed8400343246f3eb68f490d2' +intra_client_secret = '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' +`, + want: []string{ + "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", + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + chunkSpecificDetectors := make(map[ahocorasick.DetectorKey]detectors.Detector, 2) + ahoCorasickCore.PopulateMatchingDetectors(test.input, chunkSpecificDetectors) + if len(chunkSpecificDetectors) == 0 { + t.Errorf("keywords '%v' not matched by: %s", d.Keywords(), test.input) + return + } + + results, err := d.FromData(context.Background(), false, []byte(test.input)) + if err != nil { + t.Errorf("error = %v", err) + return + } + + if len(results) != len(test.want) { + if len(results) == 0 { + t.Errorf("did not receive result") + } else { + t.Errorf("expected %d results, only received %d", len(test.want), len(results)) + } + return + } + + actual := make(map[string]struct{}, len(results)) + for _, r := range results { + if len(r.RawV2) > 0 { + actual[string(r.RawV2)] = struct{}{} + } else { + actual[string(r.Raw)] = struct{}{} + } + } + expected := make(map[string]struct{}, len(test.want)) + for _, v := range test.want { + expected[v] = struct{}{} + } + + if diff := cmp.Diff(expected, actual); diff != "" { + t.Errorf("%s diff: (-want +got)\n%s", test.name, diff) + } + }) + } +} + +func TestIntra42_FromChunk(t *testing.T) { + ctx, cancel := context.WithTimeout(context.Background(), time.Second*10) + defer cancel() + testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors5") + if err != nil { + t.Fatalf("could not get test secrets from GCP: %s", err) + } + secret := testSecrets.MustGetField("INTRA42_SECRET") + id := testSecrets.MustGetField("INTRA42_ID") + inactiveSecret := testSecrets.MustGetField("INTRA42_INACTIVE") + + type args struct { + ctx context.Context + data []byte + verify bool + } + tests := []struct { + name string + s Scanner + args args + want []detectors.Result + wantErr bool + wantVerificationErr bool + }{ + { + name: "found, verified", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find an intra42 secret %s within intra42 %s", secret, id)), + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_Intra42, + Verified: true, + }, + }, + wantErr: false, + }, + { + name: "found, would be verified if not for timeout", + s: Scanner{client: common.SaneHttpClientTimeOut(1 * time.Microsecond)}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find an intra42 secret %s within intra42 %s", secret, id)), + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_Intra42, + Verified: false, + }, + }, + wantErr: false, + wantVerificationErr: true, + }, + { + name: "found, verified but unexpected api surface", + s: Scanner{client: common.ConstantResponseHttpClient(404, "")}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find an intra42 secret %s within intra42 %s", secret, id)), + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_Intra42, + Verified: false, + }, + }, + wantErr: false, + wantVerificationErr: true, + }, + { + name: "found, unverified", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte(fmt.Sprintf("You can find an intra42 secret %s within intra42 %s but not valid", inactiveSecret, id)), // the secret would satisfy the regex but not pass validation + verify: true, + }, + want: []detectors.Result{ + { + DetectorType: detectorspb.DetectorType_Intra42, + Verified: false, + }, + }, + wantErr: false, + }, + { + name: "not found", + s: Scanner{}, + args: args{ + ctx: context.Background(), + data: []byte("You cannot find the secret within"), + verify: true, + }, + want: nil, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := tt.s.FromData(tt.args.ctx, tt.args.verify, tt.args.data) + if (err != nil) != tt.wantErr { + t.Errorf("Intra42.FromData() error = %v, wantErr %v", err, tt.wantErr) + return + } + for i := range got { + if len(got[i].Raw) == 0 { + t.Fatalf("no raw secret present: \n %+v", got[i]) + } + if (got[i].VerificationError() != nil) != tt.wantVerificationErr { + t.Errorf("Intra42.FromData() verificationError = %v, wantVerificationErr %v", got[i].VerificationError(), tt.wantVerificationErr) + } + } + ignoreOpts := cmpopts.IgnoreFields(detectors.Result{}, "Raw", "verificationError") + if diff := cmp.Diff(got, tt.want, ignoreOpts); diff != "" { + t.Errorf("Intra42.FromData() %s diff: (-got +want)\n%s", tt.name, diff) + } + }) + } +} + +func BenchmarkFromData(benchmark *testing.B) { + ctx := context.Background() + s := Scanner{} + for name, data := range detectors.MustGetBenchmarkData() { + benchmark.Run(name, func(b *testing.B) { + b.ResetTimer() + for n := 0; n < b.N; n++ { + _, err := s.FromData(ctx, false, data) + if err != nil { + b.Fatal(err) + } + } + }) + } +} diff --git a/pkg/engine/defaults.go b/pkg/engine/defaults.go index c7d40b9a32d9..76bff8c3437c 100644 --- a/pkg/engine/defaults.go +++ b/pkg/engine/defaults.go @@ -347,6 +347,7 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/integromat" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/intercom" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/interseller" + "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/intra42" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/intrinio" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/invoiceocean" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/ip2location" @@ -1604,6 +1605,7 @@ func DefaultDetectors() []detectors.Detector { gcpapplicationdefaultcredentials.Scanner{}, wiz.Scanner{}, onfleet.Scanner{}, + intra42.Scanner{}, } } diff --git a/pkg/pb/detectorspb/detectors.pb.go b/pkg/pb/detectorspb/detectors.pb.go index 9a82a94a8ef0..e4b6d65406a6 100644 --- a/pkg/pb/detectorspb/detectors.pb.go +++ b/pkg/pb/detectorspb/detectors.pb.go @@ -1085,6 +1085,7 @@ const ( DetectorType_Wiz DetectorType = 984 DetectorType_Pagarme DetectorType = 985 DetectorType_Onfleet DetectorType = 986 + DetectorType_Intra42 DetectorType = 987 ) // Enum value maps for DetectorType. @@ -2073,6 +2074,7 @@ var ( 984: "Wiz", 985: "Pagarme", 986: "Onfleet", + 987: "Intra42", } DetectorType_value = map[string]int32{ "Alibaba": 0, @@ -3058,6 +3060,7 @@ var ( "Wiz": 984, "Pagarme": 985, "Onfleet": 986, + "Intra42": 987, } ) diff --git a/proto/detectors.proto b/proto/detectors.proto index fd0e4325214d..464643beb869 100644 --- a/proto/detectors.proto +++ b/proto/detectors.proto @@ -996,6 +996,7 @@ enum DetectorType { Wiz = 984; Pagarme = 985; Onfleet = 986; + Intra42 = 987; } message Result { From ead4e8fa2d577853926f800548781665d9faaf67 Mon Sep 17 00:00:00 2001 From: cuiyourong <166382782+cuiyourong@users.noreply.github.com> Date: Wed, 15 May 2024 22:36:21 +0800 Subject: [PATCH 41/51] chore: fix some typos in comments (#2851) Signed-off-by: cuiyourong --- pkg/detectors/falsepositives.go | 2 +- pkg/detectors/twilio/twilio.go | 2 +- pkg/handlers/default.go | 2 +- pkg/sources/s3/s3.go | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pkg/detectors/falsepositives.go b/pkg/detectors/falsepositives.go index 1b3594a6dbeb..9a5eb28a250d 100644 --- a/pkg/detectors/falsepositives.go +++ b/pkg/detectors/falsepositives.go @@ -57,7 +57,7 @@ func GetFalsePositiveCheck(detector Detector) func(Result) bool { } // IsKnownFalsePositive will not return a valid secret finding if any of the disqualifying conditions are met -// Currently that includes: No number, english word in key, or matches common example pattens. +// Currently that includes: No number, english word in key, or matches common example patterns. // Only the secret key material should be passed into this function func IsKnownFalsePositive(match string, falsePositives []FalsePositive, wordCheck bool) bool { if !utf8.ValidString(match) { diff --git a/pkg/detectors/twilio/twilio.go b/pkg/detectors/twilio/twilio.go index fa32247010a5..927a106da5e0 100644 --- a/pkg/detectors/twilio/twilio.go +++ b/pkg/detectors/twilio/twilio.go @@ -90,7 +90,7 @@ func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (result if res.StatusCode >= 200 && res.StatusCode < 300 { s1.Verified = true var serviceResponse serviceResponse - if err := json.NewDecoder(res.Body).Decode(&serviceResponse); err == nil && len(serviceResponse.Services) > 0 { // no error in parsing and have atleast one service + if err := json.NewDecoder(res.Body).Decode(&serviceResponse); err == nil && len(serviceResponse.Services) > 0 { // no error in parsing and have at least one service service := serviceResponse.Services[0] s1.ExtraData["friendly_name"] = service.FriendlyName s1.ExtraData["account_sid"] = service.AccountSID diff --git a/pkg/handlers/default.go b/pkg/handlers/default.go index 6b73fe03671a..a587d0696a94 100644 --- a/pkg/handlers/default.go +++ b/pkg/handlers/default.go @@ -157,7 +157,7 @@ func (h *defaultHandler) openArchive(ctx logContext.Context, depth int, reader i switch archive := format.(type) { case archiver.Decompressor: - // Decompress tha archive and feed the decompressed data back into the archive handler to extract any nested archives. + // Decompress the archive and feed the decompressed data back into the archive handler to extract any nested archives. compReader, err := archive.OpenReader(arReader) if err != nil { return fmt.Errorf("error opening decompressor with format %q: %w", format.Name(), err) diff --git a/pkg/sources/s3/s3.go b/pkg/sources/s3/s3.go index 8f90c2df5dda..ebd39a1028d4 100644 --- a/pkg/sources/s3/s3.go +++ b/pkg/sources/s3/s3.go @@ -349,7 +349,7 @@ func (s *Source) pageChunker(ctx context.Context, client *s3.S3, chunksChan chan } nErr = nErr.(int) + 1 errorCount.Store(prefix, nErr) - // too many consective errors on this page + // too many consecutive errors on this page if nErr.(int) > 3 { s.log.V(2).Info("Too many consecutive errors, excluding prefix", "prefix", prefix) } From 7025b0aa35153a55977898282cb4d4c6379a3164 Mon Sep 17 00:00:00 2001 From: Abdul Basit Date: Wed, 15 May 2024 22:36:22 +0500 Subject: [PATCH 42/51] added email and location in metadata. (#2850) --- pkg/detectors/github/v1/github_old.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/detectors/github/v1/github_old.go b/pkg/detectors/github/v1/github_old.go index 3ade673cf4f2..3340311870aa 100644 --- a/pkg/detectors/github/v1/github_old.go +++ b/pkg/detectors/github/v1/github_old.go @@ -40,6 +40,8 @@ type UserRes struct { Name string `json:"name"` Company string `json:"company"` UserURL string `json:"html_url"` + Email string `json:"email"` + Location string `json:"location"` // Included in GitHub Enterprise Server. LdapDN string `json:"ldap_dn"` } @@ -157,6 +159,14 @@ func SetUserResponse(userResponse *UserRes, s1 *detectors.Result) { if userResponse.LdapDN != "" { s1.ExtraData["ldap_dn"] = userResponse.LdapDN } + + // email & location if user has made them public + if userResponse.Email != "" { + s1.ExtraData["email"] = userResponse.Email + } + if userResponse.Location != "" { + s1.ExtraData["location"] = userResponse.Location + } } func SetHeaderInfo(headers *HeaderInfo, s1 *detectors.Result) { From ead9dd57486f43830ba2279f3a3c49d4b9c36633 Mon Sep 17 00:00:00 2001 From: ahrav Date: Wed, 15 May 2024 13:40:16 -0700 Subject: [PATCH 43/51] [refactor] - Create separate handler for non-archive data (#2825) * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * Handle non-archive data within the DefaultHandler * make structs and methods private * Remove non-archive data handling within sources * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Handle non-archive data within the DefaultHandler * rebase * Remove non-archive data handling within sources * Adjust check for rpm/deb archive type * add additional deb mime type * add gzip * move diskbuffered rereader setup into handler pkg * remove DiskBuffereReader creation logic within sources * update comment * move rewind closer * reduce log verbosity * add metrics for file handling * add metrics for errors * make defaultBufferSize a const * add metrics for file handling * add metrics for errors * fix tests * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * Address incompatible reader to openArchive * remove nil check * fix err assignment * Allow git cat-file blob to complete before trying to handle the file * wrap compReader with DiskbufferReader * Allow git cat-file blob to complete before trying to handle the file * updates * use buffer writer * update * refactor * update context pkg * revert stuff * update test * fix test * remove * use correct reader * add metrics for file handling * add metrics for errors * fix tests * rebase * add metrics for errors * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * fix err assignment * rebase * remove * Update write method in contentWriter interface * Add bufferReadSeekCloser * update name * update comment * fix lint * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Handle non-archive data within the DefaultHandler * rebase * Remove non-archive data handling within sources * Handle non-archive data within the DefaultHandler * add gzip * move diskbuffered rereader setup into handler pkg * remove DiskBuffereReader creation logic within sources * update comment * move rewind closer * reduce log verbosity * make defaultBufferSize a const * add metrics for file handling * add metrics for errors * fix tests * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * Address incompatible reader to openArchive * remove nil check * fix err assignment * wrap compReader with DiskbufferReader * Allow git cat-file blob to complete before trying to handle the file * updates * use buffer writer * update * refactor * update context pkg * revert stuff * update test * remove * rebase * go mod tidy * lint check * update metric to ms * update metric * update comments * dont use ptr * update * fix * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Adjust check for rpm/deb archive type * add additional deb mime type * update comment * go mod tidy * update go mod * Add a buffered file reader * update comments * use Buffered File Readder * return buffer * update * fix * return * go mod tidy * merge * use a shared pool * use sync.Once * reorganzie * remove unused code * fix double init * fix stuff * nil check * reduce allocations * updates * update metrics * updates * reset buffer instead of putting it back * skip binaries * skip * concurrently process diffs * close chan * concurrently enumerate orgs * increase workers * ignore pbix and vsdx files * add metrics for gitparse's Diffchan * fix metric * update metrics * update * fix checks * fix * inc * update * reduce * Create workers to handle binary files * modify workers * updates * add check * delete code * use custom reader * rename struct * add nonarchive handler * fix break * add comments * add tests * refactor * remove log * do not scan rpm links * simplify * rename var * rename * fix benchmark * add buffer * buffer * buffer * handle panic * merge main * merge main * add recover * revert stuff * revert * revert to using reader * fixes * remove * update * fixes * linter * fix test * fix comment * update field name * fix --- pkg/handlers/ar.go | 23 +- pkg/handlers/ar_test.go | 6 +- pkg/handlers/archive.go | 192 +++++++++++++++ pkg/handlers/archive_test.go | 128 ++++++++++ pkg/handlers/default.go | 199 ++-------------- pkg/handlers/default_test.go | 128 ++-------- pkg/handlers/handlers.go | 220 +++++++++--------- pkg/handlers/handlers_test.go | 49 ++-- pkg/handlers/rpm.go | 25 +- pkg/handlers/rpm_test.go | 8 +- pkg/handlers/testdata/nonarchive.txt | 68 ++++++ pkg/readers/bufferedfilereader.go | 38 ++- pkg/sources/filesystem/filesystem.go | 1 - pkg/sources/gcs/gcs.go | 2 +- pkg/sources/git/git.go | 17 +- pkg/sources/s3/s3.go | 1 - .../bufferedfilewriter.go | 4 + 17 files changed, 644 insertions(+), 465 deletions(-) create mode 100644 pkg/handlers/archive.go create mode 100644 pkg/handlers/archive_test.go create mode 100644 pkg/handlers/testdata/nonarchive.txt diff --git a/pkg/handlers/ar.go b/pkg/handlers/ar.go index 70ad4e785956..0c758ad258e5 100644 --- a/pkg/handlers/ar.go +++ b/pkg/handlers/ar.go @@ -11,8 +11,7 @@ import ( logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" ) -// arHandler specializes defaultHandler to handle AR archive formats. By embedding defaultHandler, -// arHandler inherits and can further customize the common handling behavior such as skipping binaries. +// arHandler handles AR archive formats. type arHandler struct{ *defaultHandler } // newARHandler creates an arHandler. @@ -22,7 +21,7 @@ func newARHandler() *arHandler { // HandleFile processes AR formatted files. This function needs to be implemented to extract or // manage data from AR files according to specific requirements. -func (h *arHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (chan []byte, error) { +func (h *arHandler) HandleFile(ctx logContext.Context, input fileReader) (chan []byte, error) { archiveChan := make(chan []byte, defaultBufferSize) go func() { @@ -33,7 +32,23 @@ func (h *arHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (ch // Update the metrics for the file processing. start := time.Now() var err error - defer h.measureLatencyAndHandleErrors(start, err) + defer func() { + h.measureLatencyAndHandleErrors(start, err) + h.metrics.incFilesProcessed() + }() + + // Defer a panic recovery to handle any panics that occur during the AR processing. + defer func() { + if r := recover(); r != nil { + // Return the panic as an error. + if e, ok := r.(error); ok { + err = e + } else { + err = fmt.Errorf("panic occurred: %v", r) + } + ctx.Logger().Error(err, "Panic occurred when reading ar archive") + } + }() var arReader *deb.Ar arReader, err = deb.LoadAr(input) diff --git a/pkg/handlers/ar_test.go b/pkg/handlers/ar_test.go index c3d250616b7b..59285ca47efd 100644 --- a/pkg/handlers/ar_test.go +++ b/pkg/handlers/ar_test.go @@ -18,8 +18,12 @@ func TestHandleARFile(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() + rdr, err := newFileReader(file) + assert.NoError(t, err) + defer rdr.Close() + handler := newARHandler() - archiveChan, err := handler.HandleFile(context.AddLogger(ctx), file) + archiveChan, err := handler.HandleFile(context.AddLogger(ctx), rdr) assert.NoError(t, err) wantChunkCount := 102 diff --git a/pkg/handlers/archive.go b/pkg/handlers/archive.go new file mode 100644 index 000000000000..e0e6313b1f06 --- /dev/null +++ b/pkg/handlers/archive.go @@ -0,0 +1,192 @@ +package handlers + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/mholt/archiver/v4" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" + logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" +) + +type ctxKey int + +const ( + depthKey ctxKey = iota + defaultBufferSize = 512 +) + +var ( + maxDepth = 5 + maxSize = 250 * 1024 * 1024 // 250 MB + maxTimeout = time.Duration(30) * time.Second +) + +// SetArchiveMaxSize sets the maximum size of the archive. +func SetArchiveMaxSize(size int) { maxSize = size } + +// SetArchiveMaxDepth sets the maximum depth of the archive. +func SetArchiveMaxDepth(depth int) { maxDepth = depth } + +// SetArchiveMaxTimeout sets the maximum timeout for the archive handler. +func SetArchiveMaxTimeout(timeout time.Duration) { maxTimeout = timeout } + +// archiveHandler is a handler for common archive files that are supported by the archiver library. +type archiveHandler struct{ *defaultHandler } + +func newArchiveHandler() *archiveHandler { + return &archiveHandler{defaultHandler: newDefaultHandler(archiveHandlerType)} +} + +// HandleFile processes the input as either an archive or non-archive based on its content, +// utilizing a single output channel. It first tries to identify the input as an archive. If it is an archive, +// it processes it accordingly; otherwise, it handles the input as non-archive content. +// The function returns a channel that will receive the extracted data bytes and an error if the initial setup fails. +func (h *archiveHandler) HandleFile(ctx logContext.Context, input fileReader) (chan []byte, error) { + dataChan := make(chan []byte, defaultBufferSize) + + go func() { + ctx, cancel := logContext.WithTimeout(ctx, maxTimeout) + defer cancel() + defer close(dataChan) + + // Update the metrics for the file processing. + start := time.Now() + var err error + defer func() { + h.measureLatencyAndHandleErrors(start, err) + h.metrics.incFilesProcessed() + }() + + if err = h.openArchive(ctx, 0, input, dataChan); err != nil { + ctx.Logger().Error(err, "error unarchiving chunk.") + } + }() + + return dataChan, nil +} + +var ErrMaxDepthReached = errors.New("max archive depth reached") + +// openArchive recursively extracts content from an archive up to a maximum depth, handling nested archives if necessary. +// It takes a reader from which it attempts to identify and process the archive format. Depending on the archive type, +// it either decompresses or extracts the contents directly, sending data to the provided channel. +// Returns an error if the archive cannot be processed due to issues like exceeding maximum depth or unsupported formats. +func (h *archiveHandler) openArchive(ctx logContext.Context, depth int, reader fileReader, archiveChan chan []byte) error { + if common.IsDone(ctx) { + return ctx.Err() + } + + if depth >= maxDepth { + h.metrics.incMaxArchiveDepthCount() + return ErrMaxDepthReached + } + + arReader := reader.BufferedFileReader + if reader.format == nil && depth > 0 { + return h.handleNonArchiveContent(ctx, arReader, archiveChan) + } + + switch archive := reader.format.(type) { + case archiver.Decompressor: + // Decompress tha archive and feed the decompressed data back into the archive handler to extract any nested archives. + compReader, err := archive.OpenReader(arReader) + if err != nil { + return fmt.Errorf("error opening decompressor with format: %s %w", reader.format.Name(), err) + } + defer compReader.Close() + + rdr, err := newFileReader(compReader) + if err != nil { + return fmt.Errorf("error creating custom reader: %w", err) + } + defer rdr.Close() + + return h.openArchive(ctx, depth+1, rdr, archiveChan) + case archiver.Extractor: + err := archive.Extract(logContext.WithValue(ctx, depthKey, depth+1), arReader, nil, h.extractorHandler(archiveChan)) + if err != nil { + return fmt.Errorf("error extracting archive with format: %s: %w", reader.format.Name(), err) + } + return nil + default: + return fmt.Errorf("unknown archive type: %s", reader.mimeType) + } +} + +// extractorHandler creates a closure that handles individual files extracted by an archiver. +// It logs the extraction, checks for cancellation, and decides whether to skip the file based on its name or type, +// particularly for binary files if configured to skip. If the file is not skipped, it recursively calls openArchive +// to handle nested archives or to continue processing based on the file's content and depth in the archive structure. +func (h *archiveHandler) extractorHandler(archiveChan chan []byte) func(context.Context, archiver.File) error { + return func(ctx context.Context, file archiver.File) error { + lCtx := logContext.WithValues( + logContext.AddLogger(ctx), + "filename", file.Name(), + "size", file.Size(), + ) + lCtx.Logger().V(5).Info("Handling extracted file.") + + if file.IsDir() || file.LinkTarget != "" { + lCtx.Logger().V(5).Info("skipping directory or symlink") + return nil + } + + if common.IsDone(ctx) { + return ctx.Err() + } + + depth := 0 + if ctxDepth, ok := ctx.Value(depthKey).(int); ok { + depth = ctxDepth + } + + fileSize := file.Size() + if int(fileSize) > maxSize { + lCtx.Logger().V(3).Info("skipping file due to size") + return nil + } + + if common.SkipFile(file.Name()) || common.IsBinary(file.Name()) { + lCtx.Logger().V(5).Info("skipping file") + h.metrics.incFilesSkipped() + return nil + } + + f, err := file.Open() + if err != nil { + return fmt.Errorf("error opening file %s: %w", file.Name(), err) + } + defer f.Close() + + // Archiver v4 is in alpha and using an experimental version of + // rardecode. There is a bug somewhere with rar decoder format 29 + // that can lead to a panic. An issue is open in rardecode repo + // https://github.com/nwaples/rardecode/issues/30. + defer func() { + if r := recover(); r != nil { + // Return the panic as an error. + if e, ok := r.(error); ok { + err = e + } else { + err = fmt.Errorf("panic occurred: %v", r) + } + lCtx.Logger().Error(err, "Panic occurred when reading archive") + } + }() + + rdr, err := newFileReader(f) + if err != nil { + return fmt.Errorf("error creating custom reader: %w", err) + } + defer rdr.Close() + + h.metrics.incFilesProcessed() + h.metrics.observeFileSize(fileSize) + + return h.openArchive(lCtx, depth, rdr, archiveChan) + } +} diff --git a/pkg/handlers/archive_test.go b/pkg/handlers/archive_test.go new file mode 100644 index 000000000000..1217fd01720d --- /dev/null +++ b/pkg/handlers/archive_test.go @@ -0,0 +1,128 @@ +package handlers + +import ( + "context" + "io" + "net/http" + "regexp" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + + logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" +) + +func TestArchiveHandler(t *testing.T) { + tests := map[string]struct { + archiveURL string + expectedChunks int + matchString string + expectErr bool + }{ + "gzip-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one-zip.gz", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "gzip-nested": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/double-zip.gz", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "gzip-too-deep": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six-zip.gz", + 0, + "", + true, + }, + "tar-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one.tar", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "tar-nested": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/two.tar", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "tar-too-deep": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six.tar", + 0, + "", + true, + }, + "targz-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/tar-archive.tar.gz", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "gzip-large": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/FifteenMB.gz", + 1543, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + "zip-single": { + "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/aws-canary-creds.zip", + 1, + "AKIAYVP4CIPPH5TNP3SW", + false, + }, + } + + for name, testCase := range tests { + t.Run(name, func(t *testing.T) { + resp, err := http.Get(testCase.archiveURL) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + defer resp.Body.Close() + + handler := newArchiveHandler() + + newReader, err := newFileReader(resp.Body) + if err != nil { + t.Errorf("error creating reusable reader: %s", err) + } + archiveChan, err := handler.HandleFile(logContext.Background(), newReader) + if testCase.expectErr { + assert.NoError(t, err) + return + } + + count := 0 + re := regexp.MustCompile(testCase.matchString) + matched := false + for chunk := range archiveChan { + count++ + if re.Match(chunk) { + matched = true + } + } + + assert.True(t, matched) + assert.Equal(t, testCase.expectedChunks, count) + }) + } +} + +func TestOpenInvalidArchive(t *testing.T) { + reader := strings.NewReader("invalid archive") + + ctx := logContext.AddLogger(context.Background()) + handler := archiveHandler{} + + rdr, err := newFileReader(io.NopCloser(reader)) + assert.NoError(t, err) + defer rdr.Close() + + archiveChan := make(chan []byte) + + err = handler.openArchive(ctx, 0, rdr, archiveChan) + assert.Error(t, err) +} diff --git a/pkg/handlers/default.go b/pkg/handlers/default.go index a587d0696a94..f4d617e2a68b 100644 --- a/pkg/handlers/default.go +++ b/pkg/handlers/default.go @@ -9,46 +9,23 @@ import ( "time" "github.com/gabriel-vasile/mimetype" - "github.com/mholt/archiver/v4" "github.com/trufflesecurity/trufflehog/v3/pkg/common" logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" - "github.com/trufflesecurity/trufflehog/v3/pkg/readers" "github.com/trufflesecurity/trufflehog/v3/pkg/sources" ) -type ctxKey int - -const ( - depthKey ctxKey = iota - defaultBufferSize = 512 -) - -var ( - maxDepth = 5 - maxSize = 250 * 1024 * 1024 // 250 MB - maxTimeout = time.Duration(30) * time.Second -) - -// SetArchiveMaxSize sets the maximum size of the archive. -func SetArchiveMaxSize(size int) { maxSize = size } - -// SetArchiveMaxDepth sets the maximum depth of the archive. -func SetArchiveMaxDepth(depth int) { maxDepth = depth } - -// SetArchiveMaxTimeout sets the maximum timeout for the archive handler. -func SetArchiveMaxTimeout(timeout time.Duration) { maxTimeout = timeout } - -// defaultHandler provides a base implementation for file handlers, encapsulating common behaviors -// needed across different handlers. This handler is embedded in other specialized handlers to ensure -// consistent application of these common behaviors and to simplify the extension of handler functionalities. +// defaultHandler is a handler for non-archive files. +// It is embedded in other specialized handlers to provide a consistent way of handling non-archive content +// once it has been extracted or decompressed by the specific handler. +// This allows the specialized handlers to focus on their specific archive formats while leveraging +// the common functionality provided by the defaultHandler for processing the extracted content. type defaultHandler struct{ metrics *metrics } // newDefaultHandler creates a defaultHandler with metrics configured based on the provided handlerType. // The handlerType parameter is used to initialize the metrics instance with the appropriate handler type, // ensuring that the metrics recorded within the defaultHandler methods are correctly attributed to the -// specific handler that invoked them. This allows for accurate metrics attribution when the defaultHandler -// is embedded in specialized handlers like arHandler or rpmHandler. +// specific handler that invoked them. func newDefaultHandler(handlerType handlerType) *defaultHandler { return &defaultHandler{metrics: newHandlerMetrics(handlerType)} } @@ -57,52 +34,26 @@ func newDefaultHandler(handlerType handlerType) *defaultHandler { // utilizing a single output channel. It first tries to identify the input as an archive. If it is an archive, // it processes it accordingly; otherwise, it handles the input as non-archive content. // The function returns a channel that will receive the extracted data bytes and an error if the initial setup fails. -func (h *defaultHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (chan []byte, error) { +func (h *defaultHandler) HandleFile(ctx logContext.Context, input fileReader) (chan []byte, error) { // Shared channel for both archive and non-archive content. dataChan := make(chan []byte, defaultBufferSize) - _, arReader, err := archiver.Identify("", input) - if err != nil { - if errors.Is(err, archiver.ErrNoMatch) { - // Not an archive, handle as non-archive content in a separate goroutine. - ctx.Logger().V(3).Info("File not recognized as an archive, handling as non-archive content.") - go func() { - defer close(dataChan) - - // Update the metrics for the file processing. - start := time.Now() - var err error - defer func() { - h.measureLatencyAndHandleErrors(start, err) - h.metrics.incFilesProcessed() - }() - - if err = h.handleNonArchiveContent(ctx, arReader, dataChan); err != nil { - ctx.Logger().Error(err, "error handling non-archive content.") - } - }() - - return dataChan, nil - } - - h.metrics.incErrors() - return nil, err - } - go func() { - ctx, cancel := logContext.WithTimeout(ctx, maxTimeout) - defer cancel() defer close(dataChan) // Update the metrics for the file processing. start := time.Now() var err error - defer h.measureLatencyAndHandleErrors(start, err) + defer func() { + h.measureLatencyAndHandleErrors(start, err) + h.metrics.incFilesProcessed() + }() - if err = h.openArchive(ctx, 0, arReader, dataChan); err != nil { - ctx.Logger().Error(err, "error unarchiving chunk.") + if err = h.handleNonArchiveContent(ctx, input, dataChan); err != nil { + ctx.Logger().Error(err, "error handling non-archive content.") } }() + return dataChan, nil } @@ -120,128 +71,6 @@ func (h *defaultHandler) measureLatencyAndHandleErrors(start time.Time, err erro } } -var ErrMaxDepthReached = errors.New("max archive depth reached") - -// openArchive recursively extracts content from an archive up to a maximum depth, handling nested archives if necessary. -// It takes a reader from which it attempts to identify and process the archive format. Depending on the archive type, -// it either decompresses or extracts the contents directly, sending data to the provided channel. -// Returns an error if the archive cannot be processed due to issues like exceeding maximum depth or unsupported formats. -func (h *defaultHandler) openArchive(ctx logContext.Context, depth int, reader io.Reader, archiveChan chan []byte) error { - if common.IsDone(ctx) { - return ctx.Err() - } - - if depth > maxDepth { - h.metrics.incMaxArchiveDepthCount() - return ErrMaxDepthReached - } - - format, arReader, err := archiver.Identify("", reader) - switch { - case err == nil: - // Continue with the rest of the code. - case errors.Is(err, archiver.ErrNoMatch): - if depth > 0 { - // If openArchive is called on an already extracted/decompressed file and the depth is greater than 0, - // it means we are at least 1 layer deep in the archive. In this case, we should handle the content - // as non-archive data by calling handleNonArchiveContent. - return h.handleNonArchiveContent(ctx, arReader, archiveChan) - } - // If openArchive is called on the root (depth == 0) and we can't identify the format, - // it means we can't handle the content at all. Return the archiver.ErrNoMatch error. - return err - default: - // Some other error occurred. - return fmt.Errorf("error identifying archive: %w", err) - } - - switch archive := format.(type) { - case archiver.Decompressor: - // Decompress the archive and feed the decompressed data back into the archive handler to extract any nested archives. - compReader, err := archive.OpenReader(arReader) - if err != nil { - return fmt.Errorf("error opening decompressor with format %q: %w", format.Name(), err) - } - defer compReader.Close() - - h.metrics.incFilesProcessed() - - rdr, err := readers.NewBufferedFileReader(compReader) - if err != nil { - return fmt.Errorf("error creating random access reader: %w", err) - } - defer rdr.Close() - - return h.openArchive(ctx, depth+1, rdr, archiveChan) - case archiver.Extractor: - err := archive.Extract(logContext.WithValue(ctx, depthKey, depth+1), arReader, nil, h.extractorHandler(archiveChan)) - if err != nil { - return fmt.Errorf("error extracting archive with format: %s: %w", format.Name(), err) - } - return nil - default: - return fmt.Errorf("unknown archive type: %s", format.Name()) - } -} - -// extractorHandler creates a closure that handles individual files extracted by an archiver. -// It logs the extraction, checks for cancellation, and decides whether to skip the file based on its name or type, -// particularly for binary files if configured to skip. If the file is not skipped, it recursively calls openArchive -// to handle nested archives or to continue processing based on the file's content and depth in the archive structure. -func (h *defaultHandler) extractorHandler(archiveChan chan []byte) func(context.Context, archiver.File) error { - return func(ctx context.Context, file archiver.File) error { - lCtx := logContext.WithValues( - logContext.AddLogger(ctx), - "filename", file.Name(), - "size", file.Size(), - ) - lCtx.Logger().V(5).Info("Handling extracted file.") - - if file.IsDir() || file.LinkTarget != "" { - lCtx.Logger().V(5).Info("skipping directory or symlink") - return nil - } - - if common.IsDone(ctx) { - return ctx.Err() - } - - depth := 0 - if ctxDepth, ok := ctx.Value(depthKey).(int); ok { - depth = ctxDepth - } - - fileSize := file.Size() - if int(fileSize) > maxSize { - lCtx.Logger().V(3).Info("skipping file due to size") - return nil - } - - if common.SkipFile(file.Name()) || common.IsBinary(file.Name()) { - lCtx.Logger().V(5).Info("skipping file") - h.metrics.incFilesSkipped() - return nil - } - - fReader, err := file.Open() - if err != nil { - return fmt.Errorf("error opening file %q: %w", file.Name(), err) - } - defer fReader.Close() - - rdr, err := readers.NewBufferedFileReader(fReader) - if err != nil { - return fmt.Errorf("error creating random access reader: %w", err) - } - defer rdr.Close() - - h.metrics.incFilesProcessed() - h.metrics.observeFileSize(fileSize) - - return h.openArchive(lCtx, depth, rdr, archiveChan) - } -} - // handleNonArchiveContent processes files that do not contain nested archives, serving as the final stage in the // extraction/decompression process. It reads the content to detect its MIME type and decides whether to skip based // on the type, particularly for binary files. It manages reading file chunks and writing them to the archive channel, diff --git a/pkg/handlers/default_test.go b/pkg/handlers/default_test.go index accec82edb9c..3d071ad6f382 100644 --- a/pkg/handlers/default_test.go +++ b/pkg/handlers/default_test.go @@ -1,124 +1,36 @@ package handlers import ( - "context" - "net/http" - "regexp" - "strings" + "os" "testing" + "time" "github.com/stretchr/testify/assert" - diskbufferreader "github.com/trufflesecurity/disk-buffer-reader" - logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" + "github.com/trufflesecurity/trufflehog/v3/pkg/context" ) -func TestArchiveHandler(t *testing.T) { - tests := map[string]struct { - archiveURL string - expectedChunks int - matchString string - expectErr bool - }{ - "gzip-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one-zip.gz", - 1, - "AKIAYVP4CIPPH5TNP3SW", - false, - }, - "gzip-nested": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/double-zip.gz", - 1, - "AKIAYVP4CIPPH5TNP3SW", - false, - }, - "gzip-too-deep": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six-zip.gz", - 0, - "", - true, - }, - "tar-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/one.tar", - 1, - "AKIAYVP4CIPPH5TNP3SW", - false, - }, - "tar-nested": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/two.tar", - 1, - "AKIAYVP4CIPPH5TNP3SW", - false, - }, - "tar-too-deep": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/six.tar", - 0, - "", - true, - }, - "targz-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/tar-archive.tar.gz", - 1, - "AKIAYVP4CIPPH5TNP3SW", - false, - }, - "gzip-large": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/FifteenMB.gz", - 1543, - "AKIAYVP4CIPPH5TNP3SW", - false, - }, - "zip-single": { - "https://raw.githubusercontent.com/bill-rich/bad-secrets/master/aws-canary-creds.zip", - 1, - "AKIAYVP4CIPPH5TNP3SW", - false, - }, - } - - for name, testCase := range tests { - t.Run(name, func(t *testing.T) { - resp, err := http.Get(testCase.archiveURL) - assert.NoError(t, err) - assert.Equal(t, http.StatusOK, resp.StatusCode) - defer resp.Body.Close() +func TestHandleNonArchiveFile(t *testing.T) { + file, err := os.Open("testdata/nonarchive.txt") + assert.Nil(t, err) + defer file.Close() - handler := newDefaultHandler(defaultHandlerType) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() - newReader, err := diskbufferreader.New(resp.Body) - if err != nil { - t.Errorf("error creating reusable reader: %s", err) - } - archiveChan, err := handler.HandleFile(logContext.Background(), newReader) - if testCase.expectErr { - assert.NoError(t, err) - return - } + rdr, err := newFileReader(file) + assert.NoError(t, err) + defer rdr.Close() - count := 0 - re := regexp.MustCompile(testCase.matchString) - matched := false - for chunk := range archiveChan { - count++ - if re.Match(chunk) { - matched = true - } - } + handler := newDefaultHandler(defaultHandlerType) + archiveChan, err := handler.HandleFile(context.AddLogger(ctx), rdr) + assert.NoError(t, err) - assert.True(t, matched) - assert.Equal(t, testCase.expectedChunks, count) - }) + wantChunkCount := 6 + count := 0 + for range archiveChan { + count++ } -} - -func TestOpenInvalidArchive(t *testing.T) { - reader := strings.NewReader("invalid archive") - - ctx := logContext.AddLogger(context.Background()) - handler := defaultHandler{} - - archiveChan := make(chan []byte) - err := handler.openArchive(ctx, 0, reader, archiveChan) - assert.Error(t, err) + assert.Equal(t, wantChunkCount, count) } diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index 0cc70b4705d8..e8efd4b12634 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -1,33 +1,92 @@ package handlers import ( + "errors" "fmt" "io" "github.com/gabriel-vasile/mimetype" + "github.com/mholt/archiver/v4" logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" "github.com/trufflesecurity/trufflehog/v3/pkg/readers" "github.com/trufflesecurity/trufflehog/v3/pkg/sources" ) -// readSeekCloser is an interface that combines the functionality of io.ReadSeekCloser and io.ReaderAt. -// It supports reading data, seeking within an open resource, and closing the resource once operations are complete. -// Additionally, it allows reading from a specific offset within the resource without altering its current position, -// enabling efficient and flexible data access patterns. This interface is particularly useful for handling files -// or other data streams where random access and sequential processing are required. -type readSeekCloser interface { - io.ReadSeekCloser - io.ReaderAt +// fileReader is a custom reader that wraps an io.Reader and provides additional functionality for identifying +// and handling different file types. It abstracts away the complexity of detecting file formats, MIME types, +// and archive types, allowing for a more modular and extensible file handling process. +// +// fileReader leverages the archiver and mimetype packages for file type identification and provides information +// about the detected file format, MIME type, and whether the file is an archive. This information can be +// used by FileHandler implementations to make decisions on how to process the file. +// +// The IsGenericArchive field indicates whether the file represents an archive format that is supported by the +// archiver library. This allows FileHandler implementations to determine if the file can be processed using +// the default archive handling capabilities provided by the archiver package. +// +// By encapsulating the file type detection logic, fileReader simplifies the implementation of FileHandler and +// promotes a more cohesive and maintainable codebase. It also embeds a BufferedFileReader to provide efficient +// random access to the file content. +type fileReader struct { + format archiver.Format + mimeType mimeType + *readers.BufferedFileReader + isGenericArchive bool +} + +func newFileReader(r io.ReadCloser) (fileReader, error) { + defer r.Close() + + var ( + reader fileReader + rdr *readers.BufferedFileReader + err error + ) + rdr, err = readers.NewBufferedFileReader(r) + if err != nil { + return reader, fmt.Errorf("error creating random access reader: %w", err) + } + reader.BufferedFileReader = rdr + + // Ensure the reader is closed if an error occurs after the reader is created. + // During non-error conditions, the caller is responsible for closing the reader. + defer func() { + if err != nil && rdr != nil { + _ = rdr.Close() + } + }() + + format, arReader, err := archiver.Identify("", rdr) + switch { + case err == nil: // Archive detected + reader.isGenericArchive = true + reader.mimeType = mimeType(format.Name()) + reader.format = format + case errors.Is(err, archiver.ErrNoMatch): + // Not an archive handled by archiver, try to detect MIME type. + // This will occur for un-supported archive types and non-archive files. (ex: .deb, .rpm, .txt) + mimeT, err := mimetype.DetectReader(arReader) + if err != nil { + return reader, fmt.Errorf("error detecting MIME type: %w", err) + } + reader.mimeType = mimeType(mimeT.String()) + default: // Error identifying archive + return reader, fmt.Errorf("error identifying archive: %w", err) + } + + if _, err = rdr.Seek(0, io.SeekStart); err != nil { + return reader, fmt.Errorf("error seeking to start of file: %w", err) + } + + return reader, nil } // FileHandler represents a handler for files. -// It has a single method, HandleFile, which takes a context and a readSeekCloser as input, +// It has a single method, HandleFile, which takes a context and a fileReader as input, // and returns a channel of byte slices and an error. -// The readSeekCloser extends io.ReadSeekCloser with io.ReaderAt capabilities, -// allowing handlers to perform random and direct access on the file content efficiently. type FileHandler interface { - HandleFile(ctx logContext.Context, reader readSeekCloser) (chan []byte, error) + HandleFile(ctx logContext.Context, reader fileReader) (chan []byte, error) } // fileHandlingConfig encapsulates configuration settings that control the behavior of file processing. @@ -35,10 +94,10 @@ type fileHandlingConfig struct{ skipArchives bool } // newFileHandlingConfig creates a default fileHandlingConfig with default settings. // Optional functional parameters can customize the configuration. -func newFileHandlingConfig(options ...func(*fileHandlingConfig)) *fileHandlingConfig { - config := new(fileHandlingConfig) +func newFileHandlingConfig(options ...func(*fileHandlingConfig)) fileHandlingConfig { + config := fileHandlingConfig{} for _, option := range options { - option(config) + option(&config) } return config @@ -53,138 +112,77 @@ func WithSkipArchives(skip bool) func(*fileHandlingConfig) { type handlerType string const ( - defaultHandlerType handlerType = "default" + archiveHandlerType handlerType = "archive" arHandlerType handlerType = "ar" rpmHandlerType handlerType = "rpm" + defaultHandlerType handlerType = "default" ) type mimeType string const ( - sevenZMime mimeType = "application/x-7z-compressed" - bzip2Mime mimeType = "application/x-bzip2" - rarCompressedMime mimeType = "application/x-rar-compressed" - rarMime mimeType = "application/x-rar" - tarMime mimeType = "application/x-tar" - zipMime mimeType = "application/zip" - gxzipMime mimeType = "application/x-gzip" - gzipMime mimeType = "application/gzip" - gunzipMime mimeType = "application/x-gunzip" - gzippedMime mimeType = "application/gzipped" - gzipCompressedMime mimeType = "application/x-gzip-compressed" - gzipDocumentMime mimeType = "gzip/document" - xzMime mimeType = "application/x-xz" - msCabCompressedMime mimeType = "application/vnd.ms-cab-compressed" - rpmMime mimeType = "application/x-rpm" - fitsMime mimeType = "application/fits" - xarMime mimeType = "application/x-xar" - warcMime mimeType = "application/warc" - cpioMime mimeType = "application/cpio" - unixArMime mimeType = "application/x-unix-archive" - arMime mimeType = "application/x-archive" - debMime mimeType = "application/vnd.debian.binary-package" - lzipMime mimeType = "application/lzip" - lzipXMime mimeType = "application/x-lzip" + rpmMime mimeType = "application/x-rpm" + cpioMime mimeType = "application/cpio" + unixArMime mimeType = "application/x-unix-archive" + arMime mimeType = "application/x-archive" + debMime mimeType = "application/vnd.debian.binary-package" ) -var knownArchiveMimeTypes = map[mimeType]struct{}{ - sevenZMime: {}, - bzip2Mime: {}, - gzipMime: {}, - gxzipMime: {}, - rarCompressedMime: {}, - rarMime: {}, - tarMime: {}, - zipMime: {}, - gunzipMime: {}, - gzippedMime: {}, - gzipCompressedMime: {}, - gzipDocumentMime: {}, - xzMime: {}, - msCabCompressedMime: {}, - rpmMime: {}, - fitsMime: {}, - xarMime: {}, - warcMime: {}, - cpioMime: {}, - unixArMime: {}, - arMime: {}, - debMime: {}, - lzipMime: {}, - lzipXMime: {}, -} - -// getHandlerForType dynamically selects and configures a FileHandler based on the provided MIME type. -// This method uses specialized handlers for specific archive types and RPM packages: -// - arHandler is used for 'arMime', 'unixArMime', and 'debMime' which include Unix archives and Debian packages. -// - rpmHandler is used for 'rpmMime' and 'cpioMime', handling RPM and CPIO archives. -// For all other MIME types, which typically include common archive formats like .zip, .tar, .gz, etc., -// a defaultHandler is used, leveraging the archiver library to manage these formats. -// The chosen handler is then configured with provided options, adapting it to specific operational needs. -// Returns the configured handler or an error if the handler type does not match the expected type. -func getHandlerForType(mimeT mimeType) (FileHandler, error) { - var handler FileHandler - switch mimeT { +// selectHandler dynamically selects and configures a FileHandler based on the provided fileReader. +// The fileReader contains information about the MIME type and whether the file is an archive. +// This method uses specialized handlers for specific file types: +// - arHandler is used for Unix archives and Debian packages ('arMime', 'unixArMime', and 'debMime'). +// - rpmHandler is used for RPM and CPIO archives ('rpmMime' and 'cpioMime'). +// - archiveHandler is used for common archive formats supported by the archiver library (.zip, .tar, .gz, etc.). +// - defaultHandler is used for non-archive files. +// The selected handler is then returned, ready to handle the file according to its specific format and requirements. +func selectHandler(file fileReader) FileHandler { + switch file.mimeType { case arMime, unixArMime, debMime: - handler = newARHandler() + return newARHandler() case rpmMime, cpioMime: - handler = newRPMHandler() + return newRPMHandler() default: - handler = newDefaultHandler(defaultHandlerType) + if file.isGenericArchive { + return newArchiveHandler() + } + return newDefaultHandler(defaultHandlerType) } - - return handler, nil } // HandleFile orchestrates the complete file handling process for a given file. // It determines the MIME type of the file, selects the appropriate handler based on this type, and processes the file. // This function initializes the handling process and delegates to the specific handler to manage file -// extraction or processing. Errors at any stage (MIME type determination, handler retrieval, -// seeking, or file handling) result in an error return value. +// extraction or processing. Errors at any stage result in an error return value. // Successful handling passes the file content through a channel to be chunked and reported. -// -// The function takes an io.Reader as input and wraps it with a diskbufferreader.DiskBufferReader to support -// seeking and to provide an io.ReaderAt interface. This is necessary for certain file handlers that require -// random access to the file content. +// The function will close the reader when it has consumed all the data. // // If the skipArchives option is set to true and the detected MIME type is a known archive type, // the function will skip processing the file and return nil. func HandleFile( ctx logContext.Context, - reader io.Reader, + reader io.ReadCloser, chunkSkel *sources.Chunk, reporter sources.ChunkReporter, options ...func(*fileHandlingConfig), ) error { - config := newFileHandlingConfig(options...) - - rdr, err := readers.NewBufferedFileReader(reader) - if err != nil { - return fmt.Errorf("error creating random access reader: %w", err) + if reader == nil { + return fmt.Errorf("reader is nil") } - defer rdr.Close() - mimeT, err := mimetype.DetectReader(rdr) + rdr, err := newFileReader(reader) if err != nil { - return fmt.Errorf("error detecting MIME type: %w", err) + return fmt.Errorf("error creating custom reader: %w", err) } + defer rdr.Close() - mime := mimeType(mimeT.String()) - if _, ok := knownArchiveMimeTypes[mime]; ok && config.skipArchives { - ctx.Logger().V(5).Info("skipping archive file", "mime", mimeT.String()) + config := newFileHandlingConfig(options...) + if config.skipArchives && rdr.isGenericArchive { + ctx.Logger().V(5).Info("skipping archive file", "mime", rdr.mimeType) return nil } - // Reset the reader to the start of the file since the MIME type detection may have read some bytes. - if _, err := rdr.Seek(0, io.SeekStart); err != nil { - return fmt.Errorf("error seeking to start of file: %w", err) - } - - handler, err := getHandlerForType(mime) - if err != nil { - return fmt.Errorf("error getting handler for type: %w", err) - } - + handler := selectHandler(rdr) archiveChan, err := handler.HandleFile(ctx, rdr) // Delegate to the specific handler to process the file. if err != nil { return fmt.Errorf("error handling file: %w", err) diff --git a/pkg/handlers/handlers_test.go b/pkg/handlers/handlers_test.go index d4c6430332e1..3ec232d7bcc7 100644 --- a/pkg/handlers/handlers_test.go +++ b/pkg/handlers/handlers_test.go @@ -1,7 +1,6 @@ package handlers import ( - "io" "net/http" "os" "strings" @@ -12,6 +11,7 @@ import ( diskbufferreader "github.com/trufflesecurity/disk-buffer-reader" "github.com/trufflesecurity/trufflehog/v3/pkg/context" + logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" "github.com/trufflesecurity/trufflehog/v3/pkg/sources" ) @@ -32,7 +32,9 @@ func TestHandleFile(t *testing.T) { // TODO: Embed a zip without making an HTTP request. resp, err := http.Get("https://raw.githubusercontent.com/bill-rich/bad-secrets/master/aws-canary-creds.zip") assert.NoError(t, err) - defer resp.Body.Close() + if resp != nil && resp.Body != nil { + defer resp.Body.Close() + } assert.Equal(t, 0, len(reporter.Ch)) assert.NoError(t, HandleFile(context.Background(), resp.Body, &sources.Chunk{}, reporter)) @@ -40,13 +42,10 @@ func TestHandleFile(t *testing.T) { } func BenchmarkHandleFile(b *testing.B) { - file, err := os.Open("testdata/test.tgz") - assert.Nil(b, err) - defer file.Close() - - b.ResetTimer() for i := 0; i < b.N; i++ { sourceChan := make(chan *sources.Chunk, 1) + file, err := os.Open("testdata/test.tgz") + assert.Nil(b, err) b.StartTimer() go func() { @@ -58,21 +57,17 @@ func BenchmarkHandleFile(b *testing.B) { for range sourceChan { } b.StopTimer() - - _, err = file.Seek(0, io.SeekStart) - assert.NoError(b, err) } } func TestSkipArchive(t *testing.T) { file, err := os.Open("testdata/test.tgz") assert.Nil(t, err) - defer file.Close() chunkCh := make(chan *sources.Chunk) go func() { defer close(chunkCh) - err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}, WithSkipArchives(true)) + err := HandleFile(logContext.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}, WithSkipArchives(true)) assert.NoError(t, err) }() @@ -87,12 +82,11 @@ func TestSkipArchive(t *testing.T) { func TestHandleNestedArchives(t *testing.T) { file, err := os.Open("testdata/nested-dirs.zip") assert.Nil(t, err) - defer file.Close() chunkCh := make(chan *sources.Chunk) go func() { defer close(chunkCh) - err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + err := HandleFile(logContext.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) assert.NoError(t, err) }() @@ -107,12 +101,11 @@ func TestHandleNestedArchives(t *testing.T) { func TestHandleCompressedZip(t *testing.T) { file, err := os.Open("testdata/example.zip.gz") assert.Nil(t, err) - defer file.Close() chunkCh := make(chan *sources.Chunk) go func() { defer close(chunkCh) - err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + err := HandleFile(logContext.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) assert.NoError(t, err) }() @@ -127,12 +120,11 @@ func TestHandleCompressedZip(t *testing.T) { func TestHandleNestedCompressedArchive(t *testing.T) { file, err := os.Open("testdata/nested-compressed-archive.tar.gz") assert.Nil(t, err) - defer file.Close() chunkCh := make(chan *sources.Chunk) go func() { defer close(chunkCh) - err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + err := HandleFile(logContext.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) assert.NoError(t, err) }() @@ -147,12 +139,11 @@ func TestHandleNestedCompressedArchive(t *testing.T) { func TestExtractTarContent(t *testing.T) { file, err := os.Open("testdata/test.tgz") assert.Nil(t, err) - defer file.Close() chunkCh := make(chan *sources.Chunk) go func() { defer close(chunkCh) - err := HandleFile(context.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + err := HandleFile(logContext.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) assert.NoError(t, err) }() @@ -167,7 +158,6 @@ func TestExtractTarContent(t *testing.T) { func TestNestedDirArchive(t *testing.T) { file, err := os.Open("testdata/dir-archive.zip") assert.Nil(t, err) - defer file.Close() ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() @@ -193,7 +183,6 @@ func TestHandleFileRPM(t *testing.T) { file, err := os.Open("testdata/test.rpm") assert.Nil(t, err) - defer file.Close() assert.Equal(t, 0, len(reporter.Ch)) assert.NoError(t, HandleFile(context.Background(), file, &sources.Chunk{}, reporter)) @@ -206,9 +195,23 @@ func TestHandleFileAR(t *testing.T) { file, err := os.Open("testdata/test.deb") assert.Nil(t, err) - defer file.Close() assert.Equal(t, 0, len(reporter.Ch)) assert.NoError(t, HandleFile(context.Background(), file, &sources.Chunk{}, reporter)) assert.Equal(t, wantChunkCount, len(reporter.Ch)) } + +func TestHandleFileNonArchive(t *testing.T) { + wantChunkCount := 6 + reporter := sources.ChanReporter{Ch: make(chan *sources.Chunk, wantChunkCount)} + + file, err := os.Open("testdata/nonarchive.txt") + assert.NoError(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) + defer cancel() + + assert.NoError(t, HandleFile(ctx, file, &sources.Chunk{}, reporter)) + assert.NoError(t, err) + assert.Equal(t, wantChunkCount, len(reporter.Ch)) +} diff --git a/pkg/handlers/rpm.go b/pkg/handlers/rpm.go index be799768b047..a790e520b5f8 100644 --- a/pkg/handlers/rpm.go +++ b/pkg/handlers/rpm.go @@ -11,18 +11,17 @@ import ( logContext "github.com/trufflesecurity/trufflehog/v3/pkg/context" ) -// rpmHandler specializes defaultHandler to manage RPM package files. It leverages shared behaviors -// from defaultHandler and introduces additional logic specific to RPM packages. +// rpmHandler specializes archiveHandler to manage RPM package files. type rpmHandler struct{ *defaultHandler } -// newRPMHandler creates an rpmHandler. +// newRPMHandler creates an rpmHandler with the provided metrics. func newRPMHandler() *rpmHandler { return &rpmHandler{defaultHandler: newDefaultHandler(rpmHandlerType)} } // HandleFile processes RPM formatted files. Further implementation is required to appropriately // handle RPM specific archive operations. -func (h *rpmHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (chan []byte, error) { +func (h *rpmHandler) HandleFile(ctx logContext.Context, input fileReader) (chan []byte, error) { archiveChan := make(chan []byte, defaultBufferSize) go func() { @@ -33,7 +32,23 @@ func (h *rpmHandler) HandleFile(ctx logContext.Context, input readSeekCloser) (c // Update the metrics for the file processing. start := time.Now() var err error - defer h.measureLatencyAndHandleErrors(start, err) + defer func() { + h.measureLatencyAndHandleErrors(start, err) + h.metrics.incFilesProcessed() + }() + + // Defer a panic recovery to handle any panics that occur during the RPM processing. + defer func() { + if r := recover(); r != nil { + // Return the panic as an error. + if e, ok := r.(error); ok { + err = e + } else { + err = fmt.Errorf("panic occurred: %v", r) + } + ctx.Logger().Error(err, "Panic occurred when reading rpm archive") + } + }() var rpm *rpmutils.Rpm rpm, err = rpmutils.ReadRpm(input) diff --git a/pkg/handlers/rpm_test.go b/pkg/handlers/rpm_test.go index d5e2e7b34e29..f90d7b672fa0 100644 --- a/pkg/handlers/rpm_test.go +++ b/pkg/handlers/rpm_test.go @@ -15,11 +15,15 @@ func TestHandleRPMFile(t *testing.T) { assert.Nil(t, err) defer file.Close() - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second) defer cancel() + rdr, err := newFileReader(file) + assert.NoError(t, err) + defer rdr.Close() + handler := newRPMHandler() - archiveChan, err := handler.HandleFile(context.AddLogger(ctx), file) + archiveChan, err := handler.HandleFile(context.AddLogger(ctx), rdr) assert.NoError(t, err) wantChunkCount := 179 diff --git a/pkg/handlers/testdata/nonarchive.txt b/pkg/handlers/testdata/nonarchive.txt new file mode 100644 index 000000000000..0dbcd88af714 --- /dev/null +++ b/pkg/handlers/testdata/nonarchive.txt @@ -0,0 +1,68 @@ +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed non risus. Suspendisse lectus tortor, dignissim sit amet, adipiscing nec, ultricies sed, dolor. Cras elementum ultrices diam. Maecenas ligula massa, varius a, semper con, euismod non, mi. Proin porttitor, orci nec nonummy molestie, enim est eleifend mi, non fermentum diam nisl sit amet erat. Duis semper. Duis arcu massa, scelerisque vitae, consequat in, pretium a, enim. Pellentesque congue. Ut in risus volutpat libero pharetra tempor. Cras vestibulum bibendum augue. Praesent egestas leo in pede. Praesent blandit odio eu enim. Pellentesque sed dui ut augue blandit sodales. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Aliquam nibh. Mauris ac mauris sed pede pellentesque fermentum. Maecenas adipiscing ante non diam sodales hendrerit. diff --git a/pkg/readers/bufferedfilereader.go b/pkg/readers/bufferedfilereader.go index 4b1d46b4123d..47bc2f2196e0 100644 --- a/pkg/readers/bufferedfilereader.go +++ b/pkg/readers/bufferedfilereader.go @@ -7,26 +7,26 @@ import ( bufferedfilewriter "github.com/trufflesecurity/trufflehog/v3/pkg/writers/buffered_file_writer" ) -// Compile time check to ensure that bufferedFileReader implements io.ReaderAt. -var _ io.ReaderAt = (*bufferedFileReader)(nil) +// Compile time check to ensure that BufferedFileReader implements io.ReaderAt. +var _ io.ReaderAt = (*BufferedFileReader)(nil) -// bufferedFileReader provides random access read, seek, and close capabilities on top of the BufferedFileWriter. +// BufferedFileReader provides random access read, seek, and close capabilities on top of the BufferedFileWriter. // It combines the functionality of BufferedFileWriter for buffered writing, io.ReadSeekCloser for // random access reading and seeking. -type bufferedFileReader struct { +type BufferedFileReader struct { bufWriter *bufferedfilewriter.BufferedFileWriter reader io.ReadSeekCloser } -// NewBufferedFileReader initializes a bufferedFileReader from an io.Reader by using +// NewBufferedFileReader initializes a BufferedFileReader from an io.Reader by using // the BufferedFileWriter's functionality to read and store data, then setting up a io.ReadSeekCloser // for random access reading and seeking. -// Close should be called when the bufferedFileReader is no longer needed. -// It returns the initialized bufferedFileReader and any error encountered during the process. -func NewBufferedFileReader(r io.Reader) (*bufferedFileReader, error) { +// Close should be called when the BufferedFileReader is no longer needed. +// It returns the initialized BufferedFileReader and any error encountered during the process. +func NewBufferedFileReader(r io.Reader) (*BufferedFileReader, error) { writer, err := bufferedfilewriter.NewFromReader(r) if err != nil { - return nil, fmt.Errorf("error creating bufferedFileReader: %w", err) + return nil, fmt.Errorf("error creating BufferedFileReader: %w", err) } // Ensure that the BufferedFileWriter is in read-only mode. @@ -39,25 +39,21 @@ func NewBufferedFileReader(r io.Reader) (*bufferedFileReader, error) { return nil, err } - return &bufferedFileReader{writer, rdr}, nil + return &BufferedFileReader{writer, rdr}, nil } -// Close the bufferedFileReader. -// It should be called when the bufferedFileReader is no longer needed. -// Note that closing the bufferedFileReader does not affect the underlying bytes.Reader, +// Close the BufferedFileReader. +// It should be called when the BufferedFileReader is no longer needed. +// Note that closing the BufferedFileReader does not affect the underlying bytes.Reader, // which can still be used for reading, seeking, and reading at specific positions. // Close is a no-op for the bytes.Reader. -func (b *bufferedFileReader) Close() error { - return b.reader.Close() -} +func (b *BufferedFileReader) Close() error { return b.reader.Close() } // Read reads up to len(p) bytes into p from the underlying reader. // It returns the number of bytes read and any error encountered. // If the reader reaches the end of the available data, Read returns 0, io.EOF. // It implements the io.Reader interface. -func (b *bufferedFileReader) Read(p []byte) (int, error) { - return b.reader.Read(p) -} +func (b *BufferedFileReader) Read(p []byte) (int, error) { return b.reader.Read(p) } // Seek sets the offset for the next Read operation on the underlying reader. // The offset is interpreted according to the whence parameter: @@ -67,7 +63,7 @@ func (b *bufferedFileReader) Read(p []byte) (int, error) { // // Seek returns the new offset and any error encountered. // It implements the io.Seeker interface. -func (b *bufferedFileReader) Seek(offset int64, whence int) (int64, error) { +func (b *BufferedFileReader) Seek(offset int64, whence int) (int64, error) { return b.reader.Seek(offset, whence) } @@ -76,7 +72,7 @@ func (b *bufferedFileReader) Seek(offset int64, whence int) (int64, error) { // If the io.ReadSeekCloser reaches the end of the available data before len(p) bytes are read, // ReadAt returns the number of bytes read and io.EOF. // It implements the io.ReaderAt interface. -func (b *bufferedFileReader) ReadAt(p []byte, off int64) (n int, err error) { +func (b *BufferedFileReader) ReadAt(p []byte, off int64) (n int, err error) { _, err = b.reader.Seek(off, io.SeekStart) if err != nil { return 0, err diff --git a/pkg/sources/filesystem/filesystem.go b/pkg/sources/filesystem/filesystem.go index fec6706a75f3..0db5a4c359ca 100644 --- a/pkg/sources/filesystem/filesystem.go +++ b/pkg/sources/filesystem/filesystem.go @@ -163,7 +163,6 @@ func (s *Source) scanFile(ctx context.Context, path string, chunksChan chan *sou return fmt.Errorf("unable to open file: %w", err) } - defer inputFile.Close() logger.V(3).Info("scanning file") chunkSkel := &sources.Chunk{ diff --git a/pkg/sources/gcs/gcs.go b/pkg/sources/gcs/gcs.go index b8e6c7669e44..52ecbf7e62f1 100644 --- a/pkg/sources/gcs/gcs.go +++ b/pkg/sources/gcs/gcs.go @@ -353,5 +353,5 @@ func (s *Source) processObject(ctx context.Context, o object) error { }, } - return handlers.HandleFile(ctx, o, chunkSkel, sources.ChanReporter{Ch: s.chunksCh}) + return handlers.HandleFile(ctx, io.NopCloser(o), chunkSkel, sources.ChanReporter{Ch: s.chunksCh}) } diff --git a/pkg/sources/git/git.go b/pkg/sources/git/git.go index 8ae602cb9779..4190bf4b7fce 100644 --- a/pkg/sources/git/git.go +++ b/pkg/sources/git/git.go @@ -1215,12 +1215,25 @@ func (s *Git) handleBinary(ctx context.Context, gitDir string, reporter sources. var stderr bytes.Buffer cmd.Stderr = &stderr - stdout, err := cmd.Output() + stdout, err := cmd.StdoutPipe() if err != nil { return fmt.Errorf("error running git cat-file: %w\n%s", err, stderr.Bytes()) } - return handlers.HandleFile(fileCtx, bytes.NewReader(stdout), chunkSkel, reporter, handlers.WithSkipArchives(s.skipArchives)) + defer func() { + if err = cmd.Wait(); err != nil { + ctx.Logger().Error(fmt.Errorf( + "error waiting for command: command=%s, stderr=%s, commit=%s: %w", + cmd.String(), stderr.String(), commitHash.String(), err, + ), "waiting for command failed") + } + }() + + if err := cmd.Start(); err != nil { + return fmt.Errorf("error starting git cat-file: %w\n%s", err, stderr.Bytes()) + } + + return handlers.HandleFile(fileCtx, stdout, chunkSkel, reporter, handlers.WithSkipArchives(s.skipArchives)) } func (s *Source) Enumerate(ctx context.Context, reporter sources.UnitReporter) error { diff --git a/pkg/sources/s3/s3.go b/pkg/sources/s3/s3.go index ebd39a1028d4..63ab995cddfd 100644 --- a/pkg/sources/s3/s3.go +++ b/pkg/sources/s3/s3.go @@ -355,7 +355,6 @@ func (s *Source) pageChunker(ctx context.Context, client *s3.S3, chunksChan chan } return nil } - defer res.Body.Close() email := "Unknown" if obj.Owner != nil { diff --git a/pkg/writers/buffered_file_writer/bufferedfilewriter.go b/pkg/writers/buffered_file_writer/bufferedfilewriter.go index 60a227aaf51f..16713edda954 100644 --- a/pkg/writers/buffered_file_writer/bufferedfilewriter.go +++ b/pkg/writers/buffered_file_writer/bufferedfilewriter.go @@ -88,6 +88,10 @@ func NewFromReader(r io.Reader, opts ...Option) (*BufferedFileWriter, error) { return nil, fmt.Errorf("error writing to buffered file writer: %w", err) } + if writer.buf == nil { + return nil, fmt.Errorf("reader was empty; no data written to buffered file writer") + } + return writer, nil } From 2db06f05767dd8475df2f071785d9775144ee549 Mon Sep 17 00:00:00 2001 From: ahrav Date: Wed, 15 May 2024 18:25:36 -0700 Subject: [PATCH 44/51] [bug] - Handle empty reader case in newFileReader (#2854) * Correclty handle empty files * fix * fix test --- pkg/handlers/archive.go | 13 ++++++++++-- pkg/handlers/handlers.go | 11 ++++++++++ pkg/handlers/handlers_test.go | 19 ++++++++++++++++++ pkg/handlers/testdata/testdir.zip | Bin 0 -> 946 bytes pkg/readers/bufferedfilereader.go | 3 +++ .../bufferedfilewriter.go | 8 ++------ .../bufferedfilewriter_test.go | 9 ++++++--- 7 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 pkg/handlers/testdata/testdir.zip diff --git a/pkg/handlers/archive.go b/pkg/handlers/archive.go index e0e6313b1f06..61b163322cf7 100644 --- a/pkg/handlers/archive.go +++ b/pkg/handlers/archive.go @@ -21,7 +21,7 @@ const ( var ( maxDepth = 5 - maxSize = 250 * 1024 * 1024 // 250 MB + maxSize = 2 << 30 // 2 GB maxTimeout = time.Duration(30) * time.Second ) @@ -101,6 +101,10 @@ func (h *archiveHandler) openArchive(ctx logContext.Context, depth int, reader f rdr, err := newFileReader(compReader) if err != nil { + if errors.Is(err, ErrEmptyReader) { + ctx.Logger().V(5).Info("empty reader, skipping file") + return nil + } return fmt.Errorf("error creating custom reader: %w", err) } defer rdr.Close() @@ -146,7 +150,8 @@ func (h *archiveHandler) extractorHandler(archiveChan chan []byte) func(context. fileSize := file.Size() if int(fileSize) > maxSize { - lCtx.Logger().V(3).Info("skipping file due to size") + lCtx.Logger().V(3).Info("skipping file due to size", "size", fileSize) + h.metrics.incFilesSkipped() return nil } @@ -180,6 +185,10 @@ func (h *archiveHandler) extractorHandler(archiveChan chan []byte) func(context. rdr, err := newFileReader(f) if err != nil { + if errors.Is(err, ErrEmptyReader) { + lCtx.Logger().V(5).Info("empty reader, skipping file") + return nil + } return fmt.Errorf("error creating custom reader: %w", err) } defer rdr.Close() diff --git a/pkg/handlers/handlers.go b/pkg/handlers/handlers.go index e8efd4b12634..aa810a2f2fd4 100644 --- a/pkg/handlers/handlers.go +++ b/pkg/handlers/handlers.go @@ -35,6 +35,8 @@ type fileReader struct { isGenericArchive bool } +var ErrEmptyReader = errors.New("reader is empty") + func newFileReader(r io.ReadCloser) (fileReader, error) { defer r.Close() @@ -57,6 +59,11 @@ func newFileReader(r io.ReadCloser) (fileReader, error) { } }() + // Check if the reader is empty. + if rdr.Size() == 0 { + return reader, ErrEmptyReader + } + format, arReader, err := archiver.Identify("", rdr) switch { case err == nil: // Archive detected @@ -172,6 +179,10 @@ func HandleFile( rdr, err := newFileReader(reader) if err != nil { + if errors.Is(err, ErrEmptyReader) { + ctx.Logger().V(5).Info("empty reader, skipping file") + return nil + } return fmt.Errorf("error creating custom reader: %w", err) } defer rdr.Close() diff --git a/pkg/handlers/handlers_test.go b/pkg/handlers/handlers_test.go index 3ec232d7bcc7..cfa23ab7c6b0 100644 --- a/pkg/handlers/handlers_test.go +++ b/pkg/handlers/handlers_test.go @@ -215,3 +215,22 @@ func TestHandleFileNonArchive(t *testing.T) { assert.NoError(t, err) assert.Equal(t, wantChunkCount, len(reporter.Ch)) } + +func TestExtractTarContentWithEmptyFile(t *testing.T) { + file, err := os.Open("testdata/testdir.zip") + assert.Nil(t, err) + + chunkCh := make(chan *sources.Chunk) + go func() { + defer close(chunkCh) + err := HandleFile(logContext.Background(), file, &sources.Chunk{}, sources.ChanReporter{Ch: chunkCh}) + assert.NoError(t, err) + }() + + wantCount := 4 + count := 0 + for range chunkCh { + count++ + } + assert.Equal(t, wantCount, count) +} diff --git a/pkg/handlers/testdata/testdir.zip b/pkg/handlers/testdata/testdir.zip new file mode 100644 index 0000000000000000000000000000000000000000..29c11b0b0a34ef122b86d7e2b9a60f294be21819 GIT binary patch literal 946 zcmWIWW@Zs#0DpkSY4+`t z9s9%MZPsn9nk|#J|Jj92SKF0!%f95*?6xVszUuhasYeaN`}6Ne<~}a2zWn>==1;G_ z{SA+>T>T~NyqlL6k0Od`yNfQQ^G%iIlp4fyM;LXYgGJzQg Mg@HlT$pqp70QpE#$p8QV literal 0 HcmV?d00001 diff --git a/pkg/readers/bufferedfilereader.go b/pkg/readers/bufferedfilereader.go index 47bc2f2196e0..44c2bb303e4b 100644 --- a/pkg/readers/bufferedfilereader.go +++ b/pkg/readers/bufferedfilereader.go @@ -79,3 +79,6 @@ func (b *BufferedFileReader) ReadAt(p []byte, off int64) (n int, err error) { } return b.reader.Read(p) } + +// Size returns the total size of the data stored in the BufferedFileReader. +func (b *BufferedFileReader) Size() int { return b.bufWriter.Len() } diff --git a/pkg/writers/buffered_file_writer/bufferedfilewriter.go b/pkg/writers/buffered_file_writer/bufferedfilewriter.go index 16713edda954..3e9a5aa37db4 100644 --- a/pkg/writers/buffered_file_writer/bufferedfilewriter.go +++ b/pkg/writers/buffered_file_writer/bufferedfilewriter.go @@ -84,14 +84,10 @@ func New(opts ...Option) *BufferedFileWriter { // NewFromReader creates a new instance of BufferedFileWriter and writes the content from the provided reader to the writer. func NewFromReader(r io.Reader, opts ...Option) (*BufferedFileWriter, error) { writer := New(opts...) - if _, err := io.Copy(writer, r); err != nil { + if _, err := io.Copy(writer, r); err != nil && !errors.Is(err, io.EOF) { return nil, fmt.Errorf("error writing to buffered file writer: %w", err) } - if writer.buf == nil { - return nil, fmt.Errorf("reader was empty; no data written to buffered file writer") - } - return writer, nil } @@ -271,7 +267,7 @@ func (w *BufferedFileWriter) ReadSeekCloser() (io.ReadSeekCloser, error) { } if w.buf == nil { - return nil, fmt.Errorf("BufferedFileWriter has not buffer data to read") + return nil, nil } // Data is in memory. diff --git a/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go b/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go index e40b587c251c..329bbe4182b5 100644 --- a/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go +++ b/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go @@ -518,9 +518,8 @@ func TestNewFromReader(t *testing.T) { wantData: "hello world", }, { - name: "Empty reader", - reader: strings.NewReader(""), - wantErr: true, + name: "Empty reader", + reader: strings.NewReader(""), }, { name: "Error reader", @@ -550,6 +549,10 @@ func TestNewFromReader(t *testing.T) { return } assert.NoError(t, err) + + if rdr == nil { + return + } defer rdr.Close() _, err = b.ReadFrom(rdr) From bcbc9c5ff7774223d94b7d647a655dfa50e9cecb Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 18:32:06 -0700 Subject: [PATCH 45/51] fix(deps): update module github.com/aws/aws-sdk-go to v1.53.3 (#2849) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index aba026bd30f4..244545bcc606 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/TheZeroSlave/zapsentry v1.23.0 github.com/adrg/strutil v0.3.1 github.com/alecthomas/kingpin/v2 v2.4.0 - github.com/aws/aws-sdk-go v1.53.1 + github.com/aws/aws-sdk-go v1.53.3 github.com/aymanbagabas/go-osc52 v1.2.2 github.com/bill-rich/go-syslog v0.0.0-20220413021637-49edb52a574c github.com/bitfinexcom/bitfinex-api-go v0.0.0-20210608095005-9e0b26f200fb diff --git a/go.sum b/go.sum index 722b05d55681..5c5b2592d8c5 100644 --- a/go.sum +++ b/go.sum @@ -131,6 +131,8 @@ github.com/aws/aws-sdk-go v1.53.0 h1:MMo1x1ggPPxDfHMXJnQudTbGXYlD4UigUAud1DJxPVo github.com/aws/aws-sdk-go v1.53.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.53.1 h1:15/i0m9rE8r1q3P4ooHCfZTJtkxwG2Dwqp9JhPaVbs0= github.com/aws/aws-sdk-go v1.53.1/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= +github.com/aws/aws-sdk-go v1.53.3 h1:xv0iGCCLdf6ZtlLPMCBjm+tU9UBLP5hXnSqnbKFYmto= +github.com/aws/aws-sdk-go v1.53.3/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= github.com/aws/smithy-go v1.20.1/go.mod h1:krry+ya/rV9RDcV/Q16kpu6ypI4K2czasz0NC3qS14E= github.com/aymanbagabas/go-osc52 v1.2.2 h1:NT7wkhEhPTcKnBCdPi9djmyy9L3JOL4+3SsfJyqptCo= From 15c6333987de925f0322f8b9b2c4b2013b04b7bf Mon Sep 17 00:00:00 2001 From: Abdul Basit Date: Thu, 16 May 2024 20:29:36 +0500 Subject: [PATCH 46/51] deprecated Integromat detector becuase they are gone. (#2856) remove the package as well. --- pkg/detectors/integromat/integromat.go | 73 - pkg/detectors/integromat/integromat_test.go | 120 -- pkg/engine/defaults.go | 2 - pkg/pb/detectorspb/detectors.pb.go | 1520 ++++++++++--------- proto/detectors.proto | 2 +- 5 files changed, 762 insertions(+), 955 deletions(-) delete mode 100644 pkg/detectors/integromat/integromat.go delete mode 100644 pkg/detectors/integromat/integromat_test.go diff --git a/pkg/detectors/integromat/integromat.go b/pkg/detectors/integromat/integromat.go deleted file mode 100644 index 2ca972a1cca9..000000000000 --- a/pkg/detectors/integromat/integromat.go +++ /dev/null @@ -1,73 +0,0 @@ -package integromat - -import ( - "context" - "fmt" - regexp "github.com/wasilibs/go-re2" - "net/http" - "strings" - - "github.com/trufflesecurity/trufflehog/v3/pkg/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" - "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" -) - -type Scanner struct{} - -// Ensure the Scanner satisfies the interface at compile time. -var _ detectors.Detector = (*Scanner)(nil) - -var ( - client = common.SaneHttpClient() - - // Make sure that your group is surrounded in boundary characters such as below to reduce false positives. - keyPat = regexp.MustCompile(detectors.PrefixRegex([]string{"integromat"}) + `\b([a-z0-9-]{36})\b`) -) - -// Keywords are used for efficiently pre-filtering chunks. -// Use identifiers in the secret preferably, or the provider name. -func (s Scanner) Keywords() []string { - return []string{"integromat"} -} - -// FromData will find and optionally verify Integromat secrets in a given set of bytes. -func (s Scanner) FromData(ctx context.Context, verify bool, data []byte) (results []detectors.Result, err error) { - dataStr := string(data) - - matches := keyPat.FindAllStringSubmatch(dataStr, -1) - - for _, match := range matches { - if len(match) != 2 { - continue - } - resMatch := strings.TrimSpace(match[1]) - - s1 := detectors.Result{ - DetectorType: detectorspb.DetectorType_Integromat, - Raw: []byte(resMatch), - } - - if verify { - req, err := http.NewRequestWithContext(ctx, "GET", "https://api.integromat.com/v1/whoami", nil) - if err != nil { - continue - } - req.Header.Add("Authorization", fmt.Sprintf("Token %s", resMatch)) - res, err := client.Do(req) - if err == nil { - defer res.Body.Close() - if res.StatusCode >= 200 && res.StatusCode < 300 { - s1.Verified = true - } - } - } - - results = append(results, s1) - } - - return results, nil -} - -func (s Scanner) Type() detectorspb.DetectorType { - return detectorspb.DetectorType_Integromat -} diff --git a/pkg/detectors/integromat/integromat_test.go b/pkg/detectors/integromat/integromat_test.go deleted file mode 100644 index 0f48d4d7b4e9..000000000000 --- a/pkg/detectors/integromat/integromat_test.go +++ /dev/null @@ -1,120 +0,0 @@ -//go:build detectors -// +build detectors - -package integromat - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/kylelemons/godebug/pretty" - "github.com/trufflesecurity/trufflehog/v3/pkg/detectors" - - "github.com/trufflesecurity/trufflehog/v3/pkg/common" - "github.com/trufflesecurity/trufflehog/v3/pkg/pb/detectorspb" -) - -func TestIntegromat_FromChunk(t *testing.T) { - ctx, cancel := context.WithTimeout(context.Background(), time.Second*5) - defer cancel() - testSecrets, err := common.GetSecret(ctx, "trufflehog-testing", "detectors3") - if err != nil { - t.Fatalf("could not get test secrets from GCP: %s", err) - } - secret := testSecrets.MustGetField("INTEGROMAT_TOKEN") - inactiveSecret := testSecrets.MustGetField("INTEGROMAT_INACTIVE") - - type args struct { - ctx context.Context - data []byte - verify bool - } - tests := []struct { - name string - s Scanner - args args - want []detectors.Result - wantErr bool - }{ - { - name: "found, verified", - s: Scanner{}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a integromat secret %s within", secret)), - verify: true, - }, - want: []detectors.Result{ - { - DetectorType: detectorspb.DetectorType_Integromat, - Verified: true, - }, - }, - wantErr: false, - }, - { - name: "found, unverified", - s: Scanner{}, - args: args{ - ctx: context.Background(), - data: []byte(fmt.Sprintf("You can find a integromat secret %s within but not valid", inactiveSecret)), // the secret would satisfy the regex but not pass validation - verify: true, - }, - want: []detectors.Result{ - { - DetectorType: detectorspb.DetectorType_Integromat, - Verified: false, - }, - }, - wantErr: false, - }, - { - name: "not found", - s: Scanner{}, - args: args{ - ctx: context.Background(), - data: []byte("You cannot find the secret within"), - verify: true, - }, - want: nil, - wantErr: false, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - s := Scanner{} - got, err := s.FromData(tt.args.ctx, tt.args.verify, tt.args.data) - if (err != nil) != tt.wantErr { - t.Errorf("Integromat.FromData() error = %v, wantErr %v", err, tt.wantErr) - return - } - for i := range got { - if len(got[i].Raw) == 0 { - t.Fatalf("no raw secret present: \n %+v", got[i]) - } - got[i].Raw = nil - } - if diff := pretty.Compare(got, tt.want); diff != "" { - t.Errorf("Integromat.FromData() %s diff: (-got +want)\n%s", tt.name, diff) - } - }) - } -} - -func BenchmarkFromData(benchmark *testing.B) { - ctx := context.Background() - s := Scanner{} - for name, data := range detectors.MustGetBenchmarkData() { - benchmark.Run(name, func(b *testing.B) { - b.ResetTimer() - for n := 0; n < b.N; n++ { - _, err := s.FromData(ctx, false, data) - if err != nil { - b.Fatal(err) - } - } - }) - } -} diff --git a/pkg/engine/defaults.go b/pkg/engine/defaults.go index 76bff8c3437c..612750ed5ac0 100644 --- a/pkg/engine/defaults.go +++ b/pkg/engine/defaults.go @@ -344,7 +344,6 @@ import ( "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/insightly" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/instabot" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/instamojo" - "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/integromat" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/intercom" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/interseller" "github.com/trufflesecurity/trufflehog/v3/pkg/detectors/intra42" @@ -965,7 +964,6 @@ func DefaultDetectors() []detectors.Detector { &smartsheets.Scanner{}, // &wepay.Scanner{}, // &artifactory.Scanner{}, - &integromat.Scanner{}, &linenotify.Scanner{}, &float.Scanner{}, &monday.Scanner{}, diff --git a/pkg/pb/detectorspb/detectors.pb.go b/pkg/pb/detectorspb/detectors.pb.go index e4b6d65406a6..cdb00c92324e 100644 --- a/pkg/pb/detectorspb/detectors.pb.go +++ b/pkg/pb/detectorspb/detectors.pb.go @@ -322,13 +322,14 @@ const ( DetectorType_Polygon DetectorType = 242 DetectorType_Powrbot DetectorType = 243 // Deprecated: Marked as deprecated in detectors.proto. - DetectorType_ProspectIO DetectorType = 244 - DetectorType_Skrappio DetectorType = 245 - DetectorType_Monday DetectorType = 246 - DetectorType_Smartsheets DetectorType = 247 - DetectorType_Wrike DetectorType = 248 - DetectorType_Float DetectorType = 249 - DetectorType_Imagekit DetectorType = 250 + DetectorType_ProspectIO DetectorType = 244 + DetectorType_Skrappio DetectorType = 245 + DetectorType_Monday DetectorType = 246 + DetectorType_Smartsheets DetectorType = 247 + DetectorType_Wrike DetectorType = 248 + DetectorType_Float DetectorType = 249 + DetectorType_Imagekit DetectorType = 250 + // Deprecated: Marked as deprecated in detectors.proto. DetectorType_Integromat DetectorType = 251 DetectorType_Salesblink DetectorType = 252 DetectorType_Bored DetectorType = 253 @@ -3514,7 +3515,7 @@ var file_detectors_proto_rawDesc = []byte{ 0x4c, 0x41, 0x49, 0x4e, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x42, 0x41, 0x53, 0x45, 0x36, 0x34, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x55, 0x54, 0x46, 0x31, 0x36, 0x10, 0x03, 0x12, 0x13, 0x0a, 0x0f, 0x45, 0x53, 0x43, 0x41, 0x50, 0x45, 0x44, 0x5f, 0x55, 0x4e, 0x49, 0x43, 0x4f, 0x44, 0x45, - 0x10, 0x04, 0x2a, 0xf7, 0x7d, 0x0a, 0x0c, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, + 0x10, 0x04, 0x2a, 0x89, 0x7e, 0x0a, 0x0c, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x54, 0x79, 0x70, 0x65, 0x12, 0x0b, 0x0a, 0x07, 0x41, 0x6c, 0x69, 0x62, 0x61, 0x62, 0x61, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x41, 0x4d, 0x51, 0x50, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x41, 0x57, 0x53, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x10, 0x03, 0x12, 0x0a, @@ -3776,757 +3777,758 @@ var file_detectors_proto_rawDesc = []byte{ 0x73, 0x68, 0x65, 0x65, 0x74, 0x73, 0x10, 0xf7, 0x01, 0x12, 0x0a, 0x0a, 0x05, 0x57, 0x72, 0x69, 0x6b, 0x65, 0x10, 0xf8, 0x01, 0x12, 0x0a, 0x0a, 0x05, 0x46, 0x6c, 0x6f, 0x61, 0x74, 0x10, 0xf9, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x6b, 0x69, 0x74, 0x10, 0xfa, 0x01, - 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x6f, 0x6d, 0x61, 0x74, 0x10, 0xfb, - 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x62, 0x6c, 0x69, 0x6e, 0x6b, 0x10, - 0xfc, 0x01, 0x12, 0x0a, 0x0a, 0x05, 0x42, 0x6f, 0x72, 0x65, 0x64, 0x10, 0xfd, 0x01, 0x12, 0x0c, - 0x0a, 0x07, 0x43, 0x61, 0x6d, 0x70, 0x61, 0x79, 0x6e, 0x10, 0xfe, 0x01, 0x12, 0x0e, 0x0a, 0x09, - 0x43, 0x6c, 0x69, 0x6e, 0x63, 0x68, 0x70, 0x61, 0x64, 0x10, 0xff, 0x01, 0x12, 0x0f, 0x0a, 0x0a, - 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x48, 0x75, 0x62, 0x10, 0x80, 0x02, 0x12, 0x0d, 0x0a, - 0x08, 0x44, 0x65, 0x62, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x10, 0x81, 0x02, 0x12, 0x0d, 0x0a, 0x08, - 0x44, 0x79, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x10, 0x82, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x47, - 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x70, 0x69, 0x10, 0x83, 0x02, 0x12, 0x0c, 0x0a, - 0x07, 0x48, 0x61, 0x72, 0x76, 0x65, 0x73, 0x74, 0x10, 0x84, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4d, - 0x6f, 0x6f, 0x73, 0x65, 0x6e, 0x64, 0x10, 0x85, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x4f, 0x70, 0x65, - 0x6e, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x10, 0x86, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x53, - 0x69, 0x74, 0x65, 0x6c, 0x65, 0x61, 0x66, 0x10, 0x87, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x71, - 0x75, 0x61, 0x72, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x10, 0x88, 0x02, 0x12, 0x0c, 0x0a, 0x07, - 0x46, 0x6c, 0x6f, 0x77, 0x46, 0x6c, 0x75, 0x10, 0x89, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x4e, 0x69, - 0x6d, 0x62, 0x6c, 0x65, 0x10, 0x8a, 0x02, 0x12, 0x14, 0x0a, 0x0f, 0x4c, 0x65, 0x73, 0x73, 0x41, - 0x6e, 0x6e, 0x6f, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x52, 0x4d, 0x10, 0x8b, 0x02, 0x12, 0x0c, 0x0a, - 0x07, 0x4e, 0x65, 0x74, 0x68, 0x75, 0x6e, 0x74, 0x10, 0x8c, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x41, - 0x70, 0x70, 0x74, 0x69, 0x76, 0x6f, 0x10, 0x8d, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x61, 0x70, - 0x73, 0x75, 0x6c, 0x65, 0x43, 0x52, 0x4d, 0x10, 0x8e, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x49, 0x6e, - 0x73, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x79, 0x10, 0x8f, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x4b, 0x79, - 0x6c, 0x61, 0x73, 0x10, 0x90, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x4f, 0x6e, 0x65, 0x70, 0x61, 0x67, - 0x65, 0x43, 0x52, 0x4d, 0x10, 0x91, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x55, 0x73, 0x65, 0x72, 0x10, - 0x92, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x73, 0x70, 0x65, 0x63, 0x74, 0x43, 0x52, - 0x4d, 0x10, 0x93, 0x02, 0x12, 0x18, 0x0a, 0x13, 0x52, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x53, 0x69, - 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x10, 0x94, 0x02, 0x12, 0x0c, - 0x0a, 0x07, 0x41, 0x69, 0x72, 0x73, 0x68, 0x69, 0x70, 0x10, 0x95, 0x02, 0x12, 0x0a, 0x0a, 0x05, - 0x41, 0x72, 0x74, 0x73, 0x79, 0x10, 0x96, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x59, 0x61, 0x6e, 0x64, - 0x65, 0x78, 0x10, 0x97, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x6c, 0x6f, 0x63, 0x6b, 0x69, 0x66, - 0x79, 0x10, 0x98, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x6e, 0x73, 0x63, 0x68, 0x65, 0x63, 0x6b, - 0x10, 0x99, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x45, 0x61, 0x73, 0x79, 0x49, 0x6e, 0x73, 0x69, 0x67, - 0x68, 0x74, 0x10, 0x9a, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x74, 0x68, 0x70, 0x6c, 0x6f, 0x72, - 0x65, 0x72, 0x10, 0x9b, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x45, 0x76, 0x65, 0x72, 0x68, 0x6f, 0x75, - 0x72, 0x10, 0x9c, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x75, 0x6c, 0x63, 0x72, 0x75, 0x6d, 0x10, - 0x9d, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x65, 0x6f, 0x49, 0x70, 0x69, 0x66, 0x69, 0x10, 0x9e, - 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4a, 0x6f, 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x10, 0x9f, 0x02, 0x12, - 0x0c, 0x0a, 0x07, 0x52, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x72, 0x10, 0xa0, 0x02, 0x12, 0x10, 0x0a, - 0x0b, 0x54, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x61, 0x70, 0x69, 0x10, 0xa1, 0x02, 0x12, - 0x0f, 0x0a, 0x0a, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x6b, 0x10, 0xa2, 0x02, - 0x12, 0x0b, 0x0a, 0x06, 0x56, 0x70, 0x6e, 0x61, 0x70, 0x69, 0x10, 0xa3, 0x02, 0x12, 0x0e, 0x0a, - 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xa4, 0x02, 0x12, 0x0b, 0x0a, - 0x06, 0x41, 0x70, 0x6f, 0x6c, 0x6c, 0x6f, 0x10, 0xa5, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x45, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x67, 0x6e, 0x10, 0xa6, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x4a, 0x75, 0x72, - 0x6f, 0x10, 0xa7, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x4b, 0x61, 0x72, 0x6d, 0x61, 0x43, 0x52, 0x4d, - 0x10, 0xa8, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x6c, 0x6f, 0x10, 0xa9, - 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x6e, 0x64, 0x61, 0x64, 0x6f, 0x63, 0x10, 0xaa, 0x02, - 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x61, 0x6d, 0x70, 0x43, 0x52, 0x4d, 0x10, 0xab, 0x02, - 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x10, - 0xac, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x6c, 0x63, 0x6f, 0x6e, 0x6f, 0x73, 0x74, 0x10, 0xad, - 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x72, 0x10, 0xae, 0x02, 0x12, - 0x10, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x75, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x10, 0xaf, - 0x02, 0x12, 0x13, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x6e, 0x67, 0x72, 0x61, 0x70, 0x68, 0x72, 0x10, - 0xb0, 0x02, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x61, 0x77, 0x67, 0x10, 0xb1, - 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x69, 0x6f, 0x74, 0x67, 0x61, 0x6d, 0x65, 0x73, 0x10, 0xb2, - 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x6f, 0x6e, 0x69, 0x6e, 0x41, 0x70, 0x70, 0x10, 0xb3, 0x02, - 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x72, 0x6d, 0x67, 0x6c, 0x61, 0x73, 0x73, 0x10, 0xb4, - 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x6f, 0x6d, 0x74, 0x6f, 0x6d, 0x10, 0xb5, 0x02, 0x12, 0x0b, - 0x0a, 0x06, 0x54, 0x77, 0x69, 0x74, 0x63, 0x68, 0x10, 0xb6, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x44, - 0x6f, 0x63, 0x75, 0x6d, 0x6f, 0x10, 0xb7, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x77, 0x61, 0x79, 0x73, 0x10, 0xb8, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x56, 0x65, 0x65, 0x76, - 0x61, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x10, 0xb9, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x4b, 0x69, 0x74, - 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, 0xba, 0x02, 0x12, 0x17, 0x0a, 0x12, 0x53, - 0x68, 0x6f, 0x70, 0x65, 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x50, 0x6c, 0x61, 0x74, 0x66, 0x6f, 0x72, - 0x6d, 0x10, 0xbb, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x54, 0x65, 0x61, 0x6d, 0x56, 0x69, 0x65, 0x77, - 0x65, 0x72, 0x10, 0xbc, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x75, 0x6c, 0x62, 0x75, 0x6c, 0x10, - 0xbd, 0x02, 0x12, 0x16, 0x0a, 0x11, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x53, 0x74, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x52, 0x4d, 0x10, 0xbe, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x54, 0x65, - 0x61, 0x6d, 0x67, 0x61, 0x74, 0x65, 0x10, 0xbf, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x41, 0x78, 0x6f, - 0x6e, 0x61, 0x75, 0x74, 0x10, 0xc0, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x79, 0x6e, 0x74, 0x65, - 0x63, 0x10, 0xc1, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x63, 0x75, 0x65, 0x73, 0x10, - 0xc2, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x6f, 0x6b, 0x6c, 0x6f, 0x73, 0x65, 0x10, - 0xc3, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x70, 0x6c, 0x61, 0x6e, 0x10, - 0xc4, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x6f, 0x74, 0x6d, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x10, - 0xc5, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x10, 0xc6, - 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x73, 0x10, 0xc7, - 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4b, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x10, 0xc8, 0x02, 0x12, - 0x0f, 0x0a, 0x0a, 0x4c, 0x65, 0x61, 0x64, 0x66, 0x65, 0x65, 0x64, 0x65, 0x72, 0x10, 0xc9, 0x02, - 0x12, 0x0a, 0x0a, 0x05, 0x52, 0x61, 0x76, 0x65, 0x6e, 0x10, 0xca, 0x02, 0x12, 0x10, 0x0a, 0x0b, - 0x52, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x61, 0x63, 0x68, 0x10, 0xcb, 0x02, 0x12, 0x0b, - 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x65, 0x61, 0x64, 0x10, 0xcc, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x42, - 0x72, 0x61, 0x6e, 0x64, 0x66, 0x65, 0x74, 0x63, 0x68, 0x10, 0xcd, 0x02, 0x12, 0x0d, 0x0a, 0x08, - 0x43, 0x6c, 0x65, 0x61, 0x72, 0x62, 0x69, 0x74, 0x10, 0xce, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x43, - 0x72, 0x6f, 0x77, 0x64, 0x69, 0x6e, 0x10, 0xcf, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x4d, 0x61, 0x70, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xd0, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x4e, 0x6f, 0x74, 0x69, - 0x63, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x10, 0xd1, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x4f, 0x6e, 0x62, - 0x75, 0x6b, 0x61, 0x10, 0xd2, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x6f, 0x64, 0x6f, 0x69, 0x73, - 0x74, 0x10, 0xd3, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x72, 0x79, 0x63, 0x68, 0x69, - 0x65, 0x66, 0x10, 0xd4, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x4c, 0x69, 0x6e, 0x6b, 0x65, 0x64, 0x49, - 0x6e, 0x10, 0xd5, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x59, 0x6f, 0x75, 0x53, 0x69, 0x67, 0x6e, 0x10, - 0xd6, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x10, 0xd7, 0x02, 0x12, - 0x0d, 0x0a, 0x08, 0x54, 0x65, 0x6c, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x10, 0xd8, 0x02, 0x12, 0x10, - 0x0a, 0x0b, 0x53, 0x70, 0x6f, 0x6f, 0x6e, 0x61, 0x63, 0x75, 0x6c, 0x61, 0x72, 0x10, 0xd9, 0x02, - 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x65, 0x72, 0x69, 0x73, 0x77, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, - 0x10, 0xda, 0x02, 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x6c, 0x70, 0x68, 0x61, 0x76, 0x61, 0x6e, 0x74, - 0x61, 0x67, 0x65, 0x10, 0xdb, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x6d, 0x67, 0x75, 0x72, 0x10, - 0xdc, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x6d, 0x61, 0x67, 0x67, 0x61, 0x10, 0xdd, 0x02, 0x12, - 0x0b, 0x0a, 0x06, 0x53, 0x4d, 0x53, 0x41, 0x70, 0x69, 0x10, 0xde, 0x02, 0x12, 0x11, 0x0a, 0x0c, - 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0xdf, 0x02, 0x12, - 0x12, 0x0a, 0x09, 0x42, 0x6c, 0x61, 0x62, 0x6c, 0x61, 0x62, 0x75, 0x73, 0x10, 0xe0, 0x02, 0x1a, - 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x64, 0x73, 0x41, 0x70, 0x69, 0x10, - 0xe1, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x6c, 0x61, - 0x79, 0x65, 0x72, 0x10, 0xe2, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x74, 0x6d, 0x6c, 0x32, 0x50, - 0x64, 0x66, 0x10, 0xe3, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x49, 0x50, 0x47, 0x65, 0x6f, 0x6c, 0x6f, - 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0xe4, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x4f, 0x77, 0x6c, - 0x62, 0x6f, 0x74, 0x10, 0xe5, 0x02, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x6d, - 0x65, 0x72, 0x73, 0x69, 0x76, 0x65, 0x10, 0xe6, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x79, 0x6e, - 0x61, 0x6c, 0x69, 0x73, 0x74, 0x10, 0xe7, 0x02, 0x12, 0x14, 0x0a, 0x0f, 0x45, 0x78, 0x63, 0x68, - 0x61, 0x6e, 0x67, 0x65, 0x52, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x10, 0xe8, 0x02, 0x12, 0x0f, - 0x0a, 0x0a, 0x48, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x41, 0x50, 0x49, 0x10, 0xe9, 0x02, 0x12, - 0x0a, 0x0a, 0x05, 0x49, 0x70, 0x61, 0x70, 0x69, 0x10, 0xea, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x4d, - 0x61, 0x72, 0x6b, 0x65, 0x74, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xeb, 0x02, 0x12, 0x10, 0x0a, - 0x0b, 0x4e, 0x75, 0x74, 0x72, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x78, 0x10, 0xec, 0x02, 0x12, - 0x0a, 0x0a, 0x05, 0x53, 0x77, 0x65, 0x6c, 0x6c, 0x10, 0xed, 0x02, 0x12, 0x19, 0x0a, 0x14, 0x43, - 0x6c, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, - 0x6b, 0x65, 0x6e, 0x10, 0xee, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x4e, 0x69, 0x74, 0x72, 0x6f, 0x10, - 0xef, 0x02, 0x12, 0x08, 0x0a, 0x03, 0x52, 0x65, 0x76, 0x10, 0xf0, 0x02, 0x12, 0x0d, 0x0a, 0x08, - 0x52, 0x75, 0x6e, 0x52, 0x75, 0x6e, 0x49, 0x74, 0x10, 0xf1, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x54, - 0x79, 0x70, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x10, 0xf2, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x4d, 0x69, - 0x78, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x10, 0xf3, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x72, 0x61, - 0x64, 0x69, 0x65, 0x72, 0x10, 0xf4, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x56, 0x65, 0x72, 0x69, 0x66, - 0x69, 0x65, 0x72, 0x10, 0xf5, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x56, 0x6f, 0x75, 0x63, 0x68, 0x65, - 0x72, 0x79, 0x10, 0xf6, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x41, 0x6c, 0x65, 0x67, 0x72, 0x61, 0x10, - 0xf7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x41, 0x75, 0x64, 0x64, 0x10, 0xf8, 0x02, 0x12, 0x10, 0x0a, - 0x0b, 0x42, 0x61, 0x72, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x10, 0xf9, 0x02, 0x12, - 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x69, 0x6e, 0x6c, 0x69, 0x62, 0x10, 0xfa, 0x02, 0x12, 0x15, 0x0a, - 0x10, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x61, 0x74, 0x65, 0x73, 0x41, 0x50, - 0x49, 0x10, 0xfb, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, - 0x53, 0x63, 0x6f, 0x6f, 0x70, 0x10, 0xfc, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x58, 0x4d, 0x61, - 0x72, 0x6b, 0x65, 0x74, 0x10, 0xfd, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x75, 0x72, 0x72, 0x65, - 0x6e, 0x63, 0x79, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xfe, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x47, - 0x65, 0x74, 0x47, 0x65, 0x6f, 0x41, 0x50, 0x49, 0x10, 0xff, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x41, - 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x10, 0x80, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x69, - 0x6c, 0x6c, 0x6f, 0x6d, 0x61, 0x74, 0x10, 0x81, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x6f, 0x76, - 0x69, 0x63, 0x6f, 0x10, 0x82, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x69, 0x74, 0x62, 0x61, 0x72, - 0x10, 0x83, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x75, 0x67, 0x73, 0x6e, 0x61, 0x67, 0x10, 0x84, - 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, 0x79, 0x41, 0x49, 0x10, - 0x85, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x64, 0x61, 0x66, 0x72, 0x75, 0x69, 0x74, 0x49, 0x4f, - 0x10, 0x86, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x70, 0x69, 0x66, 0x79, 0x10, 0x87, 0x03, 0x12, - 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x69, 0x6e, 0x47, 0x65, 0x63, 0x6b, 0x6f, 0x10, 0x88, 0x03, 0x12, - 0x12, 0x0a, 0x0d, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x72, 0x65, - 0x10, 0x89, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x75, 0x6c, 0x6c, 0x73, 0x74, 0x6f, 0x72, 0x79, - 0x10, 0x8a, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x53, 0x69, 0x67, 0x6e, - 0x10, 0x8b, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x4c, 0x6f, 0x79, 0x76, 0x65, 0x72, 0x73, 0x65, 0x10, - 0x8c, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x43, 0x6f, 0x72, 0x65, 0x10, 0x8d, 0x03, - 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x61, 0x75, 0x63, 0x65, 0x4c, 0x61, 0x62, 0x73, 0x10, 0x8e, 0x03, - 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x6c, 0x69, 0x65, 0x6e, 0x56, 0x61, 0x75, 0x6c, 0x74, 0x10, 0x8f, - 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x70, 0x69, 0x66, 0x6c, 0x61, 0x73, 0x68, 0x10, 0x91, 0x03, - 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x69, 0x6e, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x10, 0x92, 0x03, - 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x41, 0x50, 0x49, 0x10, - 0x93, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x61, 0x74, 0x61, 0x47, 0x6f, 0x76, 0x10, 0x94, 0x03, - 0x12, 0x0b, 0x0a, 0x06, 0x45, 0x6e, 0x69, 0x67, 0x6d, 0x61, 0x10, 0x95, 0x03, 0x12, 0x1a, 0x0a, - 0x15, 0x46, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x6c, 0x4d, 0x6f, 0x64, 0x65, 0x6c, 0x69, - 0x6e, 0x67, 0x50, 0x72, 0x65, 0x70, 0x10, 0x96, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x65, 0x6f, - 0x63, 0x6f, 0x64, 0x69, 0x6f, 0x10, 0x97, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x48, 0x65, 0x72, 0x65, - 0x41, 0x50, 0x49, 0x10, 0x98, 0x03, 0x12, 0x13, 0x0a, 0x0a, 0x4d, 0x61, 0x63, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x10, 0x99, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0c, 0x0a, 0x07, 0x4f, - 0x4f, 0x50, 0x53, 0x70, 0x61, 0x6d, 0x10, 0x9a, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x50, 0x72, 0x6f, - 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x49, 0x4f, 0x10, 0x9b, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x53, - 0x63, 0x72, 0x61, 0x70, 0x65, 0x72, 0x41, 0x50, 0x49, 0x10, 0x9c, 0x03, 0x12, 0x13, 0x0a, 0x0e, - 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x72, 0x61, 0x69, 0x6c, 0x73, 0x10, 0x9d, - 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x54, 0x6f, 0x6d, 0x6f, 0x72, 0x72, 0x6f, 0x77, 0x49, 0x4f, 0x10, - 0x9e, 0x03, 0x12, 0x13, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x43, 0x6f, 0x69, 0x6e, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x10, 0x9f, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x46, 0x61, 0x63, 0x65, 0x50, - 0x6c, 0x75, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x10, 0xa0, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x56, 0x6f, - 0x69, 0x63, 0x65, 0x67, 0x61, 0x69, 0x6e, 0x10, 0xa1, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x65, - 0x65, 0x70, 0x67, 0x72, 0x61, 0x6d, 0x10, 0xa2, 0x03, 0x12, 0x13, 0x0a, 0x0e, 0x56, 0x69, 0x73, - 0x75, 0x61, 0x6c, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x10, 0xa3, 0x03, 0x12, 0x0c, - 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x6e, 0x68, 0x75, 0x62, 0x10, 0xa4, 0x03, 0x12, 0x0b, 0x0a, 0x06, - 0x54, 0x69, 0x69, 0x6e, 0x67, 0x6f, 0x10, 0xa5, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x52, 0x69, 0x6e, - 0x67, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x10, 0xa6, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x46, - 0x69, 0x6e, 0x61, 0x67, 0x65, 0x10, 0xa7, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x45, 0x64, 0x61, 0x6d, - 0x61, 0x6d, 0x10, 0xa8, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x48, 0x79, 0x70, 0x65, 0x41, 0x75, 0x64, - 0x69, 0x74, 0x6f, 0x72, 0x10, 0xa9, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x47, 0x65, 0x6e, 0x67, 0x6f, - 0x10, 0xaa, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x46, 0x72, 0x6f, 0x6e, 0x74, 0x10, 0xab, 0x03, 0x12, - 0x0e, 0x0a, 0x09, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x62, 0x61, 0x73, 0x65, 0x10, 0xac, 0x03, 0x12, - 0x0b, 0x0a, 0x06, 0x42, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x10, 0xad, 0x03, 0x12, 0x0f, 0x0a, 0x0a, - 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x62, 0x65, 0x61, 0x72, 0x10, 0xae, 0x03, 0x12, 0x0b, 0x0a, - 0x06, 0x41, 0x64, 0x7a, 0x75, 0x6e, 0x61, 0x10, 0xaf, 0x03, 0x12, 0x13, 0x0a, 0x0e, 0x42, 0x69, - 0x74, 0x63, 0x6f, 0x69, 0x6e, 0x41, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, 0x10, 0xb0, 0x03, 0x12, - 0x0f, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x65, 0x4a, 0x53, 0x10, 0xb1, 0x03, - 0x12, 0x13, 0x0a, 0x0e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, - 0x67, 0x65, 0x10, 0xb2, 0x03, 0x12, 0x11, 0x0a, 0x08, 0x46, 0x61, 0x6b, 0x65, 0x4a, 0x53, 0x4f, - 0x4e, 0x10, 0xb3, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x47, 0x72, 0x61, 0x70, - 0x68, 0x68, 0x6f, 0x70, 0x70, 0x65, 0x72, 0x10, 0xb4, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x4c, 0x65, - 0x78, 0x69, 0x67, 0x72, 0x61, 0x6d, 0x10, 0xb5, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x4c, 0x69, 0x6e, - 0x6b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x10, 0xb6, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x4e, - 0x75, 0x6d, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x10, 0xb7, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x50, - 0x72, 0x6f, 0x78, 0x79, 0x43, 0x72, 0x61, 0x77, 0x6c, 0x10, 0xb8, 0x03, 0x12, 0x0f, 0x0a, 0x0a, - 0x5a, 0x69, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x41, 0x50, 0x49, 0x10, 0xb9, 0x03, 0x12, 0x0e, 0x0a, - 0x09, 0x43, 0x6f, 0x6d, 0x65, 0x74, 0x63, 0x68, 0x61, 0x74, 0x10, 0xba, 0x03, 0x12, 0x0b, 0x0a, - 0x06, 0x4b, 0x65, 0x79, 0x67, 0x65, 0x6e, 0x10, 0xbb, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x4d, 0x69, - 0x78, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xbc, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x61, 0x74, - 0x75, 0x6d, 0x49, 0x4f, 0x10, 0xbd, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x6d, 0x65, 0x74, 0x72, - 0x69, 0x63, 0x10, 0xbe, 0x03, 0x12, 0x0f, 0x0a, 0x06, 0x4c, 0x61, 0x73, 0x74, 0x66, 0x6d, 0x10, - 0xbf, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x68, - 0x6f, 0x74, 0x10, 0xc0, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x4a, 0x53, 0x4f, 0x4e, 0x62, 0x69, 0x6e, - 0x10, 0xc1, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x4c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x49, - 0x51, 0x10, 0xc2, 0x03, 0x12, 0x12, 0x0a, 0x0d, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, - 0x6f, 0x74, 0x41, 0x50, 0x49, 0x10, 0xc3, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x57, 0x65, 0x61, 0x74, - 0x68, 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xc4, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x41, - 0x6d, 0x61, 0x64, 0x65, 0x75, 0x73, 0x10, 0xc5, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x46, 0x6f, 0x75, - 0x72, 0x53, 0x71, 0x75, 0x61, 0x72, 0x65, 0x10, 0xc6, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x46, 0x6c, - 0x69, 0x63, 0x6b, 0x72, 0x10, 0xc7, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x63, 0x6b, - 0x48, 0x65, 0x6c, 0x70, 0x10, 0xc8, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x6d, 0x62, 0x65, 0x65, - 0x10, 0xc9, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x70, 0x69, 0x32, 0x43, 0x61, 0x72, 0x74, 0x10, - 0xca, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x48, 0x79, 0x70, 0x65, 0x72, 0x74, 0x72, 0x61, 0x63, 0x6b, - 0x10, 0xcb, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x4b, 0x61, 0x6b, 0x61, 0x6f, 0x54, 0x61, 0x6c, 0x6b, - 0x10, 0xcc, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x69, 0x74, 0x65, 0x4b, 0x69, 0x74, 0x10, 0xcd, - 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x68, 0x75, 0x74, 0x74, 0x65, 0x72, 0x73, 0x74, 0x6f, 0x63, - 0x6b, 0x10, 0xce, 0x03, 0x12, 0x12, 0x0a, 0x09, 0x54, 0x65, 0x78, 0x74, 0x32, 0x44, 0x61, 0x74, - 0x61, 0x10, 0xcf, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x13, 0x0a, 0x0e, 0x59, 0x6f, 0x75, 0x4e, - 0x65, 0x65, 0x64, 0x41, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x10, 0xd0, 0x03, 0x12, 0x0c, 0x0a, - 0x07, 0x43, 0x72, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x10, 0xd1, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x46, - 0x69, 0x6c, 0x65, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xd2, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x47, - 0x79, 0x61, 0x7a, 0x6f, 0x10, 0xd3, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x4d, 0x61, 0x76, 0x65, 0x6e, - 0x6c, 0x69, 0x6e, 0x6b, 0x10, 0xd4, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x68, 0x65, 0x65, 0x74, - 0x79, 0x10, 0xd5, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x70, 0x6f, 0x72, 0x74, 0x73, 0x6d, 0x6f, - 0x6e, 0x6b, 0x10, 0xd6, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x74, 0x6f, 0x63, 0x6b, 0x64, 0x61, - 0x74, 0x61, 0x10, 0xd7, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x55, 0x6e, 0x73, 0x70, 0x6c, 0x61, 0x73, - 0x68, 0x10, 0xd8, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x6c, 0x6c, 0x73, 0x70, 0x6f, 0x72, 0x74, - 0x73, 0x10, 0xd9, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6f, 0x72, 0x69, 0x65, 0x4e, - 0x69, 0x6e, 0x6a, 0x61, 0x10, 0xda, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x57, 0x61, 0x6c, 0x6b, 0x53, - 0x63, 0x6f, 0x72, 0x65, 0x10, 0xdb, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x61, 0x76, - 0x61, 0x10, 0xdc, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x69, 0x63, 0x65, 0x72, 0x6f, 0x10, 0xdd, - 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x49, 0x50, 0x51, 0x75, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x10, 0xde, - 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, 0x6c, 0x44, 0x6f, 0x74, - 0x73, 0x10, 0xdf, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x6f, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x10, - 0xe0, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x61, 0x69, 0x6c, 0x73, 0x61, 0x63, 0x10, 0xe1, 0x03, - 0x12, 0x0a, 0x0a, 0x05, 0x57, 0x68, 0x6f, 0x78, 0x79, 0x10, 0xe2, 0x03, 0x12, 0x11, 0x0a, 0x0c, - 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x10, 0xe3, 0x03, 0x12, - 0x0e, 0x0a, 0x09, 0x41, 0x70, 0x69, 0x46, 0x6f, 0x6e, 0x69, 0x63, 0x61, 0x10, 0xe4, 0x03, 0x12, - 0x0b, 0x0a, 0x06, 0x41, 0x79, 0x6c, 0x69, 0x65, 0x6e, 0x10, 0xe5, 0x03, 0x12, 0x0c, 0x0a, 0x07, - 0x47, 0x65, 0x6f, 0x63, 0x6f, 0x64, 0x65, 0x10, 0xe6, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x49, 0x63, - 0x6f, 0x6e, 0x46, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x10, 0xe7, 0x03, 0x12, 0x0e, 0x0a, 0x05, 0x49, - 0x70, 0x69, 0x66, 0x79, 0x10, 0xe8, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x12, 0x0a, 0x0d, 0x4c, - 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x10, 0xe9, 0x03, 0x12, - 0x08, 0x0a, 0x03, 0x4c, 0x6f, 0x62, 0x10, 0xea, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x4f, 0x6e, 0x57, - 0x61, 0x74, 0x65, 0x72, 0x49, 0x4f, 0x10, 0xeb, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x73, - 0x74, 0x65, 0x62, 0x69, 0x6e, 0x10, 0xec, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x64, 0x66, 0x4c, - 0x61, 0x79, 0x65, 0x72, 0x10, 0xed, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x69, 0x78, 0x61, 0x62, - 0x61, 0x79, 0x10, 0xee, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x52, 0x65, 0x61, 0x64, 0x4d, 0x65, 0x10, - 0xef, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x56, 0x61, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x10, 0xf0, - 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x56, 0x69, 0x72, 0x75, 0x73, 0x54, 0x6f, 0x74, 0x61, 0x6c, 0x10, - 0xf1, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x69, 0x72, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6c, 0x10, - 0xf2, 0x03, 0x12, 0x13, 0x0a, 0x0e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x66, 0x72, - 0x65, 0x61, 0x6b, 0x73, 0x10, 0xf3, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x75, 0x66, 0x66, 0x65, - 0x6c, 0x10, 0xf4, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x46, 0x6c, 0x61, 0x74, 0x49, 0x4f, 0x10, 0xf5, - 0x03, 0x12, 0x08, 0x0a, 0x03, 0x4d, 0x33, 0x6f, 0x10, 0xf6, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x4d, - 0x65, 0x73, 0x69, 0x62, 0x6f, 0x10, 0xf7, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x4f, 0x70, 0x65, 0x6e, - 0x75, 0x76, 0x10, 0xf8, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x6e, 0x69, 0x70, 0x63, 0x61, 0x72, - 0x74, 0x10, 0xf9, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x65, 0x73, 0x74, 0x74, 0x69, 0x6d, 0x65, - 0x10, 0xfa, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x48, 0x61, 0x70, 0x70, 0x79, 0x73, 0x63, 0x72, 0x69, - 0x62, 0x65, 0x10, 0xfb, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x75, 0x6d, 0x61, 0x6e, 0x69, 0x74, - 0x79, 0x10, 0xfc, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x6d, 0x70, 0x61, 0x6c, 0x61, 0x10, 0xfd, - 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x72, 0x61, 0x64, 0x69, 0x75, 0x73, - 0x10, 0xfe, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x6f, 0x50, 0x69, 0x6c, 0x6f, 0x74, - 0x10, 0xff, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x69, 0x74, 0x6d, 0x65, 0x78, 0x10, 0x80, 0x04, - 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x63, 0x10, 0x81, 0x04, 0x12, - 0x0c, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x72, 0x69, 0x10, 0x82, 0x04, 0x12, 0x0d, 0x0a, - 0x08, 0x50, 0x64, 0x66, 0x53, 0x68, 0x69, 0x66, 0x74, 0x10, 0x83, 0x04, 0x12, 0x0d, 0x0a, 0x08, - 0x50, 0x6f, 0x6c, 0x6f, 0x6e, 0x69, 0x65, 0x78, 0x10, 0x84, 0x04, 0x12, 0x19, 0x0a, 0x14, 0x52, - 0x65, 0x73, 0x74, 0x70, 0x61, 0x63, 0x6b, 0x48, 0x74, 0x6d, 0x6c, 0x54, 0x6f, 0x50, 0x64, 0x66, - 0x41, 0x50, 0x49, 0x10, 0x85, 0x04, 0x12, 0x1a, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x74, 0x70, 0x61, - 0x63, 0x6b, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x41, 0x50, 0x49, 0x10, - 0x86, 0x04, 0x12, 0x16, 0x0a, 0x11, 0x53, 0x68, 0x75, 0x74, 0x74, 0x65, 0x72, 0x73, 0x74, 0x6f, - 0x63, 0x6b, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x10, 0x87, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x6b, - 0x79, 0x42, 0x69, 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x10, 0x88, 0x04, 0x12, 0x0e, 0x0a, 0x09, - 0x41, 0x62, 0x75, 0x73, 0x65, 0x49, 0x50, 0x44, 0x42, 0x10, 0x89, 0x04, 0x12, 0x10, 0x0a, 0x0b, - 0x41, 0x6c, 0x65, 0x74, 0x68, 0x65, 0x69, 0x61, 0x41, 0x70, 0x69, 0x10, 0x8a, 0x04, 0x12, 0x0c, - 0x0a, 0x07, 0x42, 0x6c, 0x69, 0x74, 0x41, 0x70, 0x70, 0x10, 0x8b, 0x04, 0x12, 0x0b, 0x0a, 0x06, - 0x43, 0x65, 0x6e, 0x73, 0x79, 0x73, 0x10, 0x8c, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x6c, 0x6f, - 0x76, 0x65, 0x72, 0x6c, 0x79, 0x10, 0x8d, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, - 0x74, 0x72, 0x79, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x10, 0x8e, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x46, - 0x69, 0x6c, 0x65, 0x49, 0x4f, 0x10, 0x8f, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x6c, 0x69, 0x67, - 0x68, 0x74, 0x41, 0x70, 0x69, 0x10, 0x90, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x65, 0x6f, 0x61, - 0x70, 0x69, 0x66, 0x79, 0x10, 0x91, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x50, 0x69, 0x6e, 0x66, - 0x6f, 0x44, 0x42, 0x10, 0x92, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x4d, 0x65, 0x64, 0x69, 0x61, 0x53, - 0x74, 0x61, 0x63, 0x6b, 0x10, 0x93, 0x04, 0x12, 0x13, 0x0a, 0x0e, 0x4e, 0x61, 0x73, 0x64, 0x61, - 0x71, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x94, 0x04, 0x12, 0x11, 0x0a, 0x0c, - 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, 0x10, 0x95, 0x04, 0x12, - 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x79, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x10, 0x96, 0x04, 0x12, 0x12, - 0x0a, 0x0d, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, - 0x97, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x6c, 0x79, 0x10, - 0x98, 0x04, 0x12, 0x14, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, - 0x4c, 0x61, 0x79, 0x65, 0x72, 0x10, 0x99, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x74, 0x79, 0x74, - 0x63, 0x68, 0x10, 0x9a, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x55, 0x6e, 0x70, 0x6c, 0x75, 0x67, 0x67, - 0x10, 0x9b, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x55, 0x50, 0x43, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, - 0x73, 0x65, 0x10, 0x9c, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x55, 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x10, 0x9d, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x47, 0x65, 0x6f, 0x63, 0x6f, 0x64, 0x69, - 0x66, 0x79, 0x10, 0x9e, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x65, 0x77, 0x73, 0x63, 0x61, 0x74, - 0x63, 0x68, 0x65, 0x72, 0x10, 0x9f, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x4e, 0x69, 0x63, 0x65, 0x72, - 0x65, 0x70, 0x6c, 0x79, 0x10, 0xa0, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x50, 0x61, 0x72, 0x74, 0x6e, - 0x65, 0x72, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xa1, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x6f, - 0x75, 0x74, 0x65, 0x34, 0x6d, 0x65, 0x10, 0xa2, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x63, 0x72, - 0x61, 0x70, 0x65, 0x6f, 0x77, 0x6c, 0x10, 0xa3, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x63, 0x72, - 0x61, 0x70, 0x69, 0x6e, 0x67, 0x44, 0x6f, 0x67, 0x10, 0xa4, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x53, - 0x74, 0x72, 0x65, 0x61, 0x6b, 0x10, 0xa5, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x56, 0x65, 0x72, 0x69, - 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x10, 0xa6, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x57, 0x65, 0x62, 0x73, - 0x63, 0x72, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x10, 0xa7, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x5a, 0x65, - 0x6e, 0x73, 0x63, 0x72, 0x61, 0x70, 0x65, 0x10, 0xa8, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x5a, 0x65, - 0x6e, 0x73, 0x65, 0x72, 0x70, 0x10, 0xa9, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x69, 0x6e, - 0x41, 0x70, 0x69, 0x10, 0xaa, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x47, 0x69, 0x74, 0x74, 0x65, 0x72, - 0x10, 0xab, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x10, 0xac, 0x04, 0x12, 0x0d, - 0x0a, 0x08, 0x49, 0x65, 0x78, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xad, 0x04, 0x12, 0x0d, 0x0a, - 0x08, 0x52, 0x65, 0x73, 0x74, 0x70, 0x61, 0x63, 0x6b, 0x10, 0xae, 0x04, 0x12, 0x0f, 0x0a, 0x0a, - 0x53, 0x63, 0x72, 0x61, 0x70, 0x65, 0x72, 0x42, 0x6f, 0x78, 0x10, 0xaf, 0x04, 0x12, 0x10, 0x0a, - 0x0b, 0x53, 0x63, 0x72, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x74, 0x10, 0xb0, 0x04, 0x12, - 0x0e, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x70, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xb1, 0x04, 0x12, - 0x12, 0x0a, 0x0d, 0x53, 0x6d, 0x61, 0x72, 0x74, 0x79, 0x53, 0x74, 0x72, 0x65, 0x65, 0x74, 0x73, - 0x10, 0xb2, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x4d, 0x61, 0x73, - 0x74, 0x65, 0x72, 0x10, 0xb3, 0x04, 0x12, 0x12, 0x0a, 0x0d, 0x41, 0x76, 0x69, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xb4, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x6f, - 0x6d, 0x62, 0x42, 0x6f, 0x6d, 0x62, 0x10, 0xb5, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, - 0x6d, 0x6f, 0x64, 0x69, 0x74, 0x69, 0x65, 0x73, 0x10, 0xb6, 0x04, 0x12, 0x0a, 0x0a, 0x05, 0x44, - 0x66, 0x75, 0x73, 0x65, 0x10, 0xb7, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x45, 0x64, 0x65, 0x6e, 0x41, - 0x49, 0x10, 0xb8, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x47, 0x6c, 0x61, 0x73, 0x73, 0x6e, 0x6f, 0x64, - 0x65, 0x10, 0xb9, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x47, 0x75, 0x72, 0x75, 0x10, 0xba, 0x04, 0x12, - 0x09, 0x0a, 0x04, 0x48, 0x69, 0x76, 0x65, 0x10, 0xbb, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x48, 0x69, - 0x76, 0x65, 0x61, 0x67, 0x65, 0x10, 0xbc, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x4b, 0x69, 0x63, 0x6b, - 0x62, 0x6f, 0x78, 0x10, 0xbd, 0x04, 0x12, 0x11, 0x0a, 0x08, 0x50, 0x61, 0x73, 0x73, 0x62, 0x61, - 0x73, 0x65, 0x10, 0xbe, 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x50, 0x6f, 0x73, - 0x74, 0x61, 0x67, 0x65, 0x41, 0x70, 0x70, 0x10, 0xbf, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x50, 0x75, - 0x72, 0x65, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x10, 0xc0, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x51, 0x75, - 0x62, 0x6f, 0x6c, 0x65, 0x10, 0xc1, 0x04, 0x12, 0x14, 0x0a, 0x0f, 0x43, 0x61, 0x72, 0x62, 0x6f, - 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x10, 0xc2, 0x04, 0x12, 0x0d, 0x0a, - 0x08, 0x49, 0x6e, 0x74, 0x72, 0x69, 0x6e, 0x69, 0x6f, 0x10, 0xc3, 0x04, 0x12, 0x15, 0x0a, 0x0c, - 0x51, 0x75, 0x69, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, 0x10, 0xc4, 0x04, 0x1a, - 0x02, 0x08, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x63, 0x72, 0x61, 0x70, 0x65, 0x53, 0x74, 0x61, - 0x63, 0x6b, 0x10, 0xc5, 0x04, 0x12, 0x19, 0x0a, 0x14, 0x54, 0x65, 0x63, 0x68, 0x6e, 0x69, 0x63, - 0x61, 0x6c, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x41, 0x70, 0x69, 0x10, 0xc6, 0x04, - 0x12, 0x0c, 0x0a, 0x07, 0x55, 0x72, 0x6c, 0x73, 0x63, 0x61, 0x6e, 0x10, 0xc7, 0x04, 0x12, 0x0e, - 0x0a, 0x09, 0x42, 0x61, 0x73, 0x65, 0x41, 0x70, 0x69, 0x49, 0x4f, 0x10, 0xc8, 0x04, 0x12, 0x0c, - 0x0a, 0x07, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x4f, 0x10, 0xc9, 0x04, 0x12, 0x08, 0x0a, 0x03, - 0x54, 0x4c, 0x79, 0x10, 0xca, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x68, 0x6f, 0x72, 0x74, 0x63, - 0x75, 0x74, 0x10, 0xcb, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x70, 0x70, 0x66, 0x6f, 0x6c, 0x6c, - 0x6f, 0x77, 0x10, 0xcc, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x68, 0x69, 0x6e, 0x6b, 0x69, 0x66, - 0x69, 0x63, 0x10, 0xcd, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x46, 0x65, 0x65, 0x64, 0x6c, 0x79, 0x10, - 0xce, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x69, 0x74, 0x63, 0x68, 0x64, 0x61, 0x74, 0x61, - 0x10, 0xcf, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x65, 0x74, 0x63, 0x68, 0x72, 0x73, 0x73, 0x10, - 0xd0, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, 0x67, 0x65, 0x6e, 0x69, - 0x75, 0x73, 0x10, 0xd1, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, - 0x72, 0x69, 0x74, 0x10, 0xd2, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x4f, 0x70, 0x74, 0x69, 0x6d, 0x69, - 0x7a, 0x65, 0x6c, 0x79, 0x10, 0xd3, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x4f, 0x63, 0x72, 0x53, 0x70, - 0x61, 0x63, 0x65, 0x10, 0xd4, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, - 0x72, 0x42, 0x69, 0x74, 0x10, 0xd5, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x75, 0x64, 0x64, 0x79, - 0x4e, 0x53, 0x10, 0xd6, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x5a, 0x69, 0x70, 0x41, 0x50, 0x49, 0x10, - 0xd7, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x5a, 0x69, 0x70, 0x42, 0x6f, 0x6f, 0x6b, 0x73, 0x10, 0xd8, - 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x4f, 0x6e, 0x65, 0x64, 0x65, 0x73, 0x6b, 0x10, 0xd9, 0x04, 0x12, - 0x0c, 0x0a, 0x07, 0x42, 0x75, 0x67, 0x68, 0x65, 0x72, 0x64, 0x10, 0xda, 0x04, 0x12, 0x0f, 0x0a, - 0x0a, 0x42, 0x6c, 0x61, 0x7a, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x10, 0xdb, 0x04, 0x12, 0x0d, - 0x0a, 0x08, 0x41, 0x75, 0x74, 0x6f, 0x64, 0x65, 0x73, 0x6b, 0x10, 0xdc, 0x04, 0x12, 0x08, 0x0a, - 0x03, 0x54, 0x72, 0x75, 0x10, 0xdd, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x55, 0x6e, 0x69, 0x66, 0x79, - 0x49, 0x44, 0x10, 0xde, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x72, 0x69, 0x6d, 0x62, 0x6c, 0x65, - 0x10, 0xdf, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x6d, 0x6f, 0x6f, 0x63, 0x68, 0x10, 0xe0, 0x04, - 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x65, 0x6d, 0x61, 0x70, 0x68, 0x6f, 0x72, 0x65, 0x10, 0xe1, 0x04, - 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x65, 0x6c, 0x6e, 0x79, 0x78, 0x10, 0xe2, 0x04, 0x12, 0x0f, 0x0a, - 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x77, 0x69, 0x72, 0x65, 0x10, 0xe3, 0x04, 0x12, 0x0e, - 0x0a, 0x09, 0x54, 0x65, 0x78, 0x74, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x10, 0xe4, 0x04, 0x12, 0x0e, - 0x0a, 0x09, 0x53, 0x65, 0x72, 0x70, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x10, 0xe5, 0x04, 0x12, 0x0b, - 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x6e, 0x79, 0x6f, 0x10, 0xe6, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x53, - 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x62, 0x6f, 0x6f, 0x6b, 0x10, 0xe7, 0x04, 0x12, 0x09, 0x0a, 0x04, - 0x56, 0x79, 0x74, 0x65, 0x10, 0xe8, 0x04, 0x12, 0x0a, 0x0a, 0x05, 0x4e, 0x79, 0x6c, 0x61, 0x73, - 0x10, 0xe9, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x71, 0x75, 0x61, 0x72, 0x65, 0x75, 0x70, 0x10, - 0xea, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x61, 0x6e, 0x64, 0x65, 0x6c, 0x69, 0x6f, 0x6e, 0x10, - 0xeb, 0x04, 0x12, 0x11, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x46, 0x69, 0x72, 0x65, 0x10, 0xec, - 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x65, 0x65, 0x70, 0x41, 0x49, 0x10, - 0xed, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x4d, 0x65, 0x61, 0x6e, 0x69, 0x6e, 0x67, 0x43, 0x6c, 0x6f, - 0x75, 0x64, 0x10, 0xee, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x65, 0x75, 0x74, 0x72, 0x69, 0x6e, - 0x6f, 0x41, 0x70, 0x69, 0x10, 0xef, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x74, 0x6f, 0x72, 0x65, - 0x63, 0x6f, 0x76, 0x65, 0x10, 0xf0, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x68, 0x69, 0x70, 0x64, - 0x61, 0x79, 0x10, 0xf1, 0x04, 0x12, 0x12, 0x0a, 0x09, 0x53, 0x65, 0x6e, 0x74, 0x69, 0x6d, 0x65, - 0x6e, 0x74, 0x10, 0xf2, 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x18, 0x0a, 0x13, 0x53, 0x74, 0x72, - 0x65, 0x61, 0x6d, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x69, 0x6e, 0x67, - 0x10, 0xf3, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x54, 0x65, 0x61, 0x6d, 0x77, 0x6f, 0x72, 0x6b, 0x43, - 0x52, 0x4d, 0x10, 0xf4, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x65, 0x61, 0x6d, 0x77, 0x6f, 0x72, - 0x6b, 0x44, 0x65, 0x73, 0x6b, 0x10, 0xf5, 0x04, 0x12, 0x13, 0x0a, 0x0e, 0x54, 0x65, 0x61, 0x6d, - 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x70, 0x61, 0x63, 0x65, 0x73, 0x10, 0xf6, 0x04, 0x12, 0x0f, 0x0a, - 0x0a, 0x54, 0x68, 0x65, 0x4f, 0x64, 0x64, 0x73, 0x41, 0x70, 0x69, 0x10, 0xf7, 0x04, 0x12, 0x0b, - 0x0a, 0x06, 0x41, 0x70, 0x61, 0x63, 0x74, 0x61, 0x10, 0xf8, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x47, - 0x65, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x10, 0xf9, 0x04, 0x12, 0x0e, 0x0a, 0x05, - 0x48, 0x61, 0x70, 0x70, 0x69, 0x10, 0xfa, 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0a, 0x0a, 0x05, - 0x4f, 0x61, 0x6e, 0x64, 0x61, 0x10, 0xfb, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x61, 0x73, 0x74, - 0x46, 0x6f, 0x72, 0x65, 0x78, 0x10, 0xfc, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x50, 0x49, 0x4d, - 0x61, 0x74, 0x69, 0x63, 0x10, 0xfd, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x56, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x45, 0x79, 0x65, 0x10, 0xfe, 0x04, 0x12, 0x15, 0x0a, 0x10, 0x45, 0x61, 0x67, 0x6c, - 0x65, 0x45, 0x79, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, 0x10, 0xff, 0x04, 0x12, - 0x11, 0x0a, 0x0c, 0x54, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x45, 0x79, 0x65, 0x73, 0x10, - 0x80, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x50, 0x44, 0x46, 0x10, - 0x81, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x73, 0x74, 0x61, 0x74, - 0x73, 0x10, 0x82, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x68, 0x65, 0x63, 0x49, 0x4f, 0x10, 0x83, - 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, 0x74, 0x10, 0x84, 0x05, - 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x70, 0x69, 0x53, 0x63, 0x69, 0x65, 0x6e, 0x63, 0x65, 0x10, 0x85, - 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x53, 0x79, 0x6e, 0x65, 0x72, 0x67, 0x79, 0x10, - 0x86, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x61, 0x66, 0x6c, 0x6f, 0x75, 0x10, 0x87, 0x05, 0x12, - 0x0b, 0x0a, 0x06, 0x43, 0x61, 0x73, 0x70, 0x69, 0x6f, 0x10, 0x88, 0x05, 0x12, 0x0e, 0x0a, 0x09, - 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6c, 0x79, 0x48, 0x51, 0x10, 0x89, 0x05, 0x12, 0x12, 0x0a, 0x0d, - 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x10, 0x8a, 0x05, - 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x72, 0x6f, 0x6e, 0x61, 0x48, 0x51, 0x10, 0x8b, 0x05, 0x12, 0x0c, - 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x78, 0x10, 0x8c, 0x05, 0x12, 0x09, 0x0a, 0x04, - 0x46, 0x6d, 0x66, 0x77, 0x10, 0x8d, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x47, 0x6f, 0x6f, 0x64, 0x44, - 0x61, 0x79, 0x10, 0x8e, 0x05, 0x12, 0x09, 0x0a, 0x04, 0x4c, 0x75, 0x6e, 0x6f, 0x10, 0x8f, 0x05, - 0x12, 0x10, 0x0a, 0x0b, 0x4d, 0x65, 0x69, 0x73, 0x74, 0x65, 0x72, 0x74, 0x61, 0x73, 0x6b, 0x10, - 0x90, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x4d, 0x69, 0x6e, 0x64, 0x6d, 0x65, 0x69, 0x73, 0x74, 0x65, - 0x72, 0x10, 0x91, 0x05, 0x12, 0x13, 0x0a, 0x0e, 0x50, 0x65, 0x6f, 0x70, 0x6c, 0x65, 0x44, 0x61, - 0x74, 0x61, 0x4c, 0x61, 0x62, 0x73, 0x10, 0x92, 0x05, 0x12, 0x14, 0x0a, 0x0b, 0x53, 0x63, 0x72, - 0x61, 0x70, 0x65, 0x72, 0x53, 0x69, 0x74, 0x65, 0x10, 0x93, 0x05, 0x1a, 0x02, 0x08, 0x01, 0x12, - 0x0d, 0x0a, 0x08, 0x53, 0x63, 0x72, 0x61, 0x70, 0x66, 0x6c, 0x79, 0x10, 0x94, 0x05, 0x12, 0x10, - 0x0a, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x4e, 0x6f, 0x74, 0x65, 0x64, 0x10, 0x95, 0x05, - 0x12, 0x12, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x50, 0x61, 0x79, 0x6f, 0x75, 0x74, - 0x73, 0x10, 0x96, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x53, 0x63, 0x72, 0x61, 0x70, - 0x65, 0x72, 0x10, 0x97, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x76, 0x69, 0x65, 0x72, - 0x10, 0x98, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x72, 0x69, 0x65, 0x72, 0x10, 0x99, - 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x44, 0x69, 0x74, 0x74, 0x6f, 0x10, 0x9a, 0x05, 0x12, 0x0a, 0x0a, - 0x05, 0x46, 0x69, 0x6e, 0x64, 0x6c, 0x10, 0x9b, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x4c, 0x65, 0x6e, - 0x64, 0x66, 0x6c, 0x6f, 0x77, 0x10, 0x9c, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x4d, 0x6f, 0x64, 0x65, - 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x9d, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x4f, 0x70, 0x65, - 0x6e, 0x64, 0x61, 0x74, 0x61, 0x73, 0x6f, 0x66, 0x74, 0x10, 0x9e, 0x05, 0x12, 0x0a, 0x0a, 0x05, - 0x50, 0x6f, 0x64, 0x69, 0x6f, 0x10, 0x9f, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x6f, 0x63, 0x6b, - 0x73, 0x65, 0x74, 0x10, 0xa0, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x52, 0x6f, 0x77, 0x6e, 0x64, 0x10, - 0xa1, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x68, 0x6f, 0x74, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, - 0xa2, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x77, 0x69, 0x66, 0x74, 0x79, 0x70, 0x65, 0x10, 0xa3, - 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, 0x10, 0xa4, 0x05, 0x12, - 0x0a, 0x0a, 0x05, 0x48, 0x6f, 0x6e, 0x65, 0x79, 0x10, 0xa5, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x46, - 0x72, 0x65, 0x73, 0x68, 0x64, 0x65, 0x73, 0x6b, 0x10, 0xa6, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x55, - 0x70, 0x77, 0x61, 0x76, 0x65, 0x10, 0xa7, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x6f, 0x75, 0x6e, - 0x74, 0x61, 0x69, 0x6e, 0x10, 0xa8, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x46, 0x72, 0x65, 0x73, 0x68, - 0x62, 0x6f, 0x6f, 0x6b, 0x73, 0x10, 0xa9, 0x05, 0x12, 0x09, 0x0a, 0x04, 0x4d, 0x69, 0x74, 0x65, - 0x10, 0xaa, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x65, 0x70, 0x75, 0x74, 0x79, 0x10, 0xab, 0x05, - 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x65, 0x65, 0x62, 0x6f, 0x6c, 0x65, 0x10, 0xac, 0x05, 0x12, 0x0e, - 0x0a, 0x09, 0x43, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x10, 0xad, 0x05, 0x12, 0x0b, - 0x0a, 0x06, 0x4b, 0x61, 0x6e, 0x62, 0x61, 0x6e, 0x10, 0xae, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x57, - 0x6f, 0x72, 0x6b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x10, 0xaf, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x4d, - 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x10, 0xb0, 0x05, 0x12, 0x11, 0x0a, - 0x0c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x10, 0xb1, 0x05, - 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x68, 0x65, 0x72, 0x70, 0x61, 0x64, 0x65, 0x73, 0x6b, 0x10, 0xb2, - 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x4d, 0x72, 0x74, 0x69, 0x63, 0x6b, 0x74, 0x6f, 0x63, 0x6b, 0x10, - 0xb3, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x68, 0x61, 0x74, 0x66, 0x75, 0x6c, 0x65, 0x10, 0xb4, - 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x65, 0x72, 0x6f, 0x77, 0x6f, 0x72, 0x6b, 0x66, 0x6c, 0x6f, - 0x77, 0x10, 0xb5, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x6f, 0x63, 0x74, - 0x6f, 0x70, 0x75, 0x73, 0x10, 0xb6, 0x05, 0x12, 0x11, 0x0a, 0x08, 0x46, 0x75, 0x73, 0x65, 0x62, - 0x69, 0x6c, 0x6c, 0x10, 0xb7, 0x05, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x47, 0x65, - 0x63, 0x6b, 0x6f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x10, 0xb8, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x47, - 0x6f, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x64, 0x10, 0xb9, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x4d, - 0x6f, 0x6f, 0x6e, 0x63, 0x6c, 0x65, 0x72, 0x6b, 0x10, 0xba, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x50, - 0x61, 0x79, 0x6d, 0x6f, 0x61, 0x70, 0x70, 0x10, 0xbb, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x4d, 0x69, - 0x78, 0x6d, 0x61, 0x78, 0x10, 0xbc, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x73, 0x74, 0x10, 0xbd, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x52, 0x65, 0x70, 0x61, 0x69, - 0x72, 0x73, 0x68, 0x6f, 0x70, 0x72, 0x10, 0xbe, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x6f, 0x73, - 0x68, 0x69, 0x70, 0x70, 0x6f, 0x10, 0xbf, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x69, 0x67, 0x6f, - 0x70, 0x74, 0x10, 0xc0, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x75, 0x67, 0x65, 0x73, 0x74, 0x65, - 0x72, 0x10, 0xc1, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x56, 0x69, 0x65, 0x77, 0x6e, 0x65, 0x6f, 0x10, - 0xc2, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4e, 0x6f, 0x74, 0x65, 0x10, - 0xc3, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x61, 0x70, 0x74, 0x61, 0x69, 0x6e, 0x44, 0x61, 0x74, - 0x61, 0x10, 0xc4, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x76, 0x69, 0x73, - 0x74, 0x10, 0xc5, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x67, 0x6f, 0x10, - 0xc6, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x7a, 0x65, 0x10, 0xc7, 0x05, 0x12, 0x0b, - 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x49, 0x4f, 0x10, 0xc8, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x46, - 0x6f, 0x72, 0x6d, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x10, 0xc9, 0x05, 0x12, 0x0d, 0x0a, 0x08, - 0x47, 0x6f, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x10, 0xca, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x4d, - 0x61, 0x64, 0x4b, 0x75, 0x64, 0x75, 0x10, 0xcb, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x4e, 0x6f, 0x7a, - 0x62, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x10, 0xcc, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x50, 0x61, - 0x70, 0x79, 0x72, 0x73, 0x10, 0xcd, 0x05, 0x12, 0x12, 0x0a, 0x0d, 0x53, 0x75, 0x70, 0x65, 0x72, - 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x41, 0x50, 0x49, 0x10, 0xce, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x54, - 0x61, 0x6c, 0x6c, 0x79, 0x66, 0x79, 0x10, 0xcf, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x5a, 0x65, 0x6e, - 0x6b, 0x69, 0x74, 0x41, 0x50, 0x49, 0x10, 0xd0, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, - 0x75, 0x64, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0xd1, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x55, 0x70, - 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x61, 0x72, 0x65, 0x10, 0xd2, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x42, - 0x6f, 0x72, 0x67, 0x62, 0x61, 0x73, 0x65, 0x10, 0xd3, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x50, 0x69, - 0x70, 0x65, 0x64, 0x72, 0x65, 0x61, 0x6d, 0x10, 0xd4, 0x05, 0x12, 0x09, 0x0a, 0x04, 0x53, 0x69, - 0x72, 0x76, 0x10, 0xd5, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x69, 0x66, 0x66, 0x62, 0x6f, 0x74, - 0x10, 0xd6, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x45, 0x69, 0x67, 0x68, 0x74, 0x78, 0x45, 0x69, 0x67, - 0x68, 0x74, 0x10, 0xd7, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x65, 0x6e, 0x64, 0x6f, 0x73, 0x6f, - 0x10, 0xd8, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x50, 0x72, 0x69, 0x6e, 0x74, 0x66, 0x65, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x10, 0xd9, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x65, 0x10, 0xda, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x50, 0x61, 0x6e, 0x64, 0x61, 0x53, - 0x63, 0x6f, 0x72, 0x65, 0x10, 0xdb, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x50, 0x61, 0x79, 0x6d, 0x6f, - 0x10, 0xdc, 0x05, 0x12, 0x1d, 0x0a, 0x18, 0x41, 0x76, 0x61, 0x7a, 0x61, 0x50, 0x65, 0x72, 0x73, - 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, - 0xdd, 0x05, 0x12, 0x14, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x6e, 0x76, 0x69, 0x65, 0x77, 0x4c, 0x65, - 0x61, 0x6e, 0x4b, 0x69, 0x74, 0x10, 0xde, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x4c, 0x69, 0x76, 0x65, - 0x73, 0x74, 0x6f, 0x72, 0x6d, 0x10, 0xdf, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x4b, 0x75, 0x43, 0x6f, - 0x69, 0x6e, 0x10, 0xe0, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x65, 0x74, 0x61, 0x41, 0x50, 0x49, - 0x10, 0xe1, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x4e, 0x69, 0x63, 0x65, 0x48, 0x61, 0x73, 0x68, 0x10, - 0xe2, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x43, 0x65, 0x78, 0x49, 0x4f, 0x10, 0xe3, 0x05, 0x12, 0x0e, - 0x0a, 0x09, 0x4b, 0x6c, 0x69, 0x70, 0x66, 0x6f, 0x6c, 0x69, 0x6f, 0x10, 0xe4, 0x05, 0x12, 0x0e, - 0x0a, 0x09, 0x44, 0x79, 0x6e, 0x61, 0x74, 0x72, 0x61, 0x63, 0x65, 0x10, 0xe5, 0x05, 0x12, 0x11, - 0x0a, 0x0c, 0x4d, 0x6f, 0x6c, 0x6c, 0x69, 0x65, 0x41, 0x50, 0x49, 0x4b, 0x65, 0x79, 0x10, 0xe6, - 0x05, 0x12, 0x16, 0x0a, 0x11, 0x4d, 0x6f, 0x6c, 0x6c, 0x69, 0x65, 0x41, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xe7, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x61, 0x73, - 0x69, 0x73, 0x54, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x10, 0xe8, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x4e, - 0x6f, 0x72, 0x64, 0x69, 0x67, 0x65, 0x6e, 0x10, 0xe9, 0x05, 0x12, 0x1c, 0x0a, 0x17, 0x46, 0x6c, - 0x61, 0x67, 0x73, 0x6d, 0x69, 0x74, 0x68, 0x45, 0x6e, 0x76, 0x69, 0x72, 0x6f, 0x6e, 0x6d, 0x65, - 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x10, 0xea, 0x05, 0x12, 0x13, 0x0a, 0x0e, 0x46, 0x6c, 0x61, 0x67, - 0x73, 0x6d, 0x69, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xeb, 0x05, 0x12, 0x08, 0x0a, - 0x03, 0x4d, 0x75, 0x78, 0x10, 0xec, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x6f, 0x6c, 0x75, 0x6d, - 0x6e, 0x10, 0xed, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, 0x62, 0x69, 0x72, 0x64, - 0x10, 0xee, 0x05, 0x12, 0x1c, 0x0a, 0x17, 0x53, 0x65, 0x6e, 0x64, 0x62, 0x69, 0x72, 0x64, 0x4f, - 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, 0x50, 0x49, 0x10, 0xef, - 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x4d, 0x69, 0x64, 0x69, 0x73, 0x65, 0x10, 0xf0, 0x05, 0x12, 0x0d, - 0x0a, 0x08, 0x4d, 0x6f, 0x63, 0x6b, 0x61, 0x72, 0x6f, 0x6f, 0x10, 0xf1, 0x05, 0x12, 0x0b, 0x0a, - 0x06, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x34, 0x10, 0xf2, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x50, 0x69, - 0x6e, 0x61, 0x74, 0x61, 0x10, 0xf3, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x42, 0x72, 0x6f, 0x77, 0x73, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xf4, 0x05, 0x12, 0x1c, 0x0a, 0x13, 0x43, 0x72, - 0x6f, 0x73, 0x73, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x69, 0x6e, - 0x67, 0x10, 0xf5, 0x05, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x4c, 0x6f, 0x61, 0x64, - 0x6d, 0x69, 0x6c, 0x6c, 0x10, 0xf6, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x69, - 0x6e, 0x67, 0x42, 0x6f, 0x74, 0x10, 0xf7, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x4b, 0x6e, 0x61, 0x70, - 0x73, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x10, 0xf8, 0x05, 0x12, 0x09, 0x0a, 0x04, 0x51, 0x61, - 0x73, 0x65, 0x10, 0xf9, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x61, 0x72, 0x65, 0x62, 0x6f, 0x6f, - 0x73, 0x74, 0x10, 0xfa, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x54, 0x4d, 0x65, 0x74, 0x72, 0x69, - 0x78, 0x10, 0xfb, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x6f, 0x6c, 0x69, 0x73, 0x74, 0x69, 0x63, - 0x10, 0xfc, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x73, 0x65, 0x72, 0x73, 0x10, 0xfd, - 0x05, 0x12, 0x12, 0x0a, 0x0d, 0x53, 0x63, 0x72, 0x75, 0x74, 0x69, 0x6e, 0x69, 0x7a, 0x65, 0x72, - 0x43, 0x69, 0x10, 0xfe, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x6f, 0x6e, 0x61, 0x72, 0x43, 0x6c, - 0x6f, 0x75, 0x64, 0x10, 0xff, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x50, 0x49, 0x54, 0x65, 0x6d, - 0x70, 0x6c, 0x61, 0x74, 0x65, 0x10, 0x80, 0x06, 0x12, 0x14, 0x0a, 0x0f, 0x43, 0x6f, 0x6e, 0x76, - 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x10, 0x81, 0x06, 0x12, 0x0f, - 0x0a, 0x0a, 0x43, 0x72, 0x61, 0x66, 0x74, 0x4d, 0x79, 0x50, 0x44, 0x46, 0x10, 0x82, 0x06, 0x12, - 0x0e, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x44, 0x4b, 0x10, 0x83, 0x06, 0x12, - 0x15, 0x0a, 0x0c, 0x47, 0x6c, 0x69, 0x74, 0x74, 0x65, 0x72, 0x6c, 0x79, 0x41, 0x50, 0x49, 0x10, - 0x84, 0x06, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x79, 0x62, 0x69, 0x73, 0x63, - 0x75, 0x73, 0x10, 0x85, 0x06, 0x12, 0x09, 0x0a, 0x04, 0x4d, 0x69, 0x72, 0x6f, 0x10, 0x86, 0x06, - 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x70, 0x61, 0x67, 0x65, 0x10, 0x87, - 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x70, 0x61, 0x6c, 0x10, 0x88, - 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x54, 0x65, 0x6c, 0x65, 0x74, 0x79, 0x70, 0x65, 0x10, 0x89, 0x06, - 0x12, 0x0d, 0x0a, 0x08, 0x54, 0x69, 0x6d, 0x65, 0x43, 0x61, 0x6d, 0x70, 0x10, 0x8a, 0x06, 0x12, - 0x0d, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x10, 0x8b, 0x06, 0x12, 0x0b, - 0x0a, 0x06, 0x57, 0x69, 0x73, 0x74, 0x69, 0x61, 0x10, 0x8c, 0x06, 0x12, 0x13, 0x0a, 0x0a, 0x53, - 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x64, 0x61, 0x72, 0x10, 0x8d, 0x06, 0x1a, 0x02, 0x08, 0x01, - 0x12, 0x10, 0x0a, 0x0b, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x6f, 0x62, 0x6f, 0x74, 0x10, - 0x8e, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x64, 0x65, 0x71, 0x75, 0x69, 0x72, 0x79, 0x10, - 0x8f, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, 0x74, 0x6f, 0x72, 0x41, - 0x50, 0x49, 0x10, 0x90, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x10, 0x91, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x4d, 0x61, 0x67, 0x69, 0x63, 0x42, 0x65, 0x6c, - 0x6c, 0x10, 0x92, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x72, 0x6d, 0x62, 0x6f, 0x61, - 0x72, 0x64, 0x10, 0x93, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x70, 0x69, 0x6c, 0x61, 0x79, 0x65, - 0x72, 0x10, 0x94, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x69, 0x73, 0x71, 0x75, 0x73, 0x10, 0x95, - 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x57, 0x6f, 0x6f, 0x70, 0x72, 0x61, 0x10, 0x96, 0x06, 0x12, 0x0e, - 0x0a, 0x09, 0x50, 0x61, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x10, 0x97, 0x06, 0x12, 0x0c, - 0x0a, 0x07, 0x47, 0x75, 0x6d, 0x72, 0x6f, 0x61, 0x64, 0x10, 0x98, 0x06, 0x12, 0x0f, 0x0a, 0x0a, - 0x50, 0x61, 0x79, 0x64, 0x69, 0x72, 0x74, 0x61, 0x70, 0x70, 0x10, 0x99, 0x06, 0x12, 0x0e, 0x0a, - 0x09, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x66, 0x79, 0x10, 0x9a, 0x06, 0x12, 0x0f, 0x0a, - 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x63, 0x61, 0x6b, 0x65, 0x10, 0x9b, 0x06, 0x12, 0x0f, - 0x0a, 0x0a, 0x4a, 0x75, 0x6d, 0x70, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x10, 0x9c, 0x06, 0x12, - 0x0f, 0x0a, 0x0a, 0x4c, 0x75, 0x6e, 0x63, 0x68, 0x4d, 0x6f, 0x6e, 0x65, 0x79, 0x10, 0x9d, 0x06, - 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x6f, 0x73, 0x65, 0x74, 0x74, 0x65, 0x10, 0x9e, 0x06, 0x12, 0x09, - 0x0a, 0x04, 0x59, 0x65, 0x6c, 0x70, 0x10, 0x9f, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x74, 0x65, - 0x72, 0x61, 0x10, 0xa0, 0x06, 0x12, 0x12, 0x0a, 0x0d, 0x45, 0x63, 0x6f, 0x53, 0x74, 0x72, 0x75, - 0x78, 0x75, 0x72, 0x65, 0x49, 0x54, 0x10, 0xa1, 0x06, 0x12, 0x08, 0x0a, 0x03, 0x41, 0x68, 0x61, - 0x10, 0xa2, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x72, 0x73, 0x65, 0x68, 0x75, 0x62, 0x10, - 0xa3, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x43, 0x6c, 0x6f, - 0x75, 0x64, 0x10, 0xa4, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x73, 0x6d, - 0x69, 0x74, 0x68, 0x10, 0xa5, 0x06, 0x12, 0x11, 0x0a, 0x08, 0x46, 0x6c, 0x6f, 0x77, 0x64, 0x61, - 0x73, 0x68, 0x10, 0xa6, 0x06, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x11, 0x0a, 0x08, 0x46, 0x6c, 0x6f, - 0x77, 0x64, 0x6f, 0x63, 0x6b, 0x10, 0xa7, 0x06, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0b, 0x0a, 0x06, - 0x46, 0x69, 0x62, 0x65, 0x72, 0x79, 0x10, 0xa8, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x54, 0x79, 0x70, - 0x65, 0x74, 0x61, 0x6c, 0x6b, 0x10, 0xa9, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x56, 0x6f, 0x6f, 0x64, - 0x6f, 0x6f, 0x53, 0x4d, 0x53, 0x10, 0xaa, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x5a, 0x75, 0x6c, 0x69, - 0x70, 0x43, 0x68, 0x61, 0x74, 0x10, 0xab, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x6f, 0x72, 0x6d, - 0x63, 0x72, 0x61, 0x66, 0x74, 0x10, 0xac, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x65, 0x78, 0x61, - 0x70, 0x69, 0x73, 0x10, 0xad, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, 0x61, 0x63, 0x68, 0x6d, - 0x61, 0x69, 0x6c, 0x10, 0xae, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x68, 0x61, 0x72, 0x74, 0x6d, - 0x6f, 0x67, 0x75, 0x6c, 0x10, 0xaf, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x6f, 0x69, - 0x6e, 0x74, 0x65, 0x64, 0x64, 0x10, 0xb0, 0x06, 0x12, 0x08, 0x0a, 0x03, 0x57, 0x69, 0x74, 0x10, - 0xb1, 0x06, 0x12, 0x15, 0x0a, 0x10, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x50, 0x61, - 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x10, 0xb2, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x44, 0x69, 0x67, - 0x67, 0x65, 0x72, 0x6e, 0x61, 0x75, 0x74, 0x10, 0xb3, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x4d, 0x6f, - 0x6e, 0x6b, 0x65, 0x79, 0x4c, 0x65, 0x61, 0x72, 0x6e, 0x10, 0xb4, 0x06, 0x12, 0x0a, 0x0a, 0x05, - 0x44, 0x75, 0x70, 0x6c, 0x79, 0x10, 0xb5, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x50, 0x6f, 0x73, 0x74, - 0x62, 0x61, 0x63, 0x6b, 0x73, 0x10, 0xb6, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x6f, 0x6c, 0x6c, - 0x65, 0x63, 0x74, 0x32, 0x10, 0xb7, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x5a, 0x65, 0x6e, 0x52, 0x6f, - 0x77, 0x73, 0x10, 0xb8, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x5a, 0x69, 0x70, 0x63, 0x6f, 0x64, 0x65, - 0x62, 0x61, 0x73, 0x65, 0x10, 0xb9, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x65, 0x66, 0x74, 0x65, - 0x72, 0x10, 0xba, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x54, 0x77, 0x69, 0x73, 0x74, 0x10, 0xbb, 0x06, - 0x12, 0x16, 0x0a, 0x11, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x72, 0x65, 0x65, 0x50, 0x61, 0x79, - 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x10, 0xbc, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x6c, 0x6f, 0x75, - 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x10, 0xbd, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x47, - 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x10, 0xbe, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, - 0x76, 0x65, 0x72, 0x74, 0x41, 0x70, 0x69, 0x10, 0xbf, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x10, 0xc0, 0x06, 0x12, 0x0c, 0x0a, - 0x07, 0x42, 0x75, 0x6c, 0x6b, 0x73, 0x6d, 0x73, 0x10, 0xc1, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x44, - 0x61, 0x74, 0x61, 0x62, 0x6f, 0x78, 0x10, 0xc2, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x4f, 0x6e, 0x65, - 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x10, 0xc3, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x65, 0x6e, - 0x74, 0x6d, 0x61, 0x6e, 0x10, 0xc4, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x73, 0x65, - 0x75, 0x72, 0x10, 0xc5, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x6f, 0x63, 0x70, 0x61, 0x72, 0x73, - 0x65, 0x72, 0x10, 0xc6, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x6f, 0x72, 0x6d, 0x73, 0x69, 0x74, - 0x65, 0x10, 0xc7, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x74, 0x61, - 0x69, 0x6c, 0x6f, 0x72, 0x10, 0xc8, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x4c, 0x65, 0x6d, 0x6c, 0x69, - 0x73, 0x74, 0x10, 0xc9, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x72, 0x6f, 0x64, 0x70, 0x61, 0x64, - 0x10, 0xca, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x6f, 0x72, 0x6d, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x10, 0xcb, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x6f, 0x64, 0x65, 0x63, 0x6c, 0x69, 0x6d, 0x61, - 0x74, 0x65, 0x10, 0xcc, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x64, 0x65, 0x6d, 0x61, 0x67, - 0x69, 0x63, 0x10, 0xcd, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x56, 0x62, 0x6f, 0x75, 0x74, 0x10, 0xce, - 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x4e, 0x69, 0x67, 0x68, 0x74, 0x66, 0x61, 0x6c, 0x6c, 0x10, 0xcf, - 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x4c, 0x61, 0x62, 0x73, 0x10, - 0xd0, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x70, 0x65, 0x65, 0x63, 0x68, 0x54, 0x65, 0x78, 0x74, - 0x41, 0x49, 0x10, 0xd1, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x6f, 0x6c, 0x6c, 0x73, 0x41, 0x50, - 0x49, 0x10, 0xd2, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x69, 0x6d, 0x46, 0x69, 0x6e, 0x10, 0xd3, - 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x53, 0x63, 0x61, 0x6c, 0x72, 0x10, 0xd4, 0x06, 0x12, 0x0f, 0x0a, - 0x0a, 0x4b, 0x61, 0x6e, 0x62, 0x61, 0x6e, 0x74, 0x6f, 0x6f, 0x6c, 0x10, 0xd5, 0x06, 0x12, 0x10, - 0x0a, 0x0b, 0x42, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x10, 0xd6, 0x06, - 0x12, 0x0c, 0x0a, 0x07, 0x48, 0x6f, 0x74, 0x77, 0x69, 0x72, 0x65, 0x10, 0xd7, 0x06, 0x12, 0x0d, - 0x0a, 0x08, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6f, 0x74, 0x10, 0xd8, 0x06, 0x12, 0x0c, 0x0a, - 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6b, 0x69, 0x74, 0x10, 0xd9, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x49, - 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x10, 0xda, 0x06, 0x12, 0x11, 0x0a, - 0x0c, 0x4d, 0x6f, 0x6a, 0x6f, 0x68, 0x65, 0x6c, 0x70, 0x64, 0x65, 0x73, 0x6b, 0x10, 0xdb, 0x06, - 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x65, 0x6e, 0x64, 0x10, 0xdc, - 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x10, 0xdd, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x79, 0x6e, 0x61, 0x64, 0x6f, 0x74, 0x10, 0xde, - 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x44, 0x65, 0x6d, 0x69, 0x6f, 0x10, 0xdf, 0x06, 0x12, 0x0b, 0x0a, - 0x06, 0x54, 0x6f, 0x6b, 0x65, 0x65, 0x74, 0x10, 0xe0, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x4d, 0x79, - 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0xe1, 0x06, 0x12, 0x0e, 0x0a, - 0x09, 0x43, 0x6f, 0x70, 0x79, 0x73, 0x63, 0x61, 0x70, 0x65, 0x10, 0xe2, 0x06, 0x12, 0x0d, 0x0a, - 0x08, 0x42, 0x65, 0x73, 0x6e, 0x61, 0x70, 0x70, 0x79, 0x10, 0xe3, 0x06, 0x12, 0x0e, 0x0a, 0x09, - 0x53, 0x61, 0x6c, 0x65, 0x73, 0x6d, 0x61, 0x74, 0x65, 0x10, 0xe4, 0x06, 0x12, 0x13, 0x0a, 0x0a, - 0x48, 0x65, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x61, 0x70, 0x69, 0x10, 0xe5, 0x06, 0x1a, 0x02, 0x08, - 0x01, 0x12, 0x11, 0x0a, 0x0c, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, 0x70, 0x75, 0x6c, 0x73, - 0x65, 0x10, 0xe6, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x55, 0x63, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x66, - 0x79, 0x10, 0xe7, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x10, - 0xe8, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x44, 0x46, 0x6d, 0x79, 0x55, 0x52, 0x4c, 0x10, 0xe9, - 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x70, 0x69, 0x32, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, - 0x10, 0xea, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x4f, 0x70, 0x73, 0x67, 0x65, 0x6e, 0x69, 0x65, 0x10, - 0xeb, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x47, 0x65, 0x6d, 0x69, 0x6e, 0x69, 0x10, 0xec, 0x06, 0x12, - 0x0e, 0x0a, 0x09, 0x48, 0x6f, 0x6e, 0x65, 0x79, 0x63, 0x6f, 0x6d, 0x62, 0x10, 0xed, 0x06, 0x12, - 0x14, 0x0a, 0x0f, 0x4b, 0x61, 0x6c, 0x74, 0x75, 0x72, 0x61, 0x41, 0x70, 0x70, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x10, 0xee, 0x06, 0x12, 0x13, 0x0a, 0x0e, 0x4b, 0x61, 0x6c, 0x74, 0x75, 0x72, 0x61, - 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0xef, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x42, 0x69, - 0x74, 0x47, 0x6f, 0x10, 0xf0, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x4f, 0x70, 0x74, 0x69, 0x64, 0x61, - 0x73, 0x68, 0x10, 0xf1, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x6d, 0x67, 0x69, 0x78, 0x10, 0xf2, - 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x54, 0x65, 0x78, 0x74, - 0x10, 0xf3, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x50, 0x61, 0x67, 0x65, 0x32, 0x49, 0x6d, 0x61, 0x67, - 0x65, 0x73, 0x10, 0xf4, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x62, 0x61, - 0x73, 0x65, 0x10, 0xf5, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x65, 0x64, 0x62, 0x6f, 0x6f, 0x74, - 0x68, 0x10, 0xf6, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x4e, 0x75, 0x62, 0x65, 0x6c, 0x61, 0x10, 0xf7, - 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x6e, 0x66, 0x6f, 0x62, 0x69, 0x70, 0x10, 0xf8, 0x06, 0x12, - 0x0a, 0x0a, 0x05, 0x55, 0x70, 0x72, 0x6f, 0x63, 0x10, 0xf9, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x53, - 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x62, 0x65, 0x65, 0x10, 0xfa, 0x06, 0x12, 0x0e, 0x0a, 0x09, - 0x41, 0x66, 0x74, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x10, 0xfb, 0x06, 0x12, 0x0c, 0x0a, 0x07, - 0x45, 0x64, 0x75, 0x73, 0x69, 0x67, 0x6e, 0x10, 0xfc, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x65, - 0x61, 0x6d, 0x75, 0x70, 0x10, 0xfd, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x57, 0x6f, 0x72, 0x6b, 0x64, - 0x61, 0x79, 0x10, 0xfe, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x6f, 0x6e, 0x67, 0x6f, 0x44, 0x42, - 0x10, 0xff, 0x06, 0x12, 0x08, 0x0a, 0x03, 0x4e, 0x47, 0x43, 0x10, 0x80, 0x07, 0x12, 0x13, 0x0a, - 0x0e, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x4f, 0x63, 0x65, 0x61, 0x6e, 0x56, 0x32, 0x10, - 0x81, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x10, - 0x82, 0x07, 0x12, 0x08, 0x0a, 0x03, 0x46, 0x54, 0x50, 0x10, 0x83, 0x07, 0x12, 0x0a, 0x0a, 0x05, - 0x52, 0x65, 0x64, 0x69, 0x73, 0x10, 0x84, 0x07, 0x12, 0x09, 0x0a, 0x04, 0x4c, 0x44, 0x41, 0x50, - 0x10, 0x85, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x68, 0x6f, 0x70, 0x69, 0x66, 0x79, 0x10, 0x86, - 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x61, 0x62, 0x62, 0x69, 0x74, 0x4d, 0x51, 0x10, 0x87, 0x07, - 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, 0x67, 0x65, 0x78, 0x10, - 0x88, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x74, 0x68, 0x65, 0x72, 0x73, 0x63, 0x61, 0x6e, 0x10, - 0x89, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x6e, 0x66, 0x75, 0x72, 0x61, 0x10, 0x8a, 0x07, 0x12, - 0x0c, 0x0a, 0x07, 0x41, 0x6c, 0x63, 0x68, 0x65, 0x6d, 0x79, 0x10, 0x8b, 0x07, 0x12, 0x10, 0x0a, - 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, 0x10, 0x8c, 0x07, 0x12, - 0x0c, 0x0a, 0x07, 0x4d, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x73, 0x10, 0x8d, 0x07, 0x12, 0x0c, 0x0a, - 0x07, 0x42, 0x73, 0x63, 0x53, 0x63, 0x61, 0x6e, 0x10, 0x8e, 0x07, 0x12, 0x16, 0x0a, 0x0d, 0x43, - 0x6f, 0x69, 0x6e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x43, 0x61, 0x70, 0x10, 0x8f, 0x07, 0x1a, - 0x02, 0x08, 0x01, 0x12, 0x0a, 0x0a, 0x05, 0x50, 0x65, 0x72, 0x63, 0x79, 0x10, 0x90, 0x07, 0x12, - 0x11, 0x0a, 0x0c, 0x54, 0x69, 0x6e, 0x65, 0x73, 0x57, 0x65, 0x62, 0x68, 0x6f, 0x6f, 0x6b, 0x10, - 0x91, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x50, 0x75, 0x6c, 0x75, 0x6d, 0x69, 0x10, 0x92, 0x07, 0x12, - 0x12, 0x0a, 0x0d, 0x53, 0x75, 0x70, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, - 0x10, 0x93, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x75, 0x47, 0x65, 0x74, 0x41, 0x70, 0x69, 0x4b, - 0x65, 0x79, 0x10, 0x94, 0x07, 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x69, 0x76, 0x65, 0x6e, 0x10, 0x95, - 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x66, 0x65, 0x63, 0x74, 0x10, 0x96, 0x07, 0x12, - 0x0d, 0x0a, 0x08, 0x44, 0x6f, 0x63, 0x75, 0x73, 0x69, 0x67, 0x6e, 0x10, 0x97, 0x07, 0x12, 0x0e, - 0x0a, 0x09, 0x43, 0x6f, 0x75, 0x63, 0x68, 0x62, 0x61, 0x73, 0x65, 0x10, 0x98, 0x07, 0x12, 0x0e, - 0x0a, 0x09, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x68, 0x75, 0x62, 0x10, 0x99, 0x07, 0x12, 0x19, - 0x0a, 0x14, 0x54, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, 0x68, 0x6f, 0x67, 0x45, 0x6e, 0x74, 0x65, - 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x10, 0x9a, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x45, 0x6e, 0x76, - 0x6f, 0x79, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x10, 0x9b, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x47, - 0x69, 0x74, 0x48, 0x75, 0x62, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x10, 0x9c, 0x07, 0x12, 0x0f, - 0x0a, 0x0a, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x10, 0x9d, 0x07, 0x12, - 0x10, 0x0a, 0x0b, 0x48, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x46, 0x61, 0x63, 0x65, 0x10, 0x9e, - 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, 0x6b, 0x65, 0x10, 0x9f, - 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, - 0x10, 0xa0, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x61, 0x69, 0x6c, 0x73, 0x63, 0x61, 0x6c, 0x65, - 0x10, 0xa1, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x57, 0x65, 0x62, 0x33, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x10, 0xa2, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x53, 0x74, - 0x6f, 0x72, 0x61, 0x67, 0x65, 0x10, 0xa3, 0x07, 0x12, 0x12, 0x0a, 0x0d, 0x50, 0x6c, 0x61, 0x6e, - 0x65, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x44, 0x62, 0x10, 0xa4, 0x07, 0x12, 0x0e, 0x0a, 0x09, - 0x41, 0x6e, 0x74, 0x68, 0x72, 0x6f, 0x70, 0x69, 0x63, 0x10, 0xa5, 0x07, 0x12, 0x09, 0x0a, 0x04, - 0x52, 0x61, 0x6d, 0x70, 0x10, 0xa6, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x4b, 0x6c, 0x61, 0x76, 0x69, - 0x79, 0x6f, 0x10, 0xa7, 0x07, 0x12, 0x14, 0x0a, 0x0f, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, - 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x64, 0x79, 0x10, 0xa8, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x56, - 0x6f, 0x69, 0x63, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x10, 0xa9, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x50, - 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x10, 0xaa, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x50, 0x49, - 0x6e, 0x66, 0x6f, 0x10, 0xab, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x49, 0x70, 0x32, 0x6c, 0x6f, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0xac, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x49, 0x6e, 0x73, 0x74, - 0x61, 0x6d, 0x6f, 0x6a, 0x6f, 0x10, 0xad, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x50, 0x6f, 0x72, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x10, 0xae, 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x50, 0x6f, 0x72, 0x74, - 0x61, 0x69, 0x6e, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xaf, 0x07, 0x12, 0x0b, 0x0a, - 0x06, 0x4c, 0x6f, 0x67, 0x67, 0x6c, 0x79, 0x10, 0xb0, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x4f, 0x70, - 0x65, 0x6e, 0x56, 0x70, 0x6e, 0x10, 0xb1, 0x07, 0x12, 0x1e, 0x0a, 0x19, 0x56, 0x61, 0x67, 0x72, - 0x61, 0x6e, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xb2, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x65, 0x74, 0x74, - 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xb3, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x5a, 0x65, - 0x72, 0x6f, 0x54, 0x69, 0x65, 0x72, 0x10, 0xb4, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x70, 0x70, - 0x4f, 0x70, 0x74, 0x69, 0x63, 0x73, 0x10, 0xb5, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x4d, 0x65, 0x74, - 0x61, 0x62, 0x61, 0x73, 0x65, 0x10, 0xb6, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x6f, 0x69, 0x6e, - 0x62, 0x61, 0x73, 0x65, 0x57, 0x61, 0x61, 0x53, 0x10, 0xb7, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x4c, - 0x65, 0x6d, 0x6f, 0x6e, 0x53, 0x71, 0x75, 0x65, 0x65, 0x7a, 0x79, 0x10, 0xb8, 0x07, 0x12, 0x0d, - 0x0a, 0x08, 0x42, 0x75, 0x64, 0x69, 0x62, 0x61, 0x73, 0x65, 0x10, 0xb9, 0x07, 0x12, 0x0f, 0x0a, - 0x0a, 0x44, 0x65, 0x6e, 0x6f, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x10, 0xba, 0x07, 0x12, 0x0b, - 0x0a, 0x06, 0x53, 0x74, 0x72, 0x69, 0x70, 0x6f, 0x10, 0xbb, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x52, - 0x65, 0x70, 0x6c, 0x79, 0x49, 0x4f, 0x10, 0xbc, 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x7a, 0x75, - 0x72, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x10, 0xbd, 0x07, 0x12, 0x1b, 0x0a, 0x16, 0x41, 0x7a, - 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x52, 0x65, 0x67, 0x69, - 0x73, 0x74, 0x72, 0x79, 0x10, 0xbe, 0x07, 0x12, 0x12, 0x0a, 0x0d, 0x41, 0x57, 0x53, 0x53, 0x65, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0xbf, 0x07, 0x12, 0x09, 0x0a, 0x04, 0x43, - 0x6f, 0x64, 0x61, 0x10, 0xc0, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x7a, 0x49, 0x4f, - 0x10, 0xc1, 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x62, 0x72, 0x69, 0x74, - 0x65, 0x10, 0xc2, 0x07, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x10, 0xc3, 0x07, - 0x12, 0x13, 0x0a, 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, 0x69, 0x6e, 0x61, 0x6e, - 0x63, 0x65, 0x10, 0xc4, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x4f, 0x76, 0x65, 0x72, 0x6c, 0x6f, 0x6f, - 0x70, 0x10, 0xc5, 0x07, 0x12, 0x0a, 0x0a, 0x05, 0x4e, 0x67, 0x72, 0x6f, 0x6b, 0x10, 0xc6, 0x07, - 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x65, 0x10, 0xc7, 0x07, - 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, 0x10, 0xc8, 0x07, 0x12, - 0x2a, 0x0a, 0x25, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, 0x76, 0x65, 0x44, 0x69, - 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x10, 0xc9, 0x07, 0x12, 0x20, 0x0a, 0x1b, 0x41, - 0x7a, 0x75, 0x72, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x6f, 0x72, 0x52, 0x65, 0x64, 0x69, - 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x10, 0xca, 0x07, 0x12, 0x21, 0x0a, - 0x1c, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x44, 0x42, 0x4b, 0x65, - 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x10, 0xcb, 0x07, - 0x12, 0x23, 0x0a, 0x1e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x44, 0x65, 0x76, 0x6f, 0x70, 0x73, 0x50, - 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, - 0x65, 0x6e, 0x10, 0xcc, 0x07, 0x12, 0x15, 0x0a, 0x10, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x46, 0x75, - 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0xcd, 0x07, 0x12, 0x2c, 0x0a, 0x27, - 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, 0x4c, 0x57, 0x65, 0x62, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, - 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x10, 0xce, 0x07, 0x12, 0x12, 0x0a, 0x0d, 0x41, 0x7a, - 0x75, 0x72, 0x65, 0x53, 0x61, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xcf, 0x07, 0x12, 0x18, - 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x41, 0x64, 0x6d, - 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0xd0, 0x07, 0x12, 0x18, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, - 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, 0x4b, 0x65, 0x79, 0x10, - 0xd1, 0x07, 0x12, 0x1f, 0x0a, 0x1a, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, 0x61, 0x6e, 0x61, 0x67, - 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, - 0x10, 0xd2, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x53, 0x51, 0x4c, 0x10, - 0xd3, 0x07, 0x12, 0x0a, 0x0a, 0x05, 0x46, 0x6c, 0x79, 0x49, 0x4f, 0x10, 0xd4, 0x07, 0x12, 0x0e, - 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x57, 0x69, 0x74, 0x68, 0x10, 0xd5, 0x07, 0x12, 0x0f, - 0x0a, 0x0a, 0x4a, 0x75, 0x70, 0x69, 0x74, 0x65, 0x72, 0x4f, 0x6e, 0x65, 0x10, 0xd6, 0x07, 0x12, - 0x25, 0x0a, 0x20, 0x47, 0x43, 0x50, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, - 0x61, 0x6c, 0x73, 0x10, 0xd7, 0x07, 0x12, 0x08, 0x0a, 0x03, 0x57, 0x69, 0x7a, 0x10, 0xd8, 0x07, - 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x61, 0x67, 0x61, 0x72, 0x6d, 0x65, 0x10, 0xd9, 0x07, 0x12, 0x0c, - 0x0a, 0x07, 0x4f, 0x6e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x10, 0xda, 0x07, 0x42, 0x3d, 0x5a, 0x3b, - 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, - 0x6c, 0x65, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, 0x66, 0x66, - 0x6c, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, 0x62, 0x2f, - 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x12, 0x13, 0x0a, 0x0a, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x6f, 0x6d, 0x61, 0x74, 0x10, 0xfb, + 0x01, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x62, 0x6c, + 0x69, 0x6e, 0x6b, 0x10, 0xfc, 0x01, 0x12, 0x0a, 0x0a, 0x05, 0x42, 0x6f, 0x72, 0x65, 0x64, 0x10, + 0xfd, 0x01, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x61, 0x6d, 0x70, 0x61, 0x79, 0x6e, 0x10, 0xfe, 0x01, + 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6c, 0x69, 0x6e, 0x63, 0x68, 0x70, 0x61, 0x64, 0x10, 0xff, 0x01, + 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x48, 0x75, 0x62, 0x10, 0x80, + 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x65, 0x62, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x10, 0x81, 0x02, + 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x79, 0x73, 0x70, 0x61, 0x74, 0x63, 0x68, 0x10, 0x82, 0x02, 0x12, + 0x10, 0x0a, 0x0b, 0x47, 0x75, 0x61, 0x72, 0x64, 0x69, 0x61, 0x6e, 0x61, 0x70, 0x69, 0x10, 0x83, + 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x48, 0x61, 0x72, 0x76, 0x65, 0x73, 0x74, 0x10, 0x84, 0x02, 0x12, + 0x0c, 0x0a, 0x07, 0x4d, 0x6f, 0x6f, 0x73, 0x65, 0x6e, 0x64, 0x10, 0x85, 0x02, 0x12, 0x10, 0x0a, + 0x0b, 0x4f, 0x70, 0x65, 0x6e, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x10, 0x86, 0x02, 0x12, + 0x0d, 0x0a, 0x08, 0x53, 0x69, 0x74, 0x65, 0x6c, 0x65, 0x61, 0x66, 0x10, 0x87, 0x02, 0x12, 0x10, + 0x0a, 0x0b, 0x53, 0x71, 0x75, 0x61, 0x72, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x10, 0x88, 0x02, + 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x6c, 0x6f, 0x77, 0x46, 0x6c, 0x75, 0x10, 0x89, 0x02, 0x12, 0x0b, + 0x0a, 0x06, 0x4e, 0x69, 0x6d, 0x62, 0x6c, 0x65, 0x10, 0x8a, 0x02, 0x12, 0x14, 0x0a, 0x0f, 0x4c, + 0x65, 0x73, 0x73, 0x41, 0x6e, 0x6e, 0x6f, 0x79, 0x69, 0x6e, 0x67, 0x43, 0x52, 0x4d, 0x10, 0x8b, + 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x68, 0x75, 0x6e, 0x74, 0x10, 0x8c, 0x02, 0x12, + 0x0c, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x74, 0x69, 0x76, 0x6f, 0x10, 0x8d, 0x02, 0x12, 0x0f, 0x0a, + 0x0a, 0x43, 0x61, 0x70, 0x73, 0x75, 0x6c, 0x65, 0x43, 0x52, 0x4d, 0x10, 0x8e, 0x02, 0x12, 0x0e, + 0x0a, 0x09, 0x49, 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x79, 0x10, 0x8f, 0x02, 0x12, 0x0a, + 0x0a, 0x05, 0x4b, 0x79, 0x6c, 0x61, 0x73, 0x10, 0x90, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x4f, 0x6e, + 0x65, 0x70, 0x61, 0x67, 0x65, 0x43, 0x52, 0x4d, 0x10, 0x91, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x55, + 0x73, 0x65, 0x72, 0x10, 0x92, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x50, 0x72, 0x6f, 0x73, 0x70, 0x65, + 0x63, 0x74, 0x43, 0x52, 0x4d, 0x10, 0x93, 0x02, 0x12, 0x18, 0x0a, 0x13, 0x52, 0x65, 0x61, 0x6c, + 0x6c, 0x79, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x65, 0x53, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x73, 0x10, + 0x94, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x41, 0x69, 0x72, 0x73, 0x68, 0x69, 0x70, 0x10, 0x95, 0x02, + 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x72, 0x74, 0x73, 0x79, 0x10, 0x96, 0x02, 0x12, 0x0b, 0x0a, 0x06, + 0x59, 0x61, 0x6e, 0x64, 0x65, 0x78, 0x10, 0x97, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x6c, 0x6f, + 0x63, 0x6b, 0x69, 0x66, 0x79, 0x10, 0x98, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x6e, 0x73, 0x63, + 0x68, 0x65, 0x63, 0x6b, 0x10, 0x99, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x45, 0x61, 0x73, 0x79, 0x49, + 0x6e, 0x73, 0x69, 0x67, 0x68, 0x74, 0x10, 0x9a, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x74, 0x68, + 0x70, 0x6c, 0x6f, 0x72, 0x65, 0x72, 0x10, 0x9b, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x45, 0x76, 0x65, + 0x72, 0x68, 0x6f, 0x75, 0x72, 0x10, 0x9c, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x75, 0x6c, 0x63, + 0x72, 0x75, 0x6d, 0x10, 0x9d, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x65, 0x6f, 0x49, 0x70, 0x69, + 0x66, 0x69, 0x10, 0x9e, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4a, 0x6f, 0x74, 0x66, 0x6f, 0x72, 0x6d, + 0x10, 0x9f, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x65, 0x66, 0x69, 0x6e, 0x65, 0x72, 0x10, 0xa0, + 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x54, 0x69, 0x6d, 0x65, 0x7a, 0x6f, 0x6e, 0x65, 0x61, 0x70, 0x69, + 0x10, 0xa1, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x54, 0x6f, 0x67, 0x67, 0x6c, 0x54, 0x72, 0x61, 0x63, + 0x6b, 0x10, 0xa2, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x56, 0x70, 0x6e, 0x61, 0x70, 0x69, 0x10, 0xa3, + 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xa4, + 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x41, 0x70, 0x6f, 0x6c, 0x6c, 0x6f, 0x10, 0xa5, 0x02, 0x12, 0x0d, + 0x0a, 0x08, 0x45, 0x76, 0x65, 0x72, 0x73, 0x69, 0x67, 0x6e, 0x10, 0xa6, 0x02, 0x12, 0x09, 0x0a, + 0x04, 0x4a, 0x75, 0x72, 0x6f, 0x10, 0xa7, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x4b, 0x61, 0x72, 0x6d, + 0x61, 0x43, 0x52, 0x4d, 0x10, 0xa8, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x65, 0x74, 0x72, 0x69, + 0x6c, 0x6f, 0x10, 0xa9, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x6e, 0x64, 0x61, 0x64, 0x6f, + 0x63, 0x10, 0xaa, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, 0x76, 0x61, 0x6d, 0x70, 0x43, 0x52, + 0x4d, 0x10, 0xab, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x63, 0x6f, 0x6f, + 0x6b, 0x69, 0x65, 0x10, 0xac, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x6c, 0x63, 0x6f, 0x6e, 0x6f, + 0x73, 0x74, 0x10, 0xad, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x6c, 0x6f, 0x67, 0x67, 0x65, 0x72, + 0x10, 0xae, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x63, 0x63, 0x75, 0x77, 0x65, 0x61, 0x74, 0x68, + 0x65, 0x72, 0x10, 0xaf, 0x02, 0x12, 0x13, 0x0a, 0x0a, 0x4f, 0x70, 0x65, 0x6e, 0x67, 0x72, 0x61, + 0x70, 0x68, 0x72, 0x10, 0xb0, 0x02, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x09, 0x0a, 0x04, 0x52, 0x61, + 0x77, 0x67, 0x10, 0xb1, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x69, 0x6f, 0x74, 0x67, 0x61, 0x6d, + 0x65, 0x73, 0x10, 0xb2, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x6f, 0x6e, 0x69, 0x6e, 0x41, 0x70, + 0x70, 0x10, 0xb3, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x72, 0x6d, 0x67, 0x6c, 0x61, + 0x73, 0x73, 0x10, 0xb4, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x6f, 0x6d, 0x74, 0x6f, 0x6d, 0x10, + 0xb5, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x77, 0x69, 0x74, 0x63, 0x68, 0x10, 0xb6, 0x02, 0x12, + 0x0b, 0x0a, 0x06, 0x44, 0x6f, 0x63, 0x75, 0x6d, 0x6f, 0x10, 0xb7, 0x02, 0x12, 0x0e, 0x0a, 0x09, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x77, 0x61, 0x79, 0x73, 0x10, 0xb8, 0x02, 0x12, 0x0f, 0x0a, 0x0a, + 0x56, 0x65, 0x65, 0x76, 0x61, 0x76, 0x61, 0x75, 0x6c, 0x74, 0x10, 0xb9, 0x02, 0x12, 0x10, 0x0a, + 0x0b, 0x4b, 0x69, 0x74, 0x65, 0x43, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x10, 0xba, 0x02, 0x12, + 0x17, 0x0a, 0x12, 0x53, 0x68, 0x6f, 0x70, 0x65, 0x65, 0x4f, 0x70, 0x65, 0x6e, 0x50, 0x6c, 0x61, + 0x74, 0x66, 0x6f, 0x72, 0x6d, 0x10, 0xbb, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x54, 0x65, 0x61, 0x6d, + 0x56, 0x69, 0x65, 0x77, 0x65, 0x72, 0x10, 0xbc, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x75, 0x6c, + 0x62, 0x75, 0x6c, 0x10, 0xbd, 0x02, 0x12, 0x16, 0x0a, 0x11, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, + 0x6c, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x52, 0x4d, 0x10, 0xbe, 0x02, 0x12, 0x0d, + 0x0a, 0x08, 0x54, 0x65, 0x61, 0x6d, 0x67, 0x61, 0x74, 0x65, 0x10, 0xbf, 0x02, 0x12, 0x0c, 0x0a, + 0x07, 0x41, 0x78, 0x6f, 0x6e, 0x61, 0x75, 0x74, 0x10, 0xc0, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x54, + 0x79, 0x6e, 0x74, 0x65, 0x63, 0x10, 0xc1, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x41, 0x70, 0x70, 0x63, + 0x75, 0x65, 0x73, 0x10, 0xc2, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x6f, 0x6b, 0x6c, + 0x6f, 0x73, 0x65, 0x10, 0xc3, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x70, + 0x6c, 0x61, 0x6e, 0x10, 0xc4, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x6f, 0x74, 0x6d, 0x61, 0x69, + 0x6c, 0x65, 0x72, 0x10, 0xc5, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x45, 0x6d, 0x61, + 0x69, 0x6c, 0x10, 0xc6, 0x02, 0x12, 0x0e, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x45, 0x6d, 0x61, 0x69, + 0x6c, 0x73, 0x10, 0xc7, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x4b, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, + 0x10, 0xc8, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x4c, 0x65, 0x61, 0x64, 0x66, 0x65, 0x65, 0x64, 0x65, + 0x72, 0x10, 0xc9, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x52, 0x61, 0x76, 0x65, 0x6e, 0x10, 0xca, 0x02, + 0x12, 0x10, 0x0a, 0x0b, 0x52, 0x6f, 0x63, 0x6b, 0x65, 0x74, 0x52, 0x65, 0x61, 0x63, 0x68, 0x10, + 0xcb, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x55, 0x70, 0x6c, 0x65, 0x61, 0x64, 0x10, 0xcc, 0x02, 0x12, + 0x0f, 0x0a, 0x0a, 0x42, 0x72, 0x61, 0x6e, 0x64, 0x66, 0x65, 0x74, 0x63, 0x68, 0x10, 0xcd, 0x02, + 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x6c, 0x65, 0x61, 0x72, 0x62, 0x69, 0x74, 0x10, 0xce, 0x02, 0x12, + 0x0c, 0x0a, 0x07, 0x43, 0x72, 0x6f, 0x77, 0x64, 0x69, 0x6e, 0x10, 0xcf, 0x02, 0x12, 0x0d, 0x0a, + 0x08, 0x4d, 0x61, 0x70, 0x71, 0x75, 0x65, 0x73, 0x74, 0x10, 0xd0, 0x02, 0x12, 0x0f, 0x0a, 0x0a, + 0x4e, 0x6f, 0x74, 0x69, 0x63, 0x65, 0x61, 0x62, 0x6c, 0x65, 0x10, 0xd1, 0x02, 0x12, 0x0b, 0x0a, + 0x06, 0x4f, 0x6e, 0x62, 0x75, 0x6b, 0x61, 0x10, 0xd2, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x6f, + 0x64, 0x6f, 0x69, 0x73, 0x74, 0x10, 0xd3, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x72, + 0x79, 0x63, 0x68, 0x69, 0x65, 0x66, 0x10, 0xd4, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x4c, 0x69, 0x6e, + 0x6b, 0x65, 0x64, 0x49, 0x6e, 0x10, 0xd5, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x59, 0x6f, 0x75, 0x53, + 0x69, 0x67, 0x6e, 0x10, 0xd6, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, + 0x10, 0xd7, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x54, 0x65, 0x6c, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x10, + 0xd8, 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x70, 0x6f, 0x6f, 0x6e, 0x61, 0x63, 0x75, 0x6c, 0x61, + 0x72, 0x10, 0xd9, 0x02, 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x65, 0x72, 0x69, 0x73, 0x77, 0x65, 0x61, + 0x74, 0x68, 0x65, 0x72, 0x10, 0xda, 0x02, 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x6c, 0x70, 0x68, 0x61, + 0x76, 0x61, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x10, 0xdb, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x6d, + 0x67, 0x75, 0x72, 0x10, 0xdc, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x6d, 0x61, 0x67, 0x67, 0x61, + 0x10, 0xdd, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x4d, 0x53, 0x41, 0x70, 0x69, 0x10, 0xde, 0x02, + 0x12, 0x11, 0x0a, 0x0c, 0x44, 0x69, 0x73, 0x74, 0x72, 0x69, 0x62, 0x75, 0x73, 0x69, 0x6f, 0x6e, + 0x10, 0xdf, 0x02, 0x12, 0x12, 0x0a, 0x09, 0x42, 0x6c, 0x61, 0x62, 0x6c, 0x61, 0x62, 0x75, 0x73, + 0x10, 0xe0, 0x02, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x57, 0x6f, 0x72, 0x64, 0x73, + 0x41, 0x70, 0x69, 0x10, 0xe1, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x6c, 0x61, 0x79, 0x65, 0x72, 0x10, 0xe2, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x74, + 0x6d, 0x6c, 0x32, 0x50, 0x64, 0x66, 0x10, 0xe3, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x49, 0x50, 0x47, + 0x65, 0x6f, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0xe4, 0x02, 0x12, 0x0b, 0x0a, + 0x06, 0x4f, 0x77, 0x6c, 0x62, 0x6f, 0x74, 0x10, 0xe5, 0x02, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x6c, + 0x6f, 0x75, 0x64, 0x6d, 0x65, 0x72, 0x73, 0x69, 0x76, 0x65, 0x10, 0xe6, 0x02, 0x12, 0x0d, 0x0a, + 0x08, 0x44, 0x79, 0x6e, 0x61, 0x6c, 0x69, 0x73, 0x74, 0x10, 0xe7, 0x02, 0x12, 0x14, 0x0a, 0x0f, + 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x61, 0x74, 0x65, 0x41, 0x50, 0x49, 0x10, + 0xe8, 0x02, 0x12, 0x0f, 0x0a, 0x0a, 0x48, 0x6f, 0x6c, 0x69, 0x64, 0x61, 0x79, 0x41, 0x50, 0x49, + 0x10, 0xe9, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x70, 0x61, 0x70, 0x69, 0x10, 0xea, 0x02, 0x12, + 0x10, 0x0a, 0x0b, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xeb, + 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x75, 0x74, 0x72, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x69, 0x78, + 0x10, 0xec, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x53, 0x77, 0x65, 0x6c, 0x6c, 0x10, 0xed, 0x02, 0x12, + 0x19, 0x0a, 0x14, 0x43, 0x6c, 0x69, 0x63, 0x6b, 0x75, 0x70, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, + 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xee, 0x02, 0x12, 0x0a, 0x0a, 0x05, 0x4e, 0x69, + 0x74, 0x72, 0x6f, 0x10, 0xef, 0x02, 0x12, 0x08, 0x0a, 0x03, 0x52, 0x65, 0x76, 0x10, 0xf0, 0x02, + 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x75, 0x6e, 0x52, 0x75, 0x6e, 0x49, 0x74, 0x10, 0xf1, 0x02, 0x12, + 0x0d, 0x0a, 0x08, 0x54, 0x79, 0x70, 0x65, 0x66, 0x6f, 0x72, 0x6d, 0x10, 0xf2, 0x02, 0x12, 0x0d, + 0x0a, 0x08, 0x4d, 0x69, 0x78, 0x70, 0x61, 0x6e, 0x65, 0x6c, 0x10, 0xf3, 0x02, 0x12, 0x0c, 0x0a, + 0x07, 0x54, 0x72, 0x61, 0x64, 0x69, 0x65, 0x72, 0x10, 0xf4, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x56, + 0x65, 0x72, 0x69, 0x66, 0x69, 0x65, 0x72, 0x10, 0xf5, 0x02, 0x12, 0x0d, 0x0a, 0x08, 0x56, 0x6f, + 0x75, 0x63, 0x68, 0x65, 0x72, 0x79, 0x10, 0xf6, 0x02, 0x12, 0x0b, 0x0a, 0x06, 0x41, 0x6c, 0x65, + 0x67, 0x72, 0x61, 0x10, 0xf7, 0x02, 0x12, 0x09, 0x0a, 0x04, 0x41, 0x75, 0x64, 0x64, 0x10, 0xf8, + 0x02, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x61, 0x72, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x10, 0xf9, 0x02, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x69, 0x6e, 0x6c, 0x69, 0x62, 0x10, 0xfa, + 0x02, 0x12, 0x15, 0x0a, 0x10, 0x45, 0x78, 0x63, 0x68, 0x61, 0x6e, 0x67, 0x65, 0x52, 0x61, 0x74, + 0x65, 0x73, 0x41, 0x50, 0x49, 0x10, 0xfb, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x75, 0x72, 0x72, + 0x65, 0x6e, 0x63, 0x79, 0x53, 0x63, 0x6f, 0x6f, 0x70, 0x10, 0xfc, 0x02, 0x12, 0x0d, 0x0a, 0x08, + 0x46, 0x58, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x10, 0xfd, 0x02, 0x12, 0x12, 0x0a, 0x0d, 0x43, + 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xfe, 0x02, 0x12, + 0x0e, 0x0a, 0x09, 0x47, 0x65, 0x74, 0x47, 0x65, 0x6f, 0x41, 0x50, 0x49, 0x10, 0xff, 0x02, 0x12, + 0x0d, 0x0a, 0x08, 0x41, 0x62, 0x73, 0x74, 0x72, 0x61, 0x63, 0x74, 0x10, 0x80, 0x03, 0x12, 0x0d, + 0x0a, 0x08, 0x42, 0x69, 0x6c, 0x6c, 0x6f, 0x6d, 0x61, 0x74, 0x10, 0x81, 0x03, 0x12, 0x0b, 0x0a, + 0x06, 0x44, 0x6f, 0x76, 0x69, 0x63, 0x6f, 0x10, 0x82, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x69, + 0x74, 0x62, 0x61, 0x72, 0x10, 0x83, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x75, 0x67, 0x73, 0x6e, + 0x61, 0x67, 0x10, 0x84, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x73, 0x73, 0x65, 0x6d, 0x62, 0x6c, + 0x79, 0x41, 0x49, 0x10, 0x85, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x64, 0x61, 0x66, 0x72, 0x75, + 0x69, 0x74, 0x49, 0x4f, 0x10, 0x86, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x70, 0x69, 0x66, 0x79, + 0x10, 0x87, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x69, 0x6e, 0x47, 0x65, 0x63, 0x6b, 0x6f, + 0x10, 0x88, 0x03, 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x43, 0x6f, 0x6d, + 0x70, 0x61, 0x72, 0x65, 0x10, 0x89, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x75, 0x6c, 0x6c, 0x73, + 0x74, 0x6f, 0x72, 0x79, 0x10, 0x8a, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x48, 0x65, 0x6c, 0x6c, 0x6f, + 0x53, 0x69, 0x67, 0x6e, 0x10, 0x8b, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x4c, 0x6f, 0x79, 0x76, 0x65, + 0x72, 0x73, 0x65, 0x10, 0x8c, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x4e, 0x65, 0x74, 0x43, 0x6f, 0x72, + 0x65, 0x10, 0x8d, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x61, 0x75, 0x63, 0x65, 0x4c, 0x61, 0x62, + 0x73, 0x10, 0x8e, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x6c, 0x69, 0x65, 0x6e, 0x56, 0x61, 0x75, + 0x6c, 0x74, 0x10, 0x8f, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x70, 0x69, 0x66, 0x6c, 0x61, 0x73, + 0x68, 0x10, 0x91, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x69, 0x6e, 0x6c, 0x61, 0x79, 0x65, + 0x72, 0x10, 0x92, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x73, + 0x41, 0x50, 0x49, 0x10, 0x93, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x61, 0x74, 0x61, 0x47, 0x6f, + 0x76, 0x10, 0x94, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x45, 0x6e, 0x69, 0x67, 0x6d, 0x61, 0x10, 0x95, + 0x03, 0x12, 0x1a, 0x0a, 0x15, 0x46, 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x69, 0x61, 0x6c, 0x4d, 0x6f, + 0x64, 0x65, 0x6c, 0x69, 0x6e, 0x67, 0x50, 0x72, 0x65, 0x70, 0x10, 0x96, 0x03, 0x12, 0x0d, 0x0a, + 0x08, 0x47, 0x65, 0x6f, 0x63, 0x6f, 0x64, 0x69, 0x6f, 0x10, 0x97, 0x03, 0x12, 0x0c, 0x0a, 0x07, + 0x48, 0x65, 0x72, 0x65, 0x41, 0x50, 0x49, 0x10, 0x98, 0x03, 0x12, 0x13, 0x0a, 0x0a, 0x4d, 0x61, + 0x63, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x10, 0x99, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, + 0x0c, 0x0a, 0x07, 0x4f, 0x4f, 0x50, 0x53, 0x70, 0x61, 0x6d, 0x10, 0x9a, 0x03, 0x12, 0x10, 0x0a, + 0x0b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x49, 0x4f, 0x10, 0x9b, 0x03, 0x12, + 0x0f, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x61, 0x70, 0x65, 0x72, 0x41, 0x50, 0x49, 0x10, 0x9c, 0x03, + 0x12, 0x13, 0x0a, 0x0e, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x54, 0x72, 0x61, 0x69, + 0x6c, 0x73, 0x10, 0x9d, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x54, 0x6f, 0x6d, 0x6f, 0x72, 0x72, 0x6f, + 0x77, 0x49, 0x4f, 0x10, 0x9e, 0x03, 0x12, 0x13, 0x0a, 0x0e, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x43, + 0x6f, 0x69, 0x6e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x10, 0x9f, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x46, + 0x61, 0x63, 0x65, 0x50, 0x6c, 0x75, 0x73, 0x50, 0x6c, 0x75, 0x73, 0x10, 0xa0, 0x03, 0x12, 0x0e, + 0x0a, 0x09, 0x56, 0x6f, 0x69, 0x63, 0x65, 0x67, 0x61, 0x69, 0x6e, 0x10, 0xa1, 0x03, 0x12, 0x0d, + 0x0a, 0x08, 0x44, 0x65, 0x65, 0x70, 0x67, 0x72, 0x61, 0x6d, 0x10, 0xa2, 0x03, 0x12, 0x13, 0x0a, + 0x0e, 0x56, 0x69, 0x73, 0x75, 0x61, 0x6c, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x69, 0x6e, 0x67, 0x10, + 0xa3, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x46, 0x69, 0x6e, 0x6e, 0x68, 0x75, 0x62, 0x10, 0xa4, 0x03, + 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x69, 0x69, 0x6e, 0x67, 0x6f, 0x10, 0xa5, 0x03, 0x12, 0x10, 0x0a, + 0x0b, 0x52, 0x69, 0x6e, 0x67, 0x43, 0x65, 0x6e, 0x74, 0x72, 0x61, 0x6c, 0x10, 0xa6, 0x03, 0x12, + 0x0b, 0x0a, 0x06, 0x46, 0x69, 0x6e, 0x61, 0x67, 0x65, 0x10, 0xa7, 0x03, 0x12, 0x0b, 0x0a, 0x06, + 0x45, 0x64, 0x61, 0x6d, 0x61, 0x6d, 0x10, 0xa8, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x48, 0x79, 0x70, + 0x65, 0x41, 0x75, 0x64, 0x69, 0x74, 0x6f, 0x72, 0x10, 0xa9, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x47, + 0x65, 0x6e, 0x67, 0x6f, 0x10, 0xaa, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x46, 0x72, 0x6f, 0x6e, 0x74, + 0x10, 0xab, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x6c, 0x65, 0x65, 0x74, 0x62, 0x61, 0x73, 0x65, + 0x10, 0xac, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x75, 0x62, 0x62, 0x6c, 0x65, 0x10, 0xad, 0x03, + 0x12, 0x0f, 0x0a, 0x0a, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x62, 0x65, 0x61, 0x72, 0x10, 0xae, + 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x41, 0x64, 0x7a, 0x75, 0x6e, 0x61, 0x10, 0xaf, 0x03, 0x12, 0x13, + 0x0a, 0x0e, 0x42, 0x69, 0x74, 0x63, 0x6f, 0x69, 0x6e, 0x41, 0x76, 0x65, 0x72, 0x61, 0x67, 0x65, + 0x10, 0xb0, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x6f, 0x6d, 0x6d, 0x65, 0x72, 0x63, 0x65, 0x4a, + 0x53, 0x10, 0xb1, 0x03, 0x12, 0x13, 0x0a, 0x0e, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x4c, 0x61, + 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x10, 0xb2, 0x03, 0x12, 0x11, 0x0a, 0x08, 0x46, 0x61, 0x6b, + 0x65, 0x4a, 0x53, 0x4f, 0x4e, 0x10, 0xb3, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x10, 0x0a, 0x0b, + 0x47, 0x72, 0x61, 0x70, 0x68, 0x68, 0x6f, 0x70, 0x70, 0x65, 0x72, 0x10, 0xb4, 0x03, 0x12, 0x0d, + 0x0a, 0x08, 0x4c, 0x65, 0x78, 0x69, 0x67, 0x72, 0x61, 0x6d, 0x10, 0xb5, 0x03, 0x12, 0x10, 0x0a, + 0x0b, 0x4c, 0x69, 0x6e, 0x6b, 0x50, 0x72, 0x65, 0x76, 0x69, 0x65, 0x77, 0x10, 0xb6, 0x03, 0x12, + 0x0e, 0x0a, 0x09, 0x4e, 0x75, 0x6d, 0x76, 0x65, 0x72, 0x69, 0x66, 0x79, 0x10, 0xb7, 0x03, 0x12, + 0x0f, 0x0a, 0x0a, 0x50, 0x72, 0x6f, 0x78, 0x79, 0x43, 0x72, 0x61, 0x77, 0x6c, 0x10, 0xb8, 0x03, + 0x12, 0x0f, 0x0a, 0x0a, 0x5a, 0x69, 0x70, 0x43, 0x6f, 0x64, 0x65, 0x41, 0x50, 0x49, 0x10, 0xb9, + 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x6d, 0x65, 0x74, 0x63, 0x68, 0x61, 0x74, 0x10, 0xba, + 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x4b, 0x65, 0x79, 0x67, 0x65, 0x6e, 0x10, 0xbb, 0x03, 0x12, 0x0d, + 0x0a, 0x08, 0x4d, 0x69, 0x78, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xbc, 0x03, 0x12, 0x0c, 0x0a, + 0x07, 0x54, 0x61, 0x74, 0x75, 0x6d, 0x49, 0x4f, 0x10, 0xbd, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x54, + 0x6d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x10, 0xbe, 0x03, 0x12, 0x0f, 0x0a, 0x06, 0x4c, 0x61, 0x73, + 0x74, 0x66, 0x6d, 0x10, 0xbf, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x72, + 0x6f, 0x77, 0x73, 0x68, 0x6f, 0x74, 0x10, 0xc0, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x4a, 0x53, 0x4f, + 0x4e, 0x62, 0x69, 0x6e, 0x10, 0xc1, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x4c, 0x6f, 0x63, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x49, 0x51, 0x10, 0xc2, 0x03, 0x12, 0x12, 0x0a, 0x0d, 0x53, 0x63, 0x72, 0x65, + 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, 0x41, 0x50, 0x49, 0x10, 0xc3, 0x03, 0x12, 0x11, 0x0a, 0x0c, + 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xc4, 0x03, 0x12, + 0x0c, 0x0a, 0x07, 0x41, 0x6d, 0x61, 0x64, 0x65, 0x75, 0x73, 0x10, 0xc5, 0x03, 0x12, 0x0f, 0x0a, + 0x0a, 0x46, 0x6f, 0x75, 0x72, 0x53, 0x71, 0x75, 0x61, 0x72, 0x65, 0x10, 0xc6, 0x03, 0x12, 0x0b, + 0x0a, 0x06, 0x46, 0x6c, 0x69, 0x63, 0x6b, 0x72, 0x10, 0xc7, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x43, + 0x6c, 0x69, 0x63, 0x6b, 0x48, 0x65, 0x6c, 0x70, 0x10, 0xc8, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x41, + 0x6d, 0x62, 0x65, 0x65, 0x10, 0xc9, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x70, 0x69, 0x32, 0x43, + 0x61, 0x72, 0x74, 0x10, 0xca, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x48, 0x79, 0x70, 0x65, 0x72, 0x74, + 0x72, 0x61, 0x63, 0x6b, 0x10, 0xcb, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x4b, 0x61, 0x6b, 0x61, 0x6f, + 0x54, 0x61, 0x6c, 0x6b, 0x10, 0xcc, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x69, 0x74, 0x65, 0x4b, + 0x69, 0x74, 0x10, 0xcd, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x68, 0x75, 0x74, 0x74, 0x65, 0x72, + 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x10, 0xce, 0x03, 0x12, 0x12, 0x0a, 0x09, 0x54, 0x65, 0x78, 0x74, + 0x32, 0x44, 0x61, 0x74, 0x61, 0x10, 0xcf, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x13, 0x0a, 0x0e, + 0x59, 0x6f, 0x75, 0x4e, 0x65, 0x65, 0x64, 0x41, 0x42, 0x75, 0x64, 0x67, 0x65, 0x74, 0x10, 0xd0, + 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x72, 0x69, 0x63, 0x6b, 0x65, 0x74, 0x10, 0xd1, 0x03, 0x12, + 0x0e, 0x0a, 0x09, 0x46, 0x69, 0x6c, 0x65, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xd2, 0x03, 0x12, + 0x0a, 0x0a, 0x05, 0x47, 0x79, 0x61, 0x7a, 0x6f, 0x10, 0xd3, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x4d, + 0x61, 0x76, 0x65, 0x6e, 0x6c, 0x69, 0x6e, 0x6b, 0x10, 0xd4, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x53, + 0x68, 0x65, 0x65, 0x74, 0x79, 0x10, 0xd5, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x70, 0x6f, 0x72, + 0x74, 0x73, 0x6d, 0x6f, 0x6e, 0x6b, 0x10, 0xd6, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x74, 0x6f, + 0x63, 0x6b, 0x64, 0x61, 0x74, 0x61, 0x10, 0xd7, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x55, 0x6e, 0x73, + 0x70, 0x6c, 0x61, 0x73, 0x68, 0x10, 0xd8, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x6c, 0x6c, 0x73, + 0x70, 0x6f, 0x72, 0x74, 0x73, 0x10, 0xd9, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x43, 0x61, 0x6c, 0x6f, + 0x72, 0x69, 0x65, 0x4e, 0x69, 0x6e, 0x6a, 0x61, 0x10, 0xda, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x57, + 0x61, 0x6c, 0x6b, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x10, 0xdb, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x53, + 0x74, 0x72, 0x61, 0x76, 0x61, 0x10, 0xdc, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x69, 0x63, 0x65, + 0x72, 0x6f, 0x10, 0xdd, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x49, 0x50, 0x51, 0x75, 0x61, 0x6c, 0x69, + 0x74, 0x79, 0x10, 0xde, 0x03, 0x12, 0x11, 0x0a, 0x0c, 0x50, 0x61, 0x72, 0x61, 0x6c, 0x6c, 0x65, + 0x6c, 0x44, 0x6f, 0x74, 0x73, 0x10, 0xdf, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x6f, 0x61, 0x72, + 0x69, 0x6e, 0x67, 0x10, 0xe0, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x61, 0x69, 0x6c, 0x73, 0x61, + 0x63, 0x10, 0xe1, 0x03, 0x12, 0x0a, 0x0a, 0x05, 0x57, 0x68, 0x6f, 0x78, 0x79, 0x10, 0xe2, 0x03, + 0x12, 0x11, 0x0a, 0x0c, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x57, 0x65, 0x61, 0x74, 0x68, 0x65, 0x72, + 0x10, 0xe3, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x70, 0x69, 0x46, 0x6f, 0x6e, 0x69, 0x63, 0x61, + 0x10, 0xe4, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x41, 0x79, 0x6c, 0x69, 0x65, 0x6e, 0x10, 0xe5, 0x03, + 0x12, 0x0c, 0x0a, 0x07, 0x47, 0x65, 0x6f, 0x63, 0x6f, 0x64, 0x65, 0x10, 0xe6, 0x03, 0x12, 0x0f, + 0x0a, 0x0a, 0x49, 0x63, 0x6f, 0x6e, 0x46, 0x69, 0x6e, 0x64, 0x65, 0x72, 0x10, 0xe7, 0x03, 0x12, + 0x0e, 0x0a, 0x05, 0x49, 0x70, 0x69, 0x66, 0x79, 0x10, 0xe8, 0x03, 0x1a, 0x02, 0x08, 0x01, 0x12, + 0x12, 0x0a, 0x0d, 0x4c, 0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x4c, 0x61, 0x79, 0x65, 0x72, + 0x10, 0xe9, 0x03, 0x12, 0x08, 0x0a, 0x03, 0x4c, 0x6f, 0x62, 0x10, 0xea, 0x03, 0x12, 0x0e, 0x0a, + 0x09, 0x4f, 0x6e, 0x57, 0x61, 0x74, 0x65, 0x72, 0x49, 0x4f, 0x10, 0xeb, 0x03, 0x12, 0x0d, 0x0a, + 0x08, 0x50, 0x61, 0x73, 0x74, 0x65, 0x62, 0x69, 0x6e, 0x10, 0xec, 0x03, 0x12, 0x0d, 0x0a, 0x08, + 0x50, 0x64, 0x66, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x10, 0xed, 0x03, 0x12, 0x0c, 0x0a, 0x07, 0x50, + 0x69, 0x78, 0x61, 0x62, 0x61, 0x79, 0x10, 0xee, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x52, 0x65, 0x61, + 0x64, 0x4d, 0x65, 0x10, 0xef, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x56, 0x61, 0x74, 0x4c, 0x61, 0x79, + 0x65, 0x72, 0x10, 0xf0, 0x03, 0x12, 0x0f, 0x0a, 0x0a, 0x56, 0x69, 0x72, 0x75, 0x73, 0x54, 0x6f, + 0x74, 0x61, 0x6c, 0x10, 0xf1, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x69, 0x72, 0x56, 0x69, 0x73, + 0x75, 0x61, 0x6c, 0x10, 0xf2, 0x03, 0x12, 0x13, 0x0a, 0x0e, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x63, 0x79, 0x66, 0x72, 0x65, 0x61, 0x6b, 0x73, 0x10, 0xf3, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x44, + 0x75, 0x66, 0x66, 0x65, 0x6c, 0x10, 0xf4, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x46, 0x6c, 0x61, 0x74, + 0x49, 0x4f, 0x10, 0xf5, 0x03, 0x12, 0x08, 0x0a, 0x03, 0x4d, 0x33, 0x6f, 0x10, 0xf6, 0x03, 0x12, + 0x0b, 0x0a, 0x06, 0x4d, 0x65, 0x73, 0x69, 0x62, 0x6f, 0x10, 0xf7, 0x03, 0x12, 0x0b, 0x0a, 0x06, + 0x4f, 0x70, 0x65, 0x6e, 0x75, 0x76, 0x10, 0xf8, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x6e, 0x69, + 0x70, 0x63, 0x61, 0x72, 0x74, 0x10, 0xf9, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x65, 0x73, 0x74, + 0x74, 0x69, 0x6d, 0x65, 0x10, 0xfa, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x48, 0x61, 0x70, 0x70, 0x79, + 0x73, 0x63, 0x72, 0x69, 0x62, 0x65, 0x10, 0xfb, 0x03, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x75, 0x6d, + 0x61, 0x6e, 0x69, 0x74, 0x79, 0x10, 0xfc, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x6d, 0x70, 0x61, + 0x6c, 0x61, 0x10, 0xfd, 0x03, 0x12, 0x10, 0x0a, 0x0b, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x72, 0x61, + 0x64, 0x69, 0x75, 0x73, 0x10, 0xfe, 0x03, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x75, 0x74, 0x6f, 0x50, + 0x69, 0x6c, 0x6f, 0x74, 0x10, 0xff, 0x03, 0x12, 0x0b, 0x0a, 0x06, 0x42, 0x69, 0x74, 0x6d, 0x65, + 0x78, 0x10, 0x80, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x6c, 0x75, 0x73, 0x74, 0x44, 0x6f, 0x63, + 0x10, 0x81, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x72, 0x69, 0x10, 0x82, + 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x64, 0x66, 0x53, 0x68, 0x69, 0x66, 0x74, 0x10, 0x83, 0x04, + 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x6f, 0x6c, 0x6f, 0x6e, 0x69, 0x65, 0x78, 0x10, 0x84, 0x04, 0x12, + 0x19, 0x0a, 0x14, 0x52, 0x65, 0x73, 0x74, 0x70, 0x61, 0x63, 0x6b, 0x48, 0x74, 0x6d, 0x6c, 0x54, + 0x6f, 0x50, 0x64, 0x66, 0x41, 0x50, 0x49, 0x10, 0x85, 0x04, 0x12, 0x1a, 0x0a, 0x15, 0x52, 0x65, + 0x73, 0x74, 0x70, 0x61, 0x63, 0x6b, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, 0x73, 0x68, 0x6f, 0x74, + 0x41, 0x50, 0x49, 0x10, 0x86, 0x04, 0x12, 0x16, 0x0a, 0x11, 0x53, 0x68, 0x75, 0x74, 0x74, 0x65, + 0x72, 0x73, 0x74, 0x6f, 0x63, 0x6b, 0x4f, 0x41, 0x75, 0x74, 0x68, 0x10, 0x87, 0x04, 0x12, 0x10, + 0x0a, 0x0b, 0x53, 0x6b, 0x79, 0x42, 0x69, 0x6f, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x10, 0x88, 0x04, + 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x62, 0x75, 0x73, 0x65, 0x49, 0x50, 0x44, 0x42, 0x10, 0x89, 0x04, + 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x6c, 0x65, 0x74, 0x68, 0x65, 0x69, 0x61, 0x41, 0x70, 0x69, 0x10, + 0x8a, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x6c, 0x69, 0x74, 0x41, 0x70, 0x70, 0x10, 0x8b, 0x04, + 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x65, 0x6e, 0x73, 0x79, 0x73, 0x10, 0x8c, 0x04, 0x12, 0x0d, 0x0a, + 0x08, 0x43, 0x6c, 0x6f, 0x76, 0x65, 0x72, 0x6c, 0x79, 0x10, 0x8d, 0x04, 0x12, 0x11, 0x0a, 0x0c, + 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x72, 0x79, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x10, 0x8e, 0x04, 0x12, + 0x0b, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x65, 0x49, 0x4f, 0x10, 0x8f, 0x04, 0x12, 0x0e, 0x0a, 0x09, + 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x41, 0x70, 0x69, 0x10, 0x90, 0x04, 0x12, 0x0d, 0x0a, 0x08, + 0x47, 0x65, 0x6f, 0x61, 0x70, 0x69, 0x66, 0x79, 0x10, 0x91, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x49, + 0x50, 0x69, 0x6e, 0x66, 0x6f, 0x44, 0x42, 0x10, 0x92, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x4d, 0x65, + 0x64, 0x69, 0x61, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0x93, 0x04, 0x12, 0x13, 0x0a, 0x0e, 0x4e, + 0x61, 0x73, 0x64, 0x61, 0x71, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x69, 0x6e, 0x6b, 0x10, 0x94, 0x04, + 0x12, 0x11, 0x0a, 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x61, 0x67, 0x65, 0x44, 0x61, 0x74, 0x61, + 0x10, 0x95, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x79, 0x6d, 0x6f, 0x6e, 0x67, 0x6f, 0x10, + 0x96, 0x04, 0x12, 0x12, 0x0a, 0x0d, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, + 0x61, 0x63, 0x6b, 0x10, 0x97, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, 0x62, 0x72, 0x61, 0x6e, + 0x64, 0x6c, 0x79, 0x10, 0x98, 0x04, 0x12, 0x14, 0x0a, 0x0f, 0x53, 0x63, 0x72, 0x65, 0x65, 0x6e, + 0x73, 0x68, 0x6f, 0x74, 0x4c, 0x61, 0x79, 0x65, 0x72, 0x10, 0x99, 0x04, 0x12, 0x0b, 0x0a, 0x06, + 0x53, 0x74, 0x79, 0x74, 0x63, 0x68, 0x10, 0x9a, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x55, 0x6e, 0x70, + 0x6c, 0x75, 0x67, 0x67, 0x10, 0x9b, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x55, 0x50, 0x43, 0x44, 0x61, + 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x10, 0x9c, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x55, 0x73, 0x65, + 0x72, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0x9d, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x47, 0x65, 0x6f, + 0x63, 0x6f, 0x64, 0x69, 0x66, 0x79, 0x10, 0x9e, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x65, 0x77, + 0x73, 0x63, 0x61, 0x74, 0x63, 0x68, 0x65, 0x72, 0x10, 0x9f, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x4e, + 0x69, 0x63, 0x65, 0x72, 0x65, 0x70, 0x6c, 0x79, 0x10, 0xa0, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x50, + 0x61, 0x72, 0x74, 0x6e, 0x65, 0x72, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xa1, 0x04, 0x12, 0x0d, + 0x0a, 0x08, 0x52, 0x6f, 0x75, 0x74, 0x65, 0x34, 0x6d, 0x65, 0x10, 0xa2, 0x04, 0x12, 0x0e, 0x0a, + 0x09, 0x53, 0x63, 0x72, 0x61, 0x70, 0x65, 0x6f, 0x77, 0x6c, 0x10, 0xa3, 0x04, 0x12, 0x10, 0x0a, + 0x0b, 0x53, 0x63, 0x72, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x44, 0x6f, 0x67, 0x10, 0xa4, 0x04, 0x12, + 0x0b, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6b, 0x10, 0xa5, 0x04, 0x12, 0x0e, 0x0a, 0x09, + 0x56, 0x65, 0x72, 0x69, 0x70, 0x68, 0x6f, 0x6e, 0x65, 0x10, 0xa6, 0x04, 0x12, 0x10, 0x0a, 0x0b, + 0x57, 0x65, 0x62, 0x73, 0x63, 0x72, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x10, 0xa7, 0x04, 0x12, 0x0e, + 0x0a, 0x09, 0x5a, 0x65, 0x6e, 0x73, 0x63, 0x72, 0x61, 0x70, 0x65, 0x10, 0xa8, 0x04, 0x12, 0x0c, + 0x0a, 0x07, 0x5a, 0x65, 0x6e, 0x73, 0x65, 0x72, 0x70, 0x10, 0xa9, 0x04, 0x12, 0x0c, 0x0a, 0x07, + 0x43, 0x6f, 0x69, 0x6e, 0x41, 0x70, 0x69, 0x10, 0xaa, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x47, 0x69, + 0x74, 0x74, 0x65, 0x72, 0x10, 0xab, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x48, 0x6f, 0x73, 0x74, 0x10, + 0xac, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x65, 0x78, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xad, + 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x65, 0x73, 0x74, 0x70, 0x61, 0x63, 0x6b, 0x10, 0xae, 0x04, + 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x63, 0x72, 0x61, 0x70, 0x65, 0x72, 0x42, 0x6f, 0x78, 0x10, 0xaf, + 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x63, 0x72, 0x61, 0x70, 0x69, 0x6e, 0x67, 0x41, 0x6e, 0x74, + 0x10, 0xb0, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x70, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x10, 0xb1, 0x04, 0x12, 0x12, 0x0a, 0x0d, 0x53, 0x6d, 0x61, 0x72, 0x74, 0x79, 0x53, 0x74, 0x72, + 0x65, 0x65, 0x74, 0x73, 0x10, 0xb2, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x69, 0x63, 0x6b, 0x65, + 0x74, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x10, 0xb3, 0x04, 0x12, 0x12, 0x0a, 0x0d, 0x41, 0x76, + 0x69, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xb4, 0x04, 0x12, 0x0d, + 0x0a, 0x08, 0x42, 0x6f, 0x6d, 0x62, 0x42, 0x6f, 0x6d, 0x62, 0x10, 0xb5, 0x04, 0x12, 0x10, 0x0a, + 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x6f, 0x64, 0x69, 0x74, 0x69, 0x65, 0x73, 0x10, 0xb6, 0x04, 0x12, + 0x0a, 0x0a, 0x05, 0x44, 0x66, 0x75, 0x73, 0x65, 0x10, 0xb7, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x45, + 0x64, 0x65, 0x6e, 0x41, 0x49, 0x10, 0xb8, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x47, 0x6c, 0x61, 0x73, + 0x73, 0x6e, 0x6f, 0x64, 0x65, 0x10, 0xb9, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x47, 0x75, 0x72, 0x75, + 0x10, 0xba, 0x04, 0x12, 0x09, 0x0a, 0x04, 0x48, 0x69, 0x76, 0x65, 0x10, 0xbb, 0x04, 0x12, 0x0c, + 0x0a, 0x07, 0x48, 0x69, 0x76, 0x65, 0x61, 0x67, 0x65, 0x10, 0xbc, 0x04, 0x12, 0x0c, 0x0a, 0x07, + 0x4b, 0x69, 0x63, 0x6b, 0x62, 0x6f, 0x78, 0x10, 0xbd, 0x04, 0x12, 0x11, 0x0a, 0x08, 0x50, 0x61, + 0x73, 0x73, 0x62, 0x61, 0x73, 0x65, 0x10, 0xbe, 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0f, 0x0a, + 0x0a, 0x50, 0x6f, 0x73, 0x74, 0x61, 0x67, 0x65, 0x41, 0x70, 0x70, 0x10, 0xbf, 0x04, 0x12, 0x0e, + 0x0a, 0x09, 0x50, 0x75, 0x72, 0x65, 0x53, 0x74, 0x61, 0x6b, 0x65, 0x10, 0xc0, 0x04, 0x12, 0x0b, + 0x0a, 0x06, 0x51, 0x75, 0x62, 0x6f, 0x6c, 0x65, 0x10, 0xc1, 0x04, 0x12, 0x14, 0x0a, 0x0f, 0x43, + 0x61, 0x72, 0x62, 0x6f, 0x6e, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x66, 0x61, 0x63, 0x65, 0x10, 0xc2, + 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x6e, 0x74, 0x72, 0x69, 0x6e, 0x69, 0x6f, 0x10, 0xc3, 0x04, + 0x12, 0x15, 0x0a, 0x0c, 0x51, 0x75, 0x69, 0x63, 0x6b, 0x4d, 0x65, 0x74, 0x72, 0x69, 0x63, 0x73, + 0x10, 0xc4, 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x63, 0x72, 0x61, 0x70, + 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xc5, 0x04, 0x12, 0x19, 0x0a, 0x14, 0x54, 0x65, 0x63, + 0x68, 0x6e, 0x69, 0x63, 0x61, 0x6c, 0x41, 0x6e, 0x61, 0x6c, 0x79, 0x73, 0x69, 0x73, 0x41, 0x70, + 0x69, 0x10, 0xc6, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x55, 0x72, 0x6c, 0x73, 0x63, 0x61, 0x6e, 0x10, + 0xc7, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x42, 0x61, 0x73, 0x65, 0x41, 0x70, 0x69, 0x49, 0x4f, 0x10, + 0xc8, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x61, 0x69, 0x6c, 0x79, 0x43, 0x4f, 0x10, 0xc9, 0x04, + 0x12, 0x08, 0x0a, 0x03, 0x54, 0x4c, 0x79, 0x10, 0xca, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x68, + 0x6f, 0x72, 0x74, 0x63, 0x75, 0x74, 0x10, 0xcb, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x70, 0x70, + 0x66, 0x6f, 0x6c, 0x6c, 0x6f, 0x77, 0x10, 0xcc, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x68, 0x69, + 0x6e, 0x6b, 0x69, 0x66, 0x69, 0x63, 0x10, 0xcd, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x46, 0x65, 0x65, + 0x64, 0x6c, 0x79, 0x10, 0xce, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x69, 0x74, 0x63, 0x68, + 0x64, 0x61, 0x74, 0x61, 0x10, 0xcf, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x65, 0x74, 0x63, 0x68, + 0x72, 0x73, 0x73, 0x10, 0xd0, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x69, 0x67, 0x6e, 0x75, 0x70, + 0x67, 0x65, 0x6e, 0x69, 0x75, 0x73, 0x10, 0xd1, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x69, 0x74, 0x10, 0xd2, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x4f, 0x70, + 0x74, 0x69, 0x6d, 0x69, 0x7a, 0x65, 0x6c, 0x79, 0x10, 0xd3, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x4f, + 0x63, 0x72, 0x53, 0x70, 0x61, 0x63, 0x65, 0x10, 0xd4, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x57, 0x65, + 0x61, 0x74, 0x68, 0x65, 0x72, 0x42, 0x69, 0x74, 0x10, 0xd5, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x42, + 0x75, 0x64, 0x64, 0x79, 0x4e, 0x53, 0x10, 0xd6, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x5a, 0x69, 0x70, + 0x41, 0x50, 0x49, 0x10, 0xd7, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x5a, 0x69, 0x70, 0x42, 0x6f, 0x6f, + 0x6b, 0x73, 0x10, 0xd8, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x4f, 0x6e, 0x65, 0x64, 0x65, 0x73, 0x6b, + 0x10, 0xd9, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x75, 0x67, 0x68, 0x65, 0x72, 0x64, 0x10, 0xda, + 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x42, 0x6c, 0x61, 0x7a, 0x65, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x10, + 0xdb, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x6f, 0x64, 0x65, 0x73, 0x6b, 0x10, 0xdc, + 0x04, 0x12, 0x08, 0x0a, 0x03, 0x54, 0x72, 0x75, 0x10, 0xdd, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x55, + 0x6e, 0x69, 0x66, 0x79, 0x49, 0x44, 0x10, 0xde, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x72, 0x69, + 0x6d, 0x62, 0x6c, 0x65, 0x10, 0xdf, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x6d, 0x6f, 0x6f, 0x63, + 0x68, 0x10, 0xe0, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x65, 0x6d, 0x61, 0x70, 0x68, 0x6f, 0x72, + 0x65, 0x10, 0xe1, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x65, 0x6c, 0x6e, 0x79, 0x78, 0x10, 0xe2, + 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x77, 0x69, 0x72, 0x65, 0x10, + 0xe3, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x65, 0x78, 0x74, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x10, + 0xe4, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x65, 0x72, 0x70, 0x68, 0x6f, 0x75, 0x73, 0x65, 0x10, + 0xe5, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x50, 0x6c, 0x61, 0x6e, 0x79, 0x6f, 0x10, 0xe6, 0x04, 0x12, + 0x0f, 0x0a, 0x0a, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x62, 0x6f, 0x6f, 0x6b, 0x10, 0xe7, 0x04, + 0x12, 0x09, 0x0a, 0x04, 0x56, 0x79, 0x74, 0x65, 0x10, 0xe8, 0x04, 0x12, 0x0a, 0x0a, 0x05, 0x4e, + 0x79, 0x6c, 0x61, 0x73, 0x10, 0xe9, 0x04, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x71, 0x75, 0x61, 0x72, + 0x65, 0x75, 0x70, 0x10, 0xea, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x61, 0x6e, 0x64, 0x65, 0x6c, + 0x69, 0x6f, 0x6e, 0x10, 0xeb, 0x04, 0x12, 0x11, 0x0a, 0x08, 0x44, 0x61, 0x74, 0x61, 0x46, 0x69, + 0x72, 0x65, 0x10, 0xec, 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x65, 0x65, + 0x70, 0x41, 0x49, 0x10, 0xed, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x4d, 0x65, 0x61, 0x6e, 0x69, 0x6e, + 0x67, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xee, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x65, 0x75, + 0x74, 0x72, 0x69, 0x6e, 0x6f, 0x41, 0x70, 0x69, 0x10, 0xef, 0x04, 0x12, 0x0e, 0x0a, 0x09, 0x53, + 0x74, 0x6f, 0x72, 0x65, 0x63, 0x6f, 0x76, 0x65, 0x10, 0xf0, 0x04, 0x12, 0x0c, 0x0a, 0x07, 0x53, + 0x68, 0x69, 0x70, 0x64, 0x61, 0x79, 0x10, 0xf1, 0x04, 0x12, 0x12, 0x0a, 0x09, 0x53, 0x65, 0x6e, + 0x74, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0xf2, 0x04, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x18, 0x0a, + 0x13, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x43, 0x68, 0x61, 0x74, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x69, 0x6e, 0x67, 0x10, 0xf3, 0x04, 0x12, 0x10, 0x0a, 0x0b, 0x54, 0x65, 0x61, 0x6d, 0x77, + 0x6f, 0x72, 0x6b, 0x43, 0x52, 0x4d, 0x10, 0xf4, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x65, 0x61, + 0x6d, 0x77, 0x6f, 0x72, 0x6b, 0x44, 0x65, 0x73, 0x6b, 0x10, 0xf5, 0x04, 0x12, 0x13, 0x0a, 0x0e, + 0x54, 0x65, 0x61, 0x6d, 0x77, 0x6f, 0x72, 0x6b, 0x53, 0x70, 0x61, 0x63, 0x65, 0x73, 0x10, 0xf6, + 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x54, 0x68, 0x65, 0x4f, 0x64, 0x64, 0x73, 0x41, 0x70, 0x69, 0x10, + 0xf7, 0x04, 0x12, 0x0b, 0x0a, 0x06, 0x41, 0x70, 0x61, 0x63, 0x74, 0x61, 0x10, 0xf8, 0x04, 0x12, + 0x0f, 0x0a, 0x0a, 0x47, 0x65, 0x74, 0x53, 0x61, 0x6e, 0x64, 0x62, 0x6f, 0x78, 0x10, 0xf9, 0x04, + 0x12, 0x0e, 0x0a, 0x05, 0x48, 0x61, 0x70, 0x70, 0x69, 0x10, 0xfa, 0x04, 0x1a, 0x02, 0x08, 0x01, + 0x12, 0x0a, 0x0a, 0x05, 0x4f, 0x61, 0x6e, 0x64, 0x61, 0x10, 0xfb, 0x04, 0x12, 0x0e, 0x0a, 0x09, + 0x46, 0x61, 0x73, 0x74, 0x46, 0x6f, 0x72, 0x65, 0x78, 0x10, 0xfc, 0x04, 0x12, 0x0d, 0x0a, 0x08, + 0x41, 0x50, 0x49, 0x4d, 0x61, 0x74, 0x69, 0x63, 0x10, 0xfd, 0x04, 0x12, 0x0f, 0x0a, 0x0a, 0x56, + 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x45, 0x79, 0x65, 0x10, 0xfe, 0x04, 0x12, 0x15, 0x0a, 0x10, + 0x45, 0x61, 0x67, 0x6c, 0x65, 0x45, 0x79, 0x65, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x73, + 0x10, 0xff, 0x04, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x68, 0x6f, 0x75, 0x73, 0x61, 0x6e, 0x64, 0x45, + 0x79, 0x65, 0x73, 0x10, 0x80, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, + 0x50, 0x44, 0x46, 0x10, 0x81, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, + 0x73, 0x74, 0x61, 0x74, 0x73, 0x10, 0x82, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x68, 0x65, 0x63, + 0x49, 0x4f, 0x10, 0x83, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x4d, 0x61, 0x6e, 0x69, 0x66, 0x65, 0x73, + 0x74, 0x10, 0x84, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x70, 0x69, 0x53, 0x63, 0x69, 0x65, 0x6e, + 0x63, 0x65, 0x10, 0x85, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x41, 0x70, 0x70, 0x53, 0x79, 0x6e, 0x65, + 0x72, 0x67, 0x79, 0x10, 0x86, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x61, 0x66, 0x6c, 0x6f, 0x75, + 0x10, 0x87, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x43, 0x61, 0x73, 0x70, 0x69, 0x6f, 0x10, 0x88, 0x05, + 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x6c, 0x79, 0x48, 0x51, 0x10, 0x89, 0x05, + 0x12, 0x12, 0x0a, 0x0d, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x45, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, + 0x73, 0x10, 0x8a, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x72, 0x6f, 0x6e, 0x61, 0x48, 0x51, 0x10, + 0x8b, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x78, 0x10, 0x8c, 0x05, + 0x12, 0x09, 0x0a, 0x04, 0x46, 0x6d, 0x66, 0x77, 0x10, 0x8d, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x47, + 0x6f, 0x6f, 0x64, 0x44, 0x61, 0x79, 0x10, 0x8e, 0x05, 0x12, 0x09, 0x0a, 0x04, 0x4c, 0x75, 0x6e, + 0x6f, 0x10, 0x8f, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x4d, 0x65, 0x69, 0x73, 0x74, 0x65, 0x72, 0x74, + 0x61, 0x73, 0x6b, 0x10, 0x90, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x4d, 0x69, 0x6e, 0x64, 0x6d, 0x65, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x10, 0x91, 0x05, 0x12, 0x13, 0x0a, 0x0e, 0x50, 0x65, 0x6f, 0x70, + 0x6c, 0x65, 0x44, 0x61, 0x74, 0x61, 0x4c, 0x61, 0x62, 0x73, 0x10, 0x92, 0x05, 0x12, 0x14, 0x0a, + 0x0b, 0x53, 0x63, 0x72, 0x61, 0x70, 0x65, 0x72, 0x53, 0x69, 0x74, 0x65, 0x10, 0x93, 0x05, 0x1a, + 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x63, 0x72, 0x61, 0x70, 0x66, 0x6c, 0x79, 0x10, + 0x94, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x69, 0x6d, 0x70, 0x6c, 0x79, 0x4e, 0x6f, 0x74, 0x65, + 0x64, 0x10, 0x95, 0x05, 0x12, 0x12, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x50, 0x61, + 0x79, 0x6f, 0x75, 0x74, 0x73, 0x10, 0x96, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x57, 0x65, 0x62, 0x53, + 0x63, 0x72, 0x61, 0x70, 0x65, 0x72, 0x10, 0x97, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x6e, + 0x76, 0x69, 0x65, 0x72, 0x10, 0x98, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x75, 0x72, 0x69, + 0x65, 0x72, 0x10, 0x99, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x44, 0x69, 0x74, 0x74, 0x6f, 0x10, 0x9a, + 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x46, 0x69, 0x6e, 0x64, 0x6c, 0x10, 0x9b, 0x05, 0x12, 0x0d, 0x0a, + 0x08, 0x4c, 0x65, 0x6e, 0x64, 0x66, 0x6c, 0x6f, 0x77, 0x10, 0x9c, 0x05, 0x12, 0x0f, 0x0a, 0x0a, + 0x4d, 0x6f, 0x64, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x9d, 0x05, 0x12, 0x11, 0x0a, + 0x0c, 0x4f, 0x70, 0x65, 0x6e, 0x64, 0x61, 0x74, 0x61, 0x73, 0x6f, 0x66, 0x74, 0x10, 0x9e, 0x05, + 0x12, 0x0a, 0x0a, 0x05, 0x50, 0x6f, 0x64, 0x69, 0x6f, 0x10, 0x9f, 0x05, 0x12, 0x0c, 0x0a, 0x07, + 0x52, 0x6f, 0x63, 0x6b, 0x73, 0x65, 0x74, 0x10, 0xa0, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x52, 0x6f, + 0x77, 0x6e, 0x64, 0x10, 0xa1, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x68, 0x6f, 0x74, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x10, 0xa2, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x77, 0x69, 0x66, 0x74, 0x79, + 0x70, 0x65, 0x10, 0xa3, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x77, 0x69, 0x74, 0x74, 0x65, 0x72, + 0x10, 0xa4, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x48, 0x6f, 0x6e, 0x65, 0x79, 0x10, 0xa5, 0x05, 0x12, + 0x0e, 0x0a, 0x09, 0x46, 0x72, 0x65, 0x73, 0x68, 0x64, 0x65, 0x73, 0x6b, 0x10, 0xa6, 0x05, 0x12, + 0x0b, 0x0a, 0x06, 0x55, 0x70, 0x77, 0x61, 0x76, 0x65, 0x10, 0xa7, 0x05, 0x12, 0x0d, 0x0a, 0x08, + 0x46, 0x6f, 0x75, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x10, 0xa8, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x46, + 0x72, 0x65, 0x73, 0x68, 0x62, 0x6f, 0x6f, 0x6b, 0x73, 0x10, 0xa9, 0x05, 0x12, 0x09, 0x0a, 0x04, + 0x4d, 0x69, 0x74, 0x65, 0x10, 0xaa, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x65, 0x70, 0x75, 0x74, + 0x79, 0x10, 0xab, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x65, 0x65, 0x62, 0x6f, 0x6c, 0x65, 0x10, + 0xac, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x61, 0x73, 0x68, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x10, + 0xad, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x4b, 0x61, 0x6e, 0x62, 0x61, 0x6e, 0x10, 0xae, 0x05, 0x12, + 0x0e, 0x0a, 0x09, 0x57, 0x6f, 0x72, 0x6b, 0x73, 0x6e, 0x61, 0x70, 0x73, 0x10, 0xaf, 0x05, 0x12, + 0x10, 0x0a, 0x0b, 0x4d, 0x79, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x73, 0x10, 0xb0, + 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x49, 0x6e, 0x76, 0x6f, 0x69, 0x63, 0x65, 0x4f, 0x63, 0x65, 0x61, + 0x6e, 0x10, 0xb1, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x68, 0x65, 0x72, 0x70, 0x61, 0x64, 0x65, + 0x73, 0x6b, 0x10, 0xb2, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x4d, 0x72, 0x74, 0x69, 0x63, 0x6b, 0x74, + 0x6f, 0x63, 0x6b, 0x10, 0xb3, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x43, 0x68, 0x61, 0x74, 0x66, 0x75, + 0x6c, 0x65, 0x10, 0xb4, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x65, 0x72, 0x6f, 0x77, 0x6f, 0x72, + 0x6b, 0x66, 0x6c, 0x6f, 0x77, 0x10, 0xb5, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x45, 0x6d, 0x61, 0x69, + 0x6c, 0x6f, 0x63, 0x74, 0x6f, 0x70, 0x75, 0x73, 0x10, 0xb6, 0x05, 0x12, 0x11, 0x0a, 0x08, 0x46, + 0x75, 0x73, 0x65, 0x62, 0x69, 0x6c, 0x6c, 0x10, 0xb7, 0x05, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0f, + 0x0a, 0x0a, 0x47, 0x65, 0x63, 0x6b, 0x6f, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x10, 0xb8, 0x05, 0x12, + 0x0e, 0x0a, 0x09, 0x47, 0x6f, 0x73, 0x71, 0x75, 0x61, 0x72, 0x65, 0x64, 0x10, 0xb9, 0x05, 0x12, + 0x0e, 0x0a, 0x09, 0x4d, 0x6f, 0x6f, 0x6e, 0x63, 0x6c, 0x65, 0x72, 0x6b, 0x10, 0xba, 0x05, 0x12, + 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x79, 0x6d, 0x6f, 0x61, 0x70, 0x70, 0x10, 0xbb, 0x05, 0x12, 0x0b, + 0x0a, 0x06, 0x4d, 0x69, 0x78, 0x6d, 0x61, 0x78, 0x10, 0xbc, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x73, 0x74, 0x10, 0xbd, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x52, + 0x65, 0x70, 0x61, 0x69, 0x72, 0x73, 0x68, 0x6f, 0x70, 0x72, 0x10, 0xbe, 0x05, 0x12, 0x0d, 0x0a, + 0x08, 0x47, 0x6f, 0x73, 0x68, 0x69, 0x70, 0x70, 0x6f, 0x10, 0xbf, 0x05, 0x12, 0x0b, 0x0a, 0x06, + 0x53, 0x69, 0x67, 0x6f, 0x70, 0x74, 0x10, 0xc0, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x75, 0x67, + 0x65, 0x73, 0x74, 0x65, 0x72, 0x10, 0xc1, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x56, 0x69, 0x65, 0x77, + 0x6e, 0x65, 0x6f, 0x10, 0xc2, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x73, 0x74, 0x4e, + 0x6f, 0x74, 0x65, 0x10, 0xc3, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x61, 0x70, 0x74, 0x61, 0x69, + 0x6e, 0x44, 0x61, 0x74, 0x61, 0x10, 0xc4, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x68, 0x65, 0x63, + 0x6b, 0x76, 0x69, 0x73, 0x74, 0x10, 0xc5, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6c, 0x69, 0x65, + 0x6e, 0x67, 0x6f, 0x10, 0xc6, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x43, 0x6c, 0x6f, 0x7a, 0x65, 0x10, + 0xc7, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x46, 0x6f, 0x72, 0x6d, 0x49, 0x4f, 0x10, 0xc8, 0x05, 0x12, + 0x0f, 0x0a, 0x0a, 0x46, 0x6f, 0x72, 0x6d, 0x42, 0x75, 0x63, 0x6b, 0x65, 0x74, 0x10, 0xc9, 0x05, + 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x6f, 0x43, 0x61, 0x6e, 0x76, 0x61, 0x73, 0x10, 0xca, 0x05, 0x12, + 0x0c, 0x0a, 0x07, 0x4d, 0x61, 0x64, 0x4b, 0x75, 0x64, 0x75, 0x10, 0xcb, 0x05, 0x12, 0x0f, 0x0a, + 0x0a, 0x4e, 0x6f, 0x7a, 0x62, 0x65, 0x54, 0x65, 0x61, 0x6d, 0x73, 0x10, 0xcc, 0x05, 0x12, 0x0b, + 0x0a, 0x06, 0x50, 0x61, 0x70, 0x79, 0x72, 0x73, 0x10, 0xcd, 0x05, 0x12, 0x12, 0x0a, 0x0d, 0x53, + 0x75, 0x70, 0x65, 0x72, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x41, 0x50, 0x49, 0x10, 0xce, 0x05, 0x12, + 0x0c, 0x0a, 0x07, 0x54, 0x61, 0x6c, 0x6c, 0x79, 0x66, 0x79, 0x10, 0xcf, 0x05, 0x12, 0x0e, 0x0a, + 0x09, 0x5a, 0x65, 0x6e, 0x6b, 0x69, 0x74, 0x41, 0x50, 0x49, 0x10, 0xd0, 0x05, 0x12, 0x0f, 0x0a, + 0x0a, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x10, 0xd1, 0x05, 0x12, 0x0f, + 0x0a, 0x0a, 0x55, 0x70, 0x6c, 0x6f, 0x61, 0x64, 0x43, 0x61, 0x72, 0x65, 0x10, 0xd2, 0x05, 0x12, + 0x0d, 0x0a, 0x08, 0x42, 0x6f, 0x72, 0x67, 0x62, 0x61, 0x73, 0x65, 0x10, 0xd3, 0x05, 0x12, 0x0e, + 0x0a, 0x09, 0x50, 0x69, 0x70, 0x65, 0x64, 0x72, 0x65, 0x61, 0x6d, 0x10, 0xd4, 0x05, 0x12, 0x09, + 0x0a, 0x04, 0x53, 0x69, 0x72, 0x76, 0x10, 0xd5, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x69, 0x66, + 0x66, 0x62, 0x6f, 0x74, 0x10, 0xd6, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x45, 0x69, 0x67, 0x68, 0x74, + 0x78, 0x45, 0x69, 0x67, 0x68, 0x74, 0x10, 0xd7, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x65, 0x6e, + 0x64, 0x6f, 0x73, 0x6f, 0x10, 0xd8, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x50, 0x72, 0x69, 0x6e, 0x74, + 0x66, 0x65, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0xd9, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x75, + 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x10, 0xda, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x50, 0x61, + 0x6e, 0x64, 0x61, 0x53, 0x63, 0x6f, 0x72, 0x65, 0x10, 0xdb, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x50, + 0x61, 0x79, 0x6d, 0x6f, 0x10, 0xdc, 0x05, 0x12, 0x1d, 0x0a, 0x18, 0x41, 0x76, 0x61, 0x7a, 0x61, + 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, + 0x6b, 0x65, 0x6e, 0x10, 0xdd, 0x05, 0x12, 0x14, 0x0a, 0x0f, 0x50, 0x6c, 0x61, 0x6e, 0x76, 0x69, + 0x65, 0x77, 0x4c, 0x65, 0x61, 0x6e, 0x4b, 0x69, 0x74, 0x10, 0xde, 0x05, 0x12, 0x0e, 0x0a, 0x09, + 0x4c, 0x69, 0x76, 0x65, 0x73, 0x74, 0x6f, 0x72, 0x6d, 0x10, 0xdf, 0x05, 0x12, 0x0b, 0x0a, 0x06, + 0x4b, 0x75, 0x43, 0x6f, 0x69, 0x6e, 0x10, 0xe0, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x65, 0x74, + 0x61, 0x41, 0x50, 0x49, 0x10, 0xe1, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x4e, 0x69, 0x63, 0x65, 0x48, + 0x61, 0x73, 0x68, 0x10, 0xe2, 0x05, 0x12, 0x0a, 0x0a, 0x05, 0x43, 0x65, 0x78, 0x49, 0x4f, 0x10, + 0xe3, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x4b, 0x6c, 0x69, 0x70, 0x66, 0x6f, 0x6c, 0x69, 0x6f, 0x10, + 0xe4, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x79, 0x6e, 0x61, 0x74, 0x72, 0x61, 0x63, 0x65, 0x10, + 0xe5, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x4d, 0x6f, 0x6c, 0x6c, 0x69, 0x65, 0x41, 0x50, 0x49, 0x4b, + 0x65, 0x79, 0x10, 0xe6, 0x05, 0x12, 0x16, 0x0a, 0x11, 0x4d, 0x6f, 0x6c, 0x6c, 0x69, 0x65, 0x41, + 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xe7, 0x05, 0x12, 0x10, 0x0a, + 0x0b, 0x42, 0x61, 0x73, 0x69, 0x73, 0x54, 0x68, 0x65, 0x6f, 0x72, 0x79, 0x10, 0xe8, 0x05, 0x12, + 0x0d, 0x0a, 0x08, 0x4e, 0x6f, 0x72, 0x64, 0x69, 0x67, 0x65, 0x6e, 0x10, 0xe9, 0x05, 0x12, 0x1c, + 0x0a, 0x17, 0x46, 0x6c, 0x61, 0x67, 0x73, 0x6d, 0x69, 0x74, 0x68, 0x45, 0x6e, 0x76, 0x69, 0x72, + 0x6f, 0x6e, 0x6d, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x10, 0xea, 0x05, 0x12, 0x13, 0x0a, 0x0e, + 0x46, 0x6c, 0x61, 0x67, 0x73, 0x6d, 0x69, 0x74, 0x68, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xeb, + 0x05, 0x12, 0x08, 0x0a, 0x03, 0x4d, 0x75, 0x78, 0x10, 0xec, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x43, + 0x6f, 0x6c, 0x75, 0x6d, 0x6e, 0x10, 0xed, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x65, 0x6e, 0x64, + 0x62, 0x69, 0x72, 0x64, 0x10, 0xee, 0x05, 0x12, 0x1c, 0x0a, 0x17, 0x53, 0x65, 0x6e, 0x64, 0x62, + 0x69, 0x72, 0x64, 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x41, + 0x50, 0x49, 0x10, 0xef, 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x4d, 0x69, 0x64, 0x69, 0x73, 0x65, 0x10, + 0xf0, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x4d, 0x6f, 0x63, 0x6b, 0x61, 0x72, 0x6f, 0x6f, 0x10, 0xf1, + 0x05, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x34, 0x10, 0xf2, 0x05, 0x12, 0x0b, + 0x0a, 0x06, 0x50, 0x69, 0x6e, 0x61, 0x74, 0x61, 0x10, 0xf3, 0x05, 0x12, 0x11, 0x0a, 0x0c, 0x42, + 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xf4, 0x05, 0x12, 0x1c, + 0x0a, 0x13, 0x43, 0x72, 0x6f, 0x73, 0x73, 0x42, 0x72, 0x6f, 0x77, 0x73, 0x65, 0x72, 0x54, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x67, 0x10, 0xf5, 0x05, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, + 0x4c, 0x6f, 0x61, 0x64, 0x6d, 0x69, 0x6c, 0x6c, 0x10, 0xf6, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x54, + 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x42, 0x6f, 0x74, 0x10, 0xf7, 0x05, 0x12, 0x10, 0x0a, 0x0b, + 0x4b, 0x6e, 0x61, 0x70, 0x73, 0x61, 0x63, 0x6b, 0x50, 0x72, 0x6f, 0x10, 0xf8, 0x05, 0x12, 0x09, + 0x0a, 0x04, 0x51, 0x61, 0x73, 0x65, 0x10, 0xf9, 0x05, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x61, 0x72, + 0x65, 0x62, 0x6f, 0x6f, 0x73, 0x74, 0x10, 0xfa, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x47, 0x54, 0x4d, + 0x65, 0x74, 0x72, 0x69, 0x78, 0x10, 0xfb, 0x05, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x6f, 0x6c, 0x69, + 0x73, 0x74, 0x69, 0x63, 0x10, 0xfc, 0x05, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x72, 0x73, 0x10, 0xfd, 0x05, 0x12, 0x12, 0x0a, 0x0d, 0x53, 0x63, 0x72, 0x75, 0x74, 0x69, 0x6e, + 0x69, 0x7a, 0x65, 0x72, 0x43, 0x69, 0x10, 0xfe, 0x05, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x6f, 0x6e, + 0x61, 0x72, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xff, 0x05, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x50, + 0x49, 0x54, 0x65, 0x6d, 0x70, 0x6c, 0x61, 0x74, 0x65, 0x10, 0x80, 0x06, 0x12, 0x14, 0x0a, 0x0f, + 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x10, + 0x81, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x72, 0x61, 0x66, 0x74, 0x4d, 0x79, 0x50, 0x44, 0x46, + 0x10, 0x82, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x53, 0x44, 0x4b, + 0x10, 0x83, 0x06, 0x12, 0x15, 0x0a, 0x0c, 0x47, 0x6c, 0x69, 0x74, 0x74, 0x65, 0x72, 0x6c, 0x79, + 0x41, 0x50, 0x49, 0x10, 0x84, 0x06, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0d, 0x0a, 0x08, 0x48, 0x79, + 0x62, 0x69, 0x73, 0x63, 0x75, 0x73, 0x10, 0x85, 0x06, 0x12, 0x09, 0x0a, 0x04, 0x4d, 0x69, 0x72, + 0x6f, 0x10, 0x86, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x70, 0x61, + 0x67, 0x65, 0x10, 0x87, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x70, + 0x61, 0x6c, 0x10, 0x88, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x54, 0x65, 0x6c, 0x65, 0x74, 0x79, 0x70, + 0x65, 0x10, 0x89, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x54, 0x69, 0x6d, 0x65, 0x43, 0x61, 0x6d, 0x70, + 0x10, 0x8a, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x55, 0x73, 0x65, 0x72, 0x66, 0x6c, 0x6f, 0x77, 0x10, + 0x8b, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x57, 0x69, 0x73, 0x74, 0x69, 0x61, 0x10, 0x8c, 0x06, 0x12, + 0x13, 0x0a, 0x0a, 0x53, 0x70, 0x6f, 0x72, 0x74, 0x52, 0x61, 0x64, 0x61, 0x72, 0x10, 0x8d, 0x06, + 0x1a, 0x02, 0x08, 0x01, 0x12, 0x10, 0x0a, 0x0b, 0x55, 0x70, 0x74, 0x69, 0x6d, 0x65, 0x52, 0x6f, + 0x62, 0x6f, 0x74, 0x10, 0x8e, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x64, 0x65, 0x71, 0x75, + 0x69, 0x72, 0x79, 0x10, 0x8f, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x45, 0x78, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x6f, 0x72, 0x41, 0x50, 0x49, 0x10, 0x90, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x53, 0x69, 0x67, + 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x10, 0x91, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x4d, 0x61, 0x67, 0x69, + 0x63, 0x42, 0x65, 0x6c, 0x6c, 0x10, 0x92, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x6f, 0x72, + 0x6d, 0x62, 0x6f, 0x61, 0x72, 0x64, 0x10, 0x93, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x70, 0x69, + 0x6c, 0x61, 0x79, 0x65, 0x72, 0x10, 0x94, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x44, 0x69, 0x73, 0x71, + 0x75, 0x73, 0x10, 0x95, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x57, 0x6f, 0x6f, 0x70, 0x72, 0x61, 0x10, + 0x96, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x50, 0x61, 0x70, 0x65, 0x72, 0x66, 0x6f, 0x72, 0x6d, 0x10, + 0x97, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x47, 0x75, 0x6d, 0x72, 0x6f, 0x61, 0x64, 0x10, 0x98, 0x06, + 0x12, 0x0f, 0x0a, 0x0a, 0x50, 0x61, 0x79, 0x64, 0x69, 0x72, 0x74, 0x61, 0x70, 0x70, 0x10, 0x99, + 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x65, 0x74, 0x65, 0x63, 0x74, 0x69, 0x66, 0x79, 0x10, 0x9a, + 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x63, 0x61, 0x6b, 0x65, 0x10, + 0x9b, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x4a, 0x75, 0x6d, 0x70, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, + 0x10, 0x9c, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x4c, 0x75, 0x6e, 0x63, 0x68, 0x4d, 0x6f, 0x6e, 0x65, + 0x79, 0x10, 0x9d, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x52, 0x6f, 0x73, 0x65, 0x74, 0x74, 0x65, 0x10, + 0x9e, 0x06, 0x12, 0x09, 0x0a, 0x04, 0x59, 0x65, 0x6c, 0x70, 0x10, 0x9f, 0x06, 0x12, 0x0a, 0x0a, + 0x05, 0x41, 0x74, 0x65, 0x72, 0x61, 0x10, 0xa0, 0x06, 0x12, 0x12, 0x0a, 0x0d, 0x45, 0x63, 0x6f, + 0x53, 0x74, 0x72, 0x75, 0x78, 0x75, 0x72, 0x65, 0x49, 0x54, 0x10, 0xa1, 0x06, 0x12, 0x08, 0x0a, + 0x03, 0x41, 0x68, 0x61, 0x10, 0xa2, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x61, 0x72, 0x73, 0x65, + 0x68, 0x75, 0x62, 0x10, 0xa3, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, + 0x65, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x10, 0xa4, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x6c, 0x6f, + 0x75, 0x64, 0x73, 0x6d, 0x69, 0x74, 0x68, 0x10, 0xa5, 0x06, 0x12, 0x11, 0x0a, 0x08, 0x46, 0x6c, + 0x6f, 0x77, 0x64, 0x61, 0x73, 0x68, 0x10, 0xa6, 0x06, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x11, 0x0a, + 0x08, 0x46, 0x6c, 0x6f, 0x77, 0x64, 0x6f, 0x63, 0x6b, 0x10, 0xa7, 0x06, 0x1a, 0x02, 0x08, 0x01, + 0x12, 0x0b, 0x0a, 0x06, 0x46, 0x69, 0x62, 0x65, 0x72, 0x79, 0x10, 0xa8, 0x06, 0x12, 0x0d, 0x0a, + 0x08, 0x54, 0x79, 0x70, 0x65, 0x74, 0x61, 0x6c, 0x6b, 0x10, 0xa9, 0x06, 0x12, 0x0e, 0x0a, 0x09, + 0x56, 0x6f, 0x6f, 0x64, 0x6f, 0x6f, 0x53, 0x4d, 0x53, 0x10, 0xaa, 0x06, 0x12, 0x0e, 0x0a, 0x09, + 0x5a, 0x75, 0x6c, 0x69, 0x70, 0x43, 0x68, 0x61, 0x74, 0x10, 0xab, 0x06, 0x12, 0x0e, 0x0a, 0x09, + 0x46, 0x6f, 0x72, 0x6d, 0x63, 0x72, 0x61, 0x66, 0x74, 0x10, 0xac, 0x06, 0x12, 0x0c, 0x0a, 0x07, + 0x49, 0x65, 0x78, 0x61, 0x70, 0x69, 0x73, 0x10, 0xad, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, + 0x61, 0x63, 0x68, 0x6d, 0x61, 0x69, 0x6c, 0x10, 0xae, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x68, + 0x61, 0x72, 0x74, 0x6d, 0x6f, 0x67, 0x75, 0x6c, 0x10, 0xaf, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x41, + 0x70, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x65, 0x64, 0x64, 0x10, 0xb0, 0x06, 0x12, 0x08, 0x0a, 0x03, + 0x57, 0x69, 0x74, 0x10, 0xb1, 0x06, 0x12, 0x15, 0x0a, 0x10, 0x52, 0x65, 0x63, 0x68, 0x61, 0x72, + 0x67, 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x10, 0xb2, 0x06, 0x12, 0x0f, 0x0a, + 0x0a, 0x44, 0x69, 0x67, 0x67, 0x65, 0x72, 0x6e, 0x61, 0x75, 0x74, 0x10, 0xb3, 0x06, 0x12, 0x10, + 0x0a, 0x0b, 0x4d, 0x6f, 0x6e, 0x6b, 0x65, 0x79, 0x4c, 0x65, 0x61, 0x72, 0x6e, 0x10, 0xb4, 0x06, + 0x12, 0x0a, 0x0a, 0x05, 0x44, 0x75, 0x70, 0x6c, 0x79, 0x10, 0xb5, 0x06, 0x12, 0x0e, 0x0a, 0x09, + 0x50, 0x6f, 0x73, 0x74, 0x62, 0x61, 0x63, 0x6b, 0x73, 0x10, 0xb6, 0x06, 0x12, 0x0d, 0x0a, 0x08, + 0x43, 0x6f, 0x6c, 0x6c, 0x65, 0x63, 0x74, 0x32, 0x10, 0xb7, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x5a, + 0x65, 0x6e, 0x52, 0x6f, 0x77, 0x73, 0x10, 0xb8, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x5a, 0x69, 0x70, + 0x63, 0x6f, 0x64, 0x65, 0x62, 0x61, 0x73, 0x65, 0x10, 0xb9, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x54, + 0x65, 0x66, 0x74, 0x65, 0x72, 0x10, 0xba, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x54, 0x77, 0x69, 0x73, + 0x74, 0x10, 0xbb, 0x06, 0x12, 0x16, 0x0a, 0x11, 0x42, 0x72, 0x61, 0x69, 0x6e, 0x74, 0x72, 0x65, + 0x65, 0x50, 0x61, 0x79, 0x6d, 0x65, 0x6e, 0x74, 0x73, 0x10, 0xbc, 0x06, 0x12, 0x11, 0x0a, 0x0c, + 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x10, 0xbd, 0x06, 0x12, + 0x0c, 0x0a, 0x07, 0x47, 0x72, 0x61, 0x66, 0x61, 0x6e, 0x61, 0x10, 0xbe, 0x06, 0x12, 0x0f, 0x0a, + 0x0a, 0x43, 0x6f, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x41, 0x70, 0x69, 0x10, 0xbf, 0x06, 0x12, 0x11, + 0x0a, 0x0c, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x77, 0x69, 0x73, 0x65, 0x10, 0xc0, + 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x75, 0x6c, 0x6b, 0x73, 0x6d, 0x73, 0x10, 0xc1, 0x06, 0x12, + 0x0c, 0x0a, 0x07, 0x44, 0x61, 0x74, 0x61, 0x62, 0x6f, 0x78, 0x10, 0xc2, 0x06, 0x12, 0x0e, 0x0a, + 0x09, 0x4f, 0x6e, 0x65, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x6c, 0x10, 0xc3, 0x06, 0x12, 0x0c, 0x0a, + 0x07, 0x52, 0x65, 0x6e, 0x74, 0x6d, 0x61, 0x6e, 0x10, 0xc4, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x50, + 0x61, 0x72, 0x73, 0x65, 0x75, 0x72, 0x10, 0xc5, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x6f, 0x63, + 0x70, 0x61, 0x72, 0x73, 0x65, 0x72, 0x10, 0xc6, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x46, 0x6f, 0x72, + 0x6d, 0x73, 0x69, 0x74, 0x65, 0x10, 0xc7, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x69, 0x63, 0x6b, + 0x65, 0x74, 0x74, 0x61, 0x69, 0x6c, 0x6f, 0x72, 0x10, 0xc8, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x4c, + 0x65, 0x6d, 0x6c, 0x69, 0x73, 0x74, 0x10, 0xc9, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x72, 0x6f, + 0x64, 0x70, 0x61, 0x64, 0x10, 0xca, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x46, 0x6f, 0x72, 0x6d, 0x73, + 0x74, 0x61, 0x63, 0x6b, 0x10, 0xcb, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x6f, 0x64, 0x65, 0x63, + 0x6c, 0x69, 0x6d, 0x61, 0x74, 0x65, 0x10, 0xcc, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x64, + 0x65, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x10, 0xcd, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x56, 0x62, 0x6f, + 0x75, 0x74, 0x10, 0xce, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x4e, 0x69, 0x67, 0x68, 0x74, 0x66, 0x61, + 0x6c, 0x6c, 0x10, 0xcf, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x46, 0x6c, 0x69, 0x67, 0x68, 0x74, 0x4c, + 0x61, 0x62, 0x73, 0x10, 0xd0, 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x53, 0x70, 0x65, 0x65, 0x63, 0x68, + 0x54, 0x65, 0x78, 0x74, 0x41, 0x49, 0x10, 0xd1, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x6f, 0x6c, + 0x6c, 0x73, 0x41, 0x50, 0x49, 0x10, 0xd2, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x69, 0x6d, 0x46, + 0x69, 0x6e, 0x10, 0xd3, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x53, 0x63, 0x61, 0x6c, 0x72, 0x10, 0xd4, + 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x4b, 0x61, 0x6e, 0x62, 0x61, 0x6e, 0x74, 0x6f, 0x6f, 0x6c, 0x10, + 0xd5, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x72, 0x69, 0x67, 0x68, 0x74, 0x6c, 0x6f, 0x63, 0x61, + 0x6c, 0x10, 0xd6, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x48, 0x6f, 0x74, 0x77, 0x69, 0x72, 0x65, 0x10, + 0xd7, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x62, 0x6f, 0x74, 0x10, 0xd8, + 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x54, 0x69, 0x6d, 0x65, 0x6b, 0x69, 0x74, 0x10, 0xd9, 0x06, 0x12, + 0x10, 0x0a, 0x0b, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x73, 0x65, 0x6c, 0x6c, 0x65, 0x72, 0x10, 0xda, + 0x06, 0x12, 0x11, 0x0a, 0x0c, 0x4d, 0x6f, 0x6a, 0x6f, 0x68, 0x65, 0x6c, 0x70, 0x64, 0x65, 0x73, + 0x6b, 0x10, 0xdb, 0x06, 0x12, 0x0f, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x73, 0x65, + 0x6e, 0x64, 0x10, 0xdc, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x72, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x10, 0xdd, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x44, 0x79, 0x6e, 0x61, 0x64, + 0x6f, 0x74, 0x10, 0xde, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x44, 0x65, 0x6d, 0x69, 0x6f, 0x10, 0xdf, + 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x54, 0x6f, 0x6b, 0x65, 0x65, 0x74, 0x10, 0xe0, 0x06, 0x12, 0x11, + 0x0a, 0x0c, 0x4d, 0x79, 0x65, 0x78, 0x70, 0x65, 0x72, 0x69, 0x6d, 0x65, 0x6e, 0x74, 0x10, 0xe1, + 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x70, 0x79, 0x73, 0x63, 0x61, 0x70, 0x65, 0x10, 0xe2, + 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x65, 0x73, 0x6e, 0x61, 0x70, 0x70, 0x79, 0x10, 0xe3, 0x06, + 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x6d, 0x61, 0x74, 0x65, 0x10, 0xe4, 0x06, + 0x12, 0x13, 0x0a, 0x0a, 0x48, 0x65, 0x61, 0x74, 0x6d, 0x61, 0x70, 0x61, 0x70, 0x69, 0x10, 0xe5, + 0x06, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x11, 0x0a, 0x0c, 0x57, 0x65, 0x62, 0x73, 0x69, 0x74, 0x65, + 0x70, 0x75, 0x6c, 0x73, 0x65, 0x10, 0xe6, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x55, 0x63, 0x6c, 0x61, + 0x73, 0x73, 0x69, 0x66, 0x79, 0x10, 0xe7, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x43, 0x6f, 0x6e, 0x76, + 0x65, 0x72, 0x74, 0x10, 0xe8, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x44, 0x46, 0x6d, 0x79, 0x55, + 0x52, 0x4c, 0x10, 0xe9, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x41, 0x70, 0x69, 0x32, 0x43, 0x6f, 0x6e, + 0x76, 0x65, 0x72, 0x74, 0x10, 0xea, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x4f, 0x70, 0x73, 0x67, 0x65, + 0x6e, 0x69, 0x65, 0x10, 0xeb, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x47, 0x65, 0x6d, 0x69, 0x6e, 0x69, + 0x10, 0xec, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x48, 0x6f, 0x6e, 0x65, 0x79, 0x63, 0x6f, 0x6d, 0x62, + 0x10, 0xed, 0x06, 0x12, 0x14, 0x0a, 0x0f, 0x4b, 0x61, 0x6c, 0x74, 0x75, 0x72, 0x61, 0x41, 0x70, + 0x70, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xee, 0x06, 0x12, 0x13, 0x0a, 0x0e, 0x4b, 0x61, 0x6c, + 0x74, 0x75, 0x72, 0x61, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x10, 0xef, 0x06, 0x12, 0x0a, + 0x0a, 0x05, 0x42, 0x69, 0x74, 0x47, 0x6f, 0x10, 0xf0, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x4f, 0x70, + 0x74, 0x69, 0x64, 0x61, 0x73, 0x68, 0x10, 0xf1, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x49, 0x6d, 0x67, + 0x69, 0x78, 0x10, 0xf2, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x49, 0x6d, 0x61, 0x67, 0x65, 0x54, 0x6f, + 0x54, 0x65, 0x78, 0x74, 0x10, 0xf3, 0x06, 0x12, 0x10, 0x0a, 0x0b, 0x50, 0x61, 0x67, 0x65, 0x32, + 0x49, 0x6d, 0x61, 0x67, 0x65, 0x73, 0x10, 0xf4, 0x06, 0x12, 0x0e, 0x0a, 0x09, 0x51, 0x75, 0x69, + 0x63, 0x6b, 0x62, 0x61, 0x73, 0x65, 0x10, 0xf5, 0x06, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x65, 0x64, + 0x62, 0x6f, 0x6f, 0x74, 0x68, 0x10, 0xf6, 0x06, 0x12, 0x0b, 0x0a, 0x06, 0x4e, 0x75, 0x62, 0x65, + 0x6c, 0x61, 0x10, 0xf7, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x6e, 0x66, 0x6f, 0x62, 0x69, 0x70, + 0x10, 0xf8, 0x06, 0x12, 0x0a, 0x0a, 0x05, 0x55, 0x70, 0x72, 0x6f, 0x63, 0x10, 0xf9, 0x06, 0x12, + 0x0f, 0x0a, 0x0a, 0x53, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x62, 0x65, 0x65, 0x10, 0xfa, 0x06, + 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x66, 0x74, 0x65, 0x72, 0x73, 0x68, 0x69, 0x70, 0x10, 0xfb, 0x06, + 0x12, 0x0c, 0x0a, 0x07, 0x45, 0x64, 0x75, 0x73, 0x69, 0x67, 0x6e, 0x10, 0xfc, 0x06, 0x12, 0x0b, + 0x0a, 0x06, 0x54, 0x65, 0x61, 0x6d, 0x75, 0x70, 0x10, 0xfd, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x57, + 0x6f, 0x72, 0x6b, 0x64, 0x61, 0x79, 0x10, 0xfe, 0x06, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x6f, 0x6e, + 0x67, 0x6f, 0x44, 0x42, 0x10, 0xff, 0x06, 0x12, 0x08, 0x0a, 0x03, 0x4e, 0x47, 0x43, 0x10, 0x80, + 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x44, 0x69, 0x67, 0x69, 0x74, 0x61, 0x6c, 0x4f, 0x63, 0x65, 0x61, + 0x6e, 0x56, 0x32, 0x10, 0x81, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x51, 0x4c, 0x53, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x10, 0x82, 0x07, 0x12, 0x08, 0x0a, 0x03, 0x46, 0x54, 0x50, 0x10, 0x83, 0x07, + 0x12, 0x0a, 0x0a, 0x05, 0x52, 0x65, 0x64, 0x69, 0x73, 0x10, 0x84, 0x07, 0x12, 0x09, 0x0a, 0x04, + 0x4c, 0x44, 0x41, 0x50, 0x10, 0x85, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x53, 0x68, 0x6f, 0x70, 0x69, + 0x66, 0x79, 0x10, 0x86, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x52, 0x61, 0x62, 0x62, 0x69, 0x74, 0x4d, + 0x51, 0x10, 0x87, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x43, 0x75, 0x73, 0x74, 0x6f, 0x6d, 0x52, 0x65, + 0x67, 0x65, 0x78, 0x10, 0x88, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x45, 0x74, 0x68, 0x65, 0x72, 0x73, + 0x63, 0x61, 0x6e, 0x10, 0x89, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x49, 0x6e, 0x66, 0x75, 0x72, 0x61, + 0x10, 0x8a, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x41, 0x6c, 0x63, 0x68, 0x65, 0x6d, 0x79, 0x10, 0x8b, + 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x10, 0x8c, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x4d, 0x6f, 0x72, 0x61, 0x6c, 0x69, 0x73, 0x10, 0x8d, + 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x42, 0x73, 0x63, 0x53, 0x63, 0x61, 0x6e, 0x10, 0x8e, 0x07, 0x12, + 0x16, 0x0a, 0x0d, 0x43, 0x6f, 0x69, 0x6e, 0x4d, 0x61, 0x72, 0x6b, 0x65, 0x74, 0x43, 0x61, 0x70, + 0x10, 0x8f, 0x07, 0x1a, 0x02, 0x08, 0x01, 0x12, 0x0a, 0x0a, 0x05, 0x50, 0x65, 0x72, 0x63, 0x79, + 0x10, 0x90, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x54, 0x69, 0x6e, 0x65, 0x73, 0x57, 0x65, 0x62, 0x68, + 0x6f, 0x6f, 0x6b, 0x10, 0x91, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x50, 0x75, 0x6c, 0x75, 0x6d, 0x69, + 0x10, 0x92, 0x07, 0x12, 0x12, 0x0a, 0x0d, 0x53, 0x75, 0x70, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, + 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0x93, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x4e, 0x75, 0x47, 0x65, 0x74, + 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x10, 0x94, 0x07, 0x12, 0x0a, 0x0a, 0x05, 0x41, 0x69, 0x76, + 0x65, 0x6e, 0x10, 0x95, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x72, 0x65, 0x66, 0x65, 0x63, 0x74, + 0x10, 0x96, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x44, 0x6f, 0x63, 0x75, 0x73, 0x69, 0x67, 0x6e, 0x10, + 0x97, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x43, 0x6f, 0x75, 0x63, 0x68, 0x62, 0x61, 0x73, 0x65, 0x10, + 0x98, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x44, 0x6f, 0x63, 0x6b, 0x65, 0x72, 0x68, 0x75, 0x62, 0x10, + 0x99, 0x07, 0x12, 0x19, 0x0a, 0x14, 0x54, 0x72, 0x75, 0x66, 0x66, 0x6c, 0x65, 0x68, 0x6f, 0x67, + 0x45, 0x6e, 0x74, 0x65, 0x72, 0x70, 0x72, 0x69, 0x73, 0x65, 0x10, 0x9a, 0x07, 0x12, 0x10, 0x0a, + 0x0b, 0x45, 0x6e, 0x76, 0x6f, 0x79, 0x41, 0x70, 0x69, 0x4b, 0x65, 0x79, 0x10, 0x9b, 0x07, 0x12, + 0x11, 0x0a, 0x0c, 0x47, 0x69, 0x74, 0x48, 0x75, 0x62, 0x4f, 0x61, 0x75, 0x74, 0x68, 0x32, 0x10, + 0x9c, 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x53, 0x61, 0x6c, 0x65, 0x73, 0x66, 0x6f, 0x72, 0x63, 0x65, + 0x10, 0x9d, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x48, 0x75, 0x67, 0x67, 0x69, 0x6e, 0x67, 0x46, 0x61, + 0x63, 0x65, 0x10, 0x9e, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x53, 0x6e, 0x6f, 0x77, 0x66, 0x6c, 0x61, + 0x6b, 0x65, 0x10, 0x9f, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x67, + 0x72, 0x61, 0x70, 0x68, 0x10, 0xa0, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x54, 0x61, 0x69, 0x6c, 0x73, + 0x63, 0x61, 0x6c, 0x65, 0x10, 0xa1, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x57, 0x65, 0x62, 0x33, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x10, 0xa2, 0x07, 0x12, 0x11, 0x0a, 0x0c, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x10, 0xa3, 0x07, 0x12, 0x12, 0x0a, 0x0d, + 0x50, 0x6c, 0x61, 0x6e, 0x65, 0x74, 0x53, 0x63, 0x61, 0x6c, 0x65, 0x44, 0x62, 0x10, 0xa4, 0x07, + 0x12, 0x0e, 0x0a, 0x09, 0x41, 0x6e, 0x74, 0x68, 0x72, 0x6f, 0x70, 0x69, 0x63, 0x10, 0xa5, 0x07, + 0x12, 0x09, 0x0a, 0x04, 0x52, 0x61, 0x6d, 0x70, 0x10, 0xa6, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x4b, + 0x6c, 0x61, 0x76, 0x69, 0x79, 0x6f, 0x10, 0xa7, 0x07, 0x12, 0x14, 0x0a, 0x0f, 0x53, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x67, 0x72, 0x61, 0x70, 0x68, 0x43, 0x6f, 0x64, 0x79, 0x10, 0xa8, 0x07, 0x12, + 0x0e, 0x0a, 0x09, 0x56, 0x6f, 0x69, 0x63, 0x65, 0x66, 0x6c, 0x6f, 0x77, 0x10, 0xa9, 0x07, 0x12, + 0x0c, 0x0a, 0x07, 0x50, 0x72, 0x69, 0x76, 0x61, 0x63, 0x79, 0x10, 0xaa, 0x07, 0x12, 0x0b, 0x0a, + 0x06, 0x49, 0x50, 0x49, 0x6e, 0x66, 0x6f, 0x10, 0xab, 0x07, 0x12, 0x10, 0x0a, 0x0b, 0x49, 0x70, + 0x32, 0x6c, 0x6f, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0xac, 0x07, 0x12, 0x0e, 0x0a, 0x09, + 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6d, 0x6f, 0x6a, 0x6f, 0x10, 0xad, 0x07, 0x12, 0x0e, 0x0a, 0x09, + 0x50, 0x6f, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x10, 0xae, 0x07, 0x12, 0x13, 0x0a, 0x0e, + 0x50, 0x6f, 0x72, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xaf, + 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x4c, 0x6f, 0x67, 0x67, 0x6c, 0x79, 0x10, 0xb0, 0x07, 0x12, 0x0c, + 0x0a, 0x07, 0x4f, 0x70, 0x65, 0x6e, 0x56, 0x70, 0x6e, 0x10, 0xb1, 0x07, 0x12, 0x1e, 0x0a, 0x19, + 0x56, 0x61, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x50, 0x65, 0x72, 0x73, + 0x6f, 0x6e, 0x61, 0x6c, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xb2, 0x07, 0x12, 0x10, 0x0a, 0x0b, + 0x42, 0x65, 0x74, 0x74, 0x65, 0x72, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x10, 0xb3, 0x07, 0x12, 0x0d, + 0x0a, 0x08, 0x5a, 0x65, 0x72, 0x6f, 0x54, 0x69, 0x65, 0x72, 0x10, 0xb4, 0x07, 0x12, 0x0e, 0x0a, + 0x09, 0x41, 0x70, 0x70, 0x4f, 0x70, 0x74, 0x69, 0x63, 0x73, 0x10, 0xb5, 0x07, 0x12, 0x0d, 0x0a, + 0x08, 0x4d, 0x65, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x10, 0xb6, 0x07, 0x12, 0x11, 0x0a, 0x0c, + 0x43, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x57, 0x61, 0x61, 0x53, 0x10, 0xb7, 0x07, 0x12, + 0x11, 0x0a, 0x0c, 0x4c, 0x65, 0x6d, 0x6f, 0x6e, 0x53, 0x71, 0x75, 0x65, 0x65, 0x7a, 0x79, 0x10, + 0xb8, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x42, 0x75, 0x64, 0x69, 0x62, 0x61, 0x73, 0x65, 0x10, 0xb9, + 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x44, 0x65, 0x6e, 0x6f, 0x44, 0x65, 0x70, 0x6c, 0x6f, 0x79, 0x10, + 0xba, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x53, 0x74, 0x72, 0x69, 0x70, 0x6f, 0x10, 0xbb, 0x07, 0x12, + 0x0c, 0x0a, 0x07, 0x52, 0x65, 0x70, 0x6c, 0x79, 0x49, 0x4f, 0x10, 0xbc, 0x07, 0x12, 0x0f, 0x0a, + 0x0a, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x42, 0x61, 0x74, 0x63, 0x68, 0x10, 0xbd, 0x07, 0x12, 0x1b, + 0x0a, 0x16, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x6e, 0x74, 0x61, 0x69, 0x6e, 0x65, 0x72, + 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x72, 0x79, 0x10, 0xbe, 0x07, 0x12, 0x12, 0x0a, 0x0d, 0x41, + 0x57, 0x53, 0x53, 0x65, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0xbf, 0x07, 0x12, + 0x09, 0x0a, 0x04, 0x43, 0x6f, 0x64, 0x61, 0x10, 0xc0, 0x07, 0x12, 0x0b, 0x0a, 0x06, 0x4c, 0x6f, + 0x67, 0x7a, 0x49, 0x4f, 0x10, 0xc1, 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x45, 0x76, 0x65, 0x6e, 0x74, + 0x62, 0x72, 0x69, 0x74, 0x65, 0x10, 0xc2, 0x07, 0x12, 0x1a, 0x0a, 0x15, 0x47, 0x72, 0x61, 0x66, + 0x61, 0x6e, 0x61, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x10, 0xc3, 0x07, 0x12, 0x13, 0x0a, 0x0e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x46, + 0x69, 0x6e, 0x61, 0x6e, 0x63, 0x65, 0x10, 0xc4, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x4f, 0x76, 0x65, + 0x72, 0x6c, 0x6f, 0x6f, 0x70, 0x10, 0xc5, 0x07, 0x12, 0x0a, 0x0a, 0x05, 0x4e, 0x67, 0x72, 0x6f, + 0x6b, 0x10, 0xc6, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x52, 0x65, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, + 0x65, 0x10, 0xc7, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x50, 0x6f, 0x73, 0x74, 0x67, 0x72, 0x65, 0x73, + 0x10, 0xc8, 0x07, 0x12, 0x2a, 0x0a, 0x25, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x41, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x79, 0x41, 0x70, 0x70, 0x6c, 0x69, + 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x65, 0x63, 0x72, 0x65, 0x74, 0x10, 0xc9, 0x07, 0x12, + 0x20, 0x0a, 0x1b, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x43, 0x61, 0x63, 0x68, 0x65, 0x46, 0x6f, 0x72, + 0x52, 0x65, 0x64, 0x69, 0x73, 0x41, 0x63, 0x63, 0x65, 0x73, 0x73, 0x4b, 0x65, 0x79, 0x10, 0xca, + 0x07, 0x12, 0x21, 0x0a, 0x1c, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x44, 0x42, 0x4b, 0x65, 0x79, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, + 0x65, 0x10, 0xcb, 0x07, 0x12, 0x23, 0x0a, 0x1e, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x44, 0x65, 0x76, + 0x6f, 0x70, 0x73, 0x50, 0x65, 0x72, 0x73, 0x6f, 0x6e, 0x61, 0x6c, 0x41, 0x63, 0x63, 0x65, 0x73, + 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, 0xcc, 0x07, 0x12, 0x15, 0x0a, 0x10, 0x41, 0x7a, 0x75, + 0x72, 0x65, 0x46, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0xcd, 0x07, + 0x12, 0x2c, 0x0a, 0x27, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, 0x4c, 0x57, 0x65, 0x62, 0x53, 0x65, + 0x72, 0x76, 0x69, 0x63, 0x65, 0x43, 0x6c, 0x61, 0x73, 0x73, 0x69, 0x63, 0x49, 0x64, 0x65, 0x6e, + 0x74, 0x69, 0x66, 0x69, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x10, 0xce, 0x07, 0x12, 0x12, + 0x0a, 0x0d, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x53, 0x61, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x10, + 0xcf, 0x07, 0x12, 0x18, 0x0a, 0x13, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, + 0x68, 0x41, 0x64, 0x6d, 0x69, 0x6e, 0x4b, 0x65, 0x79, 0x10, 0xd0, 0x07, 0x12, 0x18, 0x0a, 0x13, + 0x41, 0x7a, 0x75, 0x72, 0x65, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x51, 0x75, 0x65, 0x72, 0x79, + 0x4b, 0x65, 0x79, 0x10, 0xd1, 0x07, 0x12, 0x1f, 0x0a, 0x1a, 0x41, 0x7a, 0x75, 0x72, 0x65, 0x4d, + 0x61, 0x6e, 0x61, 0x67, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x10, 0xd2, 0x07, 0x12, 0x0d, 0x0a, 0x08, 0x41, 0x7a, 0x75, 0x72, 0x65, + 0x53, 0x51, 0x4c, 0x10, 0xd3, 0x07, 0x12, 0x0a, 0x0a, 0x05, 0x46, 0x6c, 0x79, 0x49, 0x4f, 0x10, + 0xd4, 0x07, 0x12, 0x0e, 0x0a, 0x09, 0x42, 0x75, 0x69, 0x6c, 0x74, 0x57, 0x69, 0x74, 0x68, 0x10, + 0xd5, 0x07, 0x12, 0x0f, 0x0a, 0x0a, 0x4a, 0x75, 0x70, 0x69, 0x74, 0x65, 0x72, 0x4f, 0x6e, 0x65, + 0x10, 0xd6, 0x07, 0x12, 0x25, 0x0a, 0x20, 0x47, 0x43, 0x50, 0x41, 0x70, 0x70, 0x6c, 0x69, 0x63, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x43, 0x72, 0x65, 0x64, + 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x10, 0xd7, 0x07, 0x12, 0x08, 0x0a, 0x03, 0x57, 0x69, + 0x7a, 0x10, 0xd8, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x50, 0x61, 0x67, 0x61, 0x72, 0x6d, 0x65, 0x10, + 0xd9, 0x07, 0x12, 0x0c, 0x0a, 0x07, 0x4f, 0x6e, 0x66, 0x6c, 0x65, 0x65, 0x74, 0x10, 0xda, 0x07, + 0x12, 0x0c, 0x0a, 0x07, 0x49, 0x6e, 0x74, 0x72, 0x61, 0x34, 0x32, 0x10, 0xdb, 0x07, 0x42, 0x3d, + 0x5a, 0x3b, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x74, 0x72, 0x75, + 0x66, 0x66, 0x6c, 0x65, 0x73, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, 0x2f, 0x74, 0x72, 0x75, + 0x66, 0x66, 0x6c, 0x65, 0x68, 0x6f, 0x67, 0x2f, 0x76, 0x33, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x70, + 0x62, 0x2f, 0x64, 0x65, 0x74, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x70, 0x62, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/detectors.proto b/proto/detectors.proto index 464643beb869..65a916add54f 100644 --- a/proto/detectors.proto +++ b/proto/detectors.proto @@ -261,7 +261,7 @@ enum DetectorType { Wrike = 248; Float = 249; Imagekit = 250; - Integromat = 251; + Integromat = 251 [deprecated = true]; Salesblink = 252; Bored = 253; Campayn = 254; From e0351c215a6c953ddd7f0df53f39554e4b6854ca Mon Sep 17 00:00:00 2001 From: Zachary Rice Date: Thu, 16 May 2024 14:03:03 -0500 Subject: [PATCH 47/51] add tolower to all keywords, and remove return on error for global vars (#2852) --- pkg/sources/postman/postman.go | 21 +++++++++++++-------- pkg/sources/postman/substitution_test.go | 12 ++++++------ 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/pkg/sources/postman/postman.go b/pkg/sources/postman/postman.go index ad6227dddbbe..2a274e03a781 100644 --- a/pkg/sources/postman/postman.go +++ b/pkg/sources/postman/postman.go @@ -55,12 +55,13 @@ type Source struct { func (s *Source) addKeywords(keywords []string) { for _, keyword := range keywords { - s.addKeyword(keyword) + s.attemptToAddKeyword(keyword) } } -func (s *Source) addKeyword(keyword string) { +func (s *Source) attemptToAddKeyword(keyword string) { // fast check + keyword = strings.ToLower(keyword) if _, ok := s.DetectorKeywords[keyword]; ok { s.keywords[keyword] = struct{}{} return @@ -238,7 +239,7 @@ func (s *Source) scanLocalWorkspace(ctx context.Context, chunksChan chan *source func (s *Source) scanWorkspace(ctx context.Context, chunksChan chan *sources.Chunk, workspace Workspace) error { // reset keywords for each workspace s.resetKeywords() - s.addKeyword(workspace.Name) + s.attemptToAddKeyword(workspace.Name) // initiate metadata to track the tree structure of postman data metadata := Metadata{ @@ -252,7 +253,8 @@ func (s *Source) scanWorkspace(ctx context.Context, chunksChan chan *sources.Chu ctx.Logger().V(2).Info("starting scanning global variables") globalVars, err := s.client.GetGlobalVariables(workspace.ID) if err != nil { - return fmt.Errorf("error getting global variables for workspace %s, %w", workspace.ID, err) + // NOTE: global endpoint is finicky + ctx.Logger().V(2).Error(err, "skipping global variables") } metadata.Type = GLOBAL_TYPE @@ -279,7 +281,7 @@ func (s *Source) scanWorkspace(ctx context.Context, chunksChan chan *sources.Chu ctx.Logger().V(2).Info("scanning environment vars", "environment_uuid", metadata.FullID) for _, word := range strings.Split(envVars.Name, " ") { - s.addKeyword(word) + s.attemptToAddKeyword(word) } s.scanVariableData(ctx, chunksChan, metadata, envVars) @@ -309,7 +311,7 @@ func (s *Source) scanCollection(ctx context.Context, chunksChan chan *sources.Ch ctx.Logger().V(2).Info("starting scanning collection", collection.Info.Name, "uuid", collection.Info.UID) metadata.CollectionInfo = collection.Info metadata.Type = COLLECTION_TYPE - s.addKeyword(collection.Info.Name) + s.attemptToAddKeyword(collection.Info.Name) if !metadata.fromLocal { metadata.FullID = metadata.CollectionInfo.UID @@ -333,7 +335,7 @@ func (s *Source) scanCollection(ctx context.Context, chunksChan chan *sources.Ch } func (s *Source) scanItem(ctx context.Context, chunksChan chan *sources.Chunk, collection Collection, metadata Metadata, item Item) { - s.addKeyword(item.Name) + s.attemptToAddKeyword(item.Name) // override the base collection metadata with item-specific metadata metadata.FolderID = item.ID @@ -479,6 +481,8 @@ func (s *Source) scanAuth(ctx context.Context, chunksChan chan *sources.Chunk, m m.Type += " > authorization" } + s.attemptToAddKeyword(authData) + m.FieldType = AUTH_TYPE s.scanData(ctx, chunksChan, s.formatAndInjectKeywords(s.buildSubstitueSet(m, authData)), m) } @@ -594,8 +598,9 @@ func (s *Source) scanVariableData(ctx context.Context, chunksChan chan *sources. values := []string{} for _, kv := range variableData.KeyValues { - s.addKeyword(kv.Key) + s.attemptToAddKeyword(kv.Key) valStr := fmt.Sprintf("%v", kv.Value) + s.attemptToAddKeyword(valStr) if valStr != "" { s.sub.add(m, kv.Key, valStr) } else if kv.SessionValue != "" { diff --git a/pkg/sources/postman/substitution_test.go b/pkg/sources/postman/substitution_test.go index 960296495b3e..dc60cde8bea2 100644 --- a/pkg/sources/postman/substitution_test.go +++ b/pkg/sources/postman/substitution_test.go @@ -46,9 +46,9 @@ func TestSource_KeywordCombinations(t *testing.T) { }, keywords: make(map[string]struct{}), } - s.addKeyword("keyword1") - s.addKeyword("keyword2") - s.addKeyword("keyword3") + s.attemptToAddKeyword("keyword1") + s.attemptToAddKeyword("keyword2") + s.attemptToAddKeyword("keyword3") // remove that \n from the end of the string got := strings.Split(strings.TrimSuffix(s.keywordCombinations("test"), "\n"), "\n") @@ -122,9 +122,9 @@ func TestSource_FormatAndInjectKeywords(t *testing.T) { }, keywords: make(map[string]struct{}), } - s.addKeyword("keyword1") - s.addKeyword("keyword2") - s.addKeyword("keyword3") + s.attemptToAddKeyword("keyword1") + s.attemptToAddKeyword("keyword2") + s.attemptToAddKeyword("keyword3") testCases := []struct { input []string From 1ac558ae90114f2fa50343cb3f18575b3e2c9b14 Mon Sep 17 00:00:00 2001 From: Carles Llobet Date: Thu, 16 May 2024 23:24:03 +0200 Subject: [PATCH 48/51] Adding postman to sub-commands list (#2813) * Adding postman to sub-commands list postman was made public so it can now be added to the sub-command list for completeness. * Update README.md --------- Co-authored-by: Dustin Decker --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e7425cd8e343..429d7f31b3a8 100644 --- a/README.md +++ b/README.md @@ -300,12 +300,13 @@ TruffleHog has a sub-command for each source of data that you may want to scan: - github - gitlab - docker -- S3 +- s3 - filesystem (files and directories) - syslog - circleci - travisci -- GCS (Google Cloud Storage) +- gcs (Google Cloud Storage) +- postman Each subcommand can have options that you can see with the `--help` flag provided to the sub command: From 896e6e7c66f9859820a9d0aea5edbd65c2faf3eb Mon Sep 17 00:00:00 2001 From: ahrav Date: Thu, 16 May 2024 14:35:08 -0700 Subject: [PATCH 49/51] upgrade github dep (#2858) --- go.mod | 1 - go.sum | 47 ++----------------------------- pkg/sources/git/git.go | 2 +- pkg/sources/github/github.go | 2 +- pkg/sources/github/github_test.go | 2 +- pkg/sources/github/repo.go | 2 +- 6 files changed, 7 insertions(+), 49 deletions(-) diff --git a/go.mod b/go.mod index 244545bcc606..3f114312e61f 100644 --- a/go.mod +++ b/go.mod @@ -45,7 +45,6 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.0 github.com/google/go-cmp v0.6.0 github.com/google/go-containerregistry v0.19.1 - github.com/google/go-github/v61 v61.0.0 github.com/google/go-github/v62 v62.0.0 github.com/google/uuid v1.6.0 github.com/googleapis/gax-go/v2 v2.12.4 diff --git a/go.sum b/go.sum index 5c5b2592d8c5..94fee3abe3f7 100644 --- a/go.sum +++ b/go.sum @@ -9,8 +9,6 @@ cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6T cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= cloud.google.com/go v0.112.2 h1:ZaGT6LiG7dBzi6zNOvVZwacaXlmf3lRqnC4DQzqyRQw= cloud.google.com/go v0.112.2/go.mod h1:iEqjp//KquGIJV/m+Pk3xecgKNhV+ry+vVTsy4TbDms= -cloud.google.com/go/auth v0.3.0 h1:PRyzEpGfx/Z9e8+lHsbkoUVXD0gnu4MNmm7Gp8TQNIs= -cloud.google.com/go/auth v0.3.0/go.mod h1:lBv6NKTWp8E3LPzmO1TbiiRKc4drLOfHsgmlH9ogv5w= cloud.google.com/go/auth v0.4.1 h1:Z7YNIhlWRtrnKlZke7z3GMqzvuYzdc2z98F9D1NV5Hg= cloud.google.com/go/auth v0.4.1/go.mod h1:QVBuVEKpCn4Zp58hzRGvL0tjRGU0YqdRTdCHM1IHnro= cloud.google.com/go/auth/oauth2adapt v0.2.2 h1:+TTV8aXpjeChS9M+aTtN/TjdQnzJvmzKFt//oWu7HX4= @@ -20,12 +18,8 @@ cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNF cloud.google.com/go/compute/metadata v0.3.0 h1:Tz+eQXMEqDIKRsmY3cHTL6FVaynIjX2QxYC4trgAKZc= cloud.google.com/go/compute/metadata v0.3.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/iam v1.1.7 h1:z4VHOhwKLF/+UYXAJDFwGtNF0b6gjsW1Pk9Ml0U/IoM= -cloud.google.com/go/iam v1.1.7/go.mod h1:J4PMPg8TtyurAUvSmPj8FF3EDgY1SPRZxcUGrn7WXGA= cloud.google.com/go/iam v1.1.8 h1:r7umDwhj+BQyz0ScZMp4QrGXjSTI3ZINnpgU2nlB/K0= cloud.google.com/go/iam v1.1.8/go.mod h1:GvE6lyMmfxXauzNq8NbgJbeVQNspG+tcdL/W8QO1+zE= -cloud.google.com/go/longrunning v0.5.6 h1:xAe8+0YaWoCKr9t1+aWe+OeQgN/iJK1fEgZSXmjuEaE= -cloud.google.com/go/longrunning v0.5.6/go.mod h1:vUaDrWYOMKRuhiv6JBnn49YxCPz2Ayn9GqyjaBT8/mA= cloud.google.com/go/longrunning v0.5.7 h1:WLbHekDbjK1fVFD3ibpFFVoyizlLRl73I7YKuAKilhU= cloud.google.com/go/longrunning v0.5.7/go.mod h1:8GClkudohy1Fxm3owmBGid8W0pSgodEMwEAztp38Xng= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= @@ -34,8 +28,6 @@ cloud.google.com/go/secretmanager v1.13.0 h1:nQ/Ca2Gzm/OEP8tr1hiFdHRi5wAnAmsm9qT cloud.google.com/go/secretmanager v1.13.0/go.mod h1:yWdfNmM2sLIiyv6RM6VqWKeBV7CdS0SO3ybxJJRhBEs= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.40.0 h1:VEpDQV5CJxFmJ6ueWNsKxcr1QAYOXEgxDa+sBbJahPw= -cloud.google.com/go/storage v1.40.0/go.mod h1:Rrj7/hKlG87BLqDJYtwR0fbPld8uJPbQ2ucUMY7Ir0g= cloud.google.com/go/storage v1.41.0 h1:RusiwatSu6lHeEXe3kglxakAmAbfV+rhtPqA6i8RBx0= cloud.google.com/go/storage v1.41.0/go.mod h1:J1WCa/Z2FcgdEDuPUY8DxT5I+d9mFKsCepp5vR6Sq80= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= @@ -125,12 +117,6 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4= github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI= -github.com/aws/aws-sdk-go v1.52.6 h1:nw1AMg0wIj5tTnI89KaDe9G5aISqXm4KJEe1DfNbFvA= -github.com/aws/aws-sdk-go v1.52.6/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.53.0 h1:MMo1x1ggPPxDfHMXJnQudTbGXYlD4UigUAud1DJxPVo= -github.com/aws/aws-sdk-go v1.53.0/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= -github.com/aws/aws-sdk-go v1.53.1 h1:15/i0m9rE8r1q3P4ooHCfZTJtkxwG2Dwqp9JhPaVbs0= -github.com/aws/aws-sdk-go v1.53.1/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/aws-sdk-go v1.53.3 h1:xv0iGCCLdf6ZtlLPMCBjm+tU9UBLP5hXnSqnbKFYmto= github.com/aws/aws-sdk-go v1.53.3/go.mod h1:LF8svs817+Nz+DmiMQKTO3ubZ/6IaTpq3TjupRn3Eqk= github.com/aws/smithy-go v1.20.1 h1:4SZlSlMr36UEqC7XOyRVb27XMeZubNcBNN+9IgEPIQw= @@ -183,15 +169,11 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn github.com/chzyer/test v1.0.0/go.mod h1:2JlltgoNkt4TW/z9V/IzDdFaMTM2JPIi26O1pF38GC8= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= -github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= -github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudflare/circl v1.3.8 h1:j+V8jJt09PoeMFIu2uh5JUyEaIHTXVOHslFoLNAKqwI= github.com/cloudflare/circl v1.3.8/go.mod h1:PDRU+oXvdD7KCtgKxW95M5Z8BpSCJXQORiZFnBQS5QU= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/coinbase/waas-client-library-go v1.0.8 h1:AdbTmBQpsSUx947GZd5/68BhNBw1CSwTfE2PcnVy3Ao= github.com/coinbase/waas-client-library-go v1.0.8/go.mod h1:RVKozprfdfMiK92ATZUWHRs0EFGHQj4rbEJjzzZzI1I= -github.com/containerd/containerd v1.7.12 h1:+KQsnv4VnzyxWcfO9mlxxELaoztsDEjOuCMPAuPqgU0= -github.com/containerd/containerd v1.7.12/go.mod h1:/5OMpE1p0ylxtEUGY8kuCYkDRzJm9NO1TFMWjUpdevk= github.com/containerd/containerd v1.7.15 h1:afEHXdil9iAm03BmhjzKyXnnEBtjaLJefdU7DV0IFes= github.com/containerd/containerd v1.7.15/go.mod h1:ISzRRTMF8EXNpJlTzyr2XMhN+j9K302C21/+cr3kUnY= github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= @@ -259,8 +241,6 @@ github.com/envoyproxy/protoc-gen-validate v1.0.4 h1:gVPz/FMfvh57HdSJQyvBtF00j8JU github.com/envoyproxy/protoc-gen-validate v1.0.4/go.mod h1:qys6tmnRsYrQqIhm2bvKZH4Blx/1gTIZ2UKVY1M+Yew= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= -github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= github.com/felixge/fgprof v0.9.4 h1:ocDNwMFlnA0NU0zSB3I52xkO4sFXk80VK9lXjLClu88= @@ -384,16 +364,15 @@ github.com/google/go-containerregistry v0.19.1 h1:yMQ62Al6/V0Z7CqIrrS1iYoA5/oQCm github.com/google/go-containerregistry v0.19.1/go.mod h1:YCMFNQeeXeLF+dnhhWkqDItx/JSkH01j1Kis4PsjzFI= github.com/google/go-github/v60 v60.0.0 h1:oLG98PsLauFvvu4D/YPxq374jhSxFYdzQGNCyONLfn8= github.com/google/go-github/v60 v60.0.0/go.mod h1:ByhX2dP9XT9o/ll2yXAu2VD8l5eNVg8hD4Cr0S/LmQk= -github.com/google/go-github/v61 v61.0.0 h1:VwQCBwhyE9JclCI+22/7mLB1PuU9eowCXKY5pNlu1go= -github.com/google/go-github/v61 v61.0.0/go.mod h1:0WR+KmsWX75G2EbpyGsGmradjo3IiciuI4BmdVCobQY= +github.com/google/go-github/v62 v62.0.0 h1:/6mGCaRywZz9MuHyw9gD1CwsbmBX8GWsbFkwMmHdhl4= github.com/google/go-github/v62 v62.0.0/go.mod h1:EMxeUqGJq2xRu9DYBMwel/mr7kZrzUOfQmmpYrZn2a4= github.com/google/go-querystring v0.0.0-20170111101155-53e6ce116135/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= -github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.3 h1:DIhPTQrbPkgs2yJYdXU/eNACCG5DVQjySNRNlflZ9Fc= +github.com/google/martian/v3 v3.3.3/go.mod h1:iEPrYcgCF7jA9OtScMFQyAlZZ4YXTKEtJ1E6RWzmBA0= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -492,8 +471,6 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d h1:RnWZeH8N8KXfbwMTex/KKMYMj0FJRCF6tQubUuQ02GM= github.com/kjk/lzma v0.0.0-20161016003348-3fd93898850d/go.mod h1:phT/jsRPBAEqjAibu1BurrabCBNTYiVI+zbmyCZJY6Q= github.com/klauspost/compress v1.4.1/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= -github.com/klauspost/compress v1.17.4 h1:Ej5ixsIri7BrIjBkRZLTo6ghwrEtHFk7ijlczPW4fZ4= -github.com/klauspost/compress v1.17.4/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= github.com/klauspost/compress v1.17.8 h1:YcnTYrq7MikUT7k0Yb5eceMmALQPYBW/Xltxn0NAMnU= github.com/klauspost/compress v1.17.8/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= github.com/klauspost/cpuid v1.2.0/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= @@ -659,8 +636,6 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/rwcarlsen/goexif v0.0.0-20190401172101-9e8deecbddbd/go.mod h1:hPqNNc0+uJM6H+SuU8sEs5K5IQeKccPqeSjfgcKGgPk= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f h1:MvTmaQdww/z0Q4wrYjDSCcZ78NoftLQyHBSLW/Cx79Y= github.com/sahilm/fuzzy v0.1.1-0.20230530133925-c48e322e2a8f/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= -github.com/sassoftware/go-rpmutils v0.3.0 h1:tE4TZ8KcOXay5iIP64P291s6Qxd9MQCYhI7DU+f3gFA= -github.com/sassoftware/go-rpmutils v0.3.0/go.mod h1:hM9wdxFsjUFR/tJ6SMsLrJuChcucCa0DsCzE9RMfwMo= github.com/sassoftware/go-rpmutils v0.4.0 h1:ojND82NYBxgwrV+mX1CWsd5QJvvEZTKddtCdFLPWhpg= github.com/sassoftware/go-rpmutils v0.4.0/go.mod h1:3goNWi7PGAT3/dlql2lv3+MSN5jNYPjT5mVcQcIsYzI= github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= @@ -707,20 +682,12 @@ github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsT github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502 h1:34icjjmqJ2HPjrSuJYEkdZ+0ItmGQAQ75cRHIiftIyE= github.com/tailscale/depaware v0.0.0-20210622194025-720c4b409502/go.mod h1:p9lPsd+cx33L3H9nNoecRRxPssFKUwwI50I3pZ0yT+8= -github.com/testcontainers/testcontainers-go v0.30.0 h1:jmn/XS22q4YRrcMwWg0pAwlClzs/abopbsBzrepyc4E= -github.com/testcontainers/testcontainers-go v0.30.0/go.mod h1:K+kHNGiM5zjklKjgTtcrEetF3uhWbMUyqAQoyoh8Pf0= github.com/testcontainers/testcontainers-go v0.31.0 h1:W0VwIhcEVhRflwL9as3dhY6jXjVCA27AkmbnZ+UTh3U= github.com/testcontainers/testcontainers-go v0.31.0/go.mod h1:D2lAoA0zUFiSY+eAflqK5mcUx/A5hrrORaEQrd0SefI= -github.com/testcontainers/testcontainers-go/modules/mssql v0.30.0 h1:jvDa5EImFyFNv6LLbd3qdcq1TXBY2LzOUZ0GbVbsI7I= -github.com/testcontainers/testcontainers-go/modules/mssql v0.30.0/go.mod h1:BYBQszX47xz69xeTg5hX62ndgwxdfAIs6w/94Pk1Z1M= github.com/testcontainers/testcontainers-go/modules/mssql v0.31.0 h1:X4MRxswzZJov/X5a5FYGzNmMRAKlnErE+5euMoMJGzM= github.com/testcontainers/testcontainers-go/modules/mssql v0.31.0/go.mod h1:GsGFz4tcxka1meZdBBHdqZCYdpHQaa/pORXW/ELWZV0= -github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0 h1:wrePvxfU/2HFALKyBqpNs6VoPPvThzHy9aN+PCxse9g= -github.com/testcontainers/testcontainers-go/modules/mysql v0.30.0/go.mod h1:Srnlf7wwA7s6K4sKKhjAoBHJcKorRINR/i5dCA4ZyGk= github.com/testcontainers/testcontainers-go/modules/mysql v0.31.0 h1:790+S8ewZYCbG+o8IiFlZ8ZZ33XbNO6zV9qhU6xhlRk= github.com/testcontainers/testcontainers-go/modules/mysql v0.31.0/go.mod h1:REFmO+lSG9S6uSBEwIMZCxeI36uhScjTwChYADeO3JA= -github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0 h1:D3HFqpZS90iRGAN7M85DFiuhPfvYvFNnx8urQ6mPAvo= -github.com/testcontainers/testcontainers-go/modules/postgres v0.30.0/go.mod h1:e1sKxwUOkqzvaqdHl/oV9mUtFmkDPTfBGp0po2tnWQU= github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0 h1:isAwFS3KNKRbJMbWv+wolWqOFUECmjYZ+sIRZCIBc/E= github.com/testcontainers/testcontainers-go/modules/postgres v0.31.0/go.mod h1:ZNYY8vumNCEG9YI59A9d6/YaMY49uwRhmeU563EzFGw= github.com/tetratelabs/wazero v1.7.0 h1:jg5qPydno59wqjpGrHph81lbtHzTrWzwwtD4cD88+hQ= @@ -738,8 +705,6 @@ github.com/trufflesecurity/gosnowflake v0.0.1/go.mod h1:BdQAJVUM19iaSM2mZ1h3QDLX github.com/trufflesecurity/overseer v1.2.7 h1:DEiu2wrL/0f+XqshIT9C4/0nj7SHZvLmFeE4jELh4Oo= github.com/trufflesecurity/overseer v1.2.7/go.mod h1:nT9w37AiO1Nop2VhVhNfzAFaPjthvxgpDV3XKsxYkcI= github.com/ulikunitz/xz v0.5.6/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8= -github.com/ulikunitz/xz v0.5.11 h1:kpFauv27b6ynzBNT/Xy+1k+fK4WswhN/6PN5WhFAGw8= -github.com/ulikunitz/xz v0.5.11/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/urfave/cli v1.22.12/go.mod h1:sSBEIC79qR6OvcmsD4U3KABeOTxDqQtdDnaFuUN30b8= @@ -751,8 +716,6 @@ github.com/wasilibs/nottinygc v0.4.0 h1:h1TJMihMC4neN6Zq+WKpLxgd9xCFMw7O9ETLwY2e github.com/wasilibs/nottinygc v0.4.0/go.mod h1:oDcIotskuYNMpqMF23l7Z8uzD4TC0WXHK8jetlB3HIo= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0 h1:3UeQBvD0TFrlVjOeLOBz+CPAI8dnbqNSVwUwRrkp7vQ= github.com/wsxiaoys/terminal v0.0.0-20160513160801-0940f3fc43a0/go.mod h1:IXCdmsXIht47RaVFLEdVnh1t+pgYtTAhQGj73kz+2DM= -github.com/xanzy/go-gitlab v0.104.1 h1:g/liXIPJH0jsTwVuzTAUMiKdTf6Qup3u2XZq5Rp90Wc= -github.com/xanzy/go-gitlab v0.104.1/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/go-gitlab v0.105.0 h1:3nyLq0ESez0crcaM19o5S//SvezOQguuIHZ3wgX64hM= github.com/xanzy/go-gitlab v0.105.0/go.mod h1:ETg8tcj4OhrB84UEgeE8dSuV/0h4BBL1uOV/qK0vlyI= github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= @@ -1052,8 +1015,6 @@ google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsb google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.178.0 h1:yoW/QMI4bRVCHF+NWOTa4cL8MoWL3Jnuc7FlcFF91Ok= -google.golang.org/api v0.178.0/go.mod h1:84/k2v8DFpDRebpGcooklv/lais3MEfqpaBLA12gl2U= google.golang.org/api v0.180.0 h1:M2D87Yo0rGBPWpo1orwfCLehUUL6E7/TYe5gvMQWDh4= google.golang.org/api v0.180.0/go.mod h1:51AiyoEg1MJPSZ9zvklA8VnRILPXxn1iVen9v25XHAE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= @@ -1078,8 +1039,6 @@ google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda h1:wu/KJm9KJwpfHWhkkZGohVC6KRrc1oJNr4jwtQMOQXw= google.golang.org/genproto v0.0.0-20240401170217-c3f982113cda/go.mod h1:g2LLCvCeCSir/JJSWosk19BR4NVxGqHUC6rxIRsd7Aw= -google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6 h1:DTJM0R8LECCgFeUwApvcEJHz85HLagW8uRENYxHh1ww= -google.golang.org/genproto/googleapis/api v0.0.0-20240429193739-8cf5692501f6/go.mod h1:10yRODfgim2/T8csjQsMPgZOMvtytXKTDRzH6HRGzRw= google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae h1:AH34z6WAGVNkllnKs5raNq3yRq93VnjBG6rpfub/jYk= google.golang.org/genproto/googleapis/api v0.0.0-20240506185236-b8a5c65736ae/go.mod h1:FfiGhwUm6CJviekPrc0oJ+7h29e+DmWU6UtjX0ZvI7Y= google.golang.org/genproto/googleapis/rpc v0.0.0-20240429193739-8cf5692501f6 h1:DujSIu+2tC9Ht0aPNA7jgj23Iq8Ewi5sgkQ++wdvonE= diff --git a/pkg/sources/git/git.go b/pkg/sources/git/git.go index 4190bf4b7fce..7eaa1ba6a246 100644 --- a/pkg/sources/git/git.go +++ b/pkg/sources/git/git.go @@ -19,7 +19,7 @@ import ( "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "golang.org/x/oauth2" "golang.org/x/sync/semaphore" "google.golang.org/protobuf/proto" diff --git a/pkg/sources/github/github.go b/pkg/sources/github/github.go index d04872d4e6e4..782f296f8ae0 100644 --- a/pkg/sources/github/github.go +++ b/pkg/sources/github/github.go @@ -19,7 +19,7 @@ import ( "github.com/bradleyfalzon/ghinstallation/v2" "github.com/go-logr/logr" "github.com/gobwas/glob" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "golang.org/x/oauth2" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/proto" diff --git a/pkg/sources/github/github_test.go b/pkg/sources/github/github_test.go index f0b14bd3b3c7..029a3974fe4f 100644 --- a/pkg/sources/github/github_test.go +++ b/pkg/sources/github/github_test.go @@ -16,7 +16,7 @@ import ( "github.com/go-logr/logr" "github.com/google/go-cmp/cmp" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/stretchr/testify/assert" "golang.org/x/sync/errgroup" "google.golang.org/protobuf/types/known/anypb" diff --git a/pkg/sources/github/repo.go b/pkg/sources/github/repo.go index f92814da155b..35a1f42b299c 100644 --- a/pkg/sources/github/repo.go +++ b/pkg/sources/github/repo.go @@ -9,7 +9,7 @@ import ( "sync" gogit "github.com/go-git/go-git/v5" - "github.com/google/go-github/v61/github" + "github.com/google/go-github/v62/github" "github.com/trufflesecurity/trufflehog/v3/pkg/context" "github.com/trufflesecurity/trufflehog/v3/pkg/giturl" From 5257069748d68c67dde9e8142193a23473904250 Mon Sep 17 00:00:00 2001 From: ahrav Date: Thu, 16 May 2024 14:38:36 -0700 Subject: [PATCH 50/51] [chore] - move buffers pkg out of writers pkg (#2826) * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * Handle non-archive data within the DefaultHandler * make structs and methods private * Remove non-archive data handling within sources * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Handle non-archive data within the DefaultHandler * rebase * Remove non-archive data handling within sources * Adjust check for rpm/deb archive type * add additional deb mime type * add gzip * move diskbuffered rereader setup into handler pkg * remove DiskBuffereReader creation logic within sources * update comment * move rewind closer * reduce log verbosity * add metrics for file handling * add metrics for errors * make defaultBufferSize a const * add metrics for file handling * add metrics for errors * fix tests * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * Address incompatible reader to openArchive * remove nil check * fix err assignment * Allow git cat-file blob to complete before trying to handle the file * wrap compReader with DiskbufferReader * Allow git cat-file blob to complete before trying to handle the file * updates * use buffer writer * update * refactor * update context pkg * revert stuff * update test * fix test * remove * use correct reader * add metrics for file handling * add metrics for errors * fix tests * rebase * add metrics for errors * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * fix err assignment * rebase * remove * Update write method in contentWriter interface * Add bufferReadSeekCloser * update name * update comment * fix lint * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Handle non-archive data within the DefaultHandler * rebase * Remove non-archive data handling within sources * Handle non-archive data within the DefaultHandler * add gzip * move diskbuffered rereader setup into handler pkg * remove DiskBuffereReader creation logic within sources * update comment * move rewind closer * reduce log verbosity * make defaultBufferSize a const * add metrics for file handling * add metrics for errors * fix tests * add metrics for max archive depth and skipped files * update error * skip symlinks and dirs * update err * Address incompatible reader to openArchive * remove nil check * fix err assignment * wrap compReader with DiskbufferReader * Allow git cat-file blob to complete before trying to handle the file * updates * use buffer writer * update * refactor * update context pkg * revert stuff * update test * remove * rebase * go mod tidy * lint check * update metric to ms * update metric * update comments * dont use ptr * update * fix * Remove specialized handler and archive struct and restructure handlers pkg. * Refactor RPM archive handlers to use a library instead of shelling out * make rpm handling context aware * update test * Refactor AR/deb archive handler to use an existing library instead of shelling out * Update tests * add max size check * add filename and size to context kvp * move skip file check and is binary check before opening file * fix test * preserve existing funcitonality of not handling non-archive files in HandleFile * Adjust check for rpm/deb archive type * add additional deb mime type * update comment * go mod tidy * update go mod * Add a buffered file reader * update comments * use Buffered File Readder * return buffer * update * fix * return * go mod tidy * merge * use a shared pool * use sync.Once * reorganzie * remove unused code * fix double init * fix stuff * nil check * reduce allocations * updates * update metrics * updates * reset buffer instead of putting it back * skip binaries * skip * concurrently process diffs * close chan * concurrently enumerate orgs * increase workers * ignore pbix and vsdx files * add metrics for gitparse's Diffchan * fix metric * update metrics * update * fix checks * fix * inc * update * reduce * Create workers to handle binary files * modify workers * updates * add check * delete code * use custom reader * rename struct * add nonarchive handler * fix break * add comments * add tests * refactor * remove log * do not scan rpm links * simplify * rename var * rename * fix benchmark * add buffer * buffer * buffer * handle panic * merge main * merge main * add recover * revert stuff * revert * revert to using reader * fixes * remove * update * fixes * linter * fix test * move buffers pkg out of writers pkg * rename * [refactor] - move buffer pool logic into own pkg (#2828) * move buffer pool logic into own pkg * fix test * fix test * whoops * [feat] - additional buffer pool (#2829) * move buffer pool logic into own pkg * move * fix test * fix test * fix test * remove * fix test * whoops * revert * fix --- pkg/{writers => buffers}/buffer/buffer.go | 88 ++----------------- .../buffer/buffer_test.go | 73 --------------- pkg/{writers => buffers}/buffer/metrics.go | 55 +++--------- pkg/buffers/pool/metrics.go | 45 ++++++++++ pkg/buffers/pool/pool.go | 78 ++++++++++++++++ pkg/buffers/pool/pool_test.go | 83 +++++++++++++++++ pkg/writers/buffer_writer/bufferwriter.go | 19 ++-- pkg/writers/buffer_writer/metrics.go | 2 +- .../bufferedfilewriter.go | 61 ++++++++++--- .../bufferedfilewriter_test.go | 4 +- 10 files changed, 287 insertions(+), 221 deletions(-) rename pkg/{writers => buffers}/buffer/buffer.go (63%) rename pkg/{writers => buffers}/buffer/buffer_test.go (56%) rename pkg/{writers => buffers}/buffer/metrics.go (59%) create mode 100644 pkg/buffers/pool/metrics.go create mode 100644 pkg/buffers/pool/pool.go create mode 100644 pkg/buffers/pool/pool_test.go diff --git a/pkg/writers/buffer/buffer.go b/pkg/buffers/buffer/buffer.go similarity index 63% rename from pkg/writers/buffer/buffer.go rename to pkg/buffers/buffer/buffer.go index 9435ab877ef5..b3bd17749d6c 100644 --- a/pkg/writers/buffer/buffer.go +++ b/pkg/buffers/buffer/buffer.go @@ -5,94 +5,16 @@ package buffer import ( "bytes" "io" - "sync" "time" ) -type poolMetrics struct{} - -func (poolMetrics) recordShrink(amount int) { - shrinkCount.Inc() - shrinkAmount.Add(float64(amount)) -} - -func (poolMetrics) recordBufferRetrival() { - activeBufferCount.Inc() - checkoutCount.Inc() - bufferCount.Inc() -} - -func (poolMetrics) recordBufferReturn(buf *Buffer) { - activeBufferCount.Dec() - totalBufferSize.Add(float64(buf.Cap())) - totalBufferLength.Add(float64(buf.Len())) - buf.recordMetric() -} - -// PoolOpts is a function that configures a BufferPool. -type PoolOpts func(pool *Pool) - -// Pool of buffers. -type Pool struct { - *sync.Pool - bufferSize uint32 - - metrics poolMetrics -} - -const defaultBufferSize = 1 << 12 // 4KB -// NewBufferPool creates a new instance of BufferPool. -func NewBufferPool(opts ...PoolOpts) *Pool { - pool := &Pool{bufferSize: defaultBufferSize} - - for _, opt := range opts { - opt(pool) - } - pool.Pool = &sync.Pool{ - New: func() any { - return &Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, pool.bufferSize))} - }, - } - - return pool -} - -// Get returns a Buffer from the pool. -func (p *Pool) Get() *Buffer { - buf, ok := p.Pool.Get().(*Buffer) - if !ok { - buf = &Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, p.bufferSize))} - } - p.metrics.recordBufferRetrival() - buf.resetMetric() - - return buf -} - -// Put returns a Buffer to the pool. -func (p *Pool) Put(buf *Buffer) { - p.metrics.recordBufferReturn(buf) - - // If the Buffer is more than twice the default size, replace it with a new Buffer. - // This prevents us from returning very large buffers to the pool. - const maxAllowedCapacity = 2 * defaultBufferSize - if buf.Cap() > maxAllowedCapacity { - p.metrics.recordShrink(buf.Cap() - defaultBufferSize) - buf = &Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, p.bufferSize))} - } else { - // Reset the Buffer to clear any existing data. - buf.Reset() - } - - p.Pool.Put(buf) -} - // Buffer is a wrapper around bytes.Buffer that includes a timestamp for tracking Buffer checkout duration. type Buffer struct { *bytes.Buffer checkedOutAt time.Time } +const defaultBufferSize = 1 << 12 // 4KB // NewBuffer creates a new instance of Buffer. func NewBuffer() *Buffer { return &Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, defaultBufferSize))} } @@ -101,12 +23,14 @@ func (b *Buffer) Grow(size int) { b.recordGrowth(size) } -func (b *Buffer) resetMetric() { b.checkedOutAt = time.Now() } +func (b *Buffer) ResetMetric() { b.checkedOutAt = time.Now() } -func (b *Buffer) recordMetric() { +func (b *Buffer) RecordMetric() { dur := time.Since(b.checkedOutAt) checkoutDuration.Observe(float64(dur.Microseconds())) checkoutDurationTotal.Add(float64(dur.Microseconds())) + totalBufferSize.Add(float64(b.Cap())) + totalBufferLength.Add(float64(b.Len())) } func (b *Buffer) recordGrowth(size int) { @@ -119,7 +43,7 @@ func (b *Buffer) Write(data []byte) (int, error) { if b.Buffer == nil { // This case should ideally never occur if buffers are properly managed. b.Buffer = bytes.NewBuffer(make([]byte, 0, defaultBufferSize)) - b.resetMetric() + b.ResetMetric() } size := len(data) diff --git a/pkg/writers/buffer/buffer_test.go b/pkg/buffers/buffer/buffer_test.go similarity index 56% rename from pkg/writers/buffer/buffer_test.go rename to pkg/buffers/buffer/buffer_test.go index 714f387af987..bbf4987e23b5 100644 --- a/pkg/writers/buffer/buffer_test.go +++ b/pkg/buffers/buffer/buffer_test.go @@ -7,79 +7,6 @@ import ( "github.com/stretchr/testify/assert" ) -func TestNewBufferPool(t *testing.T) { - t.Parallel() - tests := []struct { - name string - opts []PoolOpts - expectedBuffSize uint32 - }{ - {name: "Default pool size", expectedBuffSize: defaultBufferSize}, - { - name: "Custom pool size", - opts: []PoolOpts{func(p *Pool) { p.bufferSize = 8 * 1024 }}, // 8KB - expectedBuffSize: 8 * 1024, - }, - } - - for _, tc := range tests { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - pool := NewBufferPool(tc.opts...) - assert.Equal(t, tc.expectedBuffSize, pool.bufferSize) - }) - } -} - -func TestBufferPoolGetPut(t *testing.T) { - t.Parallel() - tests := []struct { - name string - preparePool func(p *Pool) *Buffer // Prepare the pool and return an initial buffer to put if needed - expectedCapBefore int // Expected capacity before putting it back - expectedCapAfter int // Expected capacity after retrieving it again - }{ - { - name: "Get new buffer and put back without modification", - preparePool: func(_ *Pool) *Buffer { - return nil // No initial buffer to put - }, - expectedCapBefore: int(defaultBufferSize), - expectedCapAfter: int(defaultBufferSize), - }, - { - name: "Put oversized buffer, expect shrink", - preparePool: func(p *Pool) *Buffer { - buf := &Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, 3*defaultBufferSize))} - return buf - }, - expectedCapBefore: int(defaultBufferSize), - expectedCapAfter: int(defaultBufferSize), // Should shrink back to default - }, - } - - for _, tc := range tests { - tc := tc - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - pool := NewBufferPool() - initialBuf := tc.preparePool(pool) - if initialBuf != nil { - pool.Put(initialBuf) - } - - buf := pool.Get() - assert.Equal(t, tc.expectedCapBefore, buf.Cap()) - - pool.Put(buf) - - bufAfter := pool.Get() - assert.Equal(t, tc.expectedCapAfter, bufAfter.Cap()) - }) - } -} - func TestBufferWrite(t *testing.T) { t.Parallel() tests := []struct { diff --git a/pkg/writers/buffer/metrics.go b/pkg/buffers/buffer/metrics.go similarity index 59% rename from pkg/writers/buffer/metrics.go rename to pkg/buffers/buffer/metrics.go index 7dbb2f05a8f9..4a22580ebeb8 100644 --- a/pkg/writers/buffer/metrics.go +++ b/pkg/buffers/buffer/metrics.go @@ -8,34 +8,6 @@ import ( ) var ( - activeBufferCount = promauto.NewGauge(prometheus.GaugeOpts{ - Namespace: common.MetricsNamespace, - Subsystem: common.MetricsSubsystem, - Name: "active_buffer_count", - Help: "Current number of active buffers.", - }) - - bufferCount = promauto.NewGauge(prometheus.GaugeOpts{ - Namespace: common.MetricsNamespace, - Subsystem: common.MetricsSubsystem, - Name: "buffer_count", - Help: "Total number of buffers managed by the pool.", - }) - - totalBufferLength = promauto.NewGauge(prometheus.GaugeOpts{ - Namespace: common.MetricsNamespace, - Subsystem: common.MetricsSubsystem, - Name: "total_buffer_length", - Help: "Total length of all buffers combined.", - }) - - totalBufferSize = promauto.NewGauge(prometheus.GaugeOpts{ - Namespace: common.MetricsNamespace, - Subsystem: common.MetricsSubsystem, - Name: "total_buffer_size", - Help: "Total size of all buffers combined.", - }) - growCount = promauto.NewCounter(prometheus.CounterOpts{ Namespace: common.MetricsNamespace, Subsystem: common.MetricsSubsystem, @@ -50,20 +22,6 @@ var ( Help: "Total amount of bytes buffers in the pool have grown by.", }) - shrinkCount = promauto.NewCounter(prometheus.CounterOpts{ - Namespace: common.MetricsNamespace, - Subsystem: common.MetricsSubsystem, - Name: "shrink_count", - Help: "Total number of times buffers in the pool have shrunk.", - }) - - shrinkAmount = promauto.NewCounter(prometheus.CounterOpts{ - Namespace: common.MetricsNamespace, - Subsystem: common.MetricsSubsystem, - Name: "shrink_amount", - Help: "Total amount of bytes buffers in the pool have shrunk by.", - }) - checkoutDurationTotal = promauto.NewCounter(prometheus.CounterOpts{ Namespace: common.MetricsNamespace, Subsystem: common.MetricsSubsystem, @@ -79,10 +37,17 @@ var ( Buckets: prometheus.ExponentialBuckets(10, 10, 7), }) - checkoutCount = promauto.NewCounter(prometheus.CounterOpts{ + totalBufferLength = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "total_buffer_length", + Help: "Total length of all buffers combined.", + }) + + totalBufferSize = promauto.NewGauge(prometheus.GaugeOpts{ Namespace: common.MetricsNamespace, Subsystem: common.MetricsSubsystem, - Name: "checkout_count", - Help: "Total number of Buffer checkouts.", + Name: "total_buffer_size", + Help: "Total size of all buffers combined.", }) ) diff --git a/pkg/buffers/pool/metrics.go b/pkg/buffers/pool/metrics.go new file mode 100644 index 000000000000..3d4de5410611 --- /dev/null +++ b/pkg/buffers/pool/metrics.go @@ -0,0 +1,45 @@ +package pool + +import ( + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/client_golang/prometheus/promauto" + + "github.com/trufflesecurity/trufflehog/v3/pkg/common" +) + +var ( + activeBufferCount = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "active_buffer_count", + Help: "Current number of active buffers.", + }) + + bufferCount = promauto.NewGauge(prometheus.GaugeOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "buffer_count", + Help: "Total number of buffers managed by the pool.", + }) + + shrinkCount = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "shrink_count", + Help: "Total number of times buffers in the pool have shrunk.", + }) + + shrinkAmount = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "shrink_amount", + Help: "Total amount of bytes buffers in the pool have shrunk by.", + }) + + checkoutCount = promauto.NewCounter(prometheus.CounterOpts{ + Namespace: common.MetricsNamespace, + Subsystem: common.MetricsSubsystem, + Name: "checkout_count", + Help: "Total number of Buffer checkouts.", + }) +) diff --git a/pkg/buffers/pool/pool.go b/pkg/buffers/pool/pool.go new file mode 100644 index 000000000000..d3e5c82d806e --- /dev/null +++ b/pkg/buffers/pool/pool.go @@ -0,0 +1,78 @@ +package pool + +import ( + "bytes" + "sync" + + "github.com/trufflesecurity/trufflehog/v3/pkg/buffers/buffer" +) + +type poolMetrics struct{} + +func (poolMetrics) recordShrink(amount int) { + shrinkCount.Inc() + shrinkAmount.Add(float64(amount)) +} + +func (poolMetrics) recordBufferRetrival() { + activeBufferCount.Inc() + checkoutCount.Inc() + bufferCount.Inc() +} + +func (poolMetrics) recordBufferReturn(buf *buffer.Buffer) { + activeBufferCount.Dec() + buf.RecordMetric() +} + +// Pool of buffers. +type Pool struct { + *sync.Pool + bufferSize int + + metrics poolMetrics +} + +const defaultBufferSize = 1 << 12 // 4KB +// NewBufferPool creates a new instance of BufferPool. +func NewBufferPool(size int) *Pool { + pool := &Pool{bufferSize: size} + + pool.Pool = &sync.Pool{ + New: func() any { + return &buffer.Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, pool.bufferSize))} + }, + } + + return pool +} + +// Get returns a Buffer from the pool. +func (p *Pool) Get() *buffer.Buffer { + buf, ok := p.Pool.Get().(*buffer.Buffer) + if !ok { + buf = &buffer.Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, p.bufferSize))} + } + p.metrics.recordBufferRetrival() + buf.ResetMetric() + + return buf +} + +// Put returns a Buffer to the pool. +func (p *Pool) Put(buf *buffer.Buffer) { + p.metrics.recordBufferReturn(buf) + + // If the Buffer is more than twice the default size, replace it with a new Buffer. + // This prevents us from returning very large buffers to the pool. + const maxAllowedCapacity = 2 * defaultBufferSize + if buf.Cap() > int(maxAllowedCapacity) { + p.metrics.recordShrink(buf.Cap() - defaultBufferSize) + buf = &buffer.Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, p.bufferSize))} + } else { + // Reset the Buffer to clear any existing data. + buf.Reset() + } + + p.Pool.Put(buf) +} diff --git a/pkg/buffers/pool/pool_test.go b/pkg/buffers/pool/pool_test.go new file mode 100644 index 000000000000..3fb85a028e7c --- /dev/null +++ b/pkg/buffers/pool/pool_test.go @@ -0,0 +1,83 @@ +package pool + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" + + "github.com/trufflesecurity/trufflehog/v3/pkg/buffers/buffer" +) + +func TestNewBufferPool(t *testing.T) { + t.Parallel() + tests := []struct { + name string + size int + expectedBuffSize int + }{ + {name: "Default pool size", size: defaultBufferSize, expectedBuffSize: defaultBufferSize}, + { + name: "Custom pool size", + size: 8 * 1024, + expectedBuffSize: 8 * 1024, + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + pool := NewBufferPool(tc.size) + assert.Equal(t, tc.expectedBuffSize, pool.bufferSize) + }) + } +} + +func TestBufferPoolGetPut(t *testing.T) { + t.Parallel() + tests := []struct { + name string + preparePool func(p *Pool) *buffer.Buffer // Prepare the pool and return an initial buffer to put if needed + expectedCapBefore int // Expected capacity before putting it back + expectedCapAfter int // Expected capacity after retrieving it again + }{ + { + name: "Get new buffer and put back without modification", + preparePool: func(_ *Pool) *buffer.Buffer { + return nil // No initial buffer to put + }, + expectedCapBefore: defaultBufferSize, + expectedCapAfter: defaultBufferSize, + }, + { + name: "Put oversized buffer, expect shrink", + preparePool: func(p *Pool) *buffer.Buffer { + buf := &buffer.Buffer{Buffer: bytes.NewBuffer(make([]byte, 0, 3*defaultBufferSize))} + return buf + }, + expectedCapBefore: defaultBufferSize, + expectedCapAfter: defaultBufferSize, // Should shrink back to default + }, + } + + for _, tc := range tests { + tc := tc + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + pool := NewBufferPool(defaultBufferSize) + initialBuf := tc.preparePool(pool) + if initialBuf != nil { + pool.Put(initialBuf) + } + + buf := pool.Get() + assert.Equal(t, tc.expectedCapBefore, buf.Cap()) + + pool.Put(buf) + + bufAfter := pool.Get() + assert.Equal(t, tc.expectedCapAfter, bufAfter.Cap()) + }) + } +} diff --git a/pkg/writers/buffer_writer/bufferwriter.go b/pkg/writers/buffer_writer/bufferwriter.go index 8f0122223343..fe836d942b65 100644 --- a/pkg/writers/buffer_writer/bufferwriter.go +++ b/pkg/writers/buffer_writer/bufferwriter.go @@ -1,4 +1,4 @@ -// Package bufferwritter provides a contentWriter implementation using a shared buffer pool for memory management. +// Package bufferwriter provides a contentWriter implementation using a shared buffer pool for memory management. package bufferwriter import ( @@ -6,7 +6,8 @@ import ( "io" "time" - "github.com/trufflesecurity/trufflehog/v3/pkg/writers/buffer" + "github.com/trufflesecurity/trufflehog/v3/pkg/buffers/buffer" + "github.com/trufflesecurity/trufflehog/v3/pkg/buffers/pool" ) type metrics struct{} @@ -16,11 +17,12 @@ func (metrics) recordDataProcessed(size int64, dur time.Duration) { totalWriteDuration.Add(float64(dur.Microseconds())) } -func init() { bufferPool = buffer.NewBufferPool() } +const defaultBufferSize = 1 << 12 // 4KB +func init() { bufferPool = pool.NewBufferPool(defaultBufferSize) } // bufferPool is the shared Buffer pool used by all BufferedFileWriters. // This allows for efficient reuse of buffers across multiple writers. -var bufferPool *buffer.Pool +var bufferPool *pool.Pool // state represents the current mode of buffer. type state uint8 @@ -35,7 +37,7 @@ const ( // BufferWriter implements contentWriter, using a shared buffer pool for memory management. type BufferWriter struct { buf *buffer.Buffer // The current buffer in use. - bufPool *buffer.Pool // The buffer pool used to manage the buffer. + bufPool *pool.Pool // The buffer pool used to manage the buffer. size int // The total size of the content written to the buffer. state state // The current state of the buffer. @@ -43,14 +45,15 @@ type BufferWriter struct { } // New creates a new instance of BufferWriter. -func New() *BufferWriter { return &BufferWriter{state: writeOnly, bufPool: bufferPool} } +func New() *BufferWriter { + return &BufferWriter{state: writeOnly, bufPool: bufferPool} +} // Write delegates the writing operation to the underlying bytes.Buffer. func (b *BufferWriter) Write(data []byte) (int, error) { if b.state != writeOnly { return 0, fmt.Errorf("buffer must be in write-only mode to write data; current state: %d", b.state) } - if b.buf == nil { b.buf = b.bufPool.Get() if b.buf == nil { @@ -63,8 +66,8 @@ func (b *BufferWriter) Write(data []byte) (int, error) { start := time.Now() defer func(start time.Time) { b.metrics.recordDataProcessed(int64(size), time.Since(start)) - }(start) + return b.buf.Write(data) } diff --git a/pkg/writers/buffer_writer/metrics.go b/pkg/writers/buffer_writer/metrics.go index 29c923039d95..e47c040e7cf3 100644 --- a/pkg/writers/buffer_writer/metrics.go +++ b/pkg/writers/buffer_writer/metrics.go @@ -12,7 +12,7 @@ var ( Namespace: common.MetricsNamespace, Subsystem: common.MetricsSubsystem, Name: "buffer_writer_write_size_bytes", - Help: "Size of data written by the BufferWriter in bytes.", + Help: "Total size of data written by the BufferWriter in bytes.", Buckets: prometheus.ExponentialBuckets(100, 10, 7), }) diff --git a/pkg/writers/buffered_file_writer/bufferedfilewriter.go b/pkg/writers/buffered_file_writer/bufferedfilewriter.go index 3e9a5aa37db4..63c6733bad1f 100644 --- a/pkg/writers/buffered_file_writer/bufferedfilewriter.go +++ b/pkg/writers/buffered_file_writer/bufferedfilewriter.go @@ -10,16 +10,11 @@ import ( "os" "time" + "github.com/trufflesecurity/trufflehog/v3/pkg/buffers/buffer" + "github.com/trufflesecurity/trufflehog/v3/pkg/buffers/pool" "github.com/trufflesecurity/trufflehog/v3/pkg/cleantemp" - "github.com/trufflesecurity/trufflehog/v3/pkg/writers/buffer" ) -// sharedBufferPool is the shared buffer pool used by all BufferedFileWriters. -// This allows for efficient reuse of buffers across multiple writers. -var sharedBufferPool *buffer.Pool - -func init() { sharedBufferPool = buffer.NewBufferPool() } - type bufferedFileWriterMetrics struct{} func (bufferedFileWriterMetrics) recordDataProcessed(size uint64, dur time.Duration) { @@ -32,6 +27,30 @@ func (bufferedFileWriterMetrics) recordDiskWrite(size int64) { fileSizeHistogram.Observe(float64(size)) } +type PoolSize int + +const ( + Default PoolSize = iota + Large +) + +const ( + defaultBufferSize = 1 << 12 // 4KB + largeBufferSize = 1 << 16 // 64KB +) + +func init() { + defaultBufferPool = pool.NewBufferPool(defaultBufferSize) + largeBufferPool = pool.NewBufferPool(largeBufferSize) +} + +// Different buffer pools for different buffer sizes. +// This allows for more efficient memory management based on the size of the data being written. +var ( + defaultBufferPool *pool.Pool + largeBufferPool *pool.Pool +) + // state represents the current mode of BufferedFileWriter. type state uint8 @@ -48,7 +67,7 @@ type BufferedFileWriter struct { threshold uint64 // Threshold for switching to file writing. size uint64 // Total size of the data written. - bufPool *buffer.Pool // Pool for storing buffers for reuse. + bufPool *pool.Pool // Pool for storing buffers for reuse. buf *buffer.Buffer // Buffer for storing data under the threshold in memory. filename string // Name of the temporary file. file *os.File // File for storing data over the threshold. @@ -66,23 +85,42 @@ func WithThreshold(threshold uint64) Option { return func(w *BufferedFileWriter) { w.threshold = threshold } } +// WithBufferSize sets the buffer size for the BufferedFileWriter. +func WithBufferSize(size PoolSize) Option { + return func(w *BufferedFileWriter) { + switch size { + case Default: + w.bufPool = defaultBufferPool + case Large: + w.bufPool = largeBufferPool + default: + w.bufPool = defaultBufferPool + } + } +} + const defaultThreshold = 10 * 1024 * 1024 // 10MB // New creates a new BufferedFileWriter with the given options. func New(opts ...Option) *BufferedFileWriter { w := &BufferedFileWriter{ threshold: defaultThreshold, state: writeOnly, - bufPool: sharedBufferPool, } + for _, opt := range opts { opt(w) } + if w.bufPool == nil { + w.bufPool = defaultBufferPool + } + return w } // NewFromReader creates a new instance of BufferedFileWriter and writes the content from the provided reader to the writer. func NewFromReader(r io.Reader, opts ...Option) (*BufferedFileWriter, error) { + opts = append(opts, WithBufferSize(Large)) writer := New(opts...) if _, err := io.Copy(writer, r); err != nil && !errors.Is(err, io.EOF) { return nil, fmt.Errorf("error writing to buffered file writer: %w", err) @@ -162,9 +200,12 @@ func (w *BufferedFileWriter) Write(data []byte) (int, error) { // This ensures all the data is in one place - either entirely in the buffer or the file. if bufferLength > 0 { if _, err := w.buf.WriteTo(w.file); err != nil { + if err := os.RemoveAll(w.filename); err != nil { + return 0, fmt.Errorf("failed to remove file: %w", err) + } return 0, err } - w.bufPool.Put(w.buf) + w.buf.Reset() } } diff --git a/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go b/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go index 329bbe4182b5..310b8086c855 100644 --- a/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go +++ b/pkg/writers/buffered_file_writer/bufferedfilewriter_test.go @@ -12,7 +12,7 @@ import ( "github.com/stretchr/testify/assert" - "github.com/trufflesecurity/trufflehog/v3/pkg/writers/buffer" + "github.com/trufflesecurity/trufflehog/v3/pkg/buffers/pool" ) func TestBufferedFileWriterNewThreshold(t *testing.T) { @@ -596,7 +596,7 @@ func TestNewFromReaderThresholdExceeded(t *testing.T) { } func TestBufferWriterCloseForWritingWithFile(t *testing.T) { - bufPool := buffer.NewBufferPool() + bufPool := pool.NewBufferPool(defaultBufferSize) buf := bufPool.Get() writer := &BufferedFileWriter{ From da25ac2e7f7eef8c2daf1f8b6dae34e780c7fd96 Mon Sep 17 00:00:00 2001 From: ahrav Date: Thu, 16 May 2024 14:38:50 -0700 Subject: [PATCH 51/51] remove redundant chunking (#2855) --- pkg/engine/engine.go | 64 +++++++++++++++++++++----------------------- 1 file changed, 31 insertions(+), 33 deletions(-) diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 7c1e2ca1bb60..14228d133d67 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -611,43 +611,41 @@ func (e *Engine) detectorWorker(ctx context.Context) { // Reuse the same map to avoid allocations. const avgDetectorsPerChunk = 8 chunkSpecificDetectors := make(map[ahocorasick.DetectorKey]detectors.Detector, avgDetectorsPerChunk) - for originalChunk := range e.ChunksChan() { - for chunk := range sources.Chunker(originalChunk) { - atomic.AddUint64(&e.metrics.BytesScanned, uint64(len(chunk.Data))) - for _, decoder := range e.decoders { - decoded := decoder.FromChunk(chunk) - if decoded == nil { - ctx.Logger().V(4).Info("no decoder found for chunk", "chunk", chunk) - continue - } + for chunk := range e.ChunksChan() { + atomic.AddUint64(&e.metrics.BytesScanned, uint64(len(chunk.Data))) + for _, decoder := range e.decoders { + decoded := decoder.FromChunk(chunk) + if decoded == nil { + ctx.Logger().V(4).Info("no decoder found for chunk", "chunk", chunk) + continue + } - matchingDetectors := e.ahoCorasickCore.PopulateMatchingDetectors(string(decoded.Chunk.Data), chunkSpecificDetectors) - if len(chunkSpecificDetectors) > 1 && !e.verificationOverlap { - wgVerificationOverlap.Add(1) - e.verificationOverlapChunksChan <- verificationOverlapChunk{ - chunk: *decoded.Chunk, - detectors: matchingDetectors, - decoder: decoded.DecoderType, - verificationOverlapWgDoneFn: wgVerificationOverlap.Done, - } - // Empty the map. - for k := range chunkSpecificDetectors { - delete(chunkSpecificDetectors, k) - } - continue + matchingDetectors := e.ahoCorasickCore.PopulateMatchingDetectors(string(decoded.Chunk.Data), chunkSpecificDetectors) + if len(chunkSpecificDetectors) > 1 && !e.verificationOverlap { + wgVerificationOverlap.Add(1) + e.verificationOverlapChunksChan <- verificationOverlapChunk{ + chunk: *decoded.Chunk, + detectors: matchingDetectors, + decoder: decoded.DecoderType, + verificationOverlapWgDoneFn: wgVerificationOverlap.Done, } - - for k, detector := range chunkSpecificDetectors { - decoded.Chunk.Verify = e.verify - wgDetect.Add(1) - e.detectableChunksChan <- detectableChunk{ - chunk: *decoded.Chunk, - detector: detector, - decoder: decoded.DecoderType, - wgDoneFn: wgDetect.Done, - } + // Empty the map. + for k := range chunkSpecificDetectors { delete(chunkSpecificDetectors, k) } + continue + } + + for k, detector := range chunkSpecificDetectors { + decoded.Chunk.Verify = e.verify + wgDetect.Add(1) + e.detectableChunksChan <- detectableChunk{ + chunk: *decoded.Chunk, + detector: detector, + decoder: decoded.DecoderType, + wgDoneFn: wgDetect.Done, + } + delete(chunkSpecificDetectors, k) } } atomic.AddUint64(&e.metrics.ChunksScanned, 1)