From 0a8c55bae51be128ecf3f6ab6ebb19b6cf689cb6 Mon Sep 17 00:00:00 2001 From: Jordan Lewis Date: Fri, 8 Jun 2018 17:44:49 -0400 Subject: [PATCH] storage: return byte batches in ScanResponse Previously, the MVCCScan API call completely deserialized the batch it got from C++ into a slice of roachpb.KeyValue, and sent that slice of roachpb.KeyValue over gRPC via ScanResponse. This is needlessly expensive for several reasons. - gRPC must re-serialize what we sent it to a flat byte stream. But, we already had a flat byte stream to begin with, before inflating it into KeyValues. In effect, we're doing pointless deserialization and reserialization. - We needed to dynamically allocate a slice of roachpb.KeyValue on every scan request, in buildScanResponse. This was the second largest cause of allocations in our system, beside the first copy from C++ to Go. But, it's pointless, since we're just going to throw that slice away again when we either serialize to the network or iterate over it and inflate the KeyValues into rows later down the pipe. Now, MVCCScan can optionally skip this inflation and return the raw write batch that it got from C++. The txnKVFetcher and rowFetcher are modified to use this option. They now deserialize keys from the write batch as necessary. This results in a large decrease in the number of allocations performed per scan. When going over the network, only 1 object has to be marshalled and demarshalled (the batch) instead of the number of returned keys. Also, we don't have to allocate the initial slice of []KeyValue, or any of the slices within Key or Value, to return data. Release note: None --- docs/generated/settings/settings.html | 2 +- pkg/kv/dist_sender.go | 13 + pkg/roachpb/api.go | 2 + pkg/roachpb/api.pb.go | 902 +++++++++++------- pkg/roachpb/api.proto | 35 + pkg/server/updates_test.go | 2 +- pkg/settings/cluster/cockroach_versions.go | 6 + .../testdata/logic_test/crdb_internal | 4 +- pkg/sql/sqlbase/errors.go | 13 +- pkg/sql/sqlbase/fk.go | 13 +- pkg/sql/sqlbase/kvfetcher.go | 29 +- pkg/sql/sqlbase/rowfetcher.go | 39 +- pkg/storage/batcheval/cmd_reverse_scan.go | 36 +- pkg/storage/batcheval/cmd_scan.go | 37 +- pkg/storage/engine/mvcc.go | 227 +++-- pkg/storage/engine/rocksdb.go | 28 +- 16 files changed, 933 insertions(+), 455 deletions(-) diff --git a/docs/generated/settings/settings.html b/docs/generated/settings/settings.html index 90ebcf30ab11..bfedd988bffb 100644 --- a/docs/generated/settings/settings.html +++ b/docs/generated/settings/settings.html @@ -68,6 +68,6 @@ trace.debug.enablebooleanfalseif set, traces for recent requests can be seen in the /debug page trace.lightstep.tokenstringif set, traces go to Lightstep using this token trace.zipkin.collectorstringif set, traces go to the given Zipkin instance (example: '127.0.0.1:9411'); ignored if trace.lightstep.token is set. -versioncustom validation2.0-9set the active cluster version in the format '.'. +versioncustom validation2.0-10set the active cluster version in the format '.'. diff --git a/pkg/kv/dist_sender.go b/pkg/kv/dist_sender.go index 7b7f6b80ee5f..544dfed7eb8a 100644 --- a/pkg/kv/dist_sender.go +++ b/pkg/kv/dist_sender.go @@ -519,6 +519,19 @@ func (ds *DistSender) initAndVerifyBatch( } } + // Make sure that MVCCScan requests aren't in batch form if our cluster + // version is too old. + // TODO(jordan): delete this stanza after 2.1 is released. + if !ds.st.Version.IsMinSupported(cluster.VersionBatchResponse) { + for i := range ba.Requests { + switch req := ba.Requests[i].GetInner().(type) { + case *roachpb.ScanRequest: + req.ScanFormat = roachpb.KEY_VALUES + case *roachpb.ReverseScanRequest: + req.ScanFormat = roachpb.KEY_VALUES + } + } + } return nil } diff --git a/pkg/roachpb/api.go b/pkg/roachpb/api.go index 8aa5aa8e5b7b..e4aba2fabd17 100644 --- a/pkg/roachpb/api.go +++ b/pkg/roachpb/api.go @@ -256,6 +256,7 @@ func (sr *ScanResponse) combine(c combinable) error { if sr != nil { sr.Rows = append(sr.Rows, otherSR.Rows...) sr.IntentRows = append(sr.IntentRows, otherSR.IntentRows...) + sr.BatchResponse = append(sr.BatchResponse, otherSR.BatchResponse...) if err := sr.ResponseHeader.combine(otherSR.Header()); err != nil { return err } @@ -271,6 +272,7 @@ func (sr *ReverseScanResponse) combine(c combinable) error { if sr != nil { sr.Rows = append(sr.Rows, otherSR.Rows...) sr.IntentRows = append(sr.IntentRows, otherSR.IntentRows...) + sr.BatchResponse = append(sr.BatchResponse, otherSR.BatchResponse...) if err := sr.ResponseHeader.combine(otherSR.Header()); err != nil { return err } diff --git a/pkg/roachpb/api.pb.go b/pkg/roachpb/api.pb.go index 48f8e90a4550..02178c1e1192 100644 --- a/pkg/roachpb/api.pb.go +++ b/pkg/roachpb/api.pb.go @@ -251,6 +251,32 @@ func (x ReadConsistencyType) String() string { } func (ReadConsistencyType) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{0} } +// ScanFormat is an enumeration of the available response formats for MVCCScan +// operations. +type ScanFormat int32 + +const ( + // The standard MVCCScan format: a slice of KeyValue messages. + KEY_VALUES ScanFormat = 0 + // The batch_response format: a byte slice of alternating keys and values, + // each prefixed by their length as a varint. + BATCH_RESPONSE ScanFormat = 1 +) + +var ScanFormat_name = map[int32]string{ + 0: "KEY_VALUES", + 1: "BATCH_RESPONSE", +} +var ScanFormat_value = map[string]int32{ + "KEY_VALUES": 0, + "BATCH_RESPONSE": 1, +} + +func (x ScanFormat) String() string { + return proto.EnumName(ScanFormat_name, int32(x)) +} +func (ScanFormat) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{1} } + // TxnPushType determines what action to take when pushing a transaction. type PushTxnType int32 @@ -282,7 +308,7 @@ var PushTxnType_value = map[string]int32{ func (x PushTxnType) String() string { return proto.EnumName(PushTxnType_name, int32(x)) } -func (PushTxnType) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{1} } +func (PushTxnType) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} } type ExportStorageProvider int32 @@ -315,7 +341,7 @@ var ExportStorageProvider_value = map[string]int32{ func (x ExportStorageProvider) String() string { return proto.EnumName(ExportStorageProvider_name, int32(x)) } -func (ExportStorageProvider) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{2} } +func (ExportStorageProvider) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{3} } type MVCCFilter int32 @@ -336,7 +362,7 @@ var MVCCFilter_value = map[string]int32{ func (x MVCCFilter) String() string { return proto.EnumName(MVCCFilter_name, int32(x)) } -func (MVCCFilter) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{3} } +func (MVCCFilter) EnumDescriptor() ([]byte, []int) { return fileDescriptorApi, []int{4} } type ResponseHeader_ResumeReason int32 @@ -762,6 +788,10 @@ func (*ScanOptions) Descriptor() ([]byte, []int) { return fileDescriptorApi, []i // number of results (unbounded if zero). type ScanRequest struct { RequestHeader `protobuf:"bytes,1,opt,name=header,embedded=header" json:"header"` + // The desired format for the response. If set to BATCH_RESPONSE, the server + // will set the batch_response field in the ScanResponse instead of the rows + // field. + ScanFormat ScanFormat `protobuf:"varint,4,opt,name=scan_format,json=scanFormat,proto3,enum=cockroach.roachpb.ScanFormat" json:"scan_format,omitempty"` } func (m *ScanRequest) Reset() { *m = ScanRequest{} } @@ -778,6 +808,11 @@ type ScanResponse struct { // consistency level. These rows do not count against the MaxSpanRequestKeys // count. IntentRows []KeyValue `protobuf:"bytes,3,rep,name=intent_rows,json=intentRows" json:"intent_rows"` + // If set, the results of the scan in batch format - the key/value pairs are + // a buffer of varint-prefixed slices, alternating from key to value. There + // are num_keys pairs, as defined by the ResponseHeader. If set, rows will not + // be set and vice versa. + BatchResponse []byte `protobuf:"bytes,4,opt,name=batch_response,json=batchResponse,proto3" json:"batch_response,omitempty"` } func (m *ScanResponse) Reset() { *m = ScanResponse{} } @@ -790,6 +825,10 @@ func (*ScanResponse) Descriptor() ([]byte, []int) { return fileDescriptorApi, [] // number of results (unbounded if zero). type ReverseScanRequest struct { RequestHeader `protobuf:"bytes,1,opt,name=header,embedded=header" json:"header"` + // The desired format for the response. If set to BATCH_RESPONSE, the server + // will set the batch_response field in the ScanResponse instead of the rows + // field. + ScanFormat ScanFormat `protobuf:"varint,4,opt,name=scan_format,json=scanFormat,proto3,enum=cockroach.roachpb.ScanFormat" json:"scan_format,omitempty"` } func (m *ReverseScanRequest) Reset() { *m = ReverseScanRequest{} } @@ -806,6 +845,11 @@ type ReverseScanResponse struct { // consistency level. These rows do not count against the MaxSpanRequestKeys // count. IntentRows []KeyValue `protobuf:"bytes,3,rep,name=intent_rows,json=intentRows" json:"intent_rows"` + // If set, the results of the scan in batch format - the key/value pairs are + // a buffer of varint-prefixed slices, alternating from key to value. There + // are num_keys pairs, as defined by the ResponseHeader. If set, rows will not + // be set and vice versa. + BatchResponse []byte `protobuf:"bytes,4,opt,name=batch_response,json=batchResponse,proto3" json:"batch_response,omitempty"` } func (m *ReverseScanResponse) Reset() { *m = ReverseScanResponse{} } @@ -4722,6 +4766,7 @@ func init() { proto.RegisterType((*BatchResponse)(nil), "cockroach.roachpb.BatchResponse") proto.RegisterType((*BatchResponse_Header)(nil), "cockroach.roachpb.BatchResponse.Header") proto.RegisterEnum("cockroach.roachpb.ReadConsistencyType", ReadConsistencyType_name, ReadConsistencyType_value) + proto.RegisterEnum("cockroach.roachpb.ScanFormat", ScanFormat_name, ScanFormat_value) proto.RegisterEnum("cockroach.roachpb.PushTxnType", PushTxnType_name, PushTxnType_value) proto.RegisterEnum("cockroach.roachpb.ExportStorageProvider", ExportStorageProvider_name, ExportStorageProvider_value) proto.RegisterEnum("cockroach.roachpb.MVCCFilter", MVCCFilter_name, MVCCFilter_value) @@ -5035,6 +5080,9 @@ func (this *ScanRequest) Equal(that interface{}) bool { if !this.RequestHeader.Equal(&that1.RequestHeader) { return false } + if this.ScanFormat != that1.ScanFormat { + return false + } return true } func (this *ReverseScanRequest) Equal(that interface{}) bool { @@ -5059,6 +5107,9 @@ func (this *ReverseScanRequest) Equal(that interface{}) bool { if !this.RequestHeader.Equal(&that1.RequestHeader) { return false } + if this.ScanFormat != that1.ScanFormat { + return false + } return true } func (this *CheckConsistencyRequest) Equal(that interface{}) bool { @@ -7086,6 +7137,11 @@ func (m *ScanRequest) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n27 + if m.ScanFormat != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintApi(dAtA, i, uint64(m.ScanFormat)) + } return i, nil } @@ -7136,6 +7192,12 @@ func (m *ScanResponse) MarshalTo(dAtA []byte) (int, error) { i += n } } + if len(m.BatchResponse) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintApi(dAtA, i, uint64(len(m.BatchResponse))) + i += copy(dAtA[i:], m.BatchResponse) + } return i, nil } @@ -7162,6 +7224,11 @@ func (m *ReverseScanRequest) MarshalTo(dAtA []byte) (int, error) { return 0, err } i += n29 + if m.ScanFormat != 0 { + dAtA[i] = 0x20 + i++ + i = encodeVarintApi(dAtA, i, uint64(m.ScanFormat)) + } return i, nil } @@ -7212,6 +7279,12 @@ func (m *ReverseScanResponse) MarshalTo(dAtA []byte) (int, error) { i += n } } + if len(m.BatchResponse) > 0 { + dAtA[i] = 0x22 + i++ + i = encodeVarintApi(dAtA, i, uint64(len(m.BatchResponse))) + i += copy(dAtA[i:], m.BatchResponse) + } return i, nil } @@ -11625,6 +11698,9 @@ func (m *ScanRequest) Size() (n int) { _ = l l = m.RequestHeader.Size() n += 1 + l + sovApi(uint64(l)) + if m.ScanFormat != 0 { + n += 1 + sovApi(uint64(m.ScanFormat)) + } return n } @@ -11645,6 +11721,10 @@ func (m *ScanResponse) Size() (n int) { n += 1 + l + sovApi(uint64(l)) } } + l = len(m.BatchResponse) + if l > 0 { + n += 1 + l + sovApi(uint64(l)) + } return n } @@ -11653,6 +11733,9 @@ func (m *ReverseScanRequest) Size() (n int) { _ = l l = m.RequestHeader.Size() n += 1 + l + sovApi(uint64(l)) + if m.ScanFormat != 0 { + n += 1 + sovApi(uint64(m.ScanFormat)) + } return n } @@ -11673,6 +11756,10 @@ func (m *ReverseScanResponse) Size() (n int) { n += 1 + l + sovApi(uint64(l)) } } + l = len(m.BatchResponse) + if l > 0 { + n += 1 + l + sovApi(uint64(l)) + } return n } @@ -15669,6 +15756,25 @@ func (m *ScanRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ScanFormat", wireType) + } + m.ScanFormat = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ScanFormat |= (ScanFormat(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -15811,6 +15917,37 @@ func (m *ScanResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BatchResponse", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BatchResponse = append(m.BatchResponse[:0], dAtA[iNdEx:postIndex]...) + if m.BatchResponse == nil { + m.BatchResponse = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -15891,6 +16028,25 @@ func (m *ReverseScanRequest) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ScanFormat", wireType) + } + m.ScanFormat = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ScanFormat |= (ScanFormat(b) & 0x7F) << shift + if b < 0x80 { + break + } + } default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -16033,6 +16189,37 @@ func (m *ReverseScanResponse) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field BatchResponse", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowApi + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthApi + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.BatchResponse = append(m.BatchResponse[:0], dAtA[iNdEx:postIndex]...) + if m.BatchResponse == nil { + m.BatchResponse = []byte{} + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipApi(dAtA[iNdEx:]) @@ -27956,356 +28143,361 @@ var ( func init() { proto.RegisterFile("roachpb/api.proto", fileDescriptorApi) } var fileDescriptorApi = []byte{ - // 5609 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xdc, 0x5c, 0x4d, 0x6c, 0x23, 0xc9, - 0x75, 0x56, 0x93, 0x94, 0x44, 0x3e, 0x8a, 0x54, 0xab, 0xe6, 0x8f, 0xa3, 0x99, 0x1d, 0x69, 0xb8, - 0xf3, 0xbf, 0xb6, 0x26, 0xa3, 0xf1, 0xc2, 0xce, 0xae, 0xff, 0x44, 0x4a, 0x2b, 0x72, 0xb4, 0x92, - 0x66, 0x8b, 0xd4, 0xac, 0x67, 0x9d, 0x75, 0xbb, 0xd5, 0x5d, 0xa2, 0xda, 0x43, 0x76, 0x73, 0xba, - 0x9b, 0x23, 0x69, 0x81, 0x20, 0x01, 0x12, 0xc0, 0x81, 0x61, 0x18, 0x01, 0x12, 0x04, 0x01, 0x82, - 0x20, 0x06, 0x72, 0xc8, 0x29, 0x4e, 0x82, 0x04, 0x08, 0x12, 0x20, 0xf6, 0x25, 0x07, 0x1f, 0x82, - 0xc0, 0x09, 0x60, 0x27, 0x08, 0x10, 0x21, 0x51, 0x72, 0x30, 0x72, 0xcd, 0x6d, 0x4f, 0x41, 0xfd, - 0xf4, 0x0f, 0xc9, 0x6e, 0x92, 0x33, 0xee, 0x45, 0x9c, 0x9c, 0xc8, 0x7a, 0x55, 0xef, 0x55, 0xd5, - 0xab, 0x57, 0xaf, 0xbe, 0xaa, 0x7a, 0xd5, 0xb0, 0x60, 0x5b, 0xaa, 0x76, 0xd8, 0xdd, 0xbf, 0xaf, - 0x76, 0x8d, 0x95, 0xae, 0x6d, 0xb9, 0x16, 0x5a, 0xd0, 0x2c, 0xed, 0x19, 0x23, 0xaf, 0x88, 0xcc, - 0x45, 0xe4, 0x95, 0xd2, 0x55, 0x57, 0xe5, 0xc5, 0x16, 0xcf, 0x7b, 0x34, 0x62, 0xdb, 0x96, 0xed, - 0x08, 0xea, 0x45, 0x8f, 0xda, 0x21, 0xae, 0x1a, 0x2a, 0x5d, 0x76, 0x5c, 0xcb, 0x56, 0x5b, 0xe4, - 0x3e, 0x31, 0x5b, 0x86, 0xe9, 0xfd, 0xd0, 0x72, 0x2f, 0x34, 0x4d, 0x94, 0x79, 0x7d, 0x54, 0x99, - 0x87, 0xa2, 0x50, 0xa9, 0xe7, 0x1a, 0xed, 0xfb, 0x87, 0x6d, 0xed, 0xbe, 0x6b, 0x74, 0x88, 0xe3, - 0xaa, 0x9d, 0xae, 0xc8, 0x59, 0x66, 0x39, 0xae, 0xad, 0x6a, 0x86, 0xd9, 0xba, 0x6f, 0x13, 0xcd, - 0xb2, 0x75, 0xa2, 0x2b, 0x4e, 0x57, 0x35, 0xbd, 0x26, 0xb7, 0xac, 0x96, 0xc5, 0xfe, 0xde, 0xa7, - 0xff, 0x38, 0xb5, 0xfc, 0x2b, 0x90, 0xc3, 0xaa, 0xd9, 0x22, 0x75, 0xf3, 0xc0, 0x42, 0x9f, 0x87, - 0x8c, 0x4e, 0x1c, 0xad, 0x24, 0x2d, 0x4b, 0x77, 0xf2, 0xab, 0xe5, 0x95, 0x21, 0x5d, 0xac, 0xb0, - 0xb2, 0xeb, 0xc4, 0xd1, 0x6c, 0xa3, 0xeb, 0x5a, 0x76, 0x25, 0xf3, 0xc3, 0xd3, 0xa5, 0x29, 0xcc, - 0xb8, 0xd0, 0x67, 0x60, 0xba, 0x4d, 0x54, 0x87, 0x94, 0x52, 0x8c, 0xbd, 0x14, 0xc1, 0xfe, 0x2e, - 0xcd, 0x17, 0x4c, 0xbc, 0x70, 0xf9, 0x23, 0x28, 0x60, 0xf2, 0xbc, 0x47, 0x1c, 0xb7, 0x46, 0x54, - 0x9d, 0xd8, 0xe8, 0x32, 0xa4, 0x9f, 0x91, 0x93, 0x52, 0x7a, 0x59, 0xba, 0x33, 0x57, 0x99, 0xfd, - 0xf8, 0x74, 0x29, 0xbd, 0x45, 0x4e, 0x30, 0xa5, 0xa1, 0x65, 0x98, 0x25, 0xa6, 0xae, 0xd0, 0xec, - 0x4c, 0x7f, 0xf6, 0x0c, 0x31, 0xf5, 0x2d, 0x72, 0x82, 0x16, 0x21, 0xeb, 0x50, 0x69, 0xa6, 0x46, - 0x4a, 0xd3, 0xcb, 0xd2, 0x9d, 0x69, 0xec, 0xa7, 0xdf, 0xca, 0xfc, 0xf4, 0xbb, 0x4b, 0xd2, 0xa3, - 0x4c, 0x56, 0x92, 0x53, 0x8f, 0x32, 0xd9, 0x94, 0x9c, 0x2e, 0x7f, 0x3b, 0x0d, 0x45, 0x4c, 0x9c, - 0xae, 0x65, 0x3a, 0x44, 0xd4, 0xfe, 0x0b, 0x90, 0x76, 0x8f, 0x4d, 0x56, 0x7b, 0x7e, 0xf5, 0x5a, - 0x44, 0x17, 0x9a, 0xb6, 0x6a, 0x3a, 0xaa, 0xe6, 0x1a, 0x96, 0x89, 0x69, 0x51, 0xf4, 0x39, 0xc8, - 0xdb, 0xc4, 0xe9, 0x75, 0x08, 0x53, 0x36, 0x6b, 0x58, 0x7e, 0xf5, 0x52, 0x04, 0x67, 0xa3, 0xab, - 0x9a, 0x18, 0x78, 0x59, 0xfa, 0x1f, 0x5d, 0x86, 0xac, 0xd9, 0xeb, 0xd0, 0xee, 0x38, 0xac, 0xb1, - 0x69, 0x3c, 0x6b, 0xf6, 0x3a, 0x5b, 0xe4, 0xc4, 0x41, 0x55, 0xc8, 0xdb, 0x54, 0xd5, 0x8a, 0x61, - 0x1e, 0x58, 0x4e, 0x69, 0x66, 0x39, 0x7d, 0x27, 0xbf, 0x7a, 0x35, 0x6e, 0x40, 0xe8, 0xe0, 0x09, - 0xad, 0x82, 0xed, 0x11, 0x1c, 0xd4, 0x80, 0x82, 0x68, 0x99, 0x4d, 0x54, 0xc7, 0x32, 0x4b, 0xb3, - 0xcb, 0xd2, 0x9d, 0xe2, 0xea, 0x4a, 0x94, 0x98, 0x3e, 0x2d, 0xd0, 0x64, 0xaf, 0x43, 0x30, 0xe3, - 0xc2, 0x73, 0x76, 0x28, 0x55, 0x7e, 0x0a, 0x73, 0xe1, 0x5c, 0x84, 0xa0, 0x88, 0x37, 0x1a, 0x7b, - 0xdb, 0x1b, 0xca, 0xde, 0xce, 0xd6, 0xce, 0xee, 0xfb, 0x3b, 0xf2, 0x14, 0x3a, 0x0f, 0xb2, 0xa0, - 0x6d, 0x6d, 0x3c, 0x55, 0xde, 0xad, 0x6f, 0xd7, 0x9b, 0xb2, 0x84, 0x2e, 0xc3, 0x05, 0x41, 0xc5, - 0x6b, 0x3b, 0x9b, 0x1b, 0x4a, 0x65, 0x77, 0x6f, 0x67, 0x7d, 0x0d, 0x3f, 0x95, 0x53, 0x8b, 0x99, - 0xdf, 0xf8, 0xc3, 0x6b, 0x53, 0xe5, 0x27, 0x00, 0x9b, 0xc4, 0x15, 0xd6, 0x80, 0x2a, 0x30, 0x73, - 0xc8, 0x5a, 0x23, 0xcc, 0x71, 0x39, 0xb2, 0xd9, 0x21, 0xcb, 0xa9, 0x64, 0xa9, 0x06, 0x7e, 0x74, - 0xba, 0x24, 0x61, 0xc1, 0xc9, 0x87, 0xbc, 0xfc, 0x03, 0x09, 0xf2, 0x4c, 0x30, 0xef, 0x23, 0xaa, - 0x0e, 0x48, 0xbe, 0x3e, 0x56, 0x21, 0xc3, 0xa2, 0xd1, 0x0a, 0x4c, 0xbf, 0x50, 0xdb, 0xbd, 0x51, - 0xd6, 0xfe, 0x84, 0xe6, 0x63, 0x5e, 0x0c, 0xbd, 0x0d, 0x73, 0x86, 0xe9, 0x12, 0xd3, 0x55, 0x38, - 0x5b, 0x7a, 0x0c, 0x5b, 0x9e, 0x97, 0x66, 0x89, 0xf2, 0x5f, 0x4b, 0x00, 0x8f, 0x7b, 0x49, 0xaa, - 0x86, 0xce, 0xd6, 0x89, 0xda, 0xef, 0xcd, 0x56, 0xde, 0x8b, 0x8b, 0x30, 0x63, 0x98, 0x6d, 0xc3, - 0xe4, 0xed, 0xcf, 0x62, 0x91, 0x42, 0xe7, 0x61, 0x7a, 0xbf, 0x6d, 0x98, 0x3a, 0x33, 0xff, 0x2c, - 0xe6, 0x09, 0xa1, 0x7e, 0x0c, 0x79, 0xd6, 0xf6, 0x04, 0xb5, 0x5f, 0xfe, 0x4f, 0x09, 0x2e, 0x54, - 0x2d, 0x53, 0x37, 0xe8, 0x3c, 0x54, 0xdb, 0x3f, 0x17, 0xba, 0x79, 0x13, 0x72, 0xe4, 0xb8, 0x3b, - 0xe1, 0xf0, 0x66, 0xc9, 0x71, 0x97, 0xfd, 0x1b, 0xa9, 0xba, 0x0f, 0xe1, 0xe2, 0x60, 0x2f, 0x93, - 0xd4, 0xe2, 0x3f, 0x4a, 0x50, 0xac, 0x9b, 0x86, 0xfb, 0x73, 0xa1, 0x3e, 0x5f, 0x0f, 0xe9, 0x90, - 0x1e, 0xd0, 0x3d, 0x90, 0x0f, 0x54, 0xa3, 0xbd, 0x6b, 0x36, 0xad, 0xce, 0xbe, 0xe3, 0x5a, 0x26, - 0x71, 0x84, 0xa2, 0x86, 0xe8, 0x42, 0x67, 0x4f, 0x60, 0xde, 0xef, 0x53, 0x92, 0xca, 0xfa, 0x08, - 0xe4, 0xba, 0xa9, 0xd9, 0xa4, 0x43, 0xcc, 0x44, 0xb5, 0x75, 0x15, 0x72, 0x86, 0x27, 0x97, 0x69, - 0x2c, 0x8d, 0x03, 0x82, 0xe8, 0x53, 0x0f, 0x16, 0x42, 0x75, 0x27, 0xe9, 0xc6, 0xae, 0x40, 0xce, - 0x24, 0x47, 0x4a, 0x30, 0x5e, 0x69, 0x9c, 0x35, 0xc9, 0x11, 0x77, 0x3b, 0x4f, 0xa1, 0xb0, 0x4e, - 0xda, 0xc4, 0x25, 0xc9, 0xfb, 0xe4, 0x3d, 0x28, 0x7a, 0xa2, 0x93, 0x1c, 0xa4, 0xdf, 0x97, 0x00, - 0x09, 0xb9, 0x74, 0x1d, 0x4c, 0x72, 0x9c, 0x96, 0xe8, 0x3a, 0xef, 0xf6, 0x6c, 0x93, 0x2f, 0xd8, - 0xdc, 0x4a, 0x81, 0x93, 0xd8, 0x9a, 0x1d, 0xf8, 0xc6, 0x4c, 0xd8, 0x37, 0xfa, 0xb8, 0x83, 0x22, - 0x8e, 0x23, 0x38, 0xd7, 0xd7, 0xbc, 0x64, 0x87, 0x32, 0xc3, 0x5a, 0x96, 0x5a, 0x4e, 0x87, 0xa1, - 0x11, 0x23, 0x96, 0x3f, 0x84, 0x85, 0x6a, 0x9b, 0xa8, 0x76, 0xd2, 0x6a, 0x11, 0xc3, 0xf9, 0x14, - 0x50, 0x58, 0x7c, 0x92, 0x43, 0x6a, 0x40, 0xbe, 0xa1, 0xa9, 0xe6, 0x6e, 0x97, 0x3a, 0x41, 0x07, - 0x3d, 0x84, 0x8b, 0x8e, 0x6b, 0x75, 0x15, 0xd5, 0x55, 0x38, 0x42, 0xda, 0xb7, 0x7a, 0xa6, 0xae, - 0xda, 0x27, 0xac, 0x8e, 0x2c, 0x3e, 0x47, 0x73, 0xd7, 0x5c, 0xd6, 0x90, 0x8a, 0xc8, 0xa2, 0x63, - 0xd7, 0x31, 0x4c, 0x85, 0x02, 0x99, 0xb6, 0xeb, 0x08, 0x3b, 0x87, 0x8e, 0x61, 0x62, 0x4e, 0x11, - 0xbd, 0xd0, 0x78, 0x55, 0x89, 0xab, 0x87, 0x0f, 0xfe, 0xa3, 0x4c, 0x36, 0x2d, 0x67, 0xca, 0x7f, - 0x2f, 0xc1, 0x1c, 0xaf, 0x25, 0xc9, 0xc1, 0x7f, 0x13, 0x32, 0xb6, 0x75, 0xc4, 0x07, 0x3f, 0xbf, - 0x7a, 0x25, 0x42, 0xc4, 0x16, 0x39, 0x09, 0x7b, 0x5d, 0x56, 0x1c, 0x55, 0x40, 0xe0, 0x0c, 0x85, - 0x71, 0xa7, 0x27, 0xe5, 0x06, 0xce, 0x85, 0xad, 0x23, 0xa7, 0xfc, 0x0d, 0x40, 0x98, 0xbc, 0x20, - 0xb6, 0x43, 0x3e, 0x79, 0xe5, 0xfd, 0x58, 0x82, 0x73, 0x7d, 0x95, 0xfd, 0x3f, 0xd1, 0xe1, 0xaf, - 0x4a, 0x70, 0xa9, 0x7a, 0x48, 0xb4, 0x67, 0x55, 0xcb, 0x74, 0x0c, 0xc7, 0x25, 0xa6, 0x76, 0x92, - 0xa4, 0xf3, 0xba, 0x02, 0xb9, 0x23, 0xc3, 0x3d, 0x54, 0x74, 0xe3, 0xe0, 0x80, 0x99, 0x7f, 0x16, - 0x67, 0x29, 0x61, 0xdd, 0x38, 0x38, 0x10, 0xc6, 0xaf, 0x40, 0x69, 0xb8, 0x05, 0xc9, 0x2e, 0xa0, - 0x17, 0x30, 0xd1, 0xac, 0x4e, 0xb7, 0xe7, 0x92, 0x86, 0xab, 0xba, 0x4e, 0x92, 0x1d, 0xbc, 0x04, - 0xb3, 0xba, 0x7d, 0xa2, 0xd8, 0x3d, 0x53, 0x74, 0x6f, 0x46, 0xb7, 0x4f, 0x70, 0xcf, 0x14, 0x9d, - 0xfb, 0x4b, 0x09, 0x2e, 0x0e, 0x56, 0x9e, 0xa4, 0xe9, 0x7c, 0x05, 0xf2, 0xaa, 0x4e, 0x37, 0xdc, - 0x3a, 0x69, 0xbb, 0xaa, 0x00, 0x3e, 0x0f, 0x42, 0x92, 0xc4, 0xee, 0x7e, 0x85, 0x6f, 0xeb, 0x57, - 0xbc, 0xdd, 0xfd, 0xca, 0xf6, 0x93, 0x6a, 0x95, 0xb5, 0x67, 0x9d, 0x32, 0x7a, 0x96, 0xc1, 0x64, - 0x31, 0x4a, 0x59, 0x83, 0x4b, 0x15, 0xd2, 0x32, 0xcc, 0xf0, 0xbe, 0x33, 0x71, 0xf7, 0xad, 0x40, - 0x69, 0xb8, 0x92, 0x24, 0xc7, 0xfe, 0x1f, 0xd2, 0x70, 0x61, 0xc3, 0xd4, 0x3f, 0x99, 0x4e, 0xd0, - 0x95, 0x57, 0xb3, 0x3a, 0x1d, 0xc3, 0xf5, 0xc6, 0x9e, 0xa7, 0xd0, 0x2f, 0x42, 0x56, 0x27, 0xaa, - 0xee, 0xef, 0x57, 0xf2, 0xab, 0xaf, 0x85, 0xa4, 0xf7, 0x5c, 0xa3, 0xbd, 0x72, 0xd8, 0xd6, 0x56, - 0x9a, 0xde, 0x59, 0x0a, 0xf6, 0x8b, 0xa3, 0xaf, 0xc3, 0x25, 0x3a, 0x3d, 0x6d, 0x53, 0x6d, 0x2b, - 0x5c, 0x9a, 0xe2, 0xda, 0x46, 0xab, 0x45, 0x6c, 0xb1, 0xc3, 0xbf, 0x13, 0xd1, 0xce, 0xba, 0xe0, - 0xa8, 0x32, 0x86, 0x26, 0x2f, 0x8f, 0x2f, 0x18, 0x51, 0x64, 0xf4, 0x65, 0x7f, 0x43, 0xe8, 0x74, - 0x55, 0xd3, 0x29, 0x4d, 0x33, 0xbf, 0x11, 0x77, 0x70, 0x20, 0x2c, 0x43, 0x78, 0x1a, 0x4a, 0x71, - 0xd0, 0x7d, 0x8a, 0x48, 0x9e, 0xf7, 0x0c, 0x9b, 0x28, 0x0f, 0xba, 0x5a, 0x69, 0x86, 0xf6, 0xbd, - 0x52, 0x3c, 0x3b, 0x5d, 0x02, 0xcc, 0xc9, 0x0f, 0x1e, 0x57, 0x29, 0x42, 0xe1, 0xff, 0xbb, 0x1a, - 0xba, 0x03, 0xb2, 0x69, 0x29, 0x36, 0x39, 0xb0, 0x89, 0x73, 0x28, 0xaa, 0xcd, 0x32, 0x8d, 0x15, - 0x4d, 0x0b, 0x73, 0x32, 0x17, 0x7d, 0x11, 0x66, 0xba, 0x96, 0xe1, 0x58, 0x66, 0x29, 0xc7, 0x35, - 0xca, 0x53, 0xbe, 0x47, 0x9e, 0x95, 0xb3, 0xe5, 0xdf, 0x92, 0xe0, 0xe2, 0xe0, 0x98, 0x26, 0x39, - 0xa7, 0xee, 0x80, 0x6c, 0x99, 0x44, 0xe9, 0x1e, 0xaa, 0x0e, 0x11, 0x63, 0x20, 0x90, 0x55, 0xd1, - 0x32, 0xc9, 0x63, 0x4a, 0xe6, 0x1a, 0xed, 0x5b, 0x21, 0x7e, 0x4d, 0x82, 0x85, 0x35, 0xbd, 0x63, - 0x98, 0x8d, 0x6e, 0xdb, 0x48, 0x14, 0xa8, 0xdf, 0x80, 0x9c, 0x43, 0x65, 0xb2, 0xf3, 0xa7, 0x54, - 0xff, 0xf9, 0x53, 0x96, 0xe5, 0x6c, 0x91, 0x93, 0x00, 0x0f, 0x85, 0x1b, 0x91, 0xe4, 0x54, 0xfa, - 0x50, 0xf4, 0x6f, 0x9b, 0xd8, 0x9f, 0x10, 0x92, 0x0b, 0x8b, 0x4f, 0xb2, 0xe5, 0xdf, 0x92, 0xe0, - 0x32, 0x93, 0xcd, 0x4c, 0xe6, 0x80, 0xd8, 0xec, 0x38, 0x30, 0xc9, 0x21, 0x7a, 0x1d, 0x66, 0x5c, - 0xd5, 0x6e, 0x11, 0xee, 0x08, 0xa6, 0x2b, 0xf9, 0x8f, 0x4f, 0x97, 0x66, 0x1b, 0xae, 0x65, 0x93, - 0xfa, 0x3a, 0x16, 0x59, 0xa2, 0x9f, 0x2a, 0x2c, 0x46, 0xb5, 0x25, 0xc9, 0xfe, 0xfe, 0xb7, 0x24, - 0xea, 0xa8, 0x1e, 0x72, 0x58, 0xdc, 0x6d, 0x1b, 0x9a, 0x9a, 0xe8, 0xb2, 0xb7, 0x01, 0x79, 0x8d, - 0x09, 0x57, 0xdc, 0x93, 0x2e, 0xdf, 0xc0, 0x15, 0x57, 0x6f, 0x44, 0x0a, 0x62, 0x95, 0xf3, 0x96, - 0x34, 0x4f, 0xba, 0x04, 0x83, 0xe6, 0xff, 0x47, 0xeb, 0x30, 0xcb, 0x95, 0xe3, 0xc1, 0x97, 0x11, - 0x22, 0xe8, 0x44, 0x6f, 0xb2, 0xc2, 0xc2, 0x27, 0x79, 0xac, 0x42, 0xb1, 0xfb, 0x70, 0x25, 0xb2, - 0xd3, 0x49, 0x6a, 0xf6, 0x77, 0x24, 0x38, 0x57, 0x23, 0xaa, 0xed, 0xee, 0x13, 0xd5, 0x6d, 0x1e, - 0x27, 0xba, 0x98, 0xbc, 0x09, 0x69, 0xd3, 0x3a, 0x12, 0x4b, 0xf8, 0xe8, 0xf5, 0x42, 0x28, 0x80, - 0x96, 0x17, 0x9d, 0xff, 0x2a, 0x9c, 0xef, 0x6f, 0x57, 0x92, 0xbd, 0xfe, 0xb3, 0x34, 0xe4, 0x36, - 0xab, 0x49, 0xf6, 0xf5, 0xf3, 0x62, 0xcb, 0xc8, 0x07, 0x3d, 0xea, 0xc0, 0xdf, 0xaf, 0x6f, 0x65, - 0xb3, 0xba, 0x45, 0x4e, 0x3c, 0xe0, 0x4b, 0xb9, 0xd0, 0x1a, 0xe4, 0xdc, 0x43, 0xba, 0x66, 0x58, - 0x6d, 0x5d, 0xac, 0x8a, 0x13, 0xe9, 0x2b, 0xe0, 0x42, 0x6d, 0xb8, 0xe0, 0x1e, 0x9b, 0x6c, 0x29, - 0x52, 0x5a, 0x9a, 0x12, 0x88, 0x9b, 0x9e, 0x44, 0xdc, 0x22, 0x15, 0x77, 0x76, 0xba, 0x84, 0x9a, - 0xc7, 0x26, 0x5d, 0xb7, 0x36, 0xab, 0x4d, 0x4f, 0x00, 0x46, 0xae, 0xa0, 0x69, 0x3e, 0x6d, 0xf1, - 0x19, 0x4c, 0xb3, 0x5e, 0x78, 0x77, 0x0c, 0x52, 0xc4, 0x1d, 0x03, 0xed, 0x94, 0x57, 0xc1, 0xcb, - 0x18, 0x41, 0xc0, 0xc5, 0x4d, 0x41, 0x18, 0xc4, 0x7b, 0x00, 0x54, 0x85, 0x49, 0x9a, 0xc1, 0xf7, - 0xd3, 0x50, 0x7c, 0xdc, 0x73, 0x0e, 0x13, 0xb6, 0xfb, 0x2a, 0x40, 0xb7, 0xe7, 0x1c, 0x12, 0x5b, - 0x71, 0x8f, 0x4d, 0xd1, 0xf3, 0x31, 0x17, 0x20, 0x5e, 0xd7, 0x39, 0x5f, 0xf3, 0xd8, 0x44, 0xbb, - 0x42, 0x08, 0x51, 0x82, 0x5b, 0x94, 0x7b, 0x13, 0xc0, 0xe0, 0xe6, 0xb1, 0xb9, 0x4d, 0x7c, 0xfc, - 0xcb, 0x05, 0x12, 0x2a, 0xf0, 0xf3, 0x30, 0x4b, 0x13, 0x8a, 0x6b, 0xbd, 0x8c, 0x85, 0xcd, 0x50, - 0x9e, 0xa6, 0xe5, 0xcd, 0xe5, 0xe9, 0x97, 0x9b, 0xcb, 0xe8, 0x6d, 0xc8, 0xf1, 0x4a, 0xa9, 0x4f, - 0x9d, 0x61, 0x3e, 0x35, 0x4a, 0x13, 0x62, 0x10, 0x98, 0x37, 0xcd, 0xb2, 0x1a, 0xa9, 0x2f, 0x3d, - 0x0f, 0xd3, 0x07, 0x96, 0xad, 0x11, 0x76, 0xdb, 0x92, 0xc5, 0x3c, 0xe1, 0x03, 0xa7, 0xac, 0x9c, - 0x2b, 0xff, 0x9e, 0x04, 0xf3, 0xfe, 0x00, 0x26, 0x89, 0x98, 0xaa, 0x7d, 0xda, 0x7f, 0xf9, 0x21, - 0xa4, 0x1a, 0x2f, 0x7f, 0x2f, 0x05, 0xf3, 0xef, 0xf5, 0x88, 0x7d, 0x92, 0xb0, 0x7d, 0x55, 0xf8, - 0xcd, 0x5a, 0xea, 0x15, 0x6d, 0x82, 0xdd, 0xb5, 0xdd, 0x82, 0xf9, 0x23, 0xd5, 0x70, 0x95, 0x03, - 0xcb, 0x56, 0x7a, 0x5d, 0x5d, 0x75, 0xbd, 0x7b, 0x88, 0x02, 0x25, 0xbf, 0x63, 0xd9, 0x7b, 0x8c, - 0x88, 0x08, 0xa0, 0x67, 0xa6, 0x75, 0x64, 0x2a, 0x94, 0x6c, 0x98, 0x2d, 0xaa, 0x0f, 0xa7, 0x94, - 0x61, 0x07, 0x63, 0x9f, 0xfd, 0x97, 0xd3, 0xa5, 0x87, 0x2d, 0xc3, 0x3d, 0xec, 0xed, 0xaf, 0x68, - 0x56, 0xe7, 0xbe, 0xdf, 0x10, 0x7d, 0x3f, 0xf8, 0x7f, 0xbf, 0xfb, 0xac, 0x75, 0x9f, 0x5d, 0xa9, - 0xf6, 0x7a, 0x86, 0xbe, 0xb2, 0xb7, 0x57, 0x5f, 0xc7, 0x32, 0x13, 0xf9, 0x3e, 0x97, 0xd8, 0x3c, - 0x36, 0xbd, 0x05, 0xef, 0x63, 0x09, 0xe4, 0x40, 0x61, 0x49, 0x8e, 0xe7, 0x06, 0xe4, 0x9f, 0xf7, - 0x88, 0x6d, 0x10, 0xfd, 0xa5, 0x07, 0x14, 0x04, 0x23, 0x9d, 0x43, 0x1f, 0xc0, 0x5c, 0x9f, 0x1e, - 0xd2, 0x3f, 0x9b, 0x1e, 0xf2, 0x47, 0x81, 0x0a, 0xca, 0xdf, 0x4f, 0x01, 0x62, 0x9d, 0xaf, 0xf3, - 0xc3, 0x8c, 0x9f, 0x33, 0x83, 0x79, 0x02, 0x60, 0x1c, 0x28, 0x1d, 0xc3, 0x71, 0x0c, 0xb3, 0xc5, - 0x6c, 0xa5, 0xb8, 0xfa, 0xd9, 0x88, 0xb6, 0x0c, 0x77, 0x61, 0xa5, 0x7e, 0xb0, 0xcd, 0xd9, 0x2a, - 0xe4, 0x50, 0x7d, 0x61, 0x58, 0x36, 0xce, 0x19, 0x1e, 0xa9, 0x5c, 0x81, 0x85, 0xa1, 0x7c, 0x54, - 0x04, 0x58, 0xdf, 0x55, 0x76, 0x76, 0x9b, 0xb5, 0xfa, 0xce, 0xa6, 0x3c, 0x85, 0x64, 0x98, 0xc3, - 0x1b, 0xcd, 0x3d, 0xbc, 0xa3, 0x6c, 0x60, 0xbc, 0x8b, 0x65, 0x09, 0xe5, 0x61, 0xf6, 0x31, 0xde, - 0x78, 0xb2, 0xb1, 0xd3, 0x94, 0x53, 0xc2, 0x7a, 0x7e, 0x19, 0xce, 0xf5, 0x55, 0x9e, 0xa4, 0xfd, - 0x5c, 0x87, 0xb9, 0x03, 0xab, 0x67, 0xea, 0x0a, 0xdf, 0x35, 0x8a, 0xdd, 0x71, 0x9e, 0xd1, 0x78, - 0x7d, 0xe5, 0x6f, 0xa6, 0xe0, 0x3c, 0x26, 0x8e, 0xd5, 0x7e, 0x41, 0x92, 0x1f, 0xc1, 0x5d, 0x10, - 0x67, 0x5c, 0xca, 0xcf, 0x32, 0x90, 0x39, 0x2e, 0x83, 0xaf, 0x06, 0x33, 0x8e, 0xab, 0xba, 0x3d, - 0x47, 0x0c, 0xe5, 0x8d, 0xd1, 0x73, 0xa1, 0xc1, 0xca, 0x62, 0xc1, 0x13, 0xda, 0xd4, 0x66, 0x86, - 0x37, 0xb5, 0xe5, 0x5f, 0x82, 0x0b, 0x03, 0x8a, 0x48, 0x72, 0xd1, 0xfe, 0x49, 0x0a, 0x2e, 0xf7, - 0x8b, 0x4f, 0xfa, 0x7e, 0xe2, 0xff, 0x86, 0xb2, 0x51, 0x0d, 0x0a, 0x1d, 0xc3, 0x54, 0x02, 0x8c, - 0xf5, 0x12, 0x8b, 0xf3, 0x1c, 0xdd, 0xaf, 0xf5, 0xc3, 0x2c, 0xba, 0x8f, 0x8b, 0xd2, 0x6b, 0x92, - 0x63, 0xf7, 0x1d, 0x09, 0xe6, 0x92, 0xde, 0x6d, 0xbf, 0xda, 0x25, 0xa9, 0xe8, 0x73, 0x13, 0x0a, - 0x9f, 0xc0, 0xf6, 0xfc, 0x8f, 0x24, 0x40, 0x4d, 0xbb, 0x67, 0x6a, 0xaa, 0x4b, 0xde, 0xb5, 0x5a, - 0x49, 0x76, 0xf6, 0x3c, 0x4c, 0x1b, 0xa6, 0x4e, 0x8e, 0x59, 0x67, 0x33, 0x98, 0x27, 0xd0, 0x03, - 0xc8, 0x8a, 0x20, 0x17, 0x7e, 0xe9, 0x9b, 0xae, 0x5c, 0x3c, 0x3b, 0x5d, 0x9a, 0xe5, 0x21, 0x2d, - 0xeb, 0x1f, 0x07, 0x7f, 0xf1, 0x2c, 0x8f, 0x6a, 0xf1, 0xae, 0xc5, 0x3f, 0x80, 0x73, 0x7d, 0x0d, - 0x4d, 0x52, 0x0b, 0xdf, 0x4b, 0xc1, 0x39, 0xd1, 0x9d, 0xc4, 0x8f, 0x27, 0x5e, 0x29, 0x42, 0x0a, - 0x7d, 0x01, 0xa0, 0x6b, 0x93, 0x17, 0x0a, 0x67, 0x4d, 0x4f, 0xc4, 0x9a, 0xa3, 0x1c, 0x8c, 0x80, - 0xbe, 0x02, 0xf3, 0x74, 0xc2, 0x75, 0x6d, 0xab, 0x6b, 0x39, 0x14, 0x49, 0x38, 0x93, 0x21, 0xe9, - 0x85, 0xb3, 0xd3, 0xa5, 0xc2, 0xb6, 0x61, 0x3e, 0x16, 0x8c, 0xcd, 0x06, 0xa6, 0x33, 0xd7, 0x4f, - 0x7a, 0xf0, 0xe7, 0xc7, 0x12, 0x9c, 0xff, 0xc4, 0x0e, 0x74, 0xfe, 0x37, 0x34, 0xe6, 0xaf, 0x07, - 0x32, 0x4b, 0xd6, 0xcd, 0x03, 0x2b, 0xf9, 0x63, 0xb6, 0xef, 0x48, 0xb0, 0x10, 0x12, 0x9f, 0xe4, - 0xaa, 0xff, 0x6a, 0x71, 0x78, 0x5f, 0xa5, 0x38, 0x20, 0x6c, 0xf6, 0x49, 0x4e, 0xaa, 0x5f, 0x4f, - 0xc1, 0xc5, 0x2a, 0xbf, 0x7c, 0x61, 0x77, 0x4c, 0x4e, 0xaf, 0x93, 0xa4, 0x95, 0x94, 0x60, 0xf6, - 0x05, 0xb1, 0x1d, 0xc3, 0xe2, 0xeb, 0x5e, 0x01, 0x7b, 0x49, 0xf4, 0x0d, 0xc8, 0x6b, 0xa2, 0x42, - 0xcf, 0xcb, 0xcc, 0x55, 0xea, 0x54, 0xc0, 0x2b, 0xa2, 0xdf, 0xb3, 0xd3, 0x25, 0xf0, 0xba, 0x50, - 0x5f, 0xc7, 0xe0, 0x49, 0xaf, 0xeb, 0x2c, 0xf6, 0xd0, 0x54, 0xbb, 0xce, 0xa1, 0xe5, 0x9d, 0x53, - 0xfb, 0x69, 0x31, 0xe8, 0x5f, 0x83, 0x4b, 0x43, 0x5a, 0x48, 0x52, 0xcd, 0x7f, 0x37, 0x0b, 0x85, - 0x8d, 0xe3, 0xae, 0x65, 0xbb, 0x0d, 0xbe, 0xd8, 0xa3, 0x75, 0xc8, 0x76, 0x6d, 0xeb, 0x85, 0xe1, - 0x09, 0x2e, 0x46, 0xde, 0x5b, 0xf4, 0xf1, 0x3c, 0x16, 0xe5, 0xb1, 0xcf, 0x89, 0x30, 0xe4, 0xde, - 0xb5, 0x34, 0xb5, 0xfd, 0x8e, 0xd1, 0xf6, 0xac, 0x6a, 0x65, 0x9c, 0x98, 0x15, 0x9f, 0xe3, 0xb1, - 0xea, 0x1e, 0x7a, 0x93, 0xcc, 0x27, 0xa2, 0x4d, 0xc8, 0xd6, 0x5c, 0xb7, 0x4b, 0x33, 0xc5, 0x0c, - 0xbd, 0x39, 0x56, 0x24, 0x65, 0x10, 0x92, 0x7c, 0x66, 0x84, 0x61, 0x61, 0xd3, 0xb2, 0x5a, 0x6d, - 0x52, 0x6d, 0x5b, 0x3d, 0xbd, 0x6a, 0x99, 0x07, 0x46, 0x4b, 0x78, 0xb8, 0x1b, 0x63, 0x25, 0x6e, - 0x56, 0x1b, 0x78, 0x98, 0x1d, 0x7d, 0x09, 0xb2, 0x8d, 0x87, 0x42, 0x14, 0xc7, 0x27, 0xaf, 0x8f, - 0x15, 0xd5, 0x78, 0x88, 0x7d, 0x26, 0x54, 0x83, 0xfc, 0xda, 0x47, 0x3d, 0x9b, 0x08, 0x19, 0x33, - 0x4c, 0xc6, 0xad, 0xb1, 0x32, 0x18, 0x0f, 0x0e, 0xb3, 0x2e, 0xde, 0x85, 0x42, 0x9f, 0x26, 0x11, - 0x82, 0x4c, 0x97, 0x2a, 0x8d, 0x0e, 0x67, 0x0e, 0xb3, 0xff, 0xdc, 0xbc, 0x16, 0x6f, 0x41, 0x86, - 0x6a, 0x85, 0x4e, 0x87, 0x7d, 0xd5, 0x21, 0x7b, 0xb6, 0x21, 0x0a, 0x79, 0x49, 0x51, 0xee, 0x6f, - 0x25, 0x48, 0x35, 0x1e, 0x52, 0x84, 0xb6, 0xdf, 0xd3, 0x9e, 0x11, 0x57, 0x94, 0x12, 0x29, 0x86, - 0xdc, 0x6c, 0x72, 0x60, 0xf0, 0xd5, 0x3a, 0x87, 0x45, 0x0a, 0xbd, 0x06, 0xa0, 0x6a, 0x1a, 0x71, - 0x1c, 0xc5, 0x8b, 0xcf, 0xcd, 0xe1, 0x1c, 0xa7, 0x6c, 0x91, 0x13, 0xca, 0xe6, 0x10, 0xcd, 0x26, - 0xdc, 0xf8, 0x73, 0x58, 0xa4, 0x28, 0x9b, 0x4b, 0x3a, 0x5d, 0xc5, 0xb5, 0x9e, 0x11, 0x93, 0x69, - 0x33, 0x87, 0x73, 0x94, 0xd2, 0xa4, 0x04, 0x3a, 0x6b, 0x88, 0xa9, 0x77, 0x2d, 0xc3, 0x74, 0x99, - 0x9a, 0x72, 0xd8, 0x4f, 0x53, 0x91, 0x36, 0x69, 0x19, 0x22, 0x72, 0x35, 0x87, 0x45, 0x4a, 0x74, - 0x63, 0x17, 0xd2, 0x9b, 0xd5, 0xc6, 0x4b, 0x77, 0x03, 0x41, 0x46, 0xed, 0x09, 0xa3, 0xcb, 0x61, - 0xf6, 0x5f, 0x08, 0xfc, 0xa6, 0x04, 0xd3, 0x4c, 0xf5, 0xe8, 0x2a, 0xe4, 0x34, 0xcb, 0x74, 0x55, - 0xc3, 0x14, 0xf3, 0x26, 0x87, 0x03, 0x42, 0xac, 0xe4, 0xeb, 0x30, 0xa7, 0x6a, 0x9a, 0xd5, 0x33, - 0x5d, 0xc5, 0x54, 0x3b, 0x44, 0xd4, 0x90, 0x17, 0xb4, 0x1d, 0xb5, 0x43, 0xd0, 0x12, 0x78, 0x49, - 0x3f, 0x8a, 0x39, 0x87, 0x41, 0x90, 0xfc, 0xeb, 0x23, 0xe1, 0x2e, 0xfe, 0x58, 0x82, 0x85, 0xf7, - 0x6d, 0xc3, 0x25, 0x15, 0xd5, 0xd5, 0x0e, 0x93, 0x74, 0x98, 0x6f, 0x41, 0x4e, 0x57, 0x5d, 0x95, - 0x47, 0x2c, 0xa7, 0x46, 0x46, 0x2c, 0x7b, 0xf3, 0x8d, 0x96, 0x67, 0x51, 0xcb, 0x08, 0x32, 0xf4, - 0x3f, 0xf7, 0xa5, 0x98, 0xfd, 0x0f, 0xae, 0x8e, 0xc2, 0xcd, 0x4d, 0xd2, 0xb3, 0xfd, 0x6b, 0xca, - 0xf3, 0x6c, 0x49, 0xaa, 0xe1, 0xcb, 0x30, 0x2b, 0x76, 0x45, 0x42, 0x09, 0xcb, 0xe3, 0x66, 0xa8, - 0x77, 0xe5, 0x21, 0xd8, 0x50, 0x05, 0xc0, 0x71, 0x55, 0xdb, 0x65, 0xfb, 0x99, 0x89, 0xee, 0x98, - 0x3d, 0x4f, 0xc8, 0xd8, 0x28, 0x15, 0xed, 0x40, 0xbe, 0xf3, 0x42, 0xd3, 0x94, 0x03, 0xa3, 0xed, - 0x8a, 0xeb, 0xe5, 0x62, 0x9f, 0x10, 0xaf, 0x25, 0xdb, 0x4f, 0xaa, 0xd5, 0x77, 0x58, 0x21, 0x7e, - 0xcb, 0x1b, 0xa4, 0x31, 0x50, 0x09, 0xfc, 0x3f, 0xfa, 0x14, 0x88, 0xa8, 0x34, 0xc5, 0x71, 0x5c, - 0x36, 0xe1, 0xb2, 0x95, 0xc2, 0xd9, 0xe9, 0x52, 0x0e, 0x33, 0x6a, 0xa3, 0xd1, 0xc4, 0x39, 0x5e, - 0xa0, 0xe1, 0x78, 0x2b, 0xd3, 0xb7, 0x25, 0x28, 0x54, 0x7a, 0xed, 0x67, 0xbb, 0xdd, 0x46, 0xaf, - 0xd3, 0x51, 0xed, 0x13, 0x74, 0xc5, 0x33, 0x11, 0xe3, 0x23, 0xc2, 0x54, 0x9c, 0x16, 0x36, 0x60, - 0x7c, 0x44, 0xa8, 0x0d, 0x88, 0x48, 0x19, 0x4a, 0xe7, 0x61, 0x30, 0xaf, 0x43, 0x81, 0xc1, 0x7a, - 0x85, 0x98, 0xae, 0x6d, 0x10, 0xbe, 0x6b, 0x4c, 0xe3, 0x39, 0x46, 0xdc, 0xe0, 0x34, 0x74, 0x13, - 0x8a, 0xce, 0x89, 0xe3, 0x92, 0x8e, 0xc2, 0x9f, 0x28, 0x70, 0x2c, 0x9a, 0xc6, 0x05, 0x4e, 0xc5, - 0x9c, 0x58, 0xfe, 0xd3, 0x34, 0x14, 0xbd, 0xe1, 0x4e, 0x12, 0x1a, 0x55, 0x60, 0xfa, 0xc0, 0x68, - 0x13, 0x2f, 0xc4, 0x27, 0xde, 0x21, 0x7b, 0x92, 0x56, 0xa8, 0xdb, 0xf5, 0x80, 0x12, 0x63, 0x4d, - 0x62, 0xc8, 0x17, 0x7f, 0x24, 0x41, 0x86, 0xad, 0x82, 0x0f, 0x20, 0xc3, 0xe6, 0xa0, 0x34, 0xc9, - 0x1c, 0x64, 0x45, 0x7d, 0xff, 0x9f, 0x0a, 0xfc, 0x3f, 0xf3, 0xbd, 0x87, 0xea, 0x9b, 0x0f, 0x56, - 0xd9, 0x70, 0xcf, 0x61, 0x91, 0x42, 0x15, 0xc8, 0x12, 0xd6, 0x1f, 0xa2, 0x8b, 0x35, 0x28, 0xca, - 0xc2, 0xfb, 0x06, 0xde, 0x9b, 0xef, 0x1e, 0x1f, 0xba, 0x0c, 0x69, 0x6a, 0x47, 0xb3, 0xfc, 0xae, - 0xe4, 0xec, 0x74, 0x29, 0x4d, 0x2d, 0x88, 0xd2, 0xf8, 0x8d, 0xfb, 0xa3, 0x4c, 0x36, 0x23, 0x4f, - 0x97, 0xff, 0x22, 0x03, 0x85, 0x7a, 0x27, 0xe9, 0x19, 0xba, 0xd6, 0x3f, 0x60, 0x51, 0x10, 0xa1, - 0xaf, 0xd2, 0x88, 0xf1, 0xea, 0xf3, 0x75, 0xe9, 0x97, 0xf3, 0x75, 0x75, 0xba, 0x00, 0x89, 0xf7, - 0x19, 0xb4, 0xfe, 0x37, 0xc6, 0xd6, 0xdf, 0x54, 0xf7, 0xdb, 0x04, 0x53, 0x1e, 0xef, 0x2a, 0x82, - 0x0b, 0x40, 0x5f, 0x64, 0xeb, 0x1c, 0x37, 0x9a, 0x99, 0xc9, 0x8d, 0x66, 0x96, 0x98, 0x3a, 0x33, - 0x99, 0x63, 0x61, 0x31, 0x9f, 0x83, 0xb4, 0x6e, 0x8c, 0x52, 0x69, 0x94, 0xbf, 0xa2, 0x2c, 0x63, - 0x0c, 0x27, 0x13, 0x36, 0x1c, 0xff, 0xba, 0x22, 0x2d, 0x67, 0x16, 0x77, 0x01, 0x82, 0x5e, 0xa1, - 0x65, 0x98, 0xb1, 0xda, 0x3a, 0x05, 0xd3, 0xb4, 0x09, 0x85, 0x4a, 0xee, 0xec, 0x74, 0x69, 0x7a, - 0xb7, 0xad, 0xd7, 0xd7, 0xf1, 0xb4, 0xd5, 0xd6, 0xeb, 0x3a, 0x7b, 0xd6, 0x42, 0x8e, 0x14, 0xf6, - 0x92, 0x88, 0x85, 0x49, 0xe0, 0x59, 0x93, 0x1c, 0xad, 0x13, 0x47, 0x0b, 0xaf, 0x6e, 0xc2, 0x6c, - 0xfe, 0x40, 0x82, 0xa2, 0xa7, 0xc1, 0x64, 0x67, 0x7a, 0xd6, 0xe8, 0x08, 0xcb, 0x4f, 0xbf, 0x9c, - 0xe5, 0x7b, 0x7c, 0x22, 0x64, 0xf7, 0x5b, 0x12, 0x9c, 0xe3, 0xb1, 0x1c, 0x9a, 0xea, 0x52, 0x5f, - 0x9b, 0xa0, 0x79, 0xdf, 0x05, 0xd9, 0x56, 0x4d, 0xdd, 0xea, 0x18, 0x1f, 0x11, 0xbe, 0x5b, 0x75, - 0xc4, 0x21, 0xed, 0xbc, 0x4f, 0x67, 0xdb, 0x31, 0x6f, 0xb3, 0xfd, 0x5f, 0x12, 0x9c, 0xef, 0x6f, - 0x4c, 0x92, 0x4a, 0xdb, 0x82, 0x19, 0x76, 0xd0, 0xe2, 0x4d, 0xb7, 0x4f, 0x47, 0x08, 0x89, 0xaa, - 0x9d, 0xbf, 0x42, 0xf2, 0x0d, 0x9e, 0x89, 0x58, 0xfc, 0x32, 0x4c, 0x33, 0xf2, 0x2b, 0xf8, 0x38, - 0xa1, 0xf9, 0xe7, 0xb0, 0xb0, 0xa6, 0xeb, 0x8d, 0x86, 0xb0, 0xbe, 0xe4, 0xd4, 0xee, 0x41, 0x98, - 0x54, 0x14, 0x84, 0x09, 0x57, 0x99, 0x24, 0x84, 0xe9, 0x42, 0x51, 0x84, 0x58, 0x25, 0x7c, 0xb2, - 0x76, 0x44, 0x31, 0x97, 0x30, 0x1b, 0x9e, 0x08, 0x5e, 0x42, 0xf8, 0x35, 0x26, 0xd9, 0x93, 0x1e, - 0x9c, 0xf3, 0xe4, 0x26, 0x7d, 0x88, 0x3d, 0xaa, 0x3b, 0xec, 0x84, 0x22, 0x5c, 0x6d, 0x92, 0x7d, - 0xfa, 0x13, 0x09, 0x16, 0x37, 0x89, 0xdb, 0x10, 0x1b, 0xf6, 0x77, 0x2c, 0x3b, 0xf1, 0x13, 0xdf, - 0x4d, 0x80, 0x36, 0x39, 0x10, 0x61, 0xeb, 0x02, 0x70, 0x4e, 0xfe, 0xc6, 0x32, 0x47, 0x79, 0x59, - 0x96, 0x50, 0xc7, 0x4f, 0x24, 0xb8, 0x12, 0xd9, 0xe2, 0x24, 0x3d, 0x42, 0xc4, 0x4c, 0x41, 0x5f, - 0x03, 0x86, 0x36, 0x15, 0xc7, 0x55, 0x5d, 0x47, 0x38, 0xd7, 0x4f, 0xbd, 0x4c, 0xa8, 0x6b, 0x65, - 0x41, 0xc4, 0x6d, 0xe4, 0x7c, 0x12, 0xce, 0x51, 0x91, 0xec, 0x6f, 0xf9, 0x43, 0x58, 0x60, 0xfd, - 0x4c, 0x3a, 0x46, 0x58, 0xe8, 0xed, 0xaf, 0x24, 0x40, 0x61, 0xf9, 0x49, 0xaa, 0xab, 0x5f, 0x35, - 0xa9, 0xc4, 0x55, 0xf3, 0x4f, 0x97, 0x60, 0x4e, 0xf4, 0x72, 0xcf, 0x34, 0x2c, 0x13, 0x3d, 0x80, - 0x74, 0x4b, 0xec, 0x7c, 0xf3, 0x91, 0x7b, 0x86, 0xe0, 0x41, 0x65, 0x6d, 0x0a, 0xd3, 0xb2, 0x94, - 0xa5, 0xdb, 0x73, 0x23, 0x42, 0x5b, 0x82, 0xb0, 0x86, 0x30, 0x4b, 0xb7, 0xe7, 0xa2, 0x06, 0xcc, - 0x6b, 0xc1, 0x33, 0x34, 0x85, 0xb2, 0xa7, 0x63, 0x83, 0x60, 0x23, 0x9f, 0xe5, 0xd5, 0xa6, 0x70, - 0x51, 0xeb, 0xcb, 0x40, 0xd5, 0xf0, 0xbb, 0xa7, 0x4c, 0xec, 0x21, 0xcb, 0xe0, 0x9b, 0xab, 0xda, - 0x54, 0xe8, 0x79, 0x14, 0x7a, 0x0b, 0x66, 0x74, 0xf6, 0x9e, 0x46, 0x1c, 0xd3, 0x44, 0x99, 0x45, - 0xdf, 0x13, 0xa6, 0xda, 0x14, 0x16, 0x1c, 0xe8, 0x11, 0xcc, 0xf1, 0x7f, 0x62, 0x46, 0xce, 0xc4, - 0x9e, 0x42, 0x0d, 0xbf, 0x28, 0xaa, 0x4d, 0xe1, 0xbc, 0x1e, 0x50, 0xd1, 0x67, 0x20, 0xe3, 0x68, - 0x2a, 0x3f, 0xa7, 0x88, 0xbe, 0xa2, 0x0f, 0xbd, 0x8d, 0xa8, 0xd1, 0x65, 0x4e, 0x53, 0x4d, 0xf4, - 0x14, 0x16, 0xf6, 0x49, 0xcb, 0x30, 0x15, 0x37, 0xb8, 0x46, 0x63, 0x01, 0xb9, 0xfd, 0x37, 0x77, - 0x3e, 0x5a, 0x89, 0x8e, 0x03, 0xaf, 0x4d, 0x61, 0x79, 0x7f, 0x20, 0x8b, 0x0e, 0x19, 0x83, 0x9b, - 0x21, 0xc1, 0xb9, 0xd8, 0x21, 0x8b, 0x8c, 0xcc, 0xa6, 0x43, 0x46, 0xfa, 0x32, 0xd0, 0x26, 0xe4, - 0x55, 0xba, 0xfc, 0x2b, 0x2c, 0xda, 0xb5, 0x04, 0xb1, 0x87, 0x6c, 0x43, 0x01, 0xb8, 0x35, 0x16, - 0xd4, 0xee, 0x11, 0x03, 0x41, 0x1d, 0xea, 0xb2, 0x4a, 0xf9, 0xd1, 0x82, 0xc2, 0x9e, 0xd8, 0x17, - 0xc4, 0x88, 0x68, 0x1b, 0x0a, 0x87, 0x5e, 0xbc, 0x1d, 0xbb, 0xf7, 0x9c, 0x8b, 0x3d, 0x69, 0x8b, - 0x88, 0x17, 0xac, 0x4d, 0xe1, 0xb9, 0xc3, 0x10, 0x19, 0xad, 0x40, 0xaa, 0xa5, 0x95, 0x0a, 0x4c, - 0xc6, 0xd5, 0x51, 0xd1, 0x70, 0xb5, 0x29, 0x9c, 0x6a, 0x69, 0x14, 0xd4, 0xf3, 0x40, 0xa1, 0x63, - 0xb3, 0x54, 0x8c, 0x75, 0x1b, 0xfd, 0xc1, 0x5a, 0xb5, 0x29, 0xcc, 0x42, 0x9a, 0x68, 0x7d, 0x8f, - 0xa1, 0x68, 0xf3, 0xcb, 0x4b, 0xef, 0x8a, 0x5e, 0x66, 0x52, 0x6e, 0x47, 0x3b, 0x9f, 0xa1, 0x5b, - 0xfa, 0xda, 0x14, 0x2e, 0xd8, 0x61, 0x3a, 0xfa, 0x3a, 0x9c, 0xef, 0x97, 0x28, 0x8c, 0x7b, 0x61, - 0xc8, 0x17, 0x45, 0xcb, 0xed, 0xb7, 0x71, 0x64, 0x0f, 0x65, 0xa2, 0xcf, 0xc2, 0x34, 0x1f, 0x35, - 0xc4, 0x44, 0x2e, 0x45, 0x1d, 0x54, 0xf4, 0x0f, 0x18, 0x2f, 0x4f, 0xe7, 0x9b, 0x2b, 0x6e, 0xed, - 0x94, 0xb6, 0xd5, 0x2a, 0x9d, 0x8b, 0x9d, 0x6f, 0xc3, 0xb7, 0x90, 0x74, 0xbe, 0xb9, 0x01, 0x95, - 0x8e, 0xbb, 0xcd, 0x73, 0xc4, 0x25, 0xcf, 0xf9, 0xd8, 0x71, 0x8f, 0xb8, 0xcc, 0xa3, 0xe3, 0x6e, - 0x87, 0xc8, 0xb4, 0x69, 0x36, 0x7f, 0x55, 0xa4, 0xb0, 0x69, 0x7c, 0x21, 0xb6, 0x69, 0xc3, 0x2f, - 0x9d, 0x68, 0xd3, 0xec, 0x80, 0x8a, 0x9e, 0x80, 0x2c, 0xde, 0x99, 0x28, 0xde, 0xe5, 0x40, 0xe9, - 0x22, 0x93, 0x77, 0x37, 0xd2, 0x5b, 0x46, 0xdd, 0x8a, 0xd4, 0xa6, 0xf0, 0xbc, 0xd6, 0x9f, 0x43, - 0x9d, 0x05, 0x93, 0xa7, 0x68, 0xc1, 0x03, 0x9d, 0x52, 0x29, 0xd6, 0x59, 0xc4, 0xbc, 0x26, 0xa2, - 0xce, 0x42, 0x1b, 0xc8, 0xa2, 0x66, 0x6c, 0x98, 0x86, 0xcb, 0x1c, 0xfb, 0x62, 0xac, 0x19, 0xf7, - 0xbf, 0x14, 0xa6, 0x66, 0x6c, 0x70, 0x0a, 0x35, 0x63, 0x57, 0xdc, 0x00, 0x8a, 0xe1, 0xb8, 0x1a, - 0x6b, 0xc6, 0x51, 0x57, 0x85, 0xd4, 0x8c, 0xdd, 0x30, 0x9d, 0x9a, 0x31, 0x77, 0x10, 0x03, 0x72, - 0x5f, 0x8b, 0x35, 0xe3, 0xd8, 0xc0, 0x72, 0x6a, 0xc6, 0xea, 0x50, 0x26, 0x5a, 0xa7, 0x68, 0x4c, - 0x75, 0xf8, 0x17, 0x16, 0x4a, 0xd7, 0x62, 0xd7, 0x9f, 0xc1, 0x3b, 0xc0, 0x1a, 0x83, 0x62, 0x82, - 0x46, 0x1d, 0x19, 0x83, 0xa8, 0xca, 0xbe, 0xea, 0x6a, 0x87, 0xa5, 0xa5, 0x58, 0x47, 0x36, 0x74, - 0x8e, 0x4b, 0x1d, 0xd9, 0x91, 0x4f, 0xa4, 0x0b, 0x19, 0x3f, 0x71, 0x29, 0x2d, 0x8f, 0xd9, 0xd9, - 0x87, 0x16, 0x32, 0xce, 0x81, 0xd6, 0x20, 0xf7, 0xbc, 0x47, 0xec, 0x13, 0xe6, 0x86, 0xae, 0xc7, - 0xe2, 0xca, 0x81, 0xa0, 0xbe, 0xda, 0x14, 0xce, 0x3e, 0x17, 0x24, 0x5a, 0x3d, 0xdf, 0xf6, 0x96, - 0xca, 0xb1, 0xd5, 0xf7, 0x1d, 0x74, 0xd0, 0xea, 0x39, 0x07, 0xd2, 0xe0, 0x02, 0x1f, 0x2b, 0x11, - 0x89, 0x6e, 0x8b, 0x90, 0xef, 0xd2, 0xeb, 0x4c, 0x54, 0xec, 0x26, 0x32, 0x32, 0x2a, 0xbe, 0x36, - 0x85, 0xcf, 0xa9, 0xc3, 0xb9, 0x74, 0xc2, 0x8b, 0xa5, 0x87, 0x6f, 0x3d, 0x4b, 0x37, 0x62, 0x27, - 0x7c, 0xc4, 0x66, 0x9d, 0x4e, 0x78, 0x35, 0x44, 0xe6, 0x0b, 0x90, 0xae, 0x38, 0x8e, 0x4b, 0x37, - 0x7a, 0xa5, 0x9b, 0x23, 0x16, 0xa0, 0x81, 0x0d, 0x28, 0x5f, 0x80, 0xf4, 0x06, 0xe7, 0xa4, 0x82, - 0xb4, 0x36, 0x51, 0x6d, 0xe1, 0x66, 0x6f, 0xc5, 0x0a, 0x1a, 0x7a, 0x7d, 0x4b, 0x05, 0x69, 0x3e, - 0x91, 0x2e, 0xd8, 0xb6, 0xf7, 0x40, 0x4d, 0xe0, 0xc7, 0xdb, 0xb1, 0x0b, 0x76, 0xe4, 0x3b, 0x3a, - 0xba, 0x60, 0xdb, 0x7d, 0x19, 0xe8, 0x0b, 0x30, 0x2b, 0x5e, 0xfb, 0x94, 0xee, 0x8c, 0x40, 0xb5, - 0xe1, 0x5d, 0x29, 0x9d, 0xd7, 0x82, 0x87, 0x7b, 0x59, 0xfe, 0x58, 0x88, 0x77, 0xef, 0xee, 0x08, - 0x2f, 0x3b, 0xb4, 0x21, 0xe4, 0x5e, 0x36, 0x20, 0x53, 0x2f, 0xcb, 0xed, 0x54, 0xac, 0x75, 0xf7, - 0x62, 0xbd, 0xec, 0x70, 0x38, 0x1e, 0xf5, 0xb2, 0xcf, 0x03, 0x2a, 0xd2, 0xe1, 0x62, 0x8b, 0xb8, - 0x8a, 0x77, 0xc1, 0xca, 0x22, 0x42, 0xf9, 0xb2, 0xf4, 0x46, 0xac, 0xd5, 0xc5, 0xef, 0xef, 0xa8, - 0xd5, 0xb5, 0x86, 0x73, 0xe9, 0xe8, 0xf2, 0x08, 0x15, 0x3e, 0x20, 0x9f, 0x8a, 0x1d, 0xdd, 0xa1, - 0x0d, 0x4b, 0xcd, 0xfb, 0x14, 0x0b, 0x87, 0xf5, 0xb3, 0x22, 0xda, 0xe7, 0x51, 0x26, 0x3b, 0x2f, - 0xcb, 0x8f, 0x32, 0xd9, 0x4b, 0x72, 0xe9, 0x51, 0x26, 0x7b, 0x59, 0x5e, 0x7c, 0x94, 0xc9, 0x5e, - 0x91, 0xaf, 0x96, 0xff, 0xfc, 0x12, 0x14, 0xbc, 0xed, 0x05, 0x87, 0xf6, 0xab, 0x61, 0x68, 0x7f, - 0x2d, 0x0e, 0xda, 0x8b, 0x0d, 0x89, 0xc0, 0xf6, 0xab, 0x61, 0x6c, 0x7f, 0x2d, 0x0e, 0xdb, 0x07, - 0x3c, 0x14, 0xdc, 0x37, 0xe3, 0xc0, 0xfd, 0xdd, 0x09, 0xc0, 0xbd, 0x2f, 0x6a, 0x10, 0xdd, 0xaf, - 0x0f, 0xa3, 0xfb, 0x1b, 0xa3, 0xd1, 0xbd, 0x2f, 0x2a, 0x04, 0xef, 0xdf, 0x1e, 0x80, 0xf7, 0xd7, - 0x47, 0xc0, 0x7b, 0x9f, 0xdf, 0xc3, 0xf7, 0x5b, 0x91, 0xf8, 0xfe, 0xd6, 0x38, 0x7c, 0xef, 0xcb, - 0xe9, 0x03, 0xf8, 0x6f, 0xf6, 0x01, 0xfc, 0xa5, 0x58, 0x80, 0xef, 0x73, 0x73, 0x84, 0xff, 0x41, - 0x3c, 0xc2, 0x7f, 0x63, 0x22, 0x84, 0xef, 0xcb, 0x1b, 0x86, 0xf8, 0xcd, 0x38, 0x88, 0x7f, 0x77, - 0x02, 0x88, 0x1f, 0x0c, 0xdc, 0x00, 0xc6, 0xaf, 0x45, 0x61, 0xfc, 0x9b, 0x63, 0x30, 0xbe, 0x2f, - 0x2d, 0x0c, 0xf2, 0x6b, 0x51, 0x20, 0xff, 0xe6, 0x18, 0x90, 0x3f, 0x20, 0x89, 0x4f, 0xc3, 0x9d, - 0x68, 0x94, 0x7f, 0x7b, 0x2c, 0xca, 0xf7, 0xa5, 0xf5, 0xc3, 0xfc, 0xfb, 0x21, 0x98, 0xff, 0x5a, - 0x0c, 0xcc, 0xf7, 0x59, 0x29, 0xce, 0xff, 0xd2, 0x10, 0xce, 0x2f, 0x8f, 0xc2, 0xf9, 0x3e, 0xaf, - 0x0f, 0xf4, 0xdf, 0x8b, 0x01, 0xfa, 0x77, 0xc6, 0x03, 0x7d, 0x5f, 0xd8, 0x00, 0xd2, 0x57, 0x47, - 0x22, 0xfd, 0x4f, 0x4f, 0x88, 0xf4, 0x7d, 0xe9, 0x51, 0x50, 0xff, 0x73, 0xfd, 0x50, 0x7f, 0x39, - 0x1e, 0xea, 0xfb, 0x62, 0x04, 0xd6, 0xdf, 0x8a, 0xc4, 0xfa, 0xb7, 0xc6, 0x61, 0xfd, 0x60, 0xee, - 0x85, 0xc1, 0xfe, 0x4e, 0x34, 0xd8, 0xbf, 0x3d, 0x16, 0xec, 0x07, 0xc3, 0xdf, 0x87, 0xf6, 0xb7, - 0x22, 0xd1, 0xfe, 0xad, 0x71, 0x68, 0x3f, 0x68, 0x5c, 0x18, 0xee, 0xbf, 0x1f, 0x0b, 0xf7, 0xef, - 0x4d, 0x02, 0xf7, 0x7d, 0xa1, 0x43, 0x78, 0xff, 0x83, 0x78, 0xbc, 0xff, 0xc6, 0x44, 0x78, 0x3f, - 0x70, 0x1d, 0x43, 0x80, 0xff, 0x4b, 0x43, 0x80, 0xbf, 0x3c, 0x0a, 0xf0, 0x07, 0xf6, 0xec, 0x21, - 0x7e, 0x75, 0x24, 0x3e, 0xff, 0xf4, 0x84, 0xf8, 0x3c, 0x30, 0xbe, 0x08, 0x80, 0xbe, 0x11, 0x01, - 0xd0, 0x6f, 0x8c, 0x06, 0xe8, 0xc1, 0x12, 0x12, 0x20, 0xf4, 0x5a, 0x14, 0x42, 0xbf, 0x39, 0x06, - 0xa1, 0x07, 0x5e, 0x28, 0x04, 0xd1, 0xdf, 0x1e, 0x80, 0xe8, 0xd7, 0xc7, 0xde, 0x1e, 0x87, 0x30, - 0x7a, 0x65, 0x18, 0xa3, 0xbf, 0x3e, 0x12, 0xa3, 0xfb, 0x12, 0x02, 0x90, 0xfe, 0xf6, 0x00, 0x48, - 0xbf, 0x3e, 0x02, 0xa4, 0x07, 0x0d, 0x10, 0x28, 0x5d, 0x1f, 0x8d, 0xd2, 0x57, 0x26, 0x45, 0xe9, - 0xbe, 0xe0, 0x48, 0x98, 0xbe, 0x13, 0x0d, 0xd3, 0x6f, 0x4f, 0x78, 0x91, 0x34, 0x84, 0xd3, 0x6b, - 0x51, 0x38, 0xfd, 0xe6, 0x18, 0x9c, 0x1e, 0x5e, 0x43, 0x7c, 0xa0, 0x5e, 0x8b, 0x02, 0xea, 0x37, - 0xc7, 0x00, 0xf5, 0x40, 0x52, 0x08, 0xa9, 0x37, 0xe3, 0x90, 0xfa, 0xdd, 0x09, 0x90, 0x7a, 0xb0, - 0xee, 0x0e, 0x40, 0xf5, 0x2f, 0x0e, 0x42, 0xf5, 0xf2, 0x28, 0xa8, 0x1e, 0xcc, 0x48, 0x0f, 0xab, - 0xef, 0x44, 0x63, 0xf5, 0xdb, 0x63, 0xb1, 0x7a, 0xd8, 0x49, 0x86, 0xc0, 0xfa, 0x56, 0x24, 0x58, - 0xbf, 0x35, 0x0e, 0xac, 0x07, 0x4e, 0x32, 0x8c, 0xd6, 0xc9, 0x18, 0xb4, 0xbe, 0x32, 0x29, 0x5a, - 0x0f, 0xac, 0x2f, 0x0a, 0xae, 0xd7, 0xa2, 0xe0, 0xfa, 0xcd, 0x31, 0x70, 0x3d, 0x18, 0xe3, 0x97, - 0xc0, 0xeb, 0x8f, 0x32, 0xd9, 0xab, 0xf2, 0x6b, 0xe5, 0xbf, 0x99, 0x86, 0x99, 0x9a, 0x17, 0xa9, - 0x10, 0x7a, 0x37, 0x2a, 0xbd, 0xca, 0xbb, 0x51, 0xb4, 0x4e, 0x4d, 0x80, 0x4d, 0x24, 0x81, 0xe0, - 0x47, 0xbc, 0xc2, 0x1e, 0xba, 0x1f, 0xf2, 0x58, 0x5f, 0x21, 0xaa, 0x1e, 0xbd, 0x09, 0x85, 0x9e, - 0x43, 0x6c, 0xa5, 0x6b, 0x1b, 0x96, 0x6d, 0xb8, 0x3c, 0x2e, 0x4d, 0xaa, 0xc8, 0x1f, 0x9f, 0x2e, - 0xcd, 0xed, 0x39, 0xc4, 0x7e, 0x2c, 0xe8, 0x78, 0xae, 0x17, 0x4a, 0x79, 0xdf, 0xca, 0x9c, 0x9e, - 0xfc, 0x5b, 0x99, 0xef, 0x81, 0x6c, 0x13, 0x55, 0xef, 0x5b, 0xd2, 0xf8, 0xfb, 0xca, 0xe8, 0xd5, - 0x57, 0xd5, 0x43, 0xab, 0x16, 0x7b, 0x67, 0x39, 0x6f, 0xf7, 0x13, 0xd1, 0x03, 0xb8, 0xd0, 0x51, - 0x8f, 0xf9, 0x0b, 0x62, 0x0f, 0x25, 0xb0, 0x88, 0x8d, 0x2c, 0x0b, 0x2c, 0x42, 0x1d, 0xf5, 0x98, - 0x7d, 0x78, 0x93, 0x67, 0xb1, 0x0f, 0x75, 0xdd, 0x84, 0xa2, 0x6e, 0x38, 0xae, 0x61, 0x6a, 0xde, - 0xb7, 0x37, 0xf8, 0x47, 0x2e, 0x0a, 0x1e, 0x95, 0x7f, 0x03, 0xe3, 0x1e, 0x2c, 0x88, 0x38, 0xaa, - 0xe0, 0x53, 0x9c, 0x0c, 0x0f, 0x67, 0x69, 0x2b, 0x68, 0x46, 0xf0, 0xe5, 0xd4, 0x2a, 0xcc, 0xb7, - 0x54, 0x97, 0x1c, 0xa9, 0x27, 0x8a, 0x69, 0xe9, 0x4c, 0xf7, 0x79, 0xf6, 0x05, 0x82, 0x2b, 0x67, - 0xa7, 0x4b, 0x85, 0x4d, 0x9e, 0xb5, 0x63, 0xe9, 0x7c, 0x04, 0x66, 0xf8, 0x3f, 0x5c, 0x68, 0x85, - 0x32, 0x74, 0xb4, 0x06, 0x73, 0x14, 0x8f, 0x28, 0x16, 0xff, 0xd4, 0x95, 0x40, 0xb9, 0x71, 0x97, - 0x09, 0xe2, 0x83, 0x58, 0x38, 0xef, 0x84, 0xbe, 0x8e, 0x75, 0x1b, 0xe6, 0x55, 0xe7, 0xc4, 0xd4, - 0x98, 0x86, 0x89, 0xe9, 0xf4, 0x1c, 0x06, 0x73, 0xb3, 0xb8, 0xc8, 0xc8, 0x55, 0x8f, 0x2a, 0x3e, - 0xe1, 0xf1, 0xdb, 0x12, 0xcc, 0xf5, 0x05, 0x17, 0xbe, 0x3d, 0x70, 0x0b, 0x76, 0x39, 0x1a, 0x62, - 0xc7, 0x05, 0xeb, 0x64, 0xc5, 0x08, 0x78, 0x01, 0x04, 0x4b, 0xf1, 0x10, 0x8d, 0x6d, 0x72, 0xbd, - 0x90, 0x0b, 0x8f, 0xed, 0xad, 0xcc, 0xef, 0x7e, 0x77, 0x69, 0xaa, 0xfc, 0xd3, 0x34, 0x14, 0xfa, - 0x83, 0x08, 0xeb, 0x03, 0xed, 0x8a, 0x72, 0x6b, 0x7d, 0x1c, 0xf1, 0xad, 0x5c, 0x87, 0x9c, 0x2d, - 0x0a, 0x79, 0xcd, 0x5c, 0x1e, 0x71, 0xd7, 0x17, 0x6e, 0x67, 0xc0, 0xb8, 0xf8, 0x83, 0x94, 0x3f, - 0xf3, 0x57, 0x60, 0x9a, 0x7d, 0x05, 0x58, 0x34, 0x2d, 0x2a, 0xde, 0x7e, 0x83, 0xe6, 0x63, 0x5e, - 0x8c, 0x7a, 0x8a, 0xe6, 0x2b, 0xbd, 0x30, 0xf7, 0x09, 0xaf, 0xf0, 0x95, 0xda, 0x57, 0x7c, 0x09, - 0xcd, 0x6e, 0xfe, 0xda, 0x6d, 0xa2, 0xb9, 0xe2, 0x63, 0xc2, 0xde, 0xb7, 0x68, 0x6f, 0x0c, 0x8a, - 0x10, 0x9f, 0x1e, 0x5e, 0xc1, 0xe2, 0xd3, 0xc3, 0xa1, 0x98, 0x8e, 0xa2, 0x2f, 0x82, 0x4d, 0x2c, - 0x1e, 0xf9, 0xc3, 0x87, 0xfa, 0x5e, 0x03, 0xce, 0x45, 0x4c, 0x73, 0x54, 0x04, 0xa8, 0xee, 0xee, - 0x34, 0xea, 0x8d, 0xe6, 0xc6, 0x4e, 0xd3, 0xfb, 0xa2, 0xec, 0xda, 0xba, 0xb2, 0xb7, 0x53, 0xdd, - 0xdd, 0xde, 0xae, 0x37, 0x9b, 0x1b, 0xeb, 0xb2, 0x84, 0x64, 0x98, 0xab, 0xef, 0x84, 0xca, 0x89, - 0x0f, 0xc9, 0xde, 0x7b, 0x1f, 0xf2, 0xa1, 0xb7, 0xd9, 0x08, 0x41, 0xf1, 0xf1, 0x5e, 0xa3, 0xa6, - 0x34, 0xeb, 0xdb, 0x1b, 0x8d, 0xe6, 0xda, 0xf6, 0x63, 0x79, 0x8a, 0x56, 0xc0, 0x68, 0x6b, 0x95, - 0x5d, 0xdc, 0x94, 0x25, 0x3f, 0xdd, 0xdc, 0xdd, 0xab, 0xd6, 0xe4, 0x94, 0x9f, 0x7e, 0x6f, 0x6f, - 0x03, 0x3f, 0x95, 0xd3, 0x42, 0xb0, 0x0a, 0x17, 0x22, 0x63, 0xe5, 0x51, 0x1e, 0x66, 0xf7, 0x4c, - 0xf6, 0x3e, 0x58, 0x9e, 0x42, 0x85, 0x50, 0xb8, 0xbc, 0x2c, 0xa1, 0x2c, 0x0f, 0xcb, 0x96, 0x53, - 0x68, 0x06, 0x52, 0x8d, 0x87, 0x72, 0x1a, 0xcd, 0x43, 0x3e, 0x14, 0x73, 0x2e, 0x67, 0x50, 0x4e, - 0x04, 0x1e, 0xcb, 0xd3, 0xf7, 0xae, 0x43, 0x28, 0xae, 0x13, 0x01, 0xcc, 0xbc, 0xab, 0xba, 0xc4, - 0x71, 0xe5, 0x29, 0x34, 0x0b, 0xe9, 0xb5, 0x76, 0x5b, 0x96, 0x56, 0xbf, 0x02, 0x59, 0xef, 0x4b, - 0x43, 0xe8, 0x5d, 0x98, 0xe6, 0xe8, 0x74, 0x29, 0x7e, 0x46, 0xb0, 0xb9, 0xb5, 0xb8, 0x3c, 0x6e, - 0xca, 0x94, 0xa7, 0x2a, 0xd7, 0x7f, 0xf8, 0xef, 0xd7, 0xa6, 0x7e, 0x78, 0x76, 0x4d, 0xfa, 0xd1, - 0xd9, 0x35, 0xe9, 0x9f, 0xcf, 0xae, 0x49, 0xff, 0x76, 0x76, 0x4d, 0xfa, 0xcd, 0xff, 0xb8, 0x36, - 0xf5, 0xc1, 0xac, 0x60, 0xd9, 0x9f, 0x61, 0xdf, 0x8d, 0x7e, 0xf8, 0x3f, 0x01, 0x00, 0x00, 0xff, - 0xff, 0x01, 0xd8, 0x70, 0x40, 0x3c, 0x5b, 0x00, 0x00, + // 5694 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x5c, 0x5f, 0x6c, 0x23, 0x49, + 0x5a, 0x77, 0xdb, 0x4e, 0x62, 0x7f, 0x8e, 0x9d, 0x4e, 0xcd, 0x3f, 0x4f, 0x66, 0x76, 0x92, 0xf1, + 0xce, 0xff, 0xbd, 0xcb, 0x30, 0x99, 0x5b, 0xee, 0xd8, 0xbd, 0x7f, 0xb1, 0x93, 0x8d, 0x33, 0x99, + 0xfc, 0xd9, 0xb2, 0x33, 0x7b, 0xb3, 0xc7, 0x5e, 0x5f, 0xa7, 0xbb, 0xe2, 0x34, 0x63, 0x77, 0x7b, + 0xba, 0xdb, 0x93, 0x64, 0x25, 0x04, 0x12, 0x48, 0x87, 0x4e, 0xa7, 0x13, 0x12, 0x08, 0x21, 0x21, + 0xc4, 0x49, 0xf7, 0x80, 0x84, 0xc4, 0x01, 0x02, 0x09, 0x81, 0xc4, 0xdd, 0x0b, 0x0f, 0xf7, 0xc0, + 0xc3, 0x81, 0xc4, 0x81, 0x90, 0x88, 0x20, 0xf0, 0x70, 0xe2, 0x15, 0xf1, 0xb2, 0xe2, 0x01, 0xd5, + 0x9f, 0xfe, 0xe3, 0xb8, 0xdb, 0xf6, 0xcc, 0xf5, 0x8a, 0x45, 0x3c, 0xd9, 0xfd, 0x55, 0x7d, 0x5f, + 0x55, 0x7d, 0xf5, 0xd5, 0x57, 0xbf, 0xaa, 0xfa, 0xaa, 0x60, 0xd6, 0xb6, 0x54, 0xed, 0xa0, 0xbb, + 0x77, 0x5f, 0xed, 0x1a, 0x8b, 0x5d, 0xdb, 0x72, 0x2d, 0x34, 0xab, 0x59, 0xda, 0x33, 0x46, 0x5e, + 0x14, 0x89, 0x73, 0xc8, 0xcb, 0xa5, 0xab, 0xae, 0xca, 0xb3, 0xcd, 0x9d, 0xf7, 0x68, 0xc4, 0xb6, + 0x2d, 0xdb, 0x11, 0xd4, 0x8b, 0x1e, 0xb5, 0x43, 0x5c, 0x35, 0x94, 0xbb, 0xe2, 0xb8, 0x96, 0xad, + 0xb6, 0xc8, 0x7d, 0x62, 0xb6, 0x0c, 0xd3, 0xfb, 0xa1, 0xf9, 0x5e, 0x68, 0x9a, 0xc8, 0xf3, 0xfa, + 0xb0, 0x3c, 0x0f, 0x45, 0xa6, 0x72, 0xcf, 0x35, 0xda, 0xf7, 0x0f, 0xda, 0xda, 0x7d, 0xd7, 0xe8, + 0x10, 0xc7, 0x55, 0x3b, 0x5d, 0x91, 0xb2, 0xc0, 0x52, 0x5c, 0x5b, 0xd5, 0x0c, 0xb3, 0x75, 0xdf, + 0x26, 0x9a, 0x65, 0xeb, 0x44, 0x57, 0x9c, 0xae, 0x6a, 0x7a, 0x55, 0x6e, 0x59, 0x2d, 0x8b, 0xfd, + 0xbd, 0x4f, 0xff, 0x71, 0x6a, 0xe5, 0x97, 0x20, 0x8f, 0x55, 0xb3, 0x45, 0xd6, 0xcd, 0x7d, 0x0b, + 0x7d, 0x1e, 0xb2, 0x3a, 0x71, 0xb4, 0xb2, 0xb4, 0x20, 0xdd, 0x29, 0x2c, 0x55, 0x16, 0x07, 0x74, + 0xb1, 0xc8, 0xf2, 0xae, 0x10, 0x47, 0xb3, 0x8d, 0xae, 0x6b, 0xd9, 0xd5, 0xec, 0x0f, 0x4f, 0xe6, + 0x53, 0x98, 0x71, 0xa1, 0xcf, 0xc0, 0x44, 0x9b, 0xa8, 0x0e, 0x29, 0xa7, 0x19, 0x7b, 0x39, 0x82, + 0xfd, 0x31, 0x4d, 0x17, 0x4c, 0x3c, 0x73, 0xe5, 0x43, 0x28, 0x62, 0xf2, 0xbc, 0x47, 0x1c, 0xb7, + 0x4e, 0x54, 0x9d, 0xd8, 0xe8, 0x32, 0x64, 0x9e, 0x91, 0xe3, 0x72, 0x66, 0x41, 0xba, 0x33, 0x5d, + 0x9d, 0xfa, 0xe8, 0x64, 0x3e, 0xb3, 0x41, 0x8e, 0x31, 0xa5, 0xa1, 0x05, 0x98, 0x22, 0xa6, 0xae, + 0xd0, 0xe4, 0x6c, 0x7f, 0xf2, 0x24, 0x31, 0xf5, 0x0d, 0x72, 0x8c, 0xe6, 0x20, 0xe7, 0x50, 0x69, + 0xa6, 0x46, 0xca, 0x13, 0x0b, 0xd2, 0x9d, 0x09, 0xec, 0x7f, 0xbf, 0x95, 0xfd, 0xc9, 0x77, 0xe6, + 0xa5, 0x47, 0xd9, 0x9c, 0x24, 0xa7, 0x1f, 0x65, 0x73, 0x69, 0x39, 0x53, 0xf9, 0x56, 0x06, 0x4a, + 0x98, 0x38, 0x5d, 0xcb, 0x74, 0x88, 0x28, 0xfd, 0x67, 0x20, 0xe3, 0x1e, 0x99, 0xac, 0xf4, 0xc2, + 0xd2, 0xb5, 0x88, 0x26, 0x34, 0x6d, 0xd5, 0x74, 0x54, 0xcd, 0x35, 0x2c, 0x13, 0xd3, 0xac, 0xe8, + 0x73, 0x50, 0xb0, 0x89, 0xd3, 0xeb, 0x10, 0xa6, 0x6c, 0x56, 0xb1, 0xc2, 0xd2, 0xa5, 0x08, 0xce, + 0x46, 0x57, 0x35, 0x31, 0xf0, 0xbc, 0xf4, 0x3f, 0xba, 0x0c, 0x39, 0xb3, 0xd7, 0xa1, 0xcd, 0x71, + 0x58, 0x65, 0x33, 0x78, 0xca, 0xec, 0x75, 0x36, 0xc8, 0xb1, 0x83, 0x6a, 0x50, 0xb0, 0xa9, 0xaa, + 0x15, 0xc3, 0xdc, 0xb7, 0x9c, 0xf2, 0xe4, 0x42, 0xe6, 0x4e, 0x61, 0xe9, 0x6a, 0x5c, 0x87, 0xd0, + 0xce, 0x13, 0x5a, 0x05, 0xdb, 0x23, 0x38, 0xa8, 0x01, 0x45, 0x51, 0x33, 0x9b, 0xa8, 0x8e, 0x65, + 0x96, 0xa7, 0x16, 0xa4, 0x3b, 0xa5, 0xa5, 0xc5, 0x28, 0x31, 0x7d, 0x5a, 0xa0, 0x9f, 0xbd, 0x0e, + 0xc1, 0x8c, 0x0b, 0x4f, 0xdb, 0xa1, 0xaf, 0xca, 0x53, 0x98, 0x0e, 0xa7, 0x22, 0x04, 0x25, 0xbc, + 0xda, 0xd8, 0xdd, 0x5c, 0x55, 0x76, 0xb7, 0x36, 0xb6, 0xb6, 0xdf, 0xdb, 0x92, 0x53, 0xe8, 0x3c, + 0xc8, 0x82, 0xb6, 0xb1, 0xfa, 0x54, 0x79, 0xbc, 0xbe, 0xb9, 0xde, 0x94, 0x25, 0x74, 0x19, 0x2e, + 0x08, 0x2a, 0x5e, 0xde, 0x5a, 0x5b, 0x55, 0xaa, 0xdb, 0xbb, 0x5b, 0x2b, 0xcb, 0xf8, 0xa9, 0x9c, + 0x9e, 0xcb, 0xfe, 0xda, 0x77, 0xaf, 0xa5, 0x2a, 0x4f, 0x00, 0xd6, 0x88, 0x2b, 0xac, 0x01, 0x55, + 0x61, 0xf2, 0x80, 0xd5, 0x46, 0x98, 0xe3, 0x42, 0x64, 0xb5, 0x43, 0x96, 0x53, 0xcd, 0x51, 0x0d, + 0xfc, 0xe8, 0x64, 0x5e, 0xc2, 0x82, 0x93, 0x77, 0x79, 0xe5, 0x07, 0x12, 0x14, 0x98, 0x60, 0xde, + 0x46, 0x54, 0x3b, 0x23, 0xf9, 0xfa, 0x48, 0x85, 0x0c, 0x8a, 0x46, 0x8b, 0x30, 0xf1, 0x42, 0x6d, + 0xf7, 0x86, 0x59, 0xfb, 0x13, 0x9a, 0x8e, 0x79, 0x36, 0xf4, 0x36, 0x4c, 0x1b, 0xa6, 0x4b, 0x4c, + 0x57, 0xe1, 0x6c, 0x99, 0x11, 0x6c, 0x05, 0x9e, 0x9b, 0x7d, 0x54, 0xfe, 0x52, 0x02, 0xd8, 0xe9, + 0x25, 0xa9, 0x1a, 0x3a, 0x5a, 0xc7, 0xaa, 0xbf, 0x37, 0x5a, 0x79, 0x2b, 0x2e, 0xc2, 0xa4, 0x61, + 0xb6, 0x0d, 0x93, 0xd7, 0x3f, 0x87, 0xc5, 0x17, 0x3a, 0x0f, 0x13, 0x7b, 0x6d, 0xc3, 0xd4, 0x99, + 0xf9, 0xe7, 0x30, 0xff, 0x10, 0xea, 0xc7, 0x50, 0x60, 0x75, 0x4f, 0x50, 0xfb, 0x95, 0x7f, 0x97, + 0xe0, 0x42, 0xcd, 0x32, 0x75, 0x83, 0x8e, 0x43, 0xb5, 0xfd, 0x89, 0xd0, 0xcd, 0x9b, 0x90, 0x27, + 0x47, 0xdd, 0x31, 0xbb, 0x37, 0x47, 0x8e, 0xba, 0xec, 0xdf, 0x50, 0xd5, 0x7d, 0x00, 0x17, 0xcf, + 0xb6, 0x32, 0x49, 0x2d, 0xfe, 0x9d, 0x04, 0xa5, 0x75, 0xd3, 0x70, 0x3f, 0x11, 0xea, 0xf3, 0xf5, + 0x90, 0x09, 0xe9, 0x01, 0xdd, 0x03, 0x79, 0x5f, 0x35, 0xda, 0xdb, 0x66, 0xd3, 0xea, 0xec, 0x39, + 0xae, 0x65, 0x12, 0x47, 0x28, 0x6a, 0x80, 0x2e, 0x74, 0xf6, 0x04, 0x66, 0xfc, 0x36, 0x25, 0xa9, + 0xac, 0x0f, 0x41, 0x5e, 0x37, 0x35, 0x9b, 0x74, 0x88, 0x99, 0xa8, 0xb6, 0xae, 0x42, 0xde, 0xf0, + 0xe4, 0x32, 0x8d, 0x65, 0x70, 0x40, 0x10, 0x6d, 0xea, 0xc1, 0x6c, 0xa8, 0xec, 0x24, 0xdd, 0xd8, + 0x15, 0xc8, 0x9b, 0xe4, 0x50, 0x09, 0xfa, 0x2b, 0x83, 0x73, 0x26, 0x39, 0xe4, 0x6e, 0xe7, 0x29, + 0x14, 0x57, 0x48, 0x9b, 0xb8, 0x24, 0x79, 0x9f, 0xbc, 0x0b, 0x25, 0x4f, 0x74, 0x92, 0x9d, 0xf4, + 0xbb, 0x12, 0x20, 0x21, 0x97, 0xce, 0x83, 0x49, 0xf6, 0xd3, 0x3c, 0x9d, 0xe7, 0xdd, 0x9e, 0x6d, + 0xf2, 0x09, 0x9b, 0x5b, 0x29, 0x70, 0x12, 0x9b, 0xb3, 0x03, 0xdf, 0x98, 0x0d, 0xfb, 0x46, 0x1f, + 0x77, 0x50, 0xc4, 0x71, 0x08, 0xe7, 0xfa, 0xaa, 0x97, 0x6c, 0x57, 0x66, 0x59, 0xcd, 0xd2, 0x0b, + 0x99, 0x30, 0x34, 0x62, 0xc4, 0xca, 0x07, 0x30, 0x5b, 0x6b, 0x13, 0xd5, 0x4e, 0x5a, 0x2d, 0xa2, + 0x3b, 0x9f, 0x02, 0x0a, 0x8b, 0x4f, 0xb2, 0x4b, 0x0d, 0x28, 0x34, 0x34, 0xd5, 0xdc, 0xee, 0x52, + 0x27, 0xe8, 0xa0, 0x87, 0x70, 0xd1, 0x71, 0xad, 0xae, 0xa2, 0xba, 0x0a, 0x47, 0x48, 0x7b, 0x56, + 0xcf, 0xd4, 0x55, 0xfb, 0x98, 0x95, 0x91, 0xc3, 0xe7, 0x68, 0xea, 0xb2, 0xcb, 0x2a, 0x52, 0x15, + 0x49, 0xb4, 0xef, 0x3a, 0x86, 0xa9, 0x50, 0x20, 0xd3, 0x76, 0x1d, 0x61, 0xe7, 0xd0, 0x31, 0x4c, + 0xcc, 0x29, 0xa2, 0x15, 0xdf, 0x95, 0x78, 0x59, 0x49, 0x9a, 0xcd, 0x17, 0xa1, 0xe0, 0x68, 0xaa, + 0xa9, 0xec, 0x5b, 0x76, 0x47, 0x75, 0x99, 0x69, 0x94, 0x96, 0x5e, 0x8b, 0x82, 0x87, 0x9a, 0x6a, + 0xbe, 0xc3, 0x32, 0x61, 0x70, 0xfc, 0xff, 0x61, 0xeb, 0x79, 0x94, 0xcd, 0x65, 0xe4, 0x6c, 0xe5, + 0xbf, 0x24, 0x98, 0xe6, 0xb5, 0x4c, 0xd2, 0x7a, 0xde, 0x84, 0xac, 0x6d, 0x1d, 0x72, 0xeb, 0x29, + 0x2c, 0x5d, 0x89, 0x10, 0xb1, 0x41, 0x8e, 0xc3, 0x6e, 0x9b, 0x65, 0x47, 0x55, 0x10, 0x40, 0x45, + 0x61, 0xdc, 0x99, 0x71, 0xb9, 0x81, 0x73, 0x61, 0x2a, 0xe3, 0x26, 0x94, 0xf6, 0x54, 0x57, 0x3b, + 0xa0, 0xfd, 0xc3, 0x2a, 0xc9, 0xd1, 0x3d, 0x2e, 0x32, 0xaa, 0x57, 0xf3, 0xca, 0x1f, 0x48, 0x80, + 0x30, 0x79, 0x41, 0x6c, 0x87, 0x7c, 0xf2, 0x3b, 0xe9, 0xbf, 0x25, 0x38, 0xd7, 0x57, 0xd9, 0xff, + 0x5f, 0x7d, 0xf5, 0xcb, 0x12, 0x5c, 0xaa, 0x1d, 0x10, 0xed, 0x59, 0xcd, 0x32, 0x1d, 0xc3, 0x71, + 0x89, 0xa9, 0x1d, 0x27, 0xd9, 0x61, 0x57, 0x20, 0x7f, 0x68, 0xb8, 0x07, 0x8a, 0x6e, 0xec, 0xef, + 0xb3, 0xe1, 0x9c, 0xc3, 0x39, 0x4a, 0x58, 0x31, 0xf6, 0xf7, 0xc5, 0x60, 0x56, 0xa0, 0x3c, 0x58, + 0x83, 0x64, 0x01, 0xc1, 0x05, 0x4c, 0x34, 0xab, 0xd3, 0xed, 0xb9, 0xa4, 0xe1, 0xaa, 0xae, 0x93, + 0x64, 0x03, 0x2f, 0xc1, 0x94, 0x6e, 0x1f, 0x2b, 0x76, 0xcf, 0x14, 0xcd, 0x9b, 0xd4, 0xed, 0x63, + 0xdc, 0x33, 0x45, 0xe3, 0xfe, 0x5c, 0x82, 0x8b, 0x67, 0x0b, 0x4f, 0xd2, 0xc2, 0xbe, 0x02, 0x05, + 0x55, 0xd7, 0x89, 0xae, 0xe8, 0xa4, 0xed, 0xaa, 0x02, 0xc8, 0x3d, 0x08, 0x49, 0x12, 0xbb, 0x15, + 0x8b, 0x7c, 0x9b, 0x62, 0xd1, 0xdb, 0xad, 0x58, 0xdc, 0x7c, 0x52, 0xab, 0xb1, 0xfa, 0xac, 0x50, + 0x46, 0xcf, 0x80, 0x98, 0x2c, 0x46, 0xa9, 0x68, 0x70, 0xa9, 0x4a, 0x5a, 0x86, 0x19, 0x5e, 0x47, + 0x27, 0x3e, 0x1d, 0x29, 0x50, 0x1e, 0x2c, 0x24, 0xc9, 0xbe, 0xff, 0xdb, 0x0c, 0x5c, 0x58, 0x35, + 0xf5, 0x8f, 0xa7, 0x11, 0x14, 0x49, 0x68, 0x56, 0xa7, 0x63, 0xb8, 0x5e, 0xdf, 0xf3, 0x2f, 0xf4, + 0x73, 0x90, 0xd3, 0x89, 0xaa, 0xfb, 0xeb, 0xaf, 0x42, 0x9f, 0x8f, 0xea, 0xb9, 0x46, 0x7b, 0xf1, + 0xa0, 0xad, 0x2d, 0x36, 0xbd, 0xbd, 0x21, 0xec, 0x67, 0x47, 0x5f, 0x87, 0x4b, 0x74, 0x14, 0xdb, + 0xa6, 0xda, 0x56, 0xb8, 0x34, 0xc5, 0xb5, 0x8d, 0x56, 0x8b, 0xd8, 0x62, 0xc7, 0xe2, 0x4e, 0x44, + 0x3d, 0xd7, 0x05, 0x47, 0x8d, 0x31, 0x34, 0x79, 0x7e, 0x7c, 0xc1, 0x88, 0x22, 0xa3, 0x2f, 0xfb, + 0x0b, 0x5c, 0xa7, 0xab, 0x9a, 0x4e, 0x79, 0x82, 0xb9, 0x97, 0xb8, 0x8d, 0x10, 0x61, 0x19, 0xc2, + 0x21, 0x51, 0x8a, 0x83, 0xee, 0x53, 0x84, 0xf5, 0xbc, 0x67, 0xd8, 0x44, 0x79, 0xd0, 0xd5, 0xca, + 0x93, 0xb4, 0xed, 0xd5, 0xd2, 0xe9, 0xc9, 0x3c, 0x60, 0x4e, 0x7e, 0xb0, 0x53, 0xa3, 0x88, 0x8b, + 0xff, 0xef, 0x6a, 0xe8, 0x0e, 0xc8, 0xa6, 0xa5, 0xd8, 0x64, 0xdf, 0x26, 0xce, 0x81, 0x28, 0x36, + 0xc7, 0x34, 0x56, 0x32, 0x2d, 0xcc, 0xc9, 0x5c, 0xf4, 0x45, 0x98, 0xec, 0x5a, 0x86, 0x63, 0x99, + 0xe5, 0x3c, 0xd7, 0x28, 0xff, 0xf2, 0x1d, 0xf7, 0x94, 0x9c, 0xab, 0xfc, 0x86, 0x04, 0x17, 0xcf, + 0xf6, 0x69, 0x92, 0x63, 0xea, 0x0e, 0xc8, 0x96, 0x49, 0x94, 0xee, 0x81, 0xea, 0x10, 0xd1, 0x07, + 0x02, 0x29, 0x96, 0x2c, 0x93, 0xec, 0x50, 0x32, 0xd7, 0x68, 0xdf, 0x44, 0xf2, 0x2b, 0x12, 0xcc, + 0x2e, 0xeb, 0x1d, 0xc3, 0x6c, 0x74, 0xdb, 0x46, 0xa2, 0x0b, 0x8f, 0x1b, 0x90, 0x77, 0xa8, 0x4c, + 0xb6, 0x9f, 0x96, 0xee, 0xdf, 0x4f, 0xcb, 0xb1, 0x94, 0x0d, 0x72, 0x1c, 0xe0, 0xbb, 0x70, 0x25, + 0x92, 0x1c, 0x4a, 0x1f, 0x88, 0xf6, 0x6d, 0x12, 0xfb, 0x63, 0x42, 0xa6, 0x61, 0xf1, 0x49, 0xd6, + 0xfc, 0x9b, 0x12, 0x5c, 0x66, 0xb2, 0x99, 0xc9, 0xec, 0x13, 0x9b, 0x6d, 0x6f, 0x26, 0xd9, 0x45, + 0xaf, 0xc3, 0xa4, 0xab, 0xda, 0x2d, 0xc2, 0x1d, 0xc1, 0x44, 0xb5, 0xf0, 0xd1, 0xc9, 0xfc, 0x54, + 0xc3, 0xb5, 0x6c, 0xb2, 0xbe, 0x82, 0x45, 0x92, 0x68, 0xa7, 0x0a, 0x73, 0x51, 0x75, 0x49, 0xb2, + 0xbd, 0xff, 0x29, 0x89, 0x32, 0x6a, 0x07, 0x1c, 0xe6, 0x77, 0xdb, 0x86, 0xa6, 0x26, 0x3a, 0xed, + 0xad, 0x42, 0x41, 0x63, 0xc2, 0x15, 0xf7, 0xb8, 0xcb, 0x17, 0xa4, 0xa5, 0xa5, 0x1b, 0x91, 0x82, + 0x58, 0xe1, 0xbc, 0x26, 0xcd, 0xe3, 0x2e, 0xc1, 0xa0, 0xf9, 0xff, 0xd1, 0x0a, 0x4c, 0x71, 0xe5, + 0x78, 0x28, 0x67, 0x88, 0x08, 0x3a, 0xd0, 0x9b, 0x2c, 0xb3, 0xf0, 0x49, 0x1e, 0xab, 0x50, 0xec, + 0x1e, 0x5c, 0x89, 0x6c, 0x74, 0x92, 0x9a, 0xfd, 0x2d, 0x09, 0xce, 0xd5, 0x89, 0x6a, 0xbb, 0x7b, + 0x44, 0x75, 0x9b, 0x47, 0x89, 0x4e, 0x26, 0x6f, 0x42, 0xc6, 0xb4, 0x0e, 0xc5, 0x14, 0x3e, 0x7c, + 0xbe, 0x10, 0x0a, 0xa0, 0xf9, 0x45, 0xe3, 0xbf, 0x0a, 0xe7, 0xfb, 0xeb, 0x95, 0x64, 0xab, 0xff, + 0x24, 0x03, 0xf9, 0xb5, 0x5a, 0x92, 0x6d, 0xfd, 0xbc, 0x58, 0x02, 0xf3, 0x4e, 0x8f, 0x3a, 0xc0, + 0xf0, 0xcb, 0x5b, 0x5c, 0xab, 0x6d, 0x90, 0x63, 0x0f, 0x1f, 0x53, 0x2e, 0xb4, 0x0c, 0x79, 0xf7, + 0x80, 0xce, 0x19, 0x56, 0x5b, 0x17, 0xb3, 0xe2, 0x58, 0xfa, 0x0a, 0xb8, 0x50, 0x1b, 0x2e, 0xb8, + 0x47, 0x26, 0x9b, 0x8a, 0x94, 0x96, 0xa6, 0x04, 0xe2, 0x26, 0xc6, 0x11, 0x37, 0x47, 0xc5, 0x9d, + 0x9e, 0xcc, 0xa3, 0xe6, 0x91, 0x49, 0xe7, 0xad, 0xb5, 0x5a, 0xd3, 0x13, 0x80, 0x91, 0x2b, 0x68, + 0x9a, 0x4f, 0x9b, 0x7b, 0x06, 0x13, 0xac, 0x15, 0xde, 0x99, 0x89, 0x14, 0x71, 0x66, 0x42, 0x1b, + 0xe5, 0x15, 0xf0, 0x32, 0x46, 0x10, 0x70, 0x71, 0x53, 0x10, 0x06, 0xf1, 0x2e, 0x00, 0x55, 0x61, + 0x92, 0x66, 0xf0, 0xfd, 0x0c, 0x94, 0x76, 0x7a, 0xce, 0x41, 0xc2, 0x76, 0x5f, 0x03, 0xe8, 0xf6, + 0x9c, 0x03, 0x62, 0x2b, 0xee, 0x91, 0x29, 0x5a, 0x3e, 0xe2, 0x40, 0xc7, 0x6b, 0x3a, 0xe7, 0x6b, + 0x1e, 0x99, 0x68, 0x5b, 0x08, 0x21, 0x4a, 0x70, 0x2a, 0x74, 0x6f, 0x0c, 0x18, 0xdc, 0x3c, 0x32, + 0x37, 0x89, 0x8f, 0x7f, 0xb9, 0x40, 0x42, 0x05, 0x7e, 0x1e, 0xa6, 0xe8, 0x87, 0xe2, 0x5a, 0x2f, + 0x63, 0x61, 0x93, 0x94, 0xa7, 0x69, 0x79, 0x63, 0x79, 0xe2, 0xe5, 0xc6, 0x32, 0x7a, 0x1b, 0xf2, + 0xbc, 0x50, 0xea, 0x53, 0x27, 0x99, 0x4f, 0x8d, 0xd2, 0x84, 0xe8, 0x04, 0xe6, 0x4d, 0x73, 0xac, + 0x44, 0xea, 0x4b, 0xcf, 0xc3, 0xc4, 0xbe, 0x65, 0x6b, 0x84, 0x9d, 0x1e, 0xe5, 0x30, 0xff, 0xf0, + 0x81, 0x53, 0x4e, 0xce, 0x57, 0x7e, 0x47, 0x82, 0x19, 0xbf, 0x03, 0x93, 0x44, 0x4c, 0xb5, 0x3e, + 0xed, 0xbf, 0x7c, 0x17, 0x52, 0x8d, 0x57, 0xbe, 0x97, 0x86, 0x99, 0x77, 0x7b, 0xc4, 0x3e, 0x4e, + 0xd8, 0xbe, 0xaa, 0xfc, 0xa4, 0x30, 0xfd, 0x8a, 0x36, 0xc1, 0xce, 0x0e, 0x6f, 0xc1, 0xcc, 0xa1, + 0x6a, 0xb8, 0xca, 0xbe, 0x65, 0x2b, 0xbd, 0xae, 0xae, 0xba, 0xde, 0xb9, 0x4a, 0x91, 0x92, 0xdf, + 0xb1, 0xec, 0x5d, 0x46, 0x44, 0x04, 0xd0, 0x33, 0xd3, 0x3a, 0x34, 0x15, 0x4a, 0x36, 0xcc, 0x16, + 0xd5, 0x87, 0x53, 0xce, 0xb2, 0x8d, 0xbe, 0xcf, 0xfe, 0xd3, 0xc9, 0xfc, 0xc3, 0x96, 0xe1, 0x1e, + 0xf4, 0xf6, 0x16, 0x35, 0xab, 0x73, 0xdf, 0xaf, 0x88, 0xbe, 0x17, 0xfc, 0xbf, 0xdf, 0x7d, 0xd6, + 0xba, 0xcf, 0x8e, 0x88, 0x7b, 0x3d, 0x43, 0x5f, 0xdc, 0xdd, 0x5d, 0x5f, 0xc1, 0x32, 0x13, 0xf9, + 0x1e, 0x97, 0xd8, 0x3c, 0x32, 0xbd, 0x09, 0xef, 0x23, 0x09, 0xe4, 0x40, 0x61, 0x49, 0xf6, 0xe7, + 0x2a, 0x14, 0x9e, 0xf7, 0x88, 0x6d, 0x10, 0xfd, 0xa5, 0x3b, 0x14, 0x04, 0x23, 0x1d, 0x43, 0xef, + 0xc3, 0x74, 0x9f, 0x1e, 0x32, 0x3f, 0x9d, 0x1e, 0x0a, 0x87, 0x81, 0x0a, 0x2a, 0xdf, 0x4f, 0x03, + 0x62, 0x8d, 0x5f, 0xe7, 0x7b, 0x1e, 0x9f, 0x30, 0x83, 0x79, 0x02, 0x60, 0xec, 0x2b, 0x1d, 0xc3, + 0x71, 0x0c, 0xb3, 0xc5, 0x6c, 0xa5, 0xb4, 0xf4, 0xd9, 0x88, 0xba, 0x0c, 0x36, 0x61, 0x71, 0x7d, + 0x7f, 0x93, 0xb3, 0x55, 0xc9, 0x81, 0xfa, 0xc2, 0xb0, 0x6c, 0x9c, 0x37, 0x3c, 0x52, 0xa5, 0x0a, + 0xb3, 0x03, 0xe9, 0xa8, 0x04, 0xb0, 0xb2, 0xad, 0x6c, 0x6d, 0x37, 0xeb, 0xeb, 0x5b, 0x6b, 0x72, + 0x0a, 0xc9, 0x30, 0x8d, 0x57, 0x9b, 0xbb, 0x78, 0x4b, 0x59, 0xc5, 0x78, 0x1b, 0xcb, 0x12, 0x2a, + 0xc0, 0xd4, 0x0e, 0x5e, 0x7d, 0xb2, 0xba, 0xd5, 0x94, 0xd3, 0xc2, 0x7a, 0x7e, 0x11, 0xce, 0xf5, + 0x15, 0x9e, 0xa4, 0xfd, 0x5c, 0x87, 0xe9, 0x7d, 0xab, 0x67, 0xea, 0x0a, 0x5f, 0x35, 0x8a, 0xd5, + 0x71, 0x81, 0xd1, 0x78, 0x79, 0x95, 0x6f, 0xa4, 0xe1, 0x3c, 0x26, 0x8e, 0xd5, 0x7e, 0x41, 0x92, + 0xef, 0xc1, 0x6d, 0x10, 0x5b, 0x61, 0xca, 0x4f, 0xd3, 0x91, 0x79, 0x2e, 0x83, 0xcf, 0x06, 0x93, + 0x8e, 0xab, 0xba, 0x3d, 0x47, 0x74, 0xe5, 0x8d, 0xe1, 0x63, 0xa1, 0xc1, 0xf2, 0x62, 0xc1, 0x13, + 0x5a, 0xd4, 0x66, 0x07, 0x17, 0xb5, 0x95, 0x9f, 0x87, 0x0b, 0x67, 0x14, 0x91, 0xe4, 0xa4, 0xfd, + 0xe3, 0x34, 0x5c, 0xee, 0x17, 0x9f, 0xf4, 0x79, 0xcb, 0xff, 0x0d, 0x65, 0xa3, 0x3a, 0x14, 0x3b, + 0x86, 0xa9, 0x04, 0x18, 0xeb, 0x25, 0x26, 0xe7, 0x69, 0xba, 0x5e, 0xeb, 0x87, 0x59, 0x74, 0x1d, + 0x17, 0xa5, 0xd7, 0x24, 0xfb, 0xee, 0xdb, 0x12, 0x4c, 0x27, 0xbd, 0xda, 0x7e, 0xb5, 0x43, 0x5f, + 0xd1, 0xe6, 0x26, 0x14, 0x3f, 0x86, 0xe5, 0xf9, 0xef, 0x4b, 0x80, 0x9a, 0x76, 0xcf, 0xd4, 0x54, + 0x97, 0x3c, 0xb6, 0x5a, 0x49, 0x36, 0xf6, 0x3c, 0x4c, 0x18, 0xa6, 0x4e, 0x8e, 0x58, 0x63, 0xb3, + 0x98, 0x7f, 0xa0, 0x07, 0x90, 0x13, 0x41, 0x3b, 0xfc, 0x10, 0x3b, 0x53, 0xbd, 0x78, 0x7a, 0x32, + 0x3f, 0xc5, 0x43, 0x74, 0x56, 0x3e, 0x0a, 0xfe, 0xe2, 0x29, 0x1e, 0xa5, 0xe3, 0x1d, 0xf3, 0xbf, + 0x0f, 0xe7, 0xfa, 0x2a, 0x9a, 0xa4, 0x16, 0xbe, 0x97, 0x86, 0x73, 0xa2, 0x39, 0x89, 0x6f, 0x4f, + 0xbc, 0x52, 0xc4, 0x17, 0xfa, 0x02, 0x40, 0xd7, 0x26, 0x2f, 0x14, 0xce, 0x9a, 0x19, 0x8b, 0x35, + 0x4f, 0x39, 0x18, 0x01, 0x7d, 0x05, 0x66, 0xe8, 0x80, 0xeb, 0xda, 0x56, 0xd7, 0x72, 0x28, 0x92, + 0x70, 0xc6, 0x43, 0xd2, 0xb3, 0xa7, 0x27, 0xf3, 0xc5, 0x4d, 0xc3, 0xdc, 0x11, 0x8c, 0xcd, 0x06, + 0xa6, 0x23, 0xd7, 0xff, 0xf4, 0xe0, 0xcf, 0xdf, 0x4b, 0x70, 0xfe, 0x63, 0xdb, 0xd0, 0xf9, 0xdf, + 0xd0, 0x98, 0x3f, 0x1f, 0xc8, 0xec, 0x73, 0xdd, 0xdc, 0xb7, 0x92, 0xdf, 0x66, 0xfb, 0xb6, 0x04, + 0xb3, 0x21, 0xf1, 0x49, 0xce, 0xfa, 0xaf, 0x16, 0x57, 0xf8, 0x55, 0x8a, 0x03, 0xc2, 0x66, 0x9f, + 0xe4, 0xa0, 0xfa, 0xd5, 0x34, 0x5c, 0xac, 0xf1, 0xc3, 0x17, 0x76, 0xc6, 0xe4, 0xf4, 0x3a, 0x49, + 0x5a, 0x49, 0x19, 0xa6, 0x5e, 0x10, 0xdb, 0x31, 0x2c, 0x3e, 0xef, 0x15, 0xb1, 0xf7, 0x89, 0x7e, + 0x01, 0x0a, 0x9a, 0x28, 0xd0, 0xf3, 0x32, 0xd3, 0xd5, 0x75, 0x2a, 0xe0, 0x15, 0xd1, 0xef, 0xe9, + 0xc9, 0x3c, 0x78, 0x4d, 0x58, 0x5f, 0xc1, 0xe0, 0x49, 0x5f, 0xd7, 0x59, 0x2c, 0xa5, 0xa9, 0x76, + 0x9d, 0x03, 0xcb, 0xdb, 0xa7, 0xf6, 0xbf, 0x45, 0xa7, 0x7f, 0x0d, 0x2e, 0x0d, 0x68, 0x21, 0x49, + 0x35, 0xff, 0xcd, 0x14, 0x14, 0x57, 0x8f, 0xba, 0x96, 0xed, 0x36, 0xf8, 0x64, 0x8f, 0x56, 0x20, + 0xd7, 0xb5, 0xad, 0x17, 0x86, 0x27, 0xb8, 0x14, 0x79, 0x6e, 0xd1, 0xc7, 0xb3, 0x23, 0xf2, 0x63, + 0x9f, 0x13, 0x61, 0xc8, 0x3f, 0xb6, 0x34, 0xb5, 0xfd, 0x8e, 0xd1, 0xf6, 0xac, 0x6a, 0x71, 0x94, + 0x98, 0x45, 0x9f, 0x63, 0x47, 0x75, 0x0f, 0xbc, 0x41, 0xe6, 0x13, 0xd1, 0x1a, 0xe4, 0xea, 0xae, + 0xdb, 0xa5, 0x89, 0x62, 0x84, 0xde, 0x1c, 0x29, 0x92, 0x32, 0x08, 0x49, 0x3e, 0x33, 0xc2, 0x30, + 0xbb, 0x66, 0x59, 0xad, 0x36, 0xa9, 0xb5, 0xad, 0x9e, 0x5e, 0xb3, 0xcc, 0x7d, 0xa3, 0x25, 0x3c, + 0xdc, 0x8d, 0x91, 0x12, 0xd7, 0x6a, 0x0d, 0x3c, 0xc8, 0x8e, 0xbe, 0x04, 0xb9, 0xc6, 0x43, 0x21, + 0x8a, 0xe3, 0x93, 0xd7, 0x47, 0x8a, 0x6a, 0x3c, 0xc4, 0x3e, 0x13, 0xaa, 0x43, 0x61, 0xf9, 0xc3, + 0x9e, 0x4d, 0x84, 0x8c, 0x49, 0x26, 0xe3, 0xd6, 0x48, 0x19, 0x8c, 0x07, 0x87, 0x59, 0xe7, 0xee, + 0x42, 0xb1, 0x4f, 0x93, 0x08, 0x41, 0xb6, 0x4b, 0x95, 0x46, 0xbb, 0x33, 0x8f, 0xd9, 0x7f, 0x6e, + 0x5e, 0x73, 0xb7, 0x20, 0x4b, 0xb5, 0x42, 0x87, 0xc3, 0x9e, 0xea, 0x90, 0x5d, 0xdb, 0x10, 0x99, + 0xbc, 0x4f, 0x91, 0xef, 0xaf, 0x25, 0x48, 0x37, 0x1e, 0x52, 0x84, 0xb6, 0xd7, 0xd3, 0x9e, 0x11, + 0x57, 0xe4, 0x12, 0x5f, 0x0c, 0xb9, 0xd9, 0x64, 0xdf, 0xe0, 0xb3, 0x75, 0x1e, 0x8b, 0x2f, 0xf4, + 0x1a, 0x80, 0xaa, 0x69, 0xc4, 0x71, 0x14, 0x2f, 0xde, 0x38, 0x8f, 0xf3, 0x9c, 0xb2, 0x41, 0x8e, + 0x29, 0x9b, 0x43, 0x34, 0x9b, 0x70, 0xe3, 0xcf, 0x63, 0xf1, 0x45, 0xd9, 0x5c, 0xd2, 0xe9, 0x2a, + 0xae, 0xf5, 0x8c, 0x98, 0x4c, 0x9b, 0x79, 0x9c, 0xa7, 0x94, 0x26, 0x25, 0xd0, 0x51, 0x43, 0x4c, + 0xbd, 0x6b, 0x19, 0xa6, 0xcb, 0xd4, 0x94, 0xc7, 0xfe, 0x37, 0x15, 0x69, 0x93, 0x96, 0x21, 0x22, + 0x71, 0xf3, 0x58, 0x7c, 0x89, 0x66, 0x6c, 0x43, 0x66, 0xad, 0xd6, 0x78, 0xe9, 0x66, 0x20, 0xc8, + 0xaa, 0x3d, 0x61, 0x74, 0x79, 0xcc, 0xfe, 0x0b, 0x81, 0xdf, 0x90, 0x60, 0x82, 0xa9, 0x1e, 0x5d, + 0x85, 0xbc, 0x66, 0x99, 0xae, 0x6a, 0x98, 0x62, 0xdc, 0xe4, 0x71, 0x40, 0x88, 0x95, 0x7c, 0x1d, + 0xa6, 0x55, 0x4d, 0xb3, 0x7a, 0xa6, 0xab, 0x98, 0x6a, 0x87, 0x88, 0x12, 0x0a, 0x82, 0xb6, 0xa5, + 0x76, 0x08, 0x9a, 0x07, 0xef, 0xd3, 0x8f, 0xca, 0xce, 0x63, 0x10, 0x24, 0xff, 0xf8, 0x48, 0xb8, + 0x8b, 0x3f, 0x94, 0x60, 0xf6, 0x3d, 0xdb, 0x70, 0x49, 0x95, 0xc7, 0x0a, 0x24, 0xe7, 0x30, 0xdf, + 0x82, 0xbc, 0xae, 0xba, 0x2a, 0x8f, 0xc0, 0x4e, 0x0f, 0x8d, 0xc0, 0xf6, 0xc6, 0x1b, 0xcd, 0xcf, + 0xa2, 0xb0, 0x11, 0x64, 0xe9, 0x7f, 0xee, 0x4b, 0x31, 0xfb, 0x1f, 0x1c, 0x1d, 0x85, 0xab, 0x9b, + 0xa4, 0x67, 0xfb, 0xe7, 0xb4, 0xe7, 0xd9, 0x92, 0x54, 0xc3, 0x97, 0x61, 0x4a, 0xac, 0x8a, 0x84, + 0x12, 0x16, 0x46, 0x8d, 0x50, 0xef, 0xc8, 0x43, 0xb0, 0xa1, 0x2a, 0x80, 0xe3, 0xaa, 0xb6, 0xcb, + 0xd6, 0x33, 0x63, 0x9d, 0x31, 0x7b, 0x9e, 0x90, 0xb1, 0x51, 0x2a, 0xda, 0x82, 0x42, 0xe7, 0x85, + 0xa6, 0x29, 0xfb, 0x46, 0xdb, 0x15, 0xc7, 0xcb, 0xd1, 0xc1, 0x34, 0x9b, 0x4f, 0x6a, 0xb5, 0x77, + 0x58, 0x26, 0x7e, 0xca, 0x1b, 0x7c, 0x63, 0xa0, 0x12, 0xf8, 0x7f, 0xf4, 0x29, 0x10, 0x51, 0x76, + 0x8a, 0xe3, 0xb8, 0x6c, 0xc0, 0xe5, 0xaa, 0xc5, 0xd3, 0x93, 0xf9, 0x3c, 0x66, 0xd4, 0x46, 0xa3, + 0x89, 0xf3, 0x3c, 0x43, 0xc3, 0xf1, 0x66, 0xa6, 0x6f, 0x49, 0x50, 0xac, 0xf6, 0xda, 0xcf, 0xb6, + 0xbb, 0x8d, 0x5e, 0xa7, 0xa3, 0xda, 0xc7, 0xe8, 0x8a, 0x67, 0x22, 0xc6, 0x87, 0x84, 0xa9, 0x38, + 0x23, 0x6c, 0xc0, 0xf8, 0x90, 0x50, 0x1b, 0x10, 0x01, 0x35, 0x94, 0xce, 0xa3, 0x65, 0x5e, 0x87, + 0x22, 0x83, 0xf5, 0x0a, 0x31, 0x5d, 0xdb, 0x20, 0x7c, 0xd5, 0x98, 0xc1, 0xd3, 0x8c, 0xb8, 0xca, + 0x69, 0xe8, 0x26, 0x94, 0x9c, 0x63, 0xc7, 0x25, 0x1d, 0x85, 0x5f, 0xb9, 0xe0, 0x58, 0x34, 0x83, + 0x8b, 0x9c, 0x8a, 0x39, 0xb1, 0xf2, 0xc7, 0x19, 0x28, 0x79, 0xdd, 0x9d, 0x24, 0x34, 0xaa, 0xc2, + 0xc4, 0xbe, 0xd1, 0x26, 0x5e, 0x24, 0x50, 0xbc, 0x43, 0xf6, 0x24, 0x2d, 0x52, 0xb7, 0xeb, 0x01, + 0x25, 0xc6, 0x9a, 0x44, 0x97, 0xcf, 0xfd, 0x48, 0x82, 0x2c, 0x9b, 0x05, 0x1f, 0x40, 0x96, 0x8d, + 0x41, 0x69, 0x9c, 0x31, 0xc8, 0xb2, 0xfa, 0xfe, 0x3f, 0x1d, 0xf8, 0x7f, 0xe6, 0x7b, 0x0f, 0xd4, + 0x37, 0x1f, 0x2c, 0xb1, 0xee, 0x9e, 0xc6, 0xe2, 0x0b, 0x55, 0x21, 0x47, 0x58, 0x7b, 0x88, 0x2e, + 0xe6, 0xa0, 0x28, 0x0b, 0xef, 0xeb, 0x78, 0x6f, 0xbc, 0x7b, 0x7c, 0xe8, 0x32, 0x64, 0xa8, 0x1d, + 0x4d, 0xf1, 0xb3, 0x92, 0xd3, 0x93, 0xf9, 0x0c, 0xb5, 0x20, 0x4a, 0xe3, 0x27, 0xee, 0x8f, 0xb2, + 0xb9, 0xac, 0x3c, 0x51, 0xf9, 0xb3, 0x2c, 0x14, 0xd7, 0x3b, 0x49, 0x8f, 0xd0, 0xe5, 0xfe, 0x0e, + 0x8b, 0x82, 0x08, 0x7d, 0x85, 0x46, 0xf4, 0x57, 0x9f, 0xaf, 0xcb, 0xbc, 0x9c, 0xaf, 0x5b, 0xa7, + 0x13, 0x90, 0xb8, 0x6f, 0x42, 0xcb, 0x7f, 0x63, 0x64, 0xf9, 0x4d, 0x75, 0xaf, 0x4d, 0x30, 0xe5, + 0xf1, 0x8e, 0x22, 0xb8, 0x00, 0xf4, 0x45, 0x36, 0xcf, 0x71, 0xa3, 0x99, 0x1c, 0xdf, 0x68, 0xa6, + 0x88, 0xa9, 0x33, 0x93, 0x39, 0x12, 0x16, 0xf3, 0x39, 0xc8, 0xe8, 0xc6, 0x30, 0x95, 0x46, 0xf9, + 0x2b, 0xca, 0x32, 0xc2, 0x70, 0xb2, 0x61, 0xc3, 0xf1, 0x8f, 0x2b, 0x32, 0x72, 0x76, 0x6e, 0x1b, + 0x20, 0x68, 0x15, 0x5a, 0x80, 0x49, 0xab, 0xad, 0x53, 0x30, 0x4d, 0xab, 0x50, 0xac, 0xe6, 0x4f, + 0x4f, 0xe6, 0x27, 0xb6, 0xdb, 0xfa, 0xfa, 0x0a, 0x9e, 0xb0, 0xda, 0xfa, 0xba, 0xce, 0xae, 0xe9, + 0x90, 0x43, 0x85, 0xdd, 0x8c, 0x62, 0x61, 0x12, 0x78, 0xca, 0x24, 0x87, 0x2b, 0xc4, 0xd1, 0xc2, + 0xb3, 0x9b, 0x30, 0x9b, 0xdf, 0x93, 0xa0, 0xe4, 0x69, 0x30, 0xd9, 0x91, 0x9e, 0x33, 0x3a, 0xc2, + 0xf2, 0x33, 0x2f, 0x67, 0xf9, 0x1e, 0x9f, 0x08, 0x41, 0xfe, 0xa6, 0x04, 0xe7, 0x78, 0x2c, 0x87, + 0xa6, 0xba, 0xd4, 0xd7, 0x26, 0x68, 0xde, 0x77, 0x41, 0xb6, 0x55, 0x53, 0xb7, 0x3a, 0xc6, 0x87, + 0x84, 0xaf, 0x56, 0x1d, 0xb1, 0x49, 0x3b, 0xe3, 0xd3, 0xd9, 0x72, 0xcc, 0x5b, 0x6c, 0xff, 0x87, + 0x04, 0xe7, 0xfb, 0x2b, 0x93, 0xa4, 0xd2, 0x36, 0x60, 0x92, 0x6d, 0xb4, 0x78, 0xc3, 0xed, 0xd3, + 0x11, 0x42, 0xa2, 0x4a, 0xe7, 0xb7, 0xaa, 0x7c, 0x83, 0x67, 0x22, 0xe6, 0xbe, 0x0c, 0x13, 0x8c, + 0xfc, 0x0a, 0x3e, 0x4e, 0x68, 0xfe, 0x39, 0xcc, 0x2e, 0xeb, 0x7a, 0xa3, 0x21, 0xac, 0x2f, 0x39, + 0xb5, 0x7b, 0x10, 0x26, 0x1d, 0x05, 0x61, 0xc2, 0x45, 0x26, 0x09, 0x61, 0xba, 0x50, 0x12, 0x21, + 0x56, 0x09, 0xef, 0xac, 0x1d, 0x52, 0xcc, 0x25, 0xcc, 0x86, 0x7f, 0x04, 0x37, 0x3b, 0xfc, 0x12, + 0x93, 0x6c, 0x49, 0x0f, 0xce, 0x79, 0x72, 0x93, 0xde, 0xc4, 0x1e, 0xd6, 0x1c, 0xb6, 0x43, 0x11, + 0x2e, 0x36, 0xc9, 0x36, 0xfd, 0x91, 0x04, 0x73, 0x6b, 0xc4, 0x6d, 0x88, 0x05, 0xfb, 0x3b, 0x96, + 0x9d, 0xf8, 0x8e, 0xef, 0x1a, 0x40, 0x9b, 0xec, 0x8b, 0x30, 0x7c, 0x01, 0x38, 0xc7, 0xbf, 0x33, + 0x9a, 0xa7, 0xbc, 0x2c, 0x49, 0xa8, 0xe3, 0xc7, 0x12, 0x5c, 0x89, 0xac, 0x71, 0x92, 0x1e, 0x21, + 0x62, 0xa4, 0xa0, 0xaf, 0x01, 0x43, 0x9b, 0x8a, 0xe3, 0xaa, 0xae, 0x23, 0x9c, 0xeb, 0xa7, 0x5e, + 0x26, 0xd4, 0xb5, 0x3a, 0x2b, 0xe2, 0x36, 0xf2, 0x3e, 0x09, 0xe7, 0xa9, 0x48, 0xf6, 0xb7, 0xf2, + 0x01, 0xcc, 0xb2, 0x76, 0x26, 0x1d, 0x23, 0x2c, 0xf4, 0xf6, 0x17, 0x12, 0xa0, 0xb0, 0xfc, 0x24, + 0xd5, 0xd5, 0xaf, 0x9a, 0x74, 0xe2, 0xaa, 0xf9, 0x87, 0x4b, 0x30, 0x2d, 0x5a, 0xb9, 0x6b, 0x1a, + 0x96, 0x89, 0x1e, 0x40, 0xa6, 0x25, 0x56, 0xbe, 0x85, 0xc8, 0x35, 0x43, 0x70, 0x41, 0xb4, 0x9e, + 0xc2, 0x34, 0x2f, 0x65, 0xe9, 0xf6, 0xdc, 0x88, 0xd0, 0x96, 0x20, 0xac, 0x21, 0xcc, 0xd2, 0xed, + 0xb9, 0xa8, 0x01, 0x33, 0x5a, 0x70, 0xad, 0x4e, 0xa1, 0xec, 0x99, 0xd8, 0x20, 0xd8, 0xc8, 0x6b, + 0x86, 0xf5, 0x14, 0x2e, 0x69, 0x7d, 0x09, 0xa8, 0x16, 0xbe, 0xc7, 0x95, 0x8d, 0xdd, 0x64, 0x39, + 0x7b, 0x87, 0xac, 0x9e, 0x0a, 0x5d, 0xf7, 0x42, 0x6f, 0xc1, 0xa4, 0xce, 0xee, 0x07, 0x89, 0x6d, + 0x9a, 0x28, 0xb3, 0xe8, 0xbb, 0x92, 0x55, 0x4f, 0x61, 0xc1, 0x81, 0x1e, 0xc1, 0x34, 0xff, 0x27, + 0x46, 0xe4, 0x64, 0xec, 0x2e, 0xd4, 0xe0, 0x0d, 0xa9, 0x7a, 0x0a, 0x17, 0xf4, 0x80, 0x8a, 0x3e, + 0x03, 0x59, 0x47, 0x53, 0xf9, 0x3e, 0x45, 0xf4, 0x11, 0x7d, 0xe8, 0x0a, 0x46, 0x9d, 0x4e, 0x73, + 0x9a, 0x6a, 0xa2, 0xa7, 0x30, 0xbb, 0x47, 0x5a, 0x86, 0xa9, 0xb8, 0xc1, 0x31, 0x1a, 0x0b, 0xc8, + 0xed, 0x3f, 0xb9, 0xf3, 0xd1, 0x4a, 0x74, 0x1c, 0x78, 0x3d, 0x85, 0xe5, 0xbd, 0x33, 0x49, 0xb4, + 0xcb, 0x18, 0xdc, 0x0c, 0x09, 0xce, 0xc7, 0x76, 0x59, 0x64, 0x64, 0x36, 0xed, 0x32, 0xd2, 0x97, + 0x80, 0xd6, 0xa0, 0xa0, 0xd2, 0xe9, 0x5f, 0x61, 0xd1, 0xae, 0x65, 0x88, 0xdd, 0x64, 0x1b, 0x08, + 0xc0, 0xad, 0xb3, 0xa0, 0x76, 0x8f, 0x18, 0x08, 0xea, 0x50, 0x97, 0x55, 0x2e, 0x0c, 0x17, 0x14, + 0xf6, 0xc4, 0xbe, 0x20, 0x46, 0x44, 0x9b, 0x50, 0x3c, 0xf0, 0xe2, 0xed, 0xd8, 0xb9, 0xe7, 0x74, + 0xec, 0x4e, 0x5b, 0x44, 0xbc, 0x60, 0x3d, 0x85, 0xa7, 0x0f, 0x42, 0x64, 0xb4, 0x08, 0xe9, 0x96, + 0x56, 0x2e, 0x32, 0x19, 0x57, 0x87, 0x45, 0xc3, 0xd5, 0x53, 0x38, 0xdd, 0xd2, 0x28, 0xa8, 0xe7, + 0x81, 0x42, 0x47, 0x66, 0xb9, 0x14, 0xeb, 0x36, 0xfa, 0x83, 0xb5, 0xea, 0x29, 0xcc, 0x42, 0x9a, + 0x68, 0x79, 0x3b, 0x50, 0xb2, 0xf9, 0xe1, 0xa5, 0x77, 0x44, 0x2f, 0x33, 0x29, 0xb7, 0xa3, 0x9d, + 0xcf, 0xc0, 0x29, 0x7d, 0x3d, 0x85, 0x8b, 0x76, 0x98, 0x8e, 0xbe, 0x0e, 0xe7, 0xfb, 0x25, 0x0a, + 0xe3, 0x9e, 0x1d, 0xf0, 0x45, 0xd1, 0x72, 0xfb, 0x6d, 0x1c, 0xd9, 0x03, 0x89, 0xe8, 0xb3, 0x30, + 0xc1, 0x7b, 0x0d, 0x31, 0x91, 0xf3, 0x51, 0x1b, 0x15, 0xfd, 0x1d, 0xc6, 0xf3, 0xd3, 0xf1, 0xe6, + 0x8a, 0x53, 0x3b, 0xa5, 0x6d, 0xb5, 0xca, 0xe7, 0x62, 0xc7, 0xdb, 0xe0, 0x29, 0x24, 0x1d, 0x6f, + 0x6e, 0x40, 0xa5, 0xfd, 0x6e, 0xf3, 0x14, 0x71, 0xc8, 0x73, 0x3e, 0xb6, 0xdf, 0x23, 0x0e, 0xf3, + 0x68, 0xbf, 0xdb, 0x21, 0x32, 0xad, 0x9a, 0xcd, 0x2f, 0x1f, 0x29, 0x6c, 0x18, 0x5f, 0x88, 0xad, + 0xda, 0xe0, 0x85, 0x2a, 0x5a, 0x35, 0x3b, 0xa0, 0xa2, 0x27, 0x20, 0x8b, 0x7b, 0x26, 0x8a, 0x77, + 0x38, 0x50, 0xbe, 0xc8, 0xe4, 0xdd, 0x8d, 0xf4, 0x96, 0x51, 0xa7, 0x22, 0xf5, 0x14, 0x9e, 0xd1, + 0xfa, 0x53, 0xa8, 0xb3, 0x60, 0xf2, 0x14, 0x2d, 0xb8, 0xa0, 0x53, 0x2e, 0xc7, 0x3a, 0x8b, 0x98, + 0xdb, 0x44, 0xd4, 0x59, 0x68, 0x67, 0x92, 0xa8, 0x19, 0x1b, 0xa6, 0xe1, 0x32, 0xc7, 0x3e, 0x17, + 0x6b, 0xc6, 0xfd, 0x37, 0x9f, 0xa9, 0x19, 0x1b, 0x9c, 0x42, 0xcd, 0xd8, 0x15, 0x27, 0x80, 0xa2, + 0x3b, 0xae, 0xc6, 0x9a, 0x71, 0xd4, 0x51, 0x21, 0x35, 0x63, 0x37, 0x4c, 0xa7, 0x66, 0xcc, 0x1d, + 0xc4, 0x19, 0xb9, 0xaf, 0xc5, 0x9a, 0x71, 0x6c, 0x60, 0x39, 0x35, 0x63, 0x75, 0x20, 0x11, 0xad, + 0x50, 0x34, 0xa6, 0x3a, 0xfc, 0xc5, 0x88, 0xf2, 0xb5, 0xd8, 0xf9, 0xe7, 0xec, 0x19, 0x60, 0x9d, + 0x41, 0x31, 0x41, 0xa3, 0x8e, 0x8c, 0x41, 0x54, 0x85, 0x5d, 0xe7, 0x2a, 0xcf, 0xc7, 0x3a, 0xb2, + 0x81, 0x7d, 0x5c, 0xea, 0xc8, 0x0e, 0x7d, 0x22, 0x9d, 0xc8, 0xf8, 0x8e, 0x4b, 0x79, 0x61, 0xc4, + 0xca, 0x3e, 0x34, 0x91, 0x71, 0x0e, 0xb4, 0x0c, 0xf9, 0xe7, 0x3d, 0x62, 0x1f, 0x33, 0x37, 0x74, + 0x3d, 0x16, 0x57, 0x9e, 0x09, 0xea, 0xab, 0xa7, 0x70, 0xee, 0xb9, 0x20, 0xd1, 0xe2, 0xf9, 0xb2, + 0xb7, 0x5c, 0x89, 0x2d, 0xbe, 0x6f, 0xa3, 0x83, 0x16, 0xcf, 0x39, 0x90, 0x06, 0x17, 0x78, 0x5f, + 0x89, 0x48, 0x74, 0x5b, 0x84, 0x7c, 0x97, 0x5f, 0x67, 0xa2, 0x62, 0x17, 0x91, 0x91, 0x51, 0xf1, + 0xf5, 0x14, 0x3e, 0xa7, 0x0e, 0xa6, 0xd2, 0x01, 0x2f, 0xa6, 0x1e, 0xbe, 0xf4, 0x2c, 0xdf, 0x88, + 0x1d, 0xf0, 0x11, 0x8b, 0x75, 0x3a, 0xe0, 0xd5, 0x10, 0x99, 0x4f, 0x40, 0xba, 0xe2, 0x38, 0x2e, + 0x5d, 0xe8, 0x95, 0x6f, 0x0e, 0x99, 0x80, 0xce, 0x2c, 0x40, 0xf9, 0x04, 0xa4, 0x37, 0x38, 0x27, + 0x15, 0xa4, 0xb5, 0x89, 0x6a, 0x0b, 0x37, 0x7b, 0x2b, 0x56, 0xd0, 0xc0, 0x6d, 0x62, 0x2a, 0x48, + 0xf3, 0x89, 0x74, 0xc2, 0xb6, 0xbd, 0x0b, 0x6a, 0x02, 0x3f, 0xde, 0x8e, 0x9d, 0xb0, 0x23, 0xef, + 0xd1, 0xd1, 0x09, 0xdb, 0xee, 0x4b, 0x40, 0x5f, 0x80, 0x29, 0x71, 0xdb, 0xa7, 0x7c, 0x67, 0x08, + 0xaa, 0x0d, 0xaf, 0x4a, 0xe9, 0xb8, 0x16, 0x3c, 0xdc, 0xcb, 0xf2, 0xcb, 0x42, 0xbc, 0x79, 0x77, + 0x87, 0x78, 0xd9, 0x81, 0x05, 0x21, 0xf7, 0xb2, 0x01, 0x99, 0x7a, 0x59, 0x6e, 0xa7, 0x62, 0xae, + 0xbb, 0x17, 0xeb, 0x65, 0x07, 0xc3, 0xf1, 0xa8, 0x97, 0x7d, 0x1e, 0x50, 0x91, 0x0e, 0x17, 0x5b, + 0xc4, 0x55, 0xbc, 0x03, 0x56, 0x16, 0x11, 0xca, 0xa7, 0xa5, 0x37, 0x62, 0xad, 0x2e, 0x7e, 0x7d, + 0x47, 0xad, 0xae, 0x35, 0x98, 0x4a, 0x7b, 0x97, 0x47, 0xa8, 0xf0, 0x0e, 0xf9, 0x54, 0x6c, 0xef, + 0x0e, 0x2c, 0x58, 0xea, 0xde, 0xd3, 0x32, 0x1c, 0xd6, 0x4f, 0x89, 0x68, 0x9f, 0x47, 0xd9, 0xdc, + 0x8c, 0x2c, 0x3f, 0xca, 0xe6, 0x2e, 0xc9, 0xe5, 0x47, 0xd9, 0xdc, 0x65, 0x79, 0xee, 0x51, 0x36, + 0x77, 0x45, 0xbe, 0x5a, 0xf9, 0xd3, 0x4b, 0x50, 0xf4, 0x96, 0x17, 0x1c, 0xda, 0x2f, 0x85, 0xa1, + 0xfd, 0xb5, 0x38, 0x68, 0x2f, 0x16, 0x24, 0x02, 0xdb, 0x2f, 0x85, 0xb1, 0xfd, 0xb5, 0x38, 0x6c, + 0x1f, 0xf0, 0x50, 0x70, 0xdf, 0x8c, 0x03, 0xf7, 0x77, 0xc7, 0x00, 0xf7, 0xbe, 0xa8, 0xb3, 0xe8, + 0x7e, 0x65, 0x10, 0xdd, 0xdf, 0x18, 0x8e, 0xee, 0x7d, 0x51, 0x21, 0x78, 0xff, 0xf6, 0x19, 0x78, + 0x7f, 0x7d, 0x08, 0xbc, 0xf7, 0xf9, 0x3d, 0x7c, 0xbf, 0x11, 0x89, 0xef, 0x6f, 0x8d, 0xc2, 0xf7, + 0xbe, 0x9c, 0x3e, 0x80, 0xff, 0x66, 0x1f, 0xc0, 0x9f, 0x8f, 0x05, 0xf8, 0x3e, 0x37, 0x47, 0xf8, + 0xef, 0xc7, 0x23, 0xfc, 0x37, 0xc6, 0x42, 0xf8, 0xbe, 0xbc, 0x41, 0x88, 0xdf, 0x8c, 0x83, 0xf8, + 0x77, 0xc7, 0x80, 0xf8, 0x41, 0xc7, 0x9d, 0xc1, 0xf8, 0xf5, 0x28, 0x8c, 0x7f, 0x73, 0x04, 0xc6, + 0xf7, 0xa5, 0x85, 0x41, 0x7e, 0x3d, 0x0a, 0xe4, 0xdf, 0x1c, 0x01, 0xf2, 0xcf, 0x48, 0xe2, 0xc3, + 0x70, 0x2b, 0x1a, 0xe5, 0xdf, 0x1e, 0x89, 0xf2, 0x7d, 0x69, 0xfd, 0x30, 0xff, 0x7e, 0x08, 0xe6, + 0xbf, 0x16, 0x03, 0xf3, 0x7d, 0x56, 0x8a, 0xf3, 0xbf, 0x34, 0x80, 0xf3, 0x2b, 0xc3, 0x70, 0xbe, + 0xcf, 0xeb, 0x03, 0xfd, 0x77, 0x63, 0x80, 0xfe, 0x9d, 0xd1, 0x40, 0xdf, 0x17, 0x76, 0x06, 0xe9, + 0xab, 0x43, 0x91, 0xfe, 0xa7, 0xc7, 0x44, 0xfa, 0xbe, 0xf4, 0x28, 0xa8, 0xff, 0xb9, 0x7e, 0xa8, + 0xbf, 0x10, 0x0f, 0xf5, 0x7d, 0x31, 0x02, 0xeb, 0x6f, 0x44, 0x62, 0xfd, 0x5b, 0xa3, 0xb0, 0x7e, + 0x30, 0xf6, 0xc2, 0x60, 0x7f, 0x2b, 0x1a, 0xec, 0xdf, 0x1e, 0x09, 0xf6, 0x83, 0xee, 0xef, 0x43, + 0xfb, 0x1b, 0x91, 0x68, 0xff, 0xd6, 0x28, 0xb4, 0x1f, 0x54, 0x2e, 0x0c, 0xf7, 0xdf, 0x8b, 0x85, + 0xfb, 0xf7, 0xc6, 0x81, 0xfb, 0xbe, 0xd0, 0x01, 0xbc, 0xff, 0x7e, 0x3c, 0xde, 0x7f, 0x63, 0x2c, + 0xbc, 0x1f, 0xb8, 0x8e, 0x01, 0xc0, 0xff, 0xa5, 0x01, 0xc0, 0x5f, 0x19, 0x06, 0xf8, 0x03, 0x7b, + 0xf6, 0x10, 0xbf, 0x3a, 0x14, 0x9f, 0x7f, 0x7a, 0x4c, 0x7c, 0x1e, 0x18, 0x5f, 0x04, 0x40, 0x5f, + 0x8d, 0x00, 0xe8, 0x37, 0x86, 0x03, 0xf4, 0x60, 0x0a, 0x09, 0x10, 0x7a, 0x3d, 0x0a, 0xa1, 0xdf, + 0x1c, 0x81, 0xd0, 0x03, 0x2f, 0x14, 0x82, 0xe8, 0x6f, 0x9f, 0x81, 0xe8, 0xd7, 0x47, 0x9e, 0x1e, + 0x87, 0x30, 0x7a, 0x75, 0x10, 0xa3, 0xbf, 0x3e, 0x14, 0xa3, 0xfb, 0x12, 0x02, 0x90, 0xfe, 0xf6, + 0x19, 0x90, 0x7e, 0x7d, 0x08, 0x48, 0x0f, 0x2a, 0x20, 0x50, 0xba, 0x3e, 0x1c, 0xa5, 0x2f, 0x8e, + 0x8b, 0xd2, 0x7d, 0xc1, 0x91, 0x30, 0x7d, 0x2b, 0x1a, 0xa6, 0xdf, 0x1e, 0xf3, 0x20, 0x69, 0x00, + 0xa7, 0xd7, 0xa3, 0x70, 0xfa, 0xcd, 0x11, 0x38, 0x3d, 0x3c, 0x87, 0xf8, 0x40, 0xbd, 0x1e, 0x05, + 0xd4, 0x6f, 0x8e, 0x00, 0xea, 0x81, 0xa4, 0x10, 0x52, 0x6f, 0xc6, 0x21, 0xf5, 0xbb, 0x63, 0x20, + 0xf5, 0x60, 0xde, 0x3d, 0x03, 0xd5, 0xbf, 0x78, 0x16, 0xaa, 0x57, 0x86, 0x41, 0xf5, 0x60, 0x44, + 0x7a, 0x58, 0x7d, 0x2b, 0x1a, 0xab, 0xdf, 0x1e, 0x89, 0xd5, 0xc3, 0x4e, 0x32, 0x04, 0xd6, 0x37, + 0x22, 0xc1, 0xfa, 0xad, 0x51, 0x60, 0x3d, 0x70, 0x92, 0x61, 0xb4, 0x4e, 0x46, 0xa0, 0xf5, 0xc5, + 0x71, 0xd1, 0x7a, 0x60, 0x7d, 0x51, 0x70, 0xbd, 0x1e, 0x05, 0xd7, 0x6f, 0x8e, 0x80, 0xeb, 0x41, + 0x1f, 0xbf, 0x04, 0x5e, 0x7f, 0x94, 0xcd, 0x5d, 0x95, 0x5f, 0xab, 0xfc, 0xd5, 0x04, 0x4c, 0xd6, + 0xbd, 0x48, 0x85, 0xd0, 0xbd, 0x51, 0xe9, 0x55, 0xee, 0x8d, 0xa2, 0x15, 0x6a, 0x02, 0x6c, 0x20, + 0x09, 0x04, 0x3f, 0xe4, 0x16, 0xf6, 0xc0, 0xf9, 0x90, 0xc7, 0xfa, 0x0a, 0x51, 0xf5, 0xe8, 0x4d, + 0x28, 0xf6, 0x1c, 0x62, 0x2b, 0x5d, 0xdb, 0xb0, 0x6c, 0xc3, 0xe5, 0x71, 0x69, 0x52, 0x55, 0xfe, + 0xe8, 0x64, 0x7e, 0x7a, 0xd7, 0x21, 0xf6, 0x8e, 0xa0, 0xe3, 0xe9, 0x5e, 0xe8, 0xcb, 0x7b, 0xfb, + 0x73, 0x62, 0xfc, 0xb7, 0x3f, 0xdf, 0x05, 0xd9, 0x26, 0xaa, 0xde, 0x37, 0xa5, 0xf1, 0xfb, 0x95, + 0xd1, 0xb3, 0xaf, 0xaa, 0x87, 0x66, 0x2d, 0x76, 0xcf, 0x72, 0xc6, 0xee, 0x27, 0xa2, 0x07, 0x70, + 0xa1, 0xa3, 0x1e, 0xf1, 0x1b, 0xc4, 0x1e, 0x4a, 0x60, 0x11, 0x1b, 0x39, 0x16, 0x58, 0x84, 0x3a, + 0xea, 0x11, 0x7b, 0x48, 0x94, 0x27, 0xb1, 0x87, 0xc7, 0x6e, 0x42, 0x49, 0x37, 0x1c, 0xd7, 0x30, + 0x35, 0xef, 0xed, 0x0d, 0xfe, 0xc8, 0x45, 0xd1, 0xa3, 0xf2, 0x37, 0x30, 0xee, 0xc1, 0xac, 0x88, + 0xa3, 0x0a, 0x9e, 0x16, 0x65, 0x78, 0x38, 0x47, 0x6b, 0x41, 0x13, 0x82, 0x97, 0x60, 0x6b, 0x30, + 0xd3, 0x52, 0x5d, 0x72, 0xa8, 0x1e, 0x2b, 0xa6, 0xa5, 0x33, 0xdd, 0x17, 0xd8, 0x0b, 0x04, 0x57, + 0x4e, 0x4f, 0xe6, 0x8b, 0x6b, 0x3c, 0x69, 0xcb, 0xd2, 0x79, 0x0f, 0x4c, 0xf2, 0x7f, 0xb8, 0xd8, + 0x0a, 0x25, 0xe8, 0x68, 0x19, 0xa6, 0xd9, 0xab, 0x4a, 0x16, 0x7f, 0xba, 0x4b, 0xa0, 0xdc, 0xb8, + 0xc3, 0x04, 0xf1, 0xc0, 0x17, 0x66, 0x2f, 0x31, 0x79, 0xaf, 0x7d, 0xdd, 0x86, 0x19, 0xd5, 0x39, + 0x36, 0x35, 0xa6, 0x61, 0x62, 0x3a, 0x3d, 0x87, 0xc1, 0xdc, 0x1c, 0x2e, 0x31, 0x72, 0xcd, 0xa3, + 0x8a, 0x27, 0x3c, 0x7e, 0x53, 0x82, 0xe9, 0xbe, 0xe0, 0xc2, 0xb7, 0xcf, 0x9c, 0x82, 0x5d, 0x8e, + 0x86, 0xd8, 0x71, 0xc1, 0x3a, 0x39, 0xd1, 0x03, 0x5e, 0x00, 0xc1, 0x7c, 0x3c, 0x44, 0x63, 0x8b, + 0x5c, 0x2f, 0xe4, 0xc2, 0x63, 0x7b, 0x2b, 0xfb, 0xdb, 0xdf, 0x99, 0x4f, 0x55, 0x7e, 0x92, 0x81, + 0x62, 0x7f, 0x10, 0xe1, 0xfa, 0x99, 0x7a, 0x45, 0xb9, 0xb5, 0x3e, 0x8e, 0xf8, 0x5a, 0xae, 0x40, + 0xde, 0x7b, 0x8b, 0xc9, 0xab, 0xe6, 0xc2, 0x90, 0xb3, 0xbe, 0x70, 0x3d, 0x03, 0xc6, 0xb9, 0x1f, + 0xa4, 0xfd, 0x91, 0xbf, 0x08, 0x13, 0xec, 0x55, 0x63, 0x51, 0xb5, 0xa8, 0x78, 0xfb, 0x55, 0x9a, + 0x8e, 0x79, 0x36, 0xea, 0x29, 0x9a, 0xaf, 0x74, 0xc3, 0xdc, 0x27, 0xbc, 0xc2, 0xab, 0xbb, 0xaf, + 0x78, 0x13, 0x9a, 0x9d, 0xfc, 0xb5, 0xdb, 0x44, 0x73, 0xc5, 0xe3, 0xc8, 0xde, 0xdb, 0xba, 0x37, + 0xce, 0x8a, 0x10, 0x4f, 0x29, 0x2f, 0x62, 0xf1, 0x94, 0x72, 0x28, 0xa6, 0xa3, 0xe4, 0x8b, 0x60, + 0x03, 0x8b, 0x47, 0xfe, 0xf0, 0xae, 0xbe, 0xd7, 0x80, 0x73, 0x11, 0xc3, 0x1c, 0x95, 0x00, 0x6a, + 0xdb, 0x5b, 0x8d, 0xf5, 0x46, 0x73, 0x75, 0xab, 0xe9, 0xbd, 0x90, 0xbb, 0xbc, 0xa2, 0xec, 0x6e, + 0xd5, 0xb6, 0x37, 0x37, 0xd7, 0x9b, 0xcd, 0xd5, 0x15, 0x59, 0x42, 0x32, 0x4c, 0xaf, 0x6f, 0x85, + 0xf2, 0x89, 0x87, 0x71, 0xef, 0xfd, 0x2c, 0x40, 0xf0, 0xf0, 0x18, 0x95, 0xb5, 0xb1, 0xfa, 0x54, + 0x79, 0xb2, 0xfc, 0x78, 0x77, 0xb5, 0x21, 0xa7, 0x10, 0x82, 0x52, 0x75, 0xb9, 0x59, 0xab, 0x2b, + 0x78, 0xb5, 0xb1, 0xb3, 0xbd, 0xd5, 0x58, 0x95, 0x25, 0xc1, 0xf7, 0x1e, 0x14, 0x42, 0x77, 0xba, + 0x69, 0xc6, 0x9d, 0xdd, 0x46, 0x5d, 0x69, 0xae, 0x6f, 0xae, 0x36, 0x9a, 0xcb, 0x9b, 0x3b, 0x72, + 0x8a, 0x0a, 0x63, 0xb4, 0xe5, 0xea, 0x36, 0x6e, 0xca, 0x92, 0xff, 0xdd, 0xdc, 0xde, 0xad, 0xd5, + 0xe5, 0xb4, 0xff, 0xfd, 0xee, 0xee, 0x2a, 0x7e, 0x2a, 0x67, 0x84, 0x60, 0x15, 0x2e, 0x44, 0xc6, + 0xd8, 0xa3, 0x02, 0x4c, 0xed, 0x9a, 0xec, 0x5e, 0xb1, 0x9c, 0x42, 0xc5, 0x50, 0x98, 0xbd, 0x2c, + 0xa1, 0x1c, 0x0f, 0xe7, 0x96, 0xd3, 0x68, 0x12, 0xd2, 0x8d, 0x87, 0x72, 0x06, 0xcd, 0x40, 0x21, + 0x14, 0xab, 0x2e, 0x67, 0x51, 0x5e, 0x04, 0x2c, 0xcb, 0x13, 0xf7, 0xae, 0x43, 0x28, 0x1e, 0x14, + 0x01, 0x4c, 0x3e, 0x56, 0x5d, 0xe2, 0xb8, 0x72, 0x0a, 0x4d, 0x41, 0x66, 0xb9, 0xdd, 0x96, 0xa5, + 0xa5, 0xaf, 0x40, 0xce, 0x7b, 0xa1, 0x08, 0x3d, 0x86, 0x09, 0x8e, 0x6a, 0xe7, 0xe3, 0x47, 0x12, + 0x1b, 0x93, 0x73, 0x0b, 0xa3, 0x86, 0x5a, 0x25, 0x55, 0xbd, 0xfe, 0xc3, 0x7f, 0xbd, 0x96, 0xfa, + 0xe1, 0xe9, 0x35, 0xe9, 0x47, 0xa7, 0xd7, 0xa4, 0x7f, 0x3c, 0xbd, 0x26, 0xfd, 0xcb, 0xe9, 0x35, + 0xe9, 0xd7, 0xff, 0xed, 0x5a, 0xea, 0xfd, 0x29, 0xc1, 0xb2, 0x37, 0xc9, 0xde, 0xcf, 0x7e, 0xf8, + 0x3f, 0x01, 0x00, 0x00, 0xff, 0xff, 0xc9, 0xb3, 0x3f, 0x15, 0x44, 0x5c, 0x00, 0x00, } diff --git a/pkg/roachpb/api.proto b/pkg/roachpb/api.proto index 4c14b52e62be..d45713615720 100644 --- a/pkg/roachpb/api.proto +++ b/pkg/roachpb/api.proto @@ -334,6 +334,19 @@ message ScanOptions { int64 min_results = 2; } +// ScanFormat is an enumeration of the available response formats for MVCCScan +// operations. +enum ScanFormat { + option (gogoproto.goproto_enum_prefix) = false; + + // The standard MVCCScan format: a slice of KeyValue messages. + KEY_VALUES = 0; + // The batch_response format: a byte slice of alternating keys and values, + // each prefixed by their length as a varint. + BATCH_RESPONSE = 1; +} + + // A ScanRequest is the argument to the Scan() method. It specifies the // start and end keys for an ascending scan of [start,end) and the maximum // number of results (unbounded if zero). @@ -343,6 +356,11 @@ message ScanRequest { reserved 2, 3; RequestHeader header = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true]; + + // The desired format for the response. If set to BATCH_RESPONSE, the server + // will set the batch_response field in the ScanResponse instead of the rows + // field. + ScanFormat scan_format = 4; } // A ScanResponse is the return value from the Scan() method. @@ -354,6 +372,12 @@ message ScanResponse { // consistency level. These rows do not count against the MaxSpanRequestKeys // count. repeated KeyValue intent_rows = 3 [(gogoproto.nullable) = false]; + + // If set, the results of the scan in batch format - the key/value pairs are + // a buffer of varint-prefixed slices, alternating from key to value. There + // are num_keys pairs, as defined by the ResponseHeader. If set, rows will not + // be set and vice versa. + bytes batch_response = 4; } // A ReverseScanRequest is the argument to the ReverseScan() method. It specifies the @@ -365,6 +389,11 @@ message ReverseScanRequest { reserved 2, 3; RequestHeader header = 1 [(gogoproto.nullable) = false, (gogoproto.embed) = true]; + + // The desired format for the response. If set to BATCH_RESPONSE, the server + // will set the batch_response field in the ScanResponse instead of the rows + // field. + ScanFormat scan_format = 4; } // A ReverseScanResponse is the return value from the ReverseScan() method. @@ -376,6 +405,12 @@ message ReverseScanResponse { // consistency level. These rows do not count against the MaxSpanRequestKeys // count. repeated KeyValue intent_rows = 3 [(gogoproto.nullable) = false]; + + // If set, the results of the scan in batch format - the key/value pairs are + // a buffer of varint-prefixed slices, alternating from key to value. There + // are num_keys pairs, as defined by the ResponseHeader. If set, rows will not + // be set and vice versa. + bytes batch_response = 4; } // A CheckConsistencyRequest is the argument to the CheckConsistency() method. diff --git a/pkg/server/updates_test.go b/pkg/server/updates_test.go index 5c630b4bd024..08234705e0f7 100644 --- a/pkg/server/updates_test.go +++ b/pkg/server/updates_test.go @@ -444,7 +444,7 @@ func TestReportUsage(t *testing.T) { "diagnostics.reporting.send_crash_reports": "false", "server.time_until_store_dead": "1m30s", "trace.debug.enable": "false", - "version": "2.0-9", + "version": "2.0-10", "cluster.secret": "", } { if got, ok := r.last.AlteredSettings[key]; !ok { diff --git a/pkg/settings/cluster/cockroach_versions.go b/pkg/settings/cluster/cockroach_versions.go index 0fe6112b2d62..c34ef2aed287 100644 --- a/pkg/settings/cluster/cockroach_versions.go +++ b/pkg/settings/cluster/cockroach_versions.go @@ -66,6 +66,7 @@ const ( VersionColumnarTimeSeries VersionTxnCoordMetaInvalidField VersionAsyncConsensus + VersionBatchResponse // Add new versions here (step one of two). @@ -253,6 +254,11 @@ var versionsSingleton = keyedVersions([]keyedVersion{ Key: VersionAsyncConsensus, Version: roachpb.Version{Major: 2, Minor: 0, Unstable: 9}, }, + { + // VersionBatchResponse is https://github.com/cockroachdb/cockroach/pull/26553. + Key: VersionBatchResponse, + Version: roachpb.Version{Major: 2, Minor: 0, Unstable: 10}, + }, // Add new versions here (step two of two). diff --git a/pkg/sql/logictest/testdata/logic_test/crdb_internal b/pkg/sql/logictest/testdata/logic_test/crdb_internal index 16ecdcfda2de..66012f6f46e6 100644 --- a/pkg/sql/logictest/testdata/logic_test/crdb_internal +++ b/pkg/sql/logictest/testdata/logic_test/crdb_internal @@ -244,7 +244,7 @@ select crdb_internal.set_vmodule('') query T select crdb_internal.node_executable_version() ---- -2.0-9 +2.0-10 query ITTT colnames select node_id, component, field, regexp_replace(regexp_replace(value, '^\d+$', ''), e':\\d+', ':') as value from crdb_internal.node_runtime_info @@ -332,4 +332,4 @@ select * from crdb_internal.gossip_alerts query T select crdb_internal.node_executable_version() ---- -2.0-9 +2.0-10 diff --git a/pkg/sql/sqlbase/errors.go b/pkg/sql/sqlbase/errors.go index 18d6ed82f425..5908bf1b69e7 100644 --- a/pkg/sql/sqlbase/errors.go +++ b/pkg/sql/sqlbase/errors.go @@ -255,12 +255,19 @@ type singleKVFetcher struct { // nextBatch implements the kvFetcher interface. func (f *singleKVFetcher) nextBatch( _ context.Context, -) (ok bool, kvs []roachpb.KeyValue, isNewScan bool, err error) { +) ( + ok bool, + kvs []roachpb.KeyValue, + batchResponse []byte, + numKvs int64, + maybeNewSpan bool, + err error, +) { if f.done { - return false, nil, true, nil + return false, nil, nil, 0, true, nil } f.done = true - return true, f.kvs[:], true, nil + return true, f.kvs[:], nil, 0, true, nil } // getRangesInfo implements the kvFetcher interface. diff --git a/pkg/sql/sqlbase/fk.go b/pkg/sql/sqlbase/fk.go index 23741a67d84c..e6ca4d4c90db 100644 --- a/pkg/sql/sqlbase/fk.go +++ b/pkg/sql/sqlbase/fk.go @@ -274,13 +274,20 @@ type SpanKVFetcher struct { // nextBatch implements the kvFetcher interface. func (f *SpanKVFetcher) nextBatch( _ context.Context, -) (ok bool, kvs []roachpb.KeyValue, isNewSpan bool, err error) { +) ( + ok bool, + kvs []roachpb.KeyValue, + batchResponse []byte, + numKvs int64, + maybeNewSpan bool, + err error, +) { if len(f.KVs) == 0 { - return false, nil, true, nil + return false, nil, nil, 0, true, nil } res := f.KVs f.KVs = nil - return true, res, true, nil + return true, res, nil, 0, true, nil } // getRangesInfo implements the kvFetcher interface. diff --git a/pkg/sql/sqlbase/kvfetcher.go b/pkg/sql/sqlbase/kvfetcher.go index 6acda2ba9d6d..84fde68dd4f7 100644 --- a/pkg/sql/sqlbase/kvfetcher.go +++ b/pkg/sql/sqlbase/kvfetcher.go @@ -282,12 +282,14 @@ func (f *txnKVFetcher) fetch(ctx context.Context) error { if f.reverse { scans := make([]roachpb.ReverseScanRequest, len(f.spans)) for i := range f.spans { + scans[i].ScanFormat = roachpb.BATCH_RESPONSE scans[i].SetSpan(f.spans[i]) ba.Requests[i].MustSetInner(&scans[i]) } } else { scans := make([]roachpb.ScanRequest, len(f.spans)) for i := range f.spans { + scans[i].ScanFormat = roachpb.BATCH_RESPONSE scans[i].SetSpan(f.spans[i]) ba.Requests[i].MustSetInner(&scans[i]) } @@ -355,22 +357,29 @@ func (f *txnKVFetcher) fetch(ctx context.Context) error { return nil } -func (f *txnKVFetcher) batchIsLimited(batchSize int) bool { +func (f *txnKVFetcher) batchIsLimited(batchSize int64) bool { if f.useBatchLimit { // f.batchIdx - 1 refers to the most recent fetch. - return int64(batchSize) == f.getBatchSizeForIdx(f.batchIdx-1) + return batchSize == f.getBatchSizeForIdx(f.batchIdx-1) } return false } // nextBatch returns the next batch of key/value pairs. If there are none -// available, a fetch is initiated. +// available, a fetch is initiated. When there are no more keys, returns false. // ok returns whether or not there are more kv pairs to be fetched. // maybeNewSpan returns true if it was possible that the kv pairs returned were // from a new span. func (f *txnKVFetcher) nextBatch( ctx context.Context, -) (ok bool, kvs []roachpb.KeyValue, maybeNewSpan bool, err error) { +) ( + ok bool, + kvs []roachpb.KeyValue, + batchResponse []byte, + numKvs int64, + maybeNewSpan bool, + err error, +) { if len(f.responses) > 0 { reply := f.responses[0].GetInner() f.responses = f.responses[1:] @@ -378,18 +387,18 @@ func (f *txnKVFetcher) nextBatch( maybeNewSpan = !f.lastBatchLimited switch t := reply.(type) { case *roachpb.ScanResponse: - f.lastBatchLimited = f.batchIsLimited(len(t.Rows)) - return true, t.Rows, maybeNewSpan, nil + f.lastBatchLimited = f.batchIsLimited(t.NumKeys) + return true, t.Rows, t.BatchResponse, t.NumKeys, maybeNewSpan, nil case *roachpb.ReverseScanResponse: - f.lastBatchLimited = f.batchIsLimited(len(t.Rows)) - return true, t.Rows, maybeNewSpan, nil + f.lastBatchLimited = f.batchIsLimited(t.NumKeys) + return true, t.Rows, t.BatchResponse, t.NumKeys, maybeNewSpan, nil } } if f.fetchEnd { - return false, nil, false, nil + return false, nil, nil, 0, false, nil } if err := f.fetch(ctx); err != nil { - return false, nil, false, err + return false, nil, nil, 0, false, err } return f.nextBatch(ctx) } diff --git a/pkg/sql/sqlbase/rowfetcher.go b/pkg/sql/sqlbase/rowfetcher.go index 5ec5e3784a9e..c1156f421fb3 100644 --- a/pkg/sql/sqlbase/rowfetcher.go +++ b/pkg/sql/sqlbase/rowfetcher.go @@ -27,6 +27,7 @@ import ( "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/sql/scrub" "github.com/cockroachdb/cockroach/pkg/sql/sem/tree" + "github.com/cockroachdb/cockroach/pkg/storage/engine" "github.com/cockroachdb/cockroach/pkg/util" "github.com/cockroachdb/cockroach/pkg/util/encoding" "github.com/cockroachdb/cockroach/pkg/util/hlc" @@ -38,7 +39,13 @@ import ( const debugRowFetch = false type kvFetcher interface { - nextBatch(ctx context.Context) (bool, []roachpb.KeyValue, bool, error) + // nextBatch returns the next batch of rows. Returns false in the first + // parameter if there are no more keys in the scan. May return either a slice + // of KeyValues or a batchResponse, numKvs pair, depending on the server + // version - both must be handled by calling code. maybeNewSpan is true if + // if it was possible that the kv pairs returned were from a new span. + nextBatch(ctx context.Context) (ok bool, kvs []roachpb.KeyValue, + batchResponse []byte, numKvs int64, maybeNewSpan bool, err error) getRangesInfo() []roachpb.RangeInfo } @@ -218,6 +225,9 @@ type RowFetcher struct { kvs []roachpb.KeyValue + batchResponse []byte + batchNumKvs int64 + // isCheck indicates whether or not we are running checks for k/v // correctness. It is set only during SCRUB commands. isCheck bool @@ -431,6 +441,8 @@ func (rf *RowFetcher) StartScanFrom(ctx context.Context, f kvFetcher) error { rf.indexKey = nil rf.kvFetcher = f rf.kvs = nil + rf.batchNumKvs = 0 + rf.batchResponse = nil // Retrieve the first key. _, err := rf.NextKey(ctx) return err @@ -451,7 +463,30 @@ func (rf *RowFetcher) nextKV( rf.maybeNewSpan = false return true, kv, newSpan, nil } - ok, rf.kvs, rf.maybeNewSpan, err = rf.kvFetcher.nextBatch(ctx) + if rf.batchNumKvs > 0 { + rf.batchNumKvs-- + var key engine.MVCCKey + var rawBytes []byte + var err error + newSpan = rf.maybeNewSpan + rf.maybeNewSpan = false + key, rawBytes, rf.batchResponse, err = engine.MVCCScanDecodeKeyValue(rf.batchResponse) + if err != nil { + return false, kv, false, err + } + return true, roachpb.KeyValue{ + Key: key.Key, + Value: roachpb.Value{ + RawBytes: rawBytes, + }, + }, newSpan, nil + } + + var numKeys int64 + ok, rf.kvs, rf.batchResponse, numKeys, rf.maybeNewSpan, err = rf.kvFetcher.nextBatch(ctx) + if rf.batchResponse != nil { + rf.batchNumKvs = numKeys + } if err != nil { return ok, kv, false, err } diff --git a/pkg/storage/batcheval/cmd_reverse_scan.go b/pkg/storage/batcheval/cmd_reverse_scan.go index 651ba17dad4e..6edf696073d6 100644 --- a/pkg/storage/batcheval/cmd_reverse_scan.go +++ b/pkg/storage/batcheval/cmd_reverse_scan.go @@ -17,6 +17,8 @@ package batcheval import ( "context" + "fmt" + "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/batcheval/result" "github.com/cockroachdb/cockroach/pkg/storage/engine" @@ -37,18 +39,40 @@ func ReverseScan( h := cArgs.Header reply := resp.(*roachpb.ReverseScanResponse) - rows, resumeSpan, intents, err := engine.MVCCReverseScan(ctx, batch, args.Key, args.EndKey, - cArgs.MaxKeys, h.Timestamp, h.ReadConsistency == roachpb.CONSISTENT, h.Txn) - if err != nil { - return result.Result{}, err + var err error + var intents []roachpb.Intent + var resumeSpan *roachpb.Span + + switch args.ScanFormat { + case roachpb.BATCH_RESPONSE: + var kvData []byte + var numKvs int64 + kvData, numKvs, resumeSpan, intents, err = engine.MVCCReverseScanToBytes( + ctx, batch, args.Key, args.EndKey, cArgs.MaxKeys, + h.Timestamp, h.ReadConsistency == roachpb.CONSISTENT, h.Txn) + if err != nil { + return result.Result{}, err + } + reply.NumKeys = numKvs + reply.BatchResponse = kvData + case roachpb.KEY_VALUES: + var rows []roachpb.KeyValue + rows, resumeSpan, intents, err = engine.MVCCReverseScan(ctx, batch, args.Key, args.EndKey, + cArgs.MaxKeys, h.Timestamp, h.ReadConsistency == roachpb.CONSISTENT, h.Txn) + if err != nil { + return result.Result{}, err + } + reply.NumKeys = int64(len(rows)) + reply.Rows = rows + default: + panic(fmt.Sprintf("Unknown scanFormat %d", args.ScanFormat)) } - reply.NumKeys = int64(len(rows)) if resumeSpan != nil { reply.ResumeSpan = resumeSpan reply.ResumeReason = roachpb.RESUME_KEY_LIMIT } - reply.Rows = rows + if h.ReadConsistency == roachpb.READ_UNCOMMITTED { reply.IntentRows, err = CollectIntentRows(ctx, batch, cArgs, intents) } diff --git a/pkg/storage/batcheval/cmd_scan.go b/pkg/storage/batcheval/cmd_scan.go index 20e2d93c2c0a..a373bb164471 100644 --- a/pkg/storage/batcheval/cmd_scan.go +++ b/pkg/storage/batcheval/cmd_scan.go @@ -17,6 +17,8 @@ package batcheval import ( "context" + "fmt" + "github.com/cockroachdb/cockroach/pkg/roachpb" "github.com/cockroachdb/cockroach/pkg/storage/batcheval/result" "github.com/cockroachdb/cockroach/pkg/storage/engine" @@ -37,20 +39,43 @@ func Scan( h := cArgs.Header reply := resp.(*roachpb.ScanResponse) - rows, resumeSpan, intents, err := engine.MVCCScan(ctx, batch, args.Key, args.EndKey, - cArgs.MaxKeys, h.Timestamp, h.ReadConsistency == roachpb.CONSISTENT, h.Txn) - if err != nil { - return result.Result{}, err + var err error + var intents []roachpb.Intent + var resumeSpan *roachpb.Span + + switch args.ScanFormat { + case roachpb.BATCH_RESPONSE: + var kvData []byte + var numKvs int64 + kvData, numKvs, resumeSpan, intents, err = engine.MVCCScanToBytes( + ctx, batch, args.Key, args.EndKey, cArgs.MaxKeys, + h.Timestamp, h.ReadConsistency == roachpb.CONSISTENT, h.Txn) + if err != nil { + return result.Result{}, err + } + reply.NumKeys = numKvs + reply.BatchResponse = kvData + case roachpb.KEY_VALUES: + var rows []roachpb.KeyValue + rows, resumeSpan, intents, err = engine.MVCCScan(ctx, batch, args.Key, args.EndKey, + cArgs.MaxKeys, h.Timestamp, h.ReadConsistency == roachpb.CONSISTENT, h.Txn) + if err != nil { + return result.Result{}, err + } + reply.NumKeys = int64(len(rows)) + reply.Rows = rows + default: + panic(fmt.Sprintf("Unknown scanFormat %d", args.ScanFormat)) } - reply.NumKeys = int64(len(rows)) if resumeSpan != nil { reply.ResumeSpan = resumeSpan reply.ResumeReason = roachpb.RESUME_KEY_LIMIT } - reply.Rows = rows + if h.ReadConsistency == roachpb.READ_UNCOMMITTED { reply.IntentRows, err = CollectIntentRows(ctx, batch, cArgs, intents) } return result.FromIntents(intents, args), err + } diff --git a/pkg/storage/engine/mvcc.go b/pkg/storage/engine/mvcc.go index 84dc2024c909..7e5aad26fca5 100644 --- a/pkg/storage/engine/mvcc.go +++ b/pkg/storage/engine/mvcc.go @@ -1641,7 +1641,11 @@ func MVCCDeleteRange( // mvccScanInternal scans the key range [key,endKey) up to some maximum number // of results. Specify reverse=true to scan in descending instead of ascending -// order. If iter is not specified, a new iterator is created from engine. +// order. If iter is not specified, a new iterator is created from engine. It +// returns the found keys and values in batch format, or a resumeSpan if an +// exceptional condition occurred. A resumeSpan is only set if err != nil. If +// err == nil, the caller is responsible for determining the resumeSpan of the +// scan (based on the last key returned) if kv data is returned. func mvccScanInternal( ctx context.Context, engine Reader, @@ -1654,12 +1658,9 @@ func mvccScanInternal( tombstones bool, txn *roachpb.Transaction, reverse bool, -) ([]roachpb.KeyValue, *roachpb.Span, []roachpb.Intent, error) { - if max == 0 { - return nil, &roachpb.Span{Key: key, EndKey: endKey}, nil, nil - } +) ([]byte, int64, *roachpb.Span, []roachpb.Intent, error) { if len(endKey) == 0 { - return nil, nil, nil, emptyKeyError() + return nil, 0, nil, nil, emptyKeyError() } var ownIter bool @@ -1687,25 +1688,97 @@ func mvccScanInternal( iter.Close() } if err != nil { - return nil, nil, nil, err + return nil, 0, nil, nil, err } - kvs, resumeKey, intents, err := buildScanResults(kvData, numKvs, intentData, max, consistent) - var resumeSpan *roachpb.Span - if resumeKey != nil { - // NB: we copy the resume key here to ensure that it doesn't point to the - // same shared buffer as the main results. Higher levels of the code may - // cache the resume key and we don't want them pinning excessive amounts of - // memory. - if reverse { - resumeKey = resumeKey[:len(resumeKey):len(resumeKey)] - resumeSpan = &roachpb.Span{Key: key, EndKey: resumeKey.Next()} - } else { - resumeKey = append(roachpb.Key(nil), resumeKey...) - resumeSpan = &roachpb.Span{Key: resumeKey, EndKey: endKey} + intents, err := buildScanIntents(intentData) + if err != nil { + return nil, 0, nil, nil, err + } + if consistent && len(intents) > 0 { + // When encountering intents during a consistent scan we still need to + // return the resume key. + resumeKey, _, err := buildScanResumeKey(kvData, numKvs, max) + if err != nil { + return nil, 0, nil, nil, err } + return nil, 0, resumeKeyToSpan(key, endKey, resumeKey, reverse), nil, &roachpb.WriteIntentError{Intents: intents} + } + + return kvData, numKvs, nil, intents, nil +} + +// mvccScanToBytes scans the key range [key,endKey) up to some maximum number +// of results. Specify reverse=true to scan in descending instead of ascending +// order. If iter is not specified, a new iterator is created from engine. It +// returns the found keys and values in batch format. +func mvccScanToBytes( + ctx context.Context, + engine Reader, + iter Iterator, + key, + endKey roachpb.Key, + max int64, + timestamp hlc.Timestamp, + consistent bool, + tombstones bool, + txn *roachpb.Transaction, + reverse bool, +) ([]byte, int64, *roachpb.Span, []roachpb.Intent, error) { + if max == 0 { + return nil, 0, &roachpb.Span{Key: key, EndKey: endKey}, nil, nil + } + kvData, numKvs, resumeSpan, intents, err := mvccScanInternal( + ctx, engine, iter, key, endKey, max, timestamp, consistent, tombstones, txn, reverse) + if err != nil { + return nil, 0, resumeSpan, nil, err + } + if len(kvData) == 0 || numKvs == 0 { + return nil, 0, nil, intents, nil + } + + resumeKey, offset, err := buildScanResumeKey(kvData, numKvs, max) + if err != nil { + return nil, 0, nil, nil, nil + } + if resumeKey != nil { + kvData = kvData[:offset] + numKvs = max } - return kvs, resumeSpan, intents, err + return kvData, numKvs, resumeKeyToSpan(key, endKey, resumeKey, reverse), intents, err +} + +// mvccScanToKvs scans the key range [key,endKey) up to some maximum number +// of results. Specify reverse=true to scan in descending instead of ascending +// order. If iter is not specified, a new iterator is created from engine. It +// returns the found keys and values in a slice of roachpb.KeyValue. +func mvccScanToKvs( + ctx context.Context, + engine Reader, + iter Iterator, + key, + endKey roachpb.Key, + max int64, + timestamp hlc.Timestamp, + consistent bool, + tombstones bool, + txn *roachpb.Transaction, + reverse bool, +) ([]roachpb.KeyValue, *roachpb.Span, []roachpb.Intent, error) { + if max == 0 { + return nil, &roachpb.Span{Key: key, EndKey: endKey}, nil, nil + } + kvData, numKvs, resumeSpan, intents, err := mvccScanInternal( + ctx, engine, iter, key, endKey, max, timestamp, consistent, tombstones, txn, reverse) + if err != nil { + return nil, resumeSpan, nil, err + } + if len(kvData) == 0 || numKvs == 0 { + return nil, nil, intents, nil + } + + kvs, resumeKey, err := buildScanResults(kvData, numKvs, max) + return kvs, resumeKeyToSpan(key, endKey, resumeKey, reverse), intents, err } func buildScanIntents(data []byte) ([]roachpb.Intent, error) { @@ -1741,51 +1814,51 @@ func buildScanIntents(data []byte) ([]roachpb.Intent, error) { return intents, nil } -func buildScanResumeKey(kvData []byte, numKvs int64, max int64) ([]byte, error) { - if len(kvData) == 0 { - return nil, nil +// resumeKeyToSpan creates a resumeSpan suitable for returning in a ScanResponse +// out of a resumeKey (the last key in a batch that exceeded a limit). +func resumeKeyToSpan(key, endKey, resumeKey roachpb.Key, reverse bool) (resumeSpan *roachpb.Span) { + if resumeKey != nil { + // NB: we copy the resume key here to ensure that it doesn't point to the + // same shared buffer as the main results. Higher levels of the code may + // cache the resume key and we don't want them pinning excessive amounts of + // memory. + if reverse { + resumeKey = resumeKey[:len(resumeKey):len(resumeKey)] + resumeSpan = &roachpb.Span{Key: key, EndKey: resumeKey.Next()} + } else { + resumeKey = append(roachpb.Key(nil), resumeKey...) + resumeSpan = &roachpb.Span{Key: resumeKey, EndKey: endKey} + } + } + return resumeSpan +} + +func buildScanResumeKey(kvData []byte, numKvs int64, max int64) ([]byte, int, error) { + kvLen := len(kvData) + if kvLen == 0 { + return nil, 0, nil } if numKvs <= max { - return nil, nil + return nil, 0, nil } var err error for i := int64(0); i < max; i++ { - _, _, kvData, err = mvccScanDecodeKeyValue(kvData) + kvData, err = mvccScanSkipKeyValue(kvData) if err != nil { - return nil, err + return nil, 0, err } } - key, _, _, err := mvccScanDecodeKeyValue(kvData) + offset := kvLen - len(kvData) + key, _, _, err := MVCCScanDecodeKeyValue(kvData) if err != nil { - return nil, err + return nil, 0, err } - return key.Key, nil + return key.Key, offset, nil } func buildScanResults( - kvData []byte, numKvs int64, intentData []byte, max int64, consistent bool, -) ([]roachpb.KeyValue, roachpb.Key, []roachpb.Intent, error) { - intents, err := buildScanIntents(intentData) - if err != nil { - return nil, nil, nil, err - } - if consistent && len(intents) > 0 { - // When encountering intents during a consistent scan we still need to - // return the resume key. - resumeKey, err := buildScanResumeKey(kvData, numKvs, max) - if err != nil { - return nil, nil, nil, err - } - return nil, resumeKey, nil, &roachpb.WriteIntentError{Intents: intents} - } - if len(kvData) == 0 { - return nil, nil, intents, nil - } - - if numKvs == 0 { - return nil, nil, intents, nil - } - + kvData []byte, numKvs int64, max int64, +) ([]roachpb.KeyValue, roachpb.Key, error) { // Iterator.MVCCScan will return up to max+1 results. The extra result is // returned so that we can generate the resumeKey in the same manner as the // old Go version of MVCCScan. @@ -1800,10 +1873,11 @@ func buildScanResults( var key MVCCKey var rawBytes []byte + var err error for i := range kvs { - key, rawBytes, kvData, err = mvccScanDecodeKeyValue(kvData) + key, rawBytes, kvData, err = MVCCScanDecodeKeyValue(kvData) if err != nil { - return nil, nil, nil, err + return nil, nil, err } kvs[i].Key = key.Key kvs[i].Value.RawBytes = rawBytes @@ -1812,14 +1886,14 @@ func buildScanResults( var resumeKey roachpb.Key if numKvs > max { - key, _, _, err = mvccScanDecodeKeyValue(kvData) + key, _, _, err = MVCCScanDecodeKeyValue(kvData) if err != nil { - return nil, nil, nil, err + return nil, nil, err } resumeKey = key.Key } - return kvs, resumeKey, intents, nil + return kvs, resumeKey, nil } // MVCCScan scans the key range [key,endKey) key up to some maximum number of @@ -1837,7 +1911,22 @@ func MVCCScan( consistent bool, txn *roachpb.Transaction, ) ([]roachpb.KeyValue, *roachpb.Span, []roachpb.Intent, error) { - return mvccScanInternal(ctx, engine, nil, key, endKey, max, timestamp, + return mvccScanToKvs(ctx, engine, nil, key, endKey, max, timestamp, + consistent, false /* tombstones */, txn, false /* reverse */) +} + +// MVCCScanToBytes is like MVCCScan, but it returns the results in a byte array. +func MVCCScanToBytes( + ctx context.Context, + engine Reader, + key, + endKey roachpb.Key, + max int64, + timestamp hlc.Timestamp, + consistent bool, + txn *roachpb.Transaction, +) ([]byte, int64, *roachpb.Span, []roachpb.Intent, error) { + return mvccScanToBytes(ctx, engine, nil, key, endKey, max, timestamp, consistent, false /* tombstones */, txn, false /* reverse */) } @@ -1854,7 +1943,23 @@ func MVCCReverseScan( consistent bool, txn *roachpb.Transaction, ) ([]roachpb.KeyValue, *roachpb.Span, []roachpb.Intent, error) { - return mvccScanInternal(ctx, engine, nil, key, endKey, max, timestamp, + return mvccScanToKvs(ctx, engine, nil, key, endKey, max, timestamp, + consistent, false /* tombstones */, txn, true /* reverse */) +} + +// MVCCReverseScanToBytes is like MVCCReverseScan, but it returns the results +// in a byte array. +func MVCCReverseScanToBytes( + ctx context.Context, + engine Reader, + key, + endKey roachpb.Key, + max int64, + timestamp hlc.Timestamp, + consistent bool, + txn *roachpb.Transaction, +) ([]byte, int64, *roachpb.Span, []roachpb.Intent, error) { + return mvccScanToBytes(ctx, engine, nil, key, endKey, max, timestamp, consistent, false /* tombstones */, txn, true /* reverse */) } @@ -1901,7 +2006,7 @@ func MVCCIterateUsingIter( for { const maxKeysPerScan = 1000 - kvs, resume, newIntents, err := mvccScanInternal( + kvs, resume, newIntents, err := mvccScanToKvs( ctx, engine, iter, startKey, endKey, maxKeysPerScan, timestamp, consistent, tombstones, txn, reverse) if err != nil { switch tErr := err.(type) { diff --git a/pkg/storage/engine/rocksdb.go b/pkg/storage/engine/rocksdb.go index a512e0ee1099..8764de72e159 100644 --- a/pkg/storage/engine/rocksdb.go +++ b/pkg/storage/engine/rocksdb.go @@ -2119,7 +2119,7 @@ func (r *rocksDBIterator) MVCCGet( // Extract the value from the batch data. repr := copyFromSliceVector(state.data.bufs, state.data.len) - mvccKey, rawValue, _, err := mvccScanDecodeKeyValue(repr) + mvccKey, rawValue, _, err := MVCCScanDecodeKeyValue(repr) if err != nil { return nil, nil, err } @@ -2768,10 +2768,28 @@ func unlockFile(lock C.DBFileLock) error { return statusToError(C.DBUnlockFile(lock)) } -// Decode a key/value pair returned in an MVCCScan "batch" (this is not the -// RocksDB batch repr format), returning both the key/value and the suffix of -// data remaining in the batch. -func mvccScanDecodeKeyValue(repr []byte) (key MVCCKey, value []byte, orepr []byte, err error) { +// mvccScanSkipKeyValue is like MVCCScanDecodeKeyValue, but doesn't bother +// actually decoding the kvs. Instead, it skips the kv and returns the rest of +// the byte buffer. +func mvccScanSkipKeyValue(repr []byte) ([]byte, error) { + if len(repr) < 8 { + return repr, errors.Errorf("unexpected batch EOF") + } + v := binary.LittleEndian.Uint64(repr) + keySize := v >> 32 + valSize := v & ((1 << 32) - 1) + if (keySize + valSize) > uint64(len(repr)) { + return nil, fmt.Errorf("expected %d bytes, but only %d remaining", + keySize+valSize, len(repr)) + } + repr = repr[8+keySize+valSize:] + return repr, nil +} + +// MVCCScanDecodeKeyValue decodes a key/value pair returned in an MVCCScan +// "batch" (this is not the RocksDB batch repr format), returning both the +// key/value and the suffix of data remaining in the batch. +func MVCCScanDecodeKeyValue(repr []byte) (key MVCCKey, value []byte, orepr []byte, err error) { if len(repr) < 8 { return key, nil, repr, errors.Errorf("unexpected batch EOF") }