diff --git a/api/cosmos/tx/v1beta1/tx.pulsar.go b/api/cosmos/tx/v1beta1/tx.pulsar.go index 608d8509bff5..a3a85d328e2b 100644 --- a/api/cosmos/tx/v1beta1/tx.pulsar.go +++ b/api/cosmos/tx/v1beta1/tx.pulsar.go @@ -14,6 +14,7 @@ import ( protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" anypb "google.golang.org/protobuf/types/known/anypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" io "io" reflect "reflect" sync "sync" @@ -2768,6 +2769,7 @@ var ( fd_TxBody_memo protoreflect.FieldDescriptor fd_TxBody_timeout_height protoreflect.FieldDescriptor fd_TxBody_unordered protoreflect.FieldDescriptor + fd_TxBody_timeout_timestamp protoreflect.FieldDescriptor fd_TxBody_extension_options protoreflect.FieldDescriptor fd_TxBody_non_critical_extension_options protoreflect.FieldDescriptor ) @@ -2779,6 +2781,7 @@ func init() { fd_TxBody_memo = md_TxBody.Fields().ByName("memo") fd_TxBody_timeout_height = md_TxBody.Fields().ByName("timeout_height") fd_TxBody_unordered = md_TxBody.Fields().ByName("unordered") + fd_TxBody_timeout_timestamp = md_TxBody.Fields().ByName("timeout_timestamp") fd_TxBody_extension_options = md_TxBody.Fields().ByName("extension_options") fd_TxBody_non_critical_extension_options = md_TxBody.Fields().ByName("non_critical_extension_options") } @@ -2872,6 +2875,12 @@ func (x *fastReflection_TxBody) Range(f func(protoreflect.FieldDescriptor, proto return } } + if x.TimeoutTimestamp != nil { + value := protoreflect.ValueOfMessage(x.TimeoutTimestamp.ProtoReflect()) + if !f(fd_TxBody_timeout_timestamp, value) { + return + } + } if len(x.ExtensionOptions) != 0 { value := protoreflect.ValueOfList(&_TxBody_1023_list{list: &x.ExtensionOptions}) if !f(fd_TxBody_extension_options, value) { @@ -2907,6 +2916,8 @@ func (x *fastReflection_TxBody) Has(fd protoreflect.FieldDescriptor) bool { return x.TimeoutHeight != uint64(0) case "cosmos.tx.v1beta1.TxBody.unordered": return x.Unordered != false + case "cosmos.tx.v1beta1.TxBody.timeout_timestamp": + return x.TimeoutTimestamp != nil case "cosmos.tx.v1beta1.TxBody.extension_options": return len(x.ExtensionOptions) != 0 case "cosmos.tx.v1beta1.TxBody.non_critical_extension_options": @@ -2935,6 +2946,8 @@ func (x *fastReflection_TxBody) Clear(fd protoreflect.FieldDescriptor) { x.TimeoutHeight = uint64(0) case "cosmos.tx.v1beta1.TxBody.unordered": x.Unordered = false + case "cosmos.tx.v1beta1.TxBody.timeout_timestamp": + x.TimeoutTimestamp = nil case "cosmos.tx.v1beta1.TxBody.extension_options": x.ExtensionOptions = nil case "cosmos.tx.v1beta1.TxBody.non_critical_extension_options": @@ -2970,6 +2983,9 @@ func (x *fastReflection_TxBody) Get(descriptor protoreflect.FieldDescriptor) pro case "cosmos.tx.v1beta1.TxBody.unordered": value := x.Unordered return protoreflect.ValueOfBool(value) + case "cosmos.tx.v1beta1.TxBody.timeout_timestamp": + value := x.TimeoutTimestamp + return protoreflect.ValueOfMessage(value.ProtoReflect()) case "cosmos.tx.v1beta1.TxBody.extension_options": if len(x.ExtensionOptions) == 0 { return protoreflect.ValueOfList(&_TxBody_1023_list{}) @@ -3012,6 +3028,8 @@ func (x *fastReflection_TxBody) Set(fd protoreflect.FieldDescriptor, value proto x.TimeoutHeight = value.Uint() case "cosmos.tx.v1beta1.TxBody.unordered": x.Unordered = value.Bool() + case "cosmos.tx.v1beta1.TxBody.timeout_timestamp": + x.TimeoutTimestamp = value.Message().Interface().(*timestamppb.Timestamp) case "cosmos.tx.v1beta1.TxBody.extension_options": lv := value.List() clv := lv.(*_TxBody_1023_list) @@ -3046,6 +3064,11 @@ func (x *fastReflection_TxBody) Mutable(fd protoreflect.FieldDescriptor) protore } value := &_TxBody_1_list{list: &x.Messages} return protoreflect.ValueOfList(value) + case "cosmos.tx.v1beta1.TxBody.timeout_timestamp": + if x.TimeoutTimestamp == nil { + x.TimeoutTimestamp = new(timestamppb.Timestamp) + } + return protoreflect.ValueOfMessage(x.TimeoutTimestamp.ProtoReflect()) case "cosmos.tx.v1beta1.TxBody.extension_options": if x.ExtensionOptions == nil { x.ExtensionOptions = []*anypb.Any{} @@ -3086,6 +3109,9 @@ func (x *fastReflection_TxBody) NewField(fd protoreflect.FieldDescriptor) protor return protoreflect.ValueOfUint64(uint64(0)) case "cosmos.tx.v1beta1.TxBody.unordered": return protoreflect.ValueOfBool(false) + case "cosmos.tx.v1beta1.TxBody.timeout_timestamp": + m := new(timestamppb.Timestamp) + return protoreflect.ValueOfMessage(m.ProtoReflect()) case "cosmos.tx.v1beta1.TxBody.extension_options": list := []*anypb.Any{} return protoreflect.ValueOfList(&_TxBody_1023_list{list: &list}) @@ -3177,6 +3203,10 @@ func (x *fastReflection_TxBody) ProtoMethods() *protoiface.Methods { if x.Unordered { n += 2 } + if x.TimeoutTimestamp != nil { + l = options.Size(x.TimeoutTimestamp) + n += 1 + l + runtime.Sov(uint64(l)) + } if len(x.ExtensionOptions) > 0 { for _, e := range x.ExtensionOptions { l = options.Size(e) @@ -3254,6 +3284,20 @@ func (x *fastReflection_TxBody) ProtoMethods() *protoiface.Methods { dAtA[i] = 0xfa } } + if x.TimeoutTimestamp != nil { + encoded, err := options.Marshal(x.TimeoutTimestamp) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x2a + } if x.Unordered { i-- if x.Unordered { @@ -3446,6 +3490,42 @@ func (x *fastReflection_TxBody) ProtoMethods() *protoiface.Methods { } } x.Unordered = bool(v != 0) + case 5: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.TimeoutTimestamp == nil { + x.TimeoutTimestamp = ×tamppb.Timestamp{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.TimeoutTimestamp); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex case 1023: if wireType != 2 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field ExtensionOptions", wireType) @@ -8473,10 +8553,6 @@ type TxBody struct { Memo string `protobuf:"bytes,2,opt,name=memo,proto3" json:"memo,omitempty"` // timeout_height is the block height after which this transaction will not // be processed by the chain. - // - // Note, if unordered=true this value MUST be set - // and will act as a short-lived TTL in which the transaction is deemed valid - // and kept in memory to prevent duplicates. TimeoutHeight uint64 `protobuf:"varint,3,opt,name=timeout_height,json=timeoutHeight,proto3" json:"timeout_height,omitempty"` // unordered, when set to true, indicates that the transaction signer(s) // intend for the transaction to be evaluated and executed in an un-ordered @@ -8484,10 +8560,17 @@ type TxBody struct { // incremented, which allows for fire-and-forget as well as concurrent // transaction execution. // - // Note, when set to true, the existing 'timeout_height' value must be set and - // will be used to correspond to a height in which the transaction is deemed + // Note, when set to true, the existing 'timeout_height' value must + // be set and will be used to correspond to a timestamp in which the transaction is deemed // valid. Unordered bool `protobuf:"varint,4,opt,name=unordered,proto3" json:"unordered,omitempty"` + // timeout_timestamp is the block time after which this transaction will not + // be processed by the chain. + // + // Note, if unordered=true this value MUST be set + // and will act as a short-lived TTL in which the transaction is deemed valid + // and kept in memory to prevent duplicates. + TimeoutTimestamp *timestamppb.Timestamp `protobuf:"bytes,5,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty"` // extension_options are arbitrary options that can be added by chains // when the default options are not sufficient. If any of these are present // and can't be handled, the transaction will be rejected @@ -8546,6 +8629,13 @@ func (x *TxBody) GetUnordered() bool { return false } +func (x *TxBody) GetTimeoutTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.TimeoutTimestamp + } + return nil +} + func (x *TxBody) GetExtensionOptions() []*anypb.Any { if x != nil { return x.ExtensionOptions @@ -9067,126 +9157,117 @@ var file_cosmos_tx_v1beta1_tx_proto_rawDesc = []byte{ 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x02, 0x54, 0x78, 0x12, 0x2d, 0x0a, - 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x54, 0x78, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x38, 0x0a, 0x09, - 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x61, 0x75, - 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x05, 0x54, 0x78, 0x52, 0x61, 0x77, 0x12, - 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x26, - 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62, 0x79, 0x74, 0x65, - 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, - 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, 0x74, - 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, - 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, 0x44, - 0x6f, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, - 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62, - 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, - 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, - 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, - 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xf2, 0x01, 0x0a, 0x10, - 0x53, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x41, 0x75, 0x78, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x8d, 0x01, 0x0a, 0x02, 0x54, 0x78, 0x12, 0x2d, + 0x0a, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x54, 0x78, 0x42, 0x6f, 0x64, 0x79, 0x52, 0x04, 0x62, 0x6f, 0x64, 0x79, 0x12, 0x38, 0x0a, + 0x09, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x61, + 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x6e, 0x0a, 0x05, 0x54, 0x78, 0x52, 0x61, 0x77, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, - 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, - 0x63, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, - 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, - 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, - 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x03, 0x74, 0x69, 0x70, - 0x22, 0xb3, 0x02, 0x0a, 0x06, 0x54, 0x78, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x30, 0x0a, 0x08, 0x6d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x41, 0x6e, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x6d, - 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x68, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x6f, - 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x6e, 0x6f, 0x72, - 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x75, 0x6e, 0x6f, - 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x12, 0x42, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xff, 0x07, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, - 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, 0x0a, 0x1e, 0x6e, 0x6f, - 0x6e, 0x5f, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, - 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0xff, 0x0f, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x1b, 0x6e, 0x6f, 0x6e, 0x43, 0x72, - 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, - 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x08, 0x41, 0x75, 0x74, 0x68, 0x49, - 0x6e, 0x66, 0x6f, 0x12, 0x40, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x5f, 0x69, 0x6e, - 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, - 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, - 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x03, 0x66, 0x65, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, - 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x52, 0x03, 0x66, 0x65, 0x65, 0x12, - 0x2c, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, - 0x2e, 0x54, 0x69, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x03, 0x74, 0x69, 0x70, 0x22, 0x97, 0x01, - 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x33, 0x0a, 0x0a, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, - 0x79, 0x12, 0x38, 0x0a, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x1a, 0x0a, 0x08, 0x73, - 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, - 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xe0, 0x02, 0x0a, 0x08, 0x4d, 0x6f, 0x64, 0x65, - 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x06, 0x73, 0x69, 0x6e, 0x67, - 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x4d, - 0x75, 0x6c, 0x74, 0x69, 0x48, 0x00, 0x52, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x1a, 0x41, 0x0a, - 0x06, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, - 0x78, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, - 0x1a, 0x90, 0x01, 0x0a, 0x05, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x12, 0x4b, 0x0a, 0x08, 0x62, 0x69, - 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, 0x2e, 0x6d, 0x75, 0x6c, - 0x74, 0x69, 0x73, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, - 0x6d, 0x70, 0x61, 0x63, 0x74, 0x42, 0x69, 0x74, 0x41, 0x72, 0x72, 0x61, 0x79, 0x52, 0x08, 0x62, - 0x69, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, 0x6f, 0x64, 0x65, 0x5f, - 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x49, 0x6e, - 0x66, 0x6f, 0x73, 0x42, 0x05, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x22, 0x81, 0x02, 0x0a, 0x03, 0x46, - 0x65, 0x65, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, - 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x46, 0xc8, - 0xde, 0x1f, 0x00, 0xaa, 0xdf, 0x1f, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, - 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, - 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x9a, - 0xe7, 0xb0, 0x2a, 0x0c, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x73, - 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x1b, 0x0a, - 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2e, 0x0a, 0x05, 0x70, 0x61, - 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x52, 0x05, 0x70, 0x61, 0x79, 0x65, 0x72, 0x12, 0x32, 0x0a, 0x07, 0x67, 0x72, - 0x61, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, - 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x22, 0xb6, - 0x01, 0x0a, 0x03, 0x54, 0x69, 0x70, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, + 0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x49, 0x6e, + 0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1e, 0x0a, 0x0a, 0x73, 0x69, 0x67, 0x6e, 0x61, + 0x74, 0x75, 0x72, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0a, 0x73, 0x69, 0x67, + 0x6e, 0x61, 0x74, 0x75, 0x72, 0x65, 0x73, 0x22, 0x92, 0x01, 0x0a, 0x07, 0x53, 0x69, 0x67, 0x6e, + 0x44, 0x6f, 0x63, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, + 0x65, 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, + 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, + 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x22, 0xf2, 0x01, 0x0a, + 0x10, 0x53, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x72, 0x65, 0x63, 0x74, 0x41, 0x75, + 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, + 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, + 0x64, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, + 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, + 0x6e, 0x63, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x03, 0x74, 0x69, + 0x70, 0x22, 0x86, 0x03, 0x0a, 0x06, 0x54, 0x78, 0x42, 0x6f, 0x64, 0x79, 0x12, 0x30, 0x0a, 0x08, + 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x08, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x73, 0x12, 0x12, + 0x0a, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, + 0x6d, 0x6f, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x68, 0x65, + 0x69, 0x67, 0x68, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x6e, 0x6f, + 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x75, 0x6e, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x12, 0x51, 0x0a, 0x11, 0x74, 0x69, 0x6d, 0x65, 0x6f, + 0x75, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x42, 0x08, + 0xc8, 0xde, 0x1f, 0x01, 0x90, 0xdf, 0x1f, 0x01, 0x52, 0x10, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, + 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x42, 0x0a, 0x11, 0x65, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, + 0xff, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x10, 0x65, 0x78, + 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x5a, + 0x0a, 0x1e, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x65, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, + 0x18, 0xff, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x1b, 0x6e, + 0x6f, 0x6e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, + 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x08, 0x41, + 0x75, 0x74, 0x68, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x40, 0x0a, 0x0c, 0x73, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, + 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x73, 0x69, + 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x12, 0x28, 0x0a, 0x03, 0x66, 0x65, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, + 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x46, 0x65, 0x65, 0x52, 0x03, + 0x66, 0x65, 0x65, 0x12, 0x2c, 0x0a, 0x03, 0x74, 0x69, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x16, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, + 0x65, 0x74, 0x61, 0x31, 0x2e, 0x54, 0x69, 0x70, 0x42, 0x02, 0x18, 0x01, 0x52, 0x03, 0x74, 0x69, + 0x70, 0x22, 0x97, 0x01, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, + 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, + 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, 0x70, 0x75, 0x62, 0x6c, + 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x38, 0x0a, 0x09, 0x6d, 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, + 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x6d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, + 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0xe0, 0x02, 0x0a, 0x08, + 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x12, 0x3c, 0x0a, 0x06, 0x73, 0x69, 0x6e, 0x67, + 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x22, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, + 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x2e, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x48, 0x00, 0x52, 0x06, + 0x73, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x12, 0x39, 0x0a, 0x05, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, + 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, + 0x66, 0x6f, 0x2e, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x48, 0x00, 0x52, 0x05, 0x6d, 0x75, 0x6c, 0x74, + 0x69, 0x1a, 0x41, 0x0a, 0x06, 0x53, 0x69, 0x6e, 0x67, 0x6c, 0x65, 0x12, 0x37, 0x0a, 0x04, 0x6d, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, + 0x6d, 0x6f, 0x64, 0x65, 0x1a, 0x90, 0x01, 0x0a, 0x05, 0x4d, 0x75, 0x6c, 0x74, 0x69, 0x12, 0x4b, + 0x0a, 0x08, 0x62, 0x69, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x2f, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x63, 0x72, 0x79, 0x70, 0x74, 0x6f, + 0x2e, 0x6d, 0x75, 0x6c, 0x74, 0x69, 0x73, 0x69, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x2e, 0x43, 0x6f, 0x6d, 0x70, 0x61, 0x63, 0x74, 0x42, 0x69, 0x74, 0x41, 0x72, 0x72, 0x61, + 0x79, 0x52, 0x08, 0x62, 0x69, 0x74, 0x61, 0x72, 0x72, 0x61, 0x79, 0x12, 0x3a, 0x0a, 0x0a, 0x6d, + 0x6f, 0x64, 0x65, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x1b, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x2e, 0x4d, 0x6f, 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x09, 0x6d, 0x6f, + 0x64, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x73, 0x42, 0x05, 0x0a, 0x03, 0x73, 0x75, 0x6d, 0x22, 0x81, + 0x02, 0x0a, 0x03, 0x46, 0x65, 0x65, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x46, 0xc8, 0xde, 0x1f, 0x00, 0xaa, 0xdf, 0x1f, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, @@ -9194,35 +9275,51 @@ var file_cosmos_tx_v1beta1_tx_proto_rawDesc = []byte{ 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x9a, 0xe7, 0xb0, 0x2a, 0x0c, 0x6c, 0x65, 0x67, 0x61, 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, 0x6d, 0x6f, 0x75, 0x6e, - 0x74, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x69, 0x70, 0x70, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x06, 0x74, 0x69, 0x70, - 0x70, 0x65, 0x72, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xce, 0x01, 0x0a, 0x0d, 0x41, 0x75, 0x78, 0x53, - 0x69, 0x67, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, - 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x3e, 0x0a, - 0x08, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x64, 0x6f, 0x63, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, - 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, 0x69, 0x72, 0x65, 0x63, - 0x74, 0x41, 0x75, 0x78, 0x52, 0x07, 0x73, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x12, 0x37, 0x0a, - 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x23, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x73, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x2e, - 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x4d, 0x6f, 0x64, 0x65, - 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, 0x67, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x42, 0xb4, 0x01, 0x0a, 0x15, 0x63, 0x6f, 0x6d, - 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, - 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x63, - 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, - 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x3b, 0x74, 0x78, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x43, 0x54, - 0x58, 0xaa, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x54, 0x78, 0x2e, 0x56, 0x31, - 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x54, - 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1d, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, - 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, 0x43, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x78, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, - 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x74, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x2e, + 0x0a, 0x05, 0x70, 0x61, 0x79, 0x65, 0x72, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, + 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x05, 0x70, 0x61, 0x79, 0x65, 0x72, 0x12, 0x32, + 0x0a, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x42, + 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x67, 0x72, 0x61, 0x6e, 0x74, + 0x65, 0x72, 0x22, 0xb6, 0x01, 0x0a, 0x03, 0x54, 0x69, 0x70, 0x12, 0x79, 0x0a, 0x06, 0x61, 0x6d, + 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, + 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, + 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x42, 0x46, 0xc8, 0xde, 0x1f, 0x00, 0xaa, 0xdf, 0x1f, 0x28, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, + 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x73, 0x9a, 0xe7, 0xb0, 0x2a, 0x0c, 0x6c, 0x65, 0x67, 0x61, + 0x63, 0x79, 0x5f, 0x63, 0x6f, 0x69, 0x6e, 0x73, 0xa8, 0xe7, 0xb0, 0x2a, 0x01, 0x52, 0x06, 0x61, + 0x6d, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x30, 0x0a, 0x06, 0x74, 0x69, 0x70, 0x70, 0x65, 0x72, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, + 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, + 0x06, 0x74, 0x69, 0x70, 0x70, 0x65, 0x72, 0x3a, 0x02, 0x18, 0x01, 0x22, 0xce, 0x01, 0x0a, 0x0d, + 0x41, 0x75, 0x78, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x32, 0x0a, + 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x18, + 0xd2, 0xb4, 0x2d, 0x14, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x12, 0x3e, 0x0a, 0x08, 0x73, 0x69, 0x67, 0x6e, 0x5f, 0x64, 0x6f, 0x63, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, + 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x44, 0x6f, 0x63, 0x44, + 0x69, 0x72, 0x65, 0x63, 0x74, 0x41, 0x75, 0x78, 0x52, 0x07, 0x73, 0x69, 0x67, 0x6e, 0x44, 0x6f, + 0x63, 0x12, 0x37, 0x0a, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, + 0x23, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x73, 0x69, 0x67, 0x6e, + 0x69, 0x6e, 0x67, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, + 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x04, 0x6d, 0x6f, 0x64, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x73, 0x69, + 0x67, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x73, 0x69, 0x67, 0x42, 0xb4, 0x01, 0x0a, + 0x15, 0x63, 0x6f, 0x6d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, + 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x07, 0x54, 0x78, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, + 0x01, 0x5a, 0x2c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, + 0x61, 0x70, 0x69, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2f, 0x74, 0x78, 0x2f, 0x76, 0x31, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x74, 0x78, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, + 0x02, 0x03, 0x43, 0x54, 0x58, 0xaa, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x54, + 0x78, 0x2e, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x11, 0x43, 0x6f, 0x73, 0x6d, + 0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x1d, + 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x5c, 0x54, 0x78, 0x5c, 0x56, 0x31, 0x62, 0x65, 0x74, 0x61, + 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x13, + 0x43, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x3a, 0x3a, 0x54, 0x78, 0x3a, 0x3a, 0x56, 0x31, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -9253,9 +9350,10 @@ var file_cosmos_tx_v1beta1_tx_proto_goTypes = []interface{}{ (*ModeInfo_Single)(nil), // 11: cosmos.tx.v1beta1.ModeInfo.Single (*ModeInfo_Multi)(nil), // 12: cosmos.tx.v1beta1.ModeInfo.Multi (*anypb.Any)(nil), // 13: google.protobuf.Any - (*v1beta12.Coin)(nil), // 14: cosmos.base.v1beta1.Coin - (v1beta1.SignMode)(0), // 15: cosmos.tx.signing.v1beta1.SignMode - (*v1beta11.CompactBitArray)(nil), // 16: cosmos.crypto.multisig.v1beta1.CompactBitArray + (*timestamppb.Timestamp)(nil), // 14: google.protobuf.Timestamp + (*v1beta12.Coin)(nil), // 15: cosmos.base.v1beta1.Coin + (v1beta1.SignMode)(0), // 16: cosmos.tx.signing.v1beta1.SignMode + (*v1beta11.CompactBitArray)(nil), // 17: cosmos.crypto.multisig.v1beta1.CompactBitArray } var file_cosmos_tx_v1beta1_tx_proto_depIdxs = []int32{ 4, // 0: cosmos.tx.v1beta1.Tx.body:type_name -> cosmos.tx.v1beta1.TxBody @@ -9263,27 +9361,28 @@ var file_cosmos_tx_v1beta1_tx_proto_depIdxs = []int32{ 13, // 2: cosmos.tx.v1beta1.SignDocDirectAux.public_key:type_name -> google.protobuf.Any 9, // 3: cosmos.tx.v1beta1.SignDocDirectAux.tip:type_name -> cosmos.tx.v1beta1.Tip 13, // 4: cosmos.tx.v1beta1.TxBody.messages:type_name -> google.protobuf.Any - 13, // 5: cosmos.tx.v1beta1.TxBody.extension_options:type_name -> google.protobuf.Any - 13, // 6: cosmos.tx.v1beta1.TxBody.non_critical_extension_options:type_name -> google.protobuf.Any - 6, // 7: cosmos.tx.v1beta1.AuthInfo.signer_infos:type_name -> cosmos.tx.v1beta1.SignerInfo - 8, // 8: cosmos.tx.v1beta1.AuthInfo.fee:type_name -> cosmos.tx.v1beta1.Fee - 9, // 9: cosmos.tx.v1beta1.AuthInfo.tip:type_name -> cosmos.tx.v1beta1.Tip - 13, // 10: cosmos.tx.v1beta1.SignerInfo.public_key:type_name -> google.protobuf.Any - 7, // 11: cosmos.tx.v1beta1.SignerInfo.mode_info:type_name -> cosmos.tx.v1beta1.ModeInfo - 11, // 12: cosmos.tx.v1beta1.ModeInfo.single:type_name -> cosmos.tx.v1beta1.ModeInfo.Single - 12, // 13: cosmos.tx.v1beta1.ModeInfo.multi:type_name -> cosmos.tx.v1beta1.ModeInfo.Multi - 14, // 14: cosmos.tx.v1beta1.Fee.amount:type_name -> cosmos.base.v1beta1.Coin - 14, // 15: cosmos.tx.v1beta1.Tip.amount:type_name -> cosmos.base.v1beta1.Coin - 3, // 16: cosmos.tx.v1beta1.AuxSignerData.sign_doc:type_name -> cosmos.tx.v1beta1.SignDocDirectAux - 15, // 17: cosmos.tx.v1beta1.AuxSignerData.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode - 15, // 18: cosmos.tx.v1beta1.ModeInfo.Single.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode - 16, // 19: cosmos.tx.v1beta1.ModeInfo.Multi.bitarray:type_name -> cosmos.crypto.multisig.v1beta1.CompactBitArray - 7, // 20: cosmos.tx.v1beta1.ModeInfo.Multi.mode_infos:type_name -> cosmos.tx.v1beta1.ModeInfo - 21, // [21:21] is the sub-list for method output_type - 21, // [21:21] is the sub-list for method input_type - 21, // [21:21] is the sub-list for extension type_name - 21, // [21:21] is the sub-list for extension extendee - 0, // [0:21] is the sub-list for field type_name + 14, // 5: cosmos.tx.v1beta1.TxBody.timeout_timestamp:type_name -> google.protobuf.Timestamp + 13, // 6: cosmos.tx.v1beta1.TxBody.extension_options:type_name -> google.protobuf.Any + 13, // 7: cosmos.tx.v1beta1.TxBody.non_critical_extension_options:type_name -> google.protobuf.Any + 6, // 8: cosmos.tx.v1beta1.AuthInfo.signer_infos:type_name -> cosmos.tx.v1beta1.SignerInfo + 8, // 9: cosmos.tx.v1beta1.AuthInfo.fee:type_name -> cosmos.tx.v1beta1.Fee + 9, // 10: cosmos.tx.v1beta1.AuthInfo.tip:type_name -> cosmos.tx.v1beta1.Tip + 13, // 11: cosmos.tx.v1beta1.SignerInfo.public_key:type_name -> google.protobuf.Any + 7, // 12: cosmos.tx.v1beta1.SignerInfo.mode_info:type_name -> cosmos.tx.v1beta1.ModeInfo + 11, // 13: cosmos.tx.v1beta1.ModeInfo.single:type_name -> cosmos.tx.v1beta1.ModeInfo.Single + 12, // 14: cosmos.tx.v1beta1.ModeInfo.multi:type_name -> cosmos.tx.v1beta1.ModeInfo.Multi + 15, // 15: cosmos.tx.v1beta1.Fee.amount:type_name -> cosmos.base.v1beta1.Coin + 15, // 16: cosmos.tx.v1beta1.Tip.amount:type_name -> cosmos.base.v1beta1.Coin + 3, // 17: cosmos.tx.v1beta1.AuxSignerData.sign_doc:type_name -> cosmos.tx.v1beta1.SignDocDirectAux + 16, // 18: cosmos.tx.v1beta1.AuxSignerData.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode + 16, // 19: cosmos.tx.v1beta1.ModeInfo.Single.mode:type_name -> cosmos.tx.signing.v1beta1.SignMode + 17, // 20: cosmos.tx.v1beta1.ModeInfo.Multi.bitarray:type_name -> cosmos.crypto.multisig.v1beta1.CompactBitArray + 7, // 21: cosmos.tx.v1beta1.ModeInfo.Multi.mode_infos:type_name -> cosmos.tx.v1beta1.ModeInfo + 22, // [22:22] is the sub-list for method output_type + 22, // [22:22] is the sub-list for method input_type + 22, // [22:22] is the sub-list for extension type_name + 22, // [22:22] is the sub-list for extension extendee + 0, // [0:22] is the sub-list for field type_name } func init() { file_cosmos_tx_v1beta1_tx_proto_init() } diff --git a/baseapp/abci_utils.go b/baseapp/abci_utils.go index 30914b3c8705..649ad4230b35 100644 --- a/baseapp/abci_utils.go +++ b/baseapp/abci_utils.go @@ -21,7 +21,7 @@ import ( ) type ( - // ValidatorStore defines the interface contract require for verifying vote + // ValidatorStore defines the interface contract required for verifying vote // extension signatures. Typically, this will be implemented by the x/staking // module, which has knowledge of the CometBFT public key. ValidatorStore interface { @@ -83,7 +83,7 @@ func ValidateVoteExtensions( totalVP += vote.Validator.Power // Only check + include power if the vote is a commit vote. There must be super-majority, otherwise the - // previous block (the block vote is for) could not have been committed. + // previous block (the block the vote is for) could not have been committed. if vote.BlockIdFlag != cmtproto.BlockIDFlagCommit { continue } @@ -286,35 +286,41 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan invalidTxs []sdk.Tx // invalid txs to be removed out of the loop to avoid dead lock ) mempool.SelectBy(ctx, h.mempool, req.Txs, func(memTx sdk.Tx) bool { - signerData, err := h.signerExtAdapter.GetSigners(memTx) - if err != nil { - // propagate the error to the caller - resError = err - return false - } - - // If the signers aren't in selectedTxsSignersSeqs then we haven't seen them before - // so we add them and continue given that we don't need to check the sequence. - shouldAdd := true + unorderedTx, ok := memTx.(sdk.TxWithUnordered) + isUnordered := ok && unorderedTx.GetUnordered() txSignersSeqs := make(map[string]uint64) - for _, signer := range signerData { - seq, ok := selectedTxsSignersSeqs[signer.Signer.String()] - if !ok { - txSignersSeqs[signer.Signer.String()] = signer.Sequence - continue + + // if the tx is unordered, we don't need to check the sequence, we just add it + if !isUnordered { + signerData, err := h.signerExtAdapter.GetSigners(memTx) + if err != nil { + // propagate the error to the caller + resError = err + return false } - // If we have seen this signer before in this block, we must make - // sure that the current sequence is seq+1; otherwise is invalid - // and we skip it. - if seq+1 != signer.Sequence { - shouldAdd = false - break + // If the signers aren't in selectedTxsSignersSeqs then we haven't seen them before + // so we add them and continue given that we don't need to check the sequence. + shouldAdd := true + for _, signer := range signerData { + seq, ok := selectedTxsSignersSeqs[signer.Signer.String()] + if !ok { + txSignersSeqs[signer.Signer.String()] = signer.Sequence + continue + } + + // If we have seen this signer before in this block, we must make + // sure that the current sequence is seq+1; otherwise is invalid + // and we skip it. + if seq+1 != signer.Sequence { + shouldAdd = false + break + } + txSignersSeqs[signer.Signer.String()] = signer.Sequence + } + if !shouldAdd { + return true } - txSignersSeqs[signer.Signer.String()] = signer.Sequence - } - if !shouldAdd { - return true } // NOTE: Since transaction verification was already executed in CheckTx, @@ -331,18 +337,21 @@ func (h *DefaultProposalHandler) PrepareProposalHandler() sdk.PrepareProposalHan } txsLen := len(h.txSelector.SelectedTxs(ctx)) - for sender, seq := range txSignersSeqs { - // If txsLen != selectedTxsNums is true, it means that we've - // added a new tx to the selected txs, so we need to update - // the sequence of the sender. - if txsLen != selectedTxsNums { - selectedTxsSignersSeqs[sender] = seq - } else if _, ok := selectedTxsSignersSeqs[sender]; !ok { - // The transaction hasn't been added but it passed the - // verification, so we know that the sequence is correct. - // So we set this sender's sequence to seq-1, in order - // to avoid unnecessary calls to PrepareProposalVerifyTx. - selectedTxsSignersSeqs[sender] = seq - 1 + // If the tx is unordered, we don't need to update the sender sequence. + if !isUnordered { + for sender, seq := range txSignersSeqs { + // If txsLen != selectedTxsNums is true, it means that we've + // added a new tx to the selected txs, so we need to update + // the sequence of the sender. + if txsLen != selectedTxsNums { + selectedTxsSignersSeqs[sender] = seq + } else if _, ok := selectedTxsSignersSeqs[sender]; !ok { + // The transaction hasn't been added but it passed the + // verification, so we know that the sequence is correct. + // So we set this sender's sequence to seq-1, in order + // to avoid unnecessary calls to PrepareProposalVerifyTx. + selectedTxsSignersSeqs[sender] = seq - 1 + } } } selectedTxsNums = txsLen diff --git a/client/flags/flags.go b/client/flags/flags.go index f2af30eb0714..539132b9a948 100644 --- a/client/flags/flags.go +++ b/client/flags/flags.go @@ -74,6 +74,7 @@ const ( FlagOffset = "offset" FlagCountTotal = "count-total" FlagTimeoutHeight = "timeout-height" + FlagTimeoutTimestamp = "timeout-timestamp" FlagUnordered = "unordered" FlagKeyAlgorithm = "algo" FlagKeyType = "key-type" @@ -136,8 +137,9 @@ func AddTxFlagsToCmd(cmd *cobra.Command) { f.Bool(FlagOffline, false, "Offline mode (does not allow any online functionality)") f.BoolP(FlagSkipConfirmation, "y", false, "Skip tx broadcasting prompt confirmation") f.String(FlagSignMode, "", "Choose sign mode (direct|amino-json|direct-aux|textual), this is an advanced feature") - f.Uint64(FlagTimeoutHeight, 0, "Set a block timeout height to prevent the tx from being committed past a certain height") - f.Bool(FlagUnordered, false, "Enable unordered transaction delivery; must be used in conjunction with --timeout-height") + f.Uint64(FlagTimeoutHeight, 0, "DEPRECATED: Please use --timeout-timestamp instead. Set a block timeout height to prevent the tx from being committed past a certain height") + f.Int64(FlagTimeoutTimestamp, 0, "Set a block timeout timestamp to prevent the tx from being committed past a certain time") + f.Bool(FlagUnordered, false, "Enable unordered transaction delivery; must be used in conjunction with --timeout-timestamp") f.String(FlagFeePayer, "", "Fee payer pays fees for the transaction instead of deducting from the signer") f.String(FlagFeeGranter, "", "Fee granter grants fees for the transaction") f.String(FlagTip, "", "Tip is the amount that is going to be transferred to the fee payer on the target chain. This flag is only valid when used with --aux, and is ignored if the target chain didn't enable the TipDecorator") @@ -147,6 +149,8 @@ func AddTxFlagsToCmd(cmd *cobra.Command) { f.String(FlagGas, "", fmt.Sprintf("gas limit to set per-transaction; set to %q to calculate sufficient gas automatically. Note: %q option doesn't always report accurate results. Set a valid coin value to adjust the result. Can be used instead of %q. (default %d)", GasFlagAuto, GasFlagAuto, FlagFees, DefaultGasLimit)) + cmd.MarkFlagsMutuallyExclusive(FlagTimeoutHeight, FlagTimeoutTimestamp) + AddKeyringFlags(f) } diff --git a/client/tx/aux_builder.go b/client/tx/aux_builder.go index be9616ae759e..3b4639220f82 100644 --- a/client/tx/aux_builder.go +++ b/client/tx/aux_builder.go @@ -2,9 +2,11 @@ package tx import ( "context" + "time" "github.com/cosmos/gogoproto/proto" "google.golang.org/protobuf/types/known/anypb" + "google.golang.org/protobuf/types/known/timestamppb" txv1beta1 "cosmossdk.io/api/cosmos/tx/v1beta1" txsigning "cosmossdk.io/x/tx/signing" @@ -58,6 +60,14 @@ func (b *AuxTxBuilder) SetTimeoutHeight(height uint64) { b.auxSignerData.SignDoc.BodyBytes = nil } +// SetTimeoutTimestamp sets a timeout timestamp in the tx. +func (b *AuxTxBuilder) SetTimeoutTimestamp(timestamp time.Time) { + b.checkEmptyFields() + + b.body.TimeoutTimestamp = timestamppb.New(timestamp) + b.auxSignerData.SignDoc.BodyBytes = nil +} + // SetMsgs sets an array of Msgs in the tx. func (b *AuxTxBuilder) SetMsgs(msgs ...sdk.Msg) error { anys := make([]*anypb.Any, len(msgs)) @@ -209,9 +219,10 @@ func (b *AuxTxBuilder) GetSignBytes() ([]byte, error) { }) auxBody := &txv1beta1.TxBody{ - Messages: body.Messages, - Memo: body.Memo, - TimeoutHeight: body.TimeoutHeight, + Messages: body.Messages, + Memo: body.Memo, + TimeoutHeight: body.TimeoutHeight, + TimeoutTimestamp: body.TimeoutTimestamp, // AuxTxBuilder has no concern with extension options, so we set them to nil. // This preserves pre-PR#16025 behavior where extension options were ignored, this code path: // https://github.com/cosmos/cosmos-sdk/blob/ac3c209326a26b46f65a6cc6f5b5ebf6beb79b38/client/tx/aux_builder.go#L193 diff --git a/client/tx/factory.go b/client/tx/factory.go index f8c8f9b85b15..7a0006b32b4a 100644 --- a/client/tx/factory.go +++ b/client/tx/factory.go @@ -6,6 +6,7 @@ import ( "math/big" "os" "strings" + "time" "github.com/cosmos/go-bip39" "github.com/spf13/pflag" @@ -33,6 +34,7 @@ type Factory struct { sequence uint64 gas uint64 timeoutHeight uint64 + timeoutTimestamp time.Time gasAdjustment float64 chainID string fromName string @@ -86,6 +88,8 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e gasAdj := clientCtx.Viper.GetFloat64(flags.FlagGasAdjustment) memo := clientCtx.Viper.GetString(flags.FlagNote) + timestampUnix := clientCtx.Viper.GetInt64(flags.FlagTimeoutTimestamp) + timeoutTimestamp := time.Unix(timestampUnix, 0) timeoutHeight := clientCtx.Viper.GetUint64(flags.FlagTimeoutHeight) unordered := clientCtx.Viper.GetBool(flags.FlagUnordered) @@ -105,6 +109,7 @@ func NewFactoryCLI(clientCtx client.Context, flagSet *pflag.FlagSet) (Factory, e accountNumber: accNum, sequence: accSeq, timeoutHeight: timeoutHeight, + timeoutTimestamp: timeoutTimestamp, unordered: unordered, gasAdjustment: gasAdj, memo: memo, @@ -135,6 +140,7 @@ func (f Factory) Fees() sdk.Coins { return f.fees } func (f Factory) GasPrices() sdk.DecCoins { return f.gasPrices } func (f Factory) AccountRetriever() client.AccountRetriever { return f.accountRetriever } func (f Factory) TimeoutHeight() uint64 { return f.timeoutHeight } +func (f Factory) TimeoutTimestamp() time.Time { return f.timeoutTimestamp } func (f Factory) Unordered() bool { return f.unordered } func (f Factory) FromName() string { return f.fromName } @@ -249,6 +255,12 @@ func (f Factory) WithTimeoutHeight(height uint64) Factory { return f } +// WithTimeoutTimestamp returns a copy of the Factory with an updated timeout timestamp. +func (f Factory) WithTimeoutTimestamp(timestamp time.Time) Factory { + f.timeoutTimestamp = timestamp + return f +} + // WithUnordered returns a copy of the Factory with an updated unordered field. func (f Factory) WithUnordered(v bool) Factory { f.unordered = v @@ -332,14 +344,14 @@ func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) { // f.gas is a uint64 and we should convert to LegacyDec // without the risk of under/overflow via uint64->int64. - glDec := math.LegacyNewDecFromBigInt(new(big.Int).SetUint64(f.gas)) + gasLimitDec := math.LegacyNewDecFromBigInt(new(big.Int).SetUint64(f.gas)) // Derive the fees based on the provided gas prices, where // fee = ceil(gasPrice * gasLimit). fees = make(sdk.Coins, len(f.gasPrices)) for i, gp := range f.gasPrices { - fee := gp.Amount.Mul(glDec) + fee := gp.Amount.Mul(gasLimitDec) fees[i] = sdk.NewCoin(gp.Denom, fee.Ceil().RoundInt()) } } @@ -361,6 +373,8 @@ func (f Factory) BuildUnsignedTx(msgs ...sdk.Msg) (client.TxBuilder, error) { tx.SetFeeGranter(f.feeGranter) tx.SetFeePayer(f.feePayer) tx.SetTimeoutHeight(f.TimeoutHeight()) + tx.SetTimeoutTimestamp(f.TimeoutTimestamp()) + tx.SetUnordered(f.Unordered()) if etx, ok := tx.(client.ExtendedTxBuilder); ok { etx.SetExtensionOptions(f.extOptions...) diff --git a/client/tx_config.go b/client/tx_config.go index bc0f1ca81617..44e07cdd7686 100644 --- a/client/tx_config.go +++ b/client/tx_config.go @@ -1,6 +1,8 @@ package client import ( + "time" + txsigning "cosmossdk.io/x/tx/signing" codectypes "github.com/cosmos/cosmos-sdk/codec/types" @@ -48,6 +50,7 @@ type ( SetFeePayer(feePayer sdk.AccAddress) SetGasLimit(limit uint64) SetTimeoutHeight(height uint64) + SetTimeoutTimestamp(timestamp time.Time) SetUnordered(v bool) SetFeeGranter(feeGranter sdk.AccAddress) AddAuxSignerData(tx.AuxSignerData) error diff --git a/go.sum b/go.sum index ed2b3ea67ebf..53c0dbb7ab16 100644 --- a/go.sum +++ b/go.sum @@ -727,7 +727,6 @@ github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtX github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zondax/hid v0.9.2 h1:WCJFnEDMiqGF64nlZz28E9qLVZ0KSJ7xpc5DLEyma2U= github.com/zondax/hid v0.9.2/go.mod h1:l5wttcP0jwtdLjqjMMWFVEE7d1zO0jvSPA9OPZxWpEM= @@ -803,7 +802,6 @@ golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzB golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= @@ -853,7 +851,6 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= @@ -959,7 +956,6 @@ golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= diff --git a/proto/cosmos/tx/v1beta1/tx.proto b/proto/cosmos/tx/v1beta1/tx.proto index 5e7a77df6ea4..ef15fd90d145 100644 --- a/proto/cosmos/tx/v1beta1/tx.proto +++ b/proto/cosmos/tx/v1beta1/tx.proto @@ -8,6 +8,7 @@ import "cosmos/base/v1beta1/coin.proto"; import "cosmos/tx/signing/v1beta1/signing.proto"; import "google/protobuf/any.proto"; import "cosmos_proto/cosmos.proto"; +import "google/protobuf/timestamp.proto"; option go_package = "github.com/cosmos/cosmos-sdk/types/tx"; @@ -111,10 +112,6 @@ message TxBody { // timeout_height is the block height after which this transaction will not // be processed by the chain. - // - // Note, if unordered=true this value MUST be set - // and will act as a short-lived TTL in which the transaction is deemed valid - // and kept in memory to prevent duplicates. uint64 timeout_height = 3; // unordered, when set to true, indicates that the transaction signer(s) @@ -123,11 +120,19 @@ message TxBody { // incremented, which allows for fire-and-forget as well as concurrent // transaction execution. // - // Note, when set to true, the existing 'timeout_height' value must be set and - // will be used to correspond to a height in which the transaction is deemed + // Note, when set to true, the existing 'timeout_height' value must + // be set and will be used to correspond to a timestamp in which the transaction is deemed // valid. bool unordered = 4; + // timeout_timestamp is the block time after which this transaction will not + // be processed by the chain. + // + // Note, if unordered=true this value MUST be set + // and will act as a short-lived TTL in which the transaction is deemed valid + // and kept in memory to prevent duplicates. + google.protobuf.Timestamp timeout_timestamp = 5 [(gogoproto.nullable) = true, (gogoproto.stdtime) = true]; + // extension_options are arbitrary options that can be added by chains // when the default options are not sufficient. If any of these are present // and can't be handled, the transaction will be rejected diff --git a/runtime/app.go b/runtime/app.go index d2803406f028..890b1a5a87a1 100644 --- a/runtime/app.go +++ b/runtime/app.go @@ -25,6 +25,7 @@ import ( servertypes "github.com/cosmos/cosmos-sdk/server/types" sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/module" + "github.com/cosmos/cosmos-sdk/x/auth/ante/unorderedtx" authtx "github.com/cosmos/cosmos-sdk/x/auth/tx" ) @@ -40,7 +41,9 @@ import ( type App struct { *baseapp.BaseApp - ModuleManager *module.Manager + ModuleManager *module.Manager + UnorderedTxManager *unorderedtx.Manager + configurator module.Configurator config *runtimev1alpha1.Module storeKeys []storetypes.StoreKey @@ -157,6 +160,9 @@ func (a *App) Load(loadLatest bool) error { // PreBlocker application updates every pre block func (a *App) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + if a.UnorderedTxManager != nil { + a.UnorderedTxManager.OnNewBlock(ctx.BlockTime()) + } return a.ModuleManager.PreBlock(ctx) } diff --git a/scripts/go-lint-all.bash b/scripts/go-lint-all.bash index c8bb1ea50dae..a94b513659a8 100755 --- a/scripts/go-lint-all.bash +++ b/scripts/go-lint-all.bash @@ -2,6 +2,9 @@ set -e -o pipefail +LINT_TAGS="e2e,ledger,test_ledger_mock,system_test" +export LINT_TAGS + REPO_ROOT="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd )" export REPO_ROOT @@ -10,7 +13,7 @@ lint_module() { shift cd "$(dirname "$root")" && echo "linting $(grep "^module" go.mod) [$(date -Iseconds -u)]" && - golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ + golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ --build-tags=${LINT_TAGS} } export -f lint_module @@ -31,7 +34,7 @@ else for f in $(dirname $(echo "$GIT_DIFF" | tr -d "'") | uniq); do echo "linting $f [$(date -Iseconds -u)]" && cd $f && - golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ && + golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ --build-tags=${LINT_TAGS} && cd $REPO_ROOT done fi \ No newline at end of file diff --git a/scripts/go-lint-changes.bash b/scripts/go-lint-changes.bash index c8bb1ea50dae..ce60b0bd6fe9 100755 --- a/scripts/go-lint-changes.bash +++ b/scripts/go-lint-changes.bash @@ -2,6 +2,10 @@ set -e -o pipefail + +LINT_TAGS="e2e,ledger,test_ledger_mock,system_test" +export LINT_TAGS + REPO_ROOT="$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )/.." &> /dev/null && pwd )" export REPO_ROOT @@ -10,7 +14,7 @@ lint_module() { shift cd "$(dirname "$root")" && echo "linting $(grep "^module" go.mod) [$(date -Iseconds -u)]" && - golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ + golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ --build-tags=${LINT_TAGS} } export -f lint_module @@ -31,7 +35,7 @@ else for f in $(dirname $(echo "$GIT_DIFF" | tr -d "'") | uniq); do echo "linting $f [$(date -Iseconds -u)]" && cd $f && - golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ && + golangci-lint run ./... -c "${REPO_ROOT}/.golangci.yml" "$@" --new-from-rev=HEAD~ --build-tags=${LINT_TAGS} && cd $REPO_ROOT done fi \ No newline at end of file diff --git a/simapp/ante.go b/simapp/ante.go index aaecf5e5ef46..ad2c69a925c1 100644 --- a/simapp/ante.go +++ b/simapp/ante.go @@ -14,7 +14,6 @@ import ( type HandlerOptions struct { ante.HandlerOptions CircuitKeeper circuitante.CircuitBreaker - TxManager *unorderedtx.Manager } // NewAnteHandler returns an AnteHandler that checks and increments sequence @@ -39,7 +38,7 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { ante.NewExtensionOptionsDecorator(options.ExtensionOptionChecker), ante.NewValidateBasicDecorator(), ante.NewTxTimeoutHeightDecorator(), - ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, options.TxManager), + ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, options.UnorderedTxManager, ante.DefaultSha256GasCost), ante.NewValidateMemoDecorator(options.AccountKeeper), ante.NewConsumeGasForTxSizeDecorator(options.AccountKeeper), ante.NewDeductFeeDecorator(options.AccountKeeper, options.BankKeeper, options.FeegrantKeeper, options.TxFeeChecker), diff --git a/simapp/app.go b/simapp/app.go index 2b4d137fc505..234610e9724f 100644 --- a/simapp/app.go +++ b/simapp/app.go @@ -11,11 +11,8 @@ import ( abci "github.com/cometbft/cometbft/abci/types" dbm "github.com/cosmos/cosmos-db" - "github.com/cosmos/cosmos-sdk/x/crisis" - crisistypes "github.com/cosmos/cosmos-sdk/x/crisis/types" "github.com/cosmos/gogoproto/proto" - crisiskeeper "github.com/cosmos/cosmos-sdk/x/crisis/keeper" "github.com/spf13/cast" "github.com/cosmos/cosmos-sdk/x/auth" @@ -104,9 +101,6 @@ import ( "github.com/cosmos/cosmos-sdk/x/consensus" consensusparamkeeper "github.com/cosmos/cosmos-sdk/x/consensus/keeper" consensusparamtypes "github.com/cosmos/cosmos-sdk/x/consensus/types" - distr "github.com/cosmos/cosmos-sdk/x/distribution" - distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper" - distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" "github.com/cosmos/cosmos-sdk/x/genutil" genutiltypes "github.com/cosmos/cosmos-sdk/x/genutil/types" "github.com/cosmos/cosmos-sdk/x/params" @@ -158,7 +152,6 @@ type SimApp struct { BankKeeper bankkeeper.BaseKeeper StakingKeeper *stakingkeeper.Keeper SlashingKeeper slashingkeeper.Keeper - CrisisKeeper *crisiskeeper.Keeper MintKeeper mintkeeper.Keeper DistrKeeper distrkeeper.Keeper GovKeeper govkeeper.Keeper @@ -583,14 +576,14 @@ func (app *SimApp) setAnteHandler(txConfig client.TxConfig) { anteHandler, err := NewAnteHandler( HandlerOptions{ ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - SignModeHandler: txConfig.SignModeHandler(), - FeegrantKeeper: app.FeeGrantKeeper, - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + AccountKeeper: app.AccountKeeper, + BankKeeper: app.BankKeeper, + SignModeHandler: txConfig.SignModeHandler(), + FeegrantKeeper: app.FeeGrantKeeper, + SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + UnorderedTxManager: app.UnorderedTxManager, }, &app.CircuitKeeper, - app.UnorderedTxManager, }, ) if err != nil { @@ -631,6 +624,7 @@ func (app *SimApp) Name() string { return app.BaseApp.Name() } // PreBlocker application updates every pre block func (app *SimApp) PreBlocker(ctx sdk.Context, _ *abci.RequestFinalizeBlock) (*sdk.ResponsePreBlock, error) { + app.UnorderedTxManager.OnNewBlock(ctx.BlockTime()) return app.ModuleManager.PreBlock(ctx) } @@ -791,7 +785,6 @@ func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino paramsKeeper.Subspace(distrtypes.ModuleName) paramsKeeper.Subspace(slashingtypes.ModuleName) paramsKeeper.Subspace(govtypes.ModuleName) - paramsKeeper.Subspace(crisistypes.ModuleName) return paramsKeeper } @@ -820,18 +813,3 @@ func BlockedAddresses() map[string]bool { return modAccAddrs } - -// initParamsKeeper init params keeper and its subspaces -func initParamsKeeper(appCodec codec.BinaryCodec, legacyAmino *codec.LegacyAmino, key, tkey storetypes.StoreKey) paramskeeper.Keeper { - paramsKeeper := paramskeeper.NewKeeper(appCodec, legacyAmino, key, tkey) - - paramsKeeper.Subspace(authtypes.ModuleName) - paramsKeeper.Subspace(banktypes.ModuleName) - paramsKeeper.Subspace(stakingtypes.ModuleName) - paramsKeeper.Subspace(minttypes.ModuleName) - paramsKeeper.Subspace(distrtypes.ModuleName) - paramsKeeper.Subspace(slashingtypes.ModuleName) - paramsKeeper.Subspace(govtypes.ModuleName) - - return paramsKeeper -} diff --git a/simapp/app_di.go b/simapp/app_di.go index 6df94f37c908..8b6264f7ab72 100644 --- a/simapp/app_di.go +++ b/simapp/app_di.go @@ -297,14 +297,14 @@ func (app *SimApp) setAnteHandler(txConfig client.TxConfig) { anteHandler, err := NewAnteHandler( HandlerOptions{ ante.HandlerOptions{ - AccountKeeper: app.AccountKeeper, - BankKeeper: app.BankKeeper, - SignModeHandler: txConfig.SignModeHandler(), - FeegrantKeeper: app.FeeGrantKeeper, - SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + AccountKeeper: app.AccountKeeper, + BankKeeper: app.BankKeeper, + SignModeHandler: txConfig.SignModeHandler(), + FeegrantKeeper: app.FeeGrantKeeper, + SigGasConsumer: ante.DefaultSigVerificationGasConsumer, + UnorderedTxManager: app.UnorderedTxManager, }, &app.CircuitKeeper, - app.UnorderedTxManager, }, ) if err != nil { diff --git a/simapp/go.mod b/simapp/go.mod index 5f398172372f..3f6c66613704 100644 --- a/simapp/go.mod +++ b/simapp/go.mod @@ -214,6 +214,7 @@ require ( // Below are the long-lived replace of the SimApp replace ( + cosmossdk.io/api => ../api // use cosmos fork of keyring github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 // Simapp always use the latest version of the cosmos-sdk diff --git a/simapp/go.sum b/simapp/go.sum index 26fb26bb283e..2b07535d9426 100644 --- a/simapp/go.sum +++ b/simapp/go.sum @@ -182,8 +182,6 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.6 h1:PC20PcXy1xYKH2KU4RMurVoFjjKkCgYRbVAD4PdqUuY= -cosmossdk.io/api v0.7.6/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e h1:NqQEVIjRqSdsAfTI9uDRZ1oU/cQuCoAbUuIkndQM+Bo= cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e/go.mod h1:4p0P6o0ro+FizakJUYS9SeM94RNbv0thLmkHRw5o5as= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= diff --git a/systemtests/system.go b/systemtests/system.go index ccbc9e05f5a4..bf6d50a0cee1 100644 --- a/systemtests/system.go +++ b/systemtests/system.go @@ -22,7 +22,6 @@ import ( client "github.com/cometbft/cometbft/rpc/client/http" ctypes "github.com/cometbft/cometbft/rpc/core/types" tmtypes "github.com/cometbft/cometbft/types" - "github.com/creachadair/tomledit" "github.com/stretchr/testify/require" "github.com/tidwall/sjson" @@ -733,14 +732,6 @@ func (s *SystemUnderTest) AddFullnode(t *testing.T, beforeStart ...func(nodeNumb configFile := filepath.Join(configPath, tomlFile) _ = os.Remove(configFile) _ = MustCopyFile(filepath.Join(WorkDir, s.nodePath(0), "config", tomlFile), configFile) - if tomlFile == "app.toml" && IsV2() { - file := filepath.Join(WorkDir, s.nodePath(nodeNumber), "config", tomlFile) - EditToml(file, func(doc *tomledit.Document) { - SetValue(doc, fmt.Sprintf("%s:%d", node.IP, DefaultApiPort+nodeNumber), "grpc-gateway", "address") - SetValue(doc, fmt.Sprintf("%s:%d", node.IP, DefaultRestPort+nodeNumber), "rest", "address") - SetValue(doc, fmt.Sprintf("%s:%d", node.IP, DefaultTelemetryPort+nodeNumber), "telemetry", "address") - }) - } } peers := make([]string, len(allNodes)-1) for i, n := range allNodes[0 : len(allNodes)-1] { diff --git a/systemtests/testnet_init.go b/systemtests/testnet_init.go index 1e7b41378220..6a74d92ca663 100644 --- a/systemtests/testnet_init.go +++ b/systemtests/testnet_init.go @@ -13,12 +13,6 @@ import ( "github.com/creachadair/tomledit/parser" ) -// IsV2 checks if the tests run with simapp v2 -func IsV2() bool { - buildOptions := os.Getenv("COSMOS_BUILD_OPTIONS") - return strings.Contains(buildOptions, "v2") -} - // SingleHostTestnetCmdInitializer default testnet cmd that supports the --single-host param type SingleHostTestnetCmdInitializer struct { execBinary string @@ -75,12 +69,7 @@ func (s SingleHostTestnetCmdInitializer) Initialize() { "--keyring-backend=test", "--commit-timeout=" + s.commitTimeout.String(), "--single-host", - } - - if IsV2() { - args = append(args, "--server.minimum-gas-prices="+s.minGasPrice) - } else { - args = append(args, "--minimum-gas-prices="+s.minGasPrice) + "--minimum-gas-prices=" + s.minGasPrice, } s.log(fmt.Sprintf("+++ %s %s\n", s.execBinary, strings.Join(args, " "))) @@ -127,12 +116,7 @@ func (s ModifyConfigYamlInitializer) Initialize() { "--output-dir=" + s.outputDir, "--v=" + strconv.Itoa(s.initialNodesCount), "--keyring-backend=test", - } - - if IsV2() { - args = append(args, "--server.minimum-gas-prices="+s.minGasPrice) - } else { - args = append(args, "--minimum-gas-prices="+s.minGasPrice) + "--minimum-gas-prices=" + s.minGasPrice, } s.log(fmt.Sprintf("+++ %s %s\n", s.execBinary, strings.Join(args, " "))) diff --git a/tests/go.mod b/tests/go.mod index 0b9fac5ab68d..fb7676fa2a0e 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -212,6 +212,7 @@ require ( // Below are the long-lived replace for tests. replace ( + cosmossdk.io/api => ../api // We always want to test against the latest version of the simapp. cosmossdk.io/simapp => ../simapp github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0 diff --git a/tests/go.sum b/tests/go.sum index 35962d242c8a..6bf35edeab80 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -182,8 +182,6 @@ cloud.google.com/go/webrisk v1.4.0/go.mod h1:Hn8X6Zr+ziE2aNd8SliSDWpEnSS1u4R9+xX cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= cloud.google.com/go/workflows v1.6.0/go.mod h1:6t9F5h/unJz41YqfBmqSASJSXccBLtD1Vwf+KmJENM0= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= -cosmossdk.io/api v0.7.6 h1:PC20PcXy1xYKH2KU4RMurVoFjjKkCgYRbVAD4PdqUuY= -cosmossdk.io/api v0.7.6/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e h1:NqQEVIjRqSdsAfTI9uDRZ1oU/cQuCoAbUuIkndQM+Bo= cosmossdk.io/client/v2 v2.0.0-beta.5.0.20241121152743-3dad36d9a29e/go.mod h1:4p0P6o0ro+FizakJUYS9SeM94RNbv0thLmkHRw5o5as= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= diff --git a/tests/systemtests/Makefile b/tests/systemtests/Makefile index 7acb110254a7..6680e826ce60 100644 --- a/tests/systemtests/Makefile +++ b/tests/systemtests/Makefile @@ -5,7 +5,7 @@ WAIT_TIME ?= 45s all: test format test: - go test -mod=readonly -failfast -timeout=15m -tags='system_test' ./... --wait-time=$(WAIT_TIME) + go test -mod=readonly -failfast -timeout=15m -tags='system_test' ./... --wait-time=$(WAIT_TIME) --verbose format: find . -name '*.go' -type f -not -path "./vendor*" -not -path "*.git*" -not -path "./client/lcd/statik/statik.go" | xargs gofumpt -w diff --git a/tests/systemtests/go.mod b/tests/systemtests/go.mod index fba855613631..2248c15e1f83 100644 --- a/tests/systemtests/go.mod +++ b/tests/systemtests/go.mod @@ -4,6 +4,11 @@ go 1.23.0 toolchain go1.24.0 +replace ( + cosmossdk.io/api => ../../api + cosmossdk.io/systemtests => ../../systemtests +) + require ( github.com/cosmos/cosmos-proto v1.0.0-beta.5 // indirect github.com/cosmos/cosmos-sdk v0.50.12 // indirect @@ -31,8 +36,6 @@ require ( ) require ( - buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 // indirect - buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 // indirect cosmossdk.io/api v0.8.2 // indirect cosmossdk.io/collections v0.4.0 // indirect cosmossdk.io/core v0.11.0 // indirect @@ -92,7 +95,7 @@ require ( github.com/golang/snappy v0.0.4 // indirect github.com/google/btree v1.1.3 // indirect github.com/google/flatbuffers v1.12.1 // indirect - github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-cmp v0.7.0 // indirect github.com/google/orderedcode v0.0.1 // indirect github.com/gorilla/handlers v1.5.1 // indirect github.com/gorilla/websocket v1.5.3 // indirect @@ -158,14 +161,14 @@ require ( golang.org/x/arch v0.13.0 // indirect golang.org/x/crypto v0.35.0 // indirect golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8 // indirect - golang.org/x/net v0.34.0 // indirect + golang.org/x/net v0.35.0 // indirect golang.org/x/sync v0.11.0 // indirect golang.org/x/sys v0.30.0 // indirect golang.org/x/term v0.29.0 // indirect golang.org/x/text v0.22.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4 // indirect - google.golang.org/protobuf v1.36.4 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b // indirect + google.golang.org/protobuf v1.36.5 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect gotest.tools/v3 v3.5.1 // indirect @@ -173,5 +176,3 @@ require ( pgregory.net/rapid v1.1.0 // indirect sigs.k8s.io/yaml v1.4.0 // indirect ) - -replace cosmossdk.io/systemtests => ../../systemtests diff --git a/tests/systemtests/go.sum b/tests/systemtests/go.sum index 1043646b6adf..7a0687560f08 100644 --- a/tests/systemtests/go.sum +++ b/tests/systemtests/go.sum @@ -1,11 +1,5 @@ -buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1 h1:lcvKfPJ0GTMLh1Ib9n9b3Hx/U2lXj27rb5pujo3EKko= -buf.build/gen/go/cometbft/cometbft/protocolbuffers/go v1.36.4-20241120201313-68e42a58b301.1/go.mod h1:dW1kItnxv+SgI6SBjokdyIZqKl2uhOJahkOqIXDNDC8= -buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1 h1:xn+yVpC5XMvaSQWjfRWmitcYemPznXR7Y65rIMTxoiU= -buf.build/gen/go/cosmos/gogo-proto/protocolbuffers/go v1.36.4-20240130113600-88ef6483f90f.1/go.mod h1:9oTVKh0Ppx5zXStsybi9Zb//6TuLreQxSZqBDE25JGo= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cosmossdk.io/api v0.8.2 h1:klzA1RODd9tTawJ2CbBd/34RV/cB9qtd9oJN6rcRqqg= -cosmossdk.io/api v0.8.2/go.mod h1:XJUwQrihIDjErzs3+jm1zO/9KRzKf4HMjRzXC+l+Cio= cosmossdk.io/collections v0.4.0 h1:PFmwj2W8szgpD5nOd8GWH6AbYNi1f2J6akWXJ7P5t9s= cosmossdk.io/collections v0.4.0/go.mod h1:oa5lUING2dP+gdDquow+QjlF45eL1t4TJDypgGd+tv0= cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= @@ -344,8 +338,8 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= -github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= +github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= github.com/google/gofuzz v0.0.0-20170612174753-24818f796faf/go.mod h1:HP5RmnzzSNb993RKQDq4+1A4ia9nllfqcQFTQJedwGI= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= @@ -845,8 +839,8 @@ golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= -golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= +golang.org/x/net v0.35.0 h1:T5GQRQb2y08kTAByq9L4/bz8cipCdA8FbRTXewonqY8= +golang.org/x/net v0.35.0/go.mod h1:EglIi67kWsHKlRzzVMUD93VMSWGFOMSZgxFjparz1Qk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -975,10 +969,10 @@ google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20220314164441-57ef72a4c106/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a h1:OAiGFfOiA0v9MRYsSidp3ubZaBnteRUyn3xB2ZQ5G/E= -google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a/go.mod h1:jehYqy3+AhJU9ve55aNOaSml7wUXjF9x6z2LcCfpAhY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4 h1:yrTuav+chrF0zF/joFGICKTzYv7mh/gr9AgEXrVU8ao= -google.golang.org/genproto/googleapis/rpc v0.0.0-20250122153221-138b5a5a4fd4/go.mod h1:+2Yz8+CLJbIfL9z73EW45avw8Lmge3xVElCP9zEKi50= +google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b h1:i+d0RZa8Hs2L/MuaOQYI+krthcxdEbEM2N+Tf3kJ4zk= +google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b h1:FQtJ1MxbXoIIrZHZ33M+w5+dAP9o86rgpjoKr/ZmT7k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -1013,8 +1007,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.36.4 h1:6A3ZDJHn/eNqc1i+IdefRzy/9PokBTPvcqMySR7NNIM= -google.golang.org/protobuf v1.36.4/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= +google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= +google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= diff --git a/tests/systemtests/main_test.go b/tests/systemtests/main_test.go index ecded617cc18..9bb4b2277083 100644 --- a/tests/systemtests/main_test.go +++ b/tests/systemtests/main_test.go @@ -1,3 +1,5 @@ +//go:build system_test + package systemtests import ( diff --git a/tests/systemtests/staking_test.go b/tests/systemtests/staking_test.go index 144febc49c66..4e07bf220fa3 100644 --- a/tests/systemtests/staking_test.go +++ b/tests/systemtests/staking_test.go @@ -1,3 +1,5 @@ +//go:build system_test + package systemtests import ( diff --git a/tests/systemtests/unordered_tx_test.go b/tests/systemtests/unordered_tx_test.go new file mode 100644 index 000000000000..528bf3bd33a8 --- /dev/null +++ b/tests/systemtests/unordered_tx_test.go @@ -0,0 +1,54 @@ +//go:build system_test + +package systemtests + +import ( + "fmt" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "github.com/tidwall/gjson" + + systest "cosmossdk.io/systemtests" +) + +func TestUnorderedTXDuplicate(t *testing.T) { + // scenario: test unordered tx duplicate + // given a running chain with a tx in the unordered tx pool + // when a new tx with the same hash is broadcasted + // then the new tx should be rejected + + systest.Sut.ResetChain(t) + cli := systest.NewCLIWrapper(t, systest.Sut, systest.Verbose) + // add genesis account with some tokens + account1Addr := cli.AddKey("account1") + account2Addr := cli.AddKey("account2") + systest.Sut.ModifyGenesisCLI(t, + []string{"genesis", "add-genesis-account", account1Addr, "10000000stake"}, + ) + + systest.Sut.StartChain(t) + + timeoutTimestamp := time.Now().Add(time.Minute) + // send tokens + cmd := []string{"tx", "bank", "send", account1Addr, account2Addr, "5000stake", "--from=" + account1Addr, "--fees=1stake", fmt.Sprintf("--timeout-timestamp=%v", timeoutTimestamp.Unix()), "--unordered", "--sequence=1", "--note=1"} + rsp1 := cli.Run(cmd...) + systest.RequireTxSuccess(t, rsp1) + + assertDuplicateErr := func(xt assert.TestingT, gotErr error, gotOutputs ...interface{}) bool { + require.Len(t, gotOutputs, 1) + output := gotOutputs[0].(string) + code := gjson.Get(output, "code") + require.True(t, code.Exists()) + require.Equal(t, int64(19), code.Int()) // 19 == already in mempool. + return false // always abort + } + rsp2 := cli.WithRunErrorMatcher(assertDuplicateErr).Run(cmd...) + systest.RequireTxFailure(t, rsp2) + + require.Eventually(t, func() bool { + return cli.QueryBalance(account2Addr, "stake") == 5000 + }, 10*systest.Sut.BlockTime(), 200*time.Millisecond, "TX was not executed before timeout") +} diff --git a/types/errors/errors.go b/types/errors/errors.go index 5e17f2df481a..36bb82ffd957 100644 --- a/types/errors/errors.go +++ b/types/errors/errors.go @@ -142,4 +142,8 @@ var ( // ErrPanic should only be set when we recovering from a panic ErrPanic = errorsmod.ErrPanic + + // ErrTxTimeout defines an error for when a tx is rejected out due to an + // explicitly set timeout timestamp. + ErrTxTimeout = errorsmod.Register(RootCodespace, 42, "tx timeout") ) diff --git a/types/mempool/mempool_test.go b/types/mempool/mempool_test.go index 05f61e46decd..e27ba8dcac0b 100644 --- a/types/mempool/mempool_test.go +++ b/types/mempool/mempool_test.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "testing" + "time" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/stretchr/testify/require" @@ -52,6 +53,21 @@ type testTx struct { address sdk.AccAddress // useful for debugging strAddress string + unordered bool + timeout *time.Time +} + +// GetTimeoutTimeStamp implements types.TxWithUnordered. +func (tx testTx) GetTimeoutTimeStamp() time.Time { + if tx.timeout == nil { + return time.Time{} + } + return *tx.timeout +} + +// GetUnordered implements types.TxWithUnordered. +func (tx testTx) GetUnordered() bool { + return tx.unordered } func (tx testTx) GetSigners() ([][]byte, error) { panic("not implemented") } diff --git a/types/mempool/priority_nonce.go b/types/mempool/priority_nonce.go index ba09f37cdbbe..4d0735cfd8dc 100644 --- a/types/mempool/priority_nonce.go +++ b/types/mempool/priority_nonce.go @@ -2,6 +2,7 @@ package mempool import ( "context" + "errors" "fmt" "math" "sync" @@ -222,6 +223,16 @@ func (mp *PriorityNonceMempool[C]) Insert(ctx context.Context, tx sdk.Tx) error sender := sig.Signer.String() priority := mp.cfg.TxPriority.GetTxPriority(ctx, tx) nonce := sig.Sequence + + // if it's an unordered tx, we use the timeout timestamp instead of the nonce + if unordered, ok := tx.(sdk.TxWithUnordered); ok && unordered.GetUnordered() { + timestamp := unordered.GetTimeoutTimeStamp().Unix() + if timestamp < 0 { + return errors.New("invalid timestamp value") + } + nonce = uint64(timestamp) + } + key := txMeta[C]{nonce: nonce, priority: priority, sender: sender} senderIndex, ok := mp.senderIndices[sender] @@ -458,6 +469,15 @@ func (mp *PriorityNonceMempool[C]) Remove(tx sdk.Tx) error { sender := sig.Signer.String() nonce := sig.Sequence + // if it's an unordered tx, we use the timeout timestamp instead of the nonce + if unordered, ok := tx.(sdk.TxWithUnordered); ok && unordered.GetUnordered() { + timestamp := unordered.GetTimeoutTimeStamp().Unix() + if timestamp < 0 { + return errors.New("invalid timestamp value") + } + nonce = uint64(timestamp) + } + scoreKey := txMeta[C]{nonce: nonce, sender: sender} score, ok := mp.scores[scoreKey] if !ok { diff --git a/types/mempool/priority_nonce_test.go b/types/mempool/priority_nonce_test.go index 96a047364e8a..1a0fd657f297 100644 --- a/types/mempool/priority_nonce_test.go +++ b/types/mempool/priority_nonce_test.go @@ -976,3 +976,40 @@ func TestNextSenderTx_TxReplacement(t *testing.T) { iter := mp.Select(ctx, nil) require.Equal(t, txs[3], iter.Tx()) } + +func TestPriorityNonceMempool_UnorderedTx(t *testing.T) { + ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger()) + accounts := simtypes.RandomAccounts(rand.New(rand.NewSource(0)), 2) + sa := accounts[0].Address + sb := accounts[1].Address + + mp := mempool.DefaultPriorityMempool() + + now := time.Now() + oneHour := now.Add(1 * time.Hour) + thirtyMin := now.Add(30 * time.Minute) + twoHours := now.Add(2 * time.Hour) + fifteenMin := now.Add(15 * time.Minute) + + txs := []testTx{ + {id: 1, priority: 0, address: sa, timeout: &thirtyMin, unordered: true}, + {id: 0, priority: 0, address: sa, timeout: &oneHour, unordered: true}, + {id: 3, priority: 0, address: sb, timeout: &fifteenMin, unordered: true}, + {id: 2, priority: 0, address: sb, timeout: &twoHours, unordered: true}, + } + + for _, tx := range txs { + c := ctx.WithPriority(tx.priority) + require.NoError(t, mp.Insert(c, tx)) + } + + require.Equal(t, 4, mp.CountTx()) + + orderedTxs := fetchTxs(mp.Select(ctx, nil), 100000) + require.Equal(t, len(txs), len(orderedTxs)) + + // check order + for i, tx := range orderedTxs { + require.Equal(t, txs[i].id, tx.(testTx).id) + } +} diff --git a/types/mempool/sender_nonce.go b/types/mempool/sender_nonce.go index 15d0d079105e..68959970760e 100644 --- a/types/mempool/sender_nonce.go +++ b/types/mempool/sender_nonce.go @@ -4,6 +4,7 @@ import ( "context" crand "crypto/rand" // #nosec // crypto/rand is used for seed generation "encoding/binary" + "errors" "fmt" "math/rand" // #nosec // math/rand is used for random selection and seeded from crypto/rand "sync" @@ -139,6 +140,15 @@ func (snm *SenderNonceMempool) Insert(_ context.Context, tx sdk.Tx) error { sender := sdk.AccAddress(sig.PubKey.Address()).String() nonce := sig.Sequence + // if it's an unordered tx, we use the timeout timestamp instead of the nonce + if unordered, ok := tx.(sdk.TxWithUnordered); ok && unordered.GetUnordered() { + timestamp := unordered.GetTimeoutTimeStamp().Unix() + if timestamp < 0 { + return errors.New("invalid timestamp value") + } + nonce = uint64(timestamp) + } + senderTxs, found := snm.senders[sender] if !found { senderTxs = skiplist.New(skiplist.Uint64) @@ -227,6 +237,15 @@ func (snm *SenderNonceMempool) Remove(tx sdk.Tx) error { sender := sdk.AccAddress(sig.PubKey.Address()).String() nonce := sig.Sequence + // if it's an unordered tx, we use the timeout timestamp instead of the nonce + if unordered, ok := tx.(sdk.TxWithUnordered); ok && unordered.GetUnordered() { + timestamp := unordered.GetTimeoutTimeStamp().Unix() + if timestamp < 0 { + return errors.New("invalid timestamp value") + } + nonce = uint64(timestamp) + } + senderTxs, found := snm.senders[sender] if !found { return ErrTxNotFound diff --git a/types/mempool/sender_nonce_test.go b/types/mempool/sender_nonce_test.go index 4e6b10cd7e80..cf39de452f72 100644 --- a/types/mempool/sender_nonce_test.go +++ b/types/mempool/sender_nonce_test.go @@ -4,6 +4,7 @@ import ( "fmt" "math/rand" "testing" + "time" cmtproto "github.com/cometbft/cometbft/proto/tendermint/types" "github.com/stretchr/testify/require" @@ -193,3 +194,67 @@ func (s *MempoolTestSuite) TestTxNotFoundOnSender() { err = mp.Remove(tx) require.Equal(t, mempool.ErrTxNotFound, err) } + +func (s *MempoolTestSuite) TestUnorderedTx() { + t := s.T() + + ctx := sdk.NewContext(nil, cmtproto.Header{}, false, log.NewNopLogger()) + accounts := simtypes.RandomAccounts(rand.New(rand.NewSource(0)), 2) + sa := accounts[0].Address + sb := accounts[1].Address + + mp := mempool.NewSenderNonceMempool(mempool.SenderNonceMaxTxOpt(5000)) + + now := time.Now() + oneHour := now.Add(1 * time.Hour) + thirtyMin := now.Add(30 * time.Minute) + twoHours := now.Add(2 * time.Hour) + fifteenMin := now.Add(15 * time.Minute) + + txs := []testTx{ + {id: 0, address: sa, timeout: &oneHour, unordered: true}, + {id: 1, address: sa, timeout: &thirtyMin, unordered: true}, + {id: 2, address: sb, timeout: &twoHours, unordered: true}, + {id: 3, address: sb, timeout: &fifteenMin, unordered: true}, + } + + for _, tx := range txs { + c := ctx.WithPriority(tx.priority) + require.NoError(t, mp.Insert(c, tx)) + } + + require.Equal(t, 4, mp.CountTx()) + + orderedTxs := fetchTxs(mp.Select(ctx, nil), 100000) + require.Equal(t, len(txs), len(orderedTxs)) + + // Because the sender is selected randomly it can be any of these options + acceptableOptions := [][]int{ + {3, 1, 2, 0}, + {3, 1, 0, 2}, + {3, 2, 1, 0}, + {1, 3, 0, 2}, + {1, 3, 2, 0}, + {1, 0, 3, 2}, + } + + orderedTxsIds := make([]int, len(orderedTxs)) + for i, tx := range orderedTxs { + orderedTxsIds[i] = tx.(testTx).id + } + + anyAcceptableOrder := false + for _, option := range acceptableOptions { + for i, tx := range orderedTxs { + if tx.(testTx).id != txs[option[i]].id { + break + } + + if i == len(orderedTxs)-1 { + anyAcceptableOrder = true + } + } + } + + require.True(t, anyAcceptableOrder, "expected any of %v but got %v", acceptableOptions, orderedTxsIds) +} diff --git a/types/tx/tx.pb.go b/types/tx/tx.pb.go index 5e7a992f12cf..62e142faa27f 100644 --- a/types/tx/tx.pb.go +++ b/types/tx/tx.pb.go @@ -14,15 +14,19 @@ import ( signing "github.com/cosmos/cosmos-sdk/types/tx/signing" _ "github.com/cosmos/gogoproto/gogoproto" proto "github.com/cosmos/gogoproto/proto" + github_com_cosmos_gogoproto_types "github.com/cosmos/gogoproto/types" + _ "google.golang.org/protobuf/types/known/timestamppb" io "io" math "math" math_bits "math/bits" + time "time" ) // Reference imports to suppress errors if they are not otherwise used. var _ = proto.Marshal var _ = fmt.Errorf var _ = math.Inf +var _ = time.Kitchen // This is a compile-time assertion to ensure that this generated file // is compatible with the proto package it is being compiled against. @@ -361,10 +365,6 @@ type TxBody struct { Memo string `protobuf:"bytes,2,opt,name=memo,proto3" json:"memo,omitempty"` // timeout_height is the block height after which this transaction will not // be processed by the chain. - // - // Note, if unordered=true this value MUST be set - // and will act as a short-lived TTL in which the transaction is deemed valid - // and kept in memory to prevent duplicates. TimeoutHeight uint64 `protobuf:"varint,3,opt,name=timeout_height,json=timeoutHeight,proto3" json:"timeout_height,omitempty"` // unordered, when set to true, indicates that the transaction signer(s) // intend for the transaction to be evaluated and executed in an un-ordered @@ -372,10 +372,17 @@ type TxBody struct { // incremented, which allows for fire-and-forget as well as concurrent // transaction execution. // - // Note, when set to true, the existing 'timeout_height' value must be set and - // will be used to correspond to a height in which the transaction is deemed + // Note, when set to true, the existing 'timeout_height' value must + // be set and will be used to correspond to a timestamp in which the transaction is deemed // valid. Unordered bool `protobuf:"varint,4,opt,name=unordered,proto3" json:"unordered,omitempty"` + // timeout_timestamp is the block time after which this transaction will not + // be processed by the chain. + // + // Note, if unordered=true this value MUST be set + // and will act as a short-lived TTL in which the transaction is deemed valid + // and kept in memory to prevent duplicates. + TimeoutTimestamp *time.Time `protobuf:"bytes,5,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3,stdtime" json:"timeout_timestamp,omitempty"` // extension_options are arbitrary options that can be added by chains // when the default options are not sufficient. If any of these are present // and can't be handled, the transaction will be rejected @@ -447,6 +454,13 @@ func (m *TxBody) GetUnordered() bool { return false } +func (m *TxBody) GetTimeoutTimestamp() *time.Time { + if m != nil { + return m.TimeoutTimestamp + } + return nil +} + func (m *TxBody) GetExtensionOptions() []*types.Any { if m != nil { return m.ExtensionOptions @@ -1044,75 +1058,77 @@ func init() { func init() { proto.RegisterFile("cosmos/tx/v1beta1/tx.proto", fileDescriptor_96d1575ffde80842) } var fileDescriptor_96d1575ffde80842 = []byte{ - // 1076 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0x41, 0x6f, 0x1b, 0xc5, - 0x17, 0xf7, 0x7a, 0x6d, 0xc7, 0x7e, 0x4d, 0xda, 0x64, 0x14, 0xfd, 0xe5, 0x38, 0xff, 0xba, 0xc1, - 0x55, 0xc1, 0xaa, 0xc8, 0x6e, 0x9b, 0x1e, 0x28, 0x15, 0x02, 0xec, 0x86, 0x28, 0x55, 0x29, 0x48, - 0x93, 0x9c, 0x7a, 0x59, 0x8d, 0x77, 0x27, 0xeb, 0x51, 0xbd, 0x33, 0xcb, 0xce, 0x2c, 0x78, 0x8f, - 0x7c, 0x00, 0xa4, 0x8a, 0x0b, 0x12, 0x67, 0x0e, 0x88, 0x53, 0x25, 0x10, 0x9f, 0xa1, 0x27, 0x54, - 0x71, 0xe2, 0x04, 0x55, 0x72, 0xe8, 0x9d, 0x2f, 0x00, 0xda, 0xd9, 0x59, 0x27, 0x2d, 0xa9, 0x53, - 0x04, 0x12, 0x17, 0x7b, 0xe6, 0xed, 0xef, 0xbd, 0xf9, 0xbd, 0x37, 0xbf, 0x79, 0x0f, 0x3a, 0xbe, - 0x90, 0x91, 0x90, 0xae, 0x9a, 0xba, 0x9f, 0x5e, 0x1f, 0x51, 0x45, 0xae, 0xbb, 0x6a, 0xea, 0xc4, - 0x89, 0x50, 0x02, 0xad, 0x14, 0xdf, 0x1c, 0x35, 0x75, 0xcc, 0xb7, 0xce, 0x0a, 0x89, 0x18, 0x17, - 0xae, 0xfe, 0x2d, 0x50, 0x9d, 0xd5, 0x50, 0x84, 0x42, 0x2f, 0xdd, 0x7c, 0x65, 0xac, 0x9b, 0x26, - 0xae, 0x9f, 0x64, 0xb1, 0x12, 0x6e, 0x94, 0x4e, 0x14, 0x93, 0x2c, 0x9c, 0x1d, 0x52, 0x1a, 0x0c, - 0xbc, 0x6b, 0xe0, 0x23, 0x22, 0xe9, 0x0c, 0xe3, 0x0b, 0xc6, 0xcd, 0xf7, 0x37, 0x8e, 0x69, 0x4a, - 0x16, 0x72, 0xc6, 0x8f, 0x23, 0x99, 0xbd, 0x01, 0xae, 0x85, 0x42, 0x84, 0x13, 0xea, 0xea, 0xdd, - 0x28, 0x3d, 0x70, 0x09, 0xcf, 0xca, 0x4f, 0x45, 0x0c, 0xaf, 0xe0, 0x6a, 0x72, 0xd3, 0x9b, 0xde, - 0x17, 0x16, 0x54, 0xf7, 0xa7, 0x68, 0x13, 0x6a, 0x23, 0x11, 0x64, 0x6d, 0x6b, 0xc3, 0xea, 0x9f, - 0xdb, 0x5a, 0x73, 0xfe, 0x92, 0xbf, 0xb3, 0x3f, 0x1d, 0x8a, 0x20, 0xc3, 0x1a, 0x86, 0x6e, 0x42, - 0x8b, 0xa4, 0x6a, 0xec, 0x31, 0x7e, 0x20, 0xda, 0x55, 0xed, 0xb3, 0x7e, 0x8a, 0xcf, 0x20, 0x55, - 0xe3, 0x3b, 0xfc, 0x40, 0xe0, 0x26, 0x31, 0x2b, 0xd4, 0x05, 0xc8, 0x69, 0x13, 0x95, 0x26, 0x54, - 0xb6, 0xed, 0x0d, 0xbb, 0xbf, 0x88, 0x4f, 0x58, 0x7a, 0x1c, 0xea, 0xfb, 0x53, 0x4c, 0x3e, 0x43, - 0x17, 0x01, 0xf2, 0xa3, 0xbc, 0x51, 0xa6, 0xa8, 0xd4, 0xbc, 0x16, 0x71, 0x2b, 0xb7, 0x0c, 0x73, - 0x03, 0x7a, 0x1d, 0x2e, 0xcc, 0x18, 0x18, 0x4c, 0x55, 0x63, 0x96, 0xca, 0xa3, 0x0a, 0xdc, 0x59, - 0xe7, 0x7d, 0x69, 0xc1, 0xc2, 0x1e, 0x0b, 0xf9, 0xb6, 0xf0, 0xff, 0xad, 0x23, 0xd7, 0xa0, 0xe9, - 0x8f, 0x09, 0xe3, 0x1e, 0x0b, 0xda, 0xf6, 0x86, 0xd5, 0x6f, 0xe1, 0x05, 0xbd, 0xbf, 0x13, 0xa0, - 0x2b, 0x70, 0x9e, 0xf8, 0xbe, 0x48, 0xb9, 0xf2, 0x78, 0x1a, 0x8d, 0x68, 0xd2, 0xae, 0x6d, 0x58, - 0xfd, 0x1a, 0x5e, 0x32, 0xd6, 0x8f, 0xb4, 0xb1, 0xf7, 0xbb, 0x05, 0xcb, 0x86, 0xd4, 0x36, 0x4b, - 0xa8, 0xaf, 0x06, 0xe9, 0xf4, 0x2c, 0x76, 0x37, 0x00, 0xe2, 0x74, 0x34, 0x61, 0xbe, 0xf7, 0x80, - 0x66, 0xe6, 0x4e, 0x56, 0x9d, 0x42, 0x13, 0x4e, 0xa9, 0x09, 0x67, 0xc0, 0x33, 0xdc, 0x2a, 0x70, - 0x77, 0x69, 0xf6, 0xcf, 0xa9, 0xa2, 0x0e, 0x34, 0x25, 0xfd, 0x24, 0xa5, 0xdc, 0xa7, 0xed, 0xba, - 0x06, 0xcc, 0xf6, 0xe8, 0x4d, 0xb0, 0x15, 0x8b, 0xdb, 0x0d, 0xcd, 0xe5, 0x7f, 0xa7, 0x69, 0x8a, - 0xc5, 0xc3, 0x6a, 0xdb, 0xc2, 0x39, 0xac, 0xf7, 0x7d, 0x15, 0x1a, 0x85, 0xc8, 0xd0, 0x35, 0x68, - 0x46, 0x54, 0x4a, 0x12, 0xea, 0x44, 0xed, 0x97, 0x66, 0x32, 0x43, 0x21, 0x04, 0xb5, 0x88, 0x46, - 0x85, 0x16, 0x5b, 0x58, 0xaf, 0xf3, 0x0c, 0x14, 0x8b, 0xa8, 0x48, 0x95, 0x37, 0xa6, 0x2c, 0x1c, - 0x2b, 0x9d, 0x62, 0x0d, 0x2f, 0x19, 0xeb, 0xae, 0x36, 0xa2, 0xff, 0x43, 0x2b, 0xe5, 0x22, 0x09, - 0x68, 0x42, 0x03, 0x9d, 0x63, 0x13, 0x1f, 0x1b, 0xd0, 0x10, 0x56, 0xe8, 0x54, 0x51, 0x2e, 0x99, - 0xe0, 0x9e, 0x88, 0x15, 0x13, 0x5c, 0xb6, 0xff, 0x58, 0x98, 0x43, 0x6a, 0x79, 0x86, 0xff, 0xb8, - 0x80, 0xa3, 0xfb, 0xd0, 0xe5, 0x82, 0x7b, 0x7e, 0xc2, 0x14, 0xf3, 0xc9, 0xc4, 0x3b, 0x25, 0xe0, - 0x85, 0x39, 0x01, 0xd7, 0xb9, 0xe0, 0xb7, 0x8d, 0xef, 0x07, 0x2f, 0xc4, 0xee, 0x7d, 0x63, 0x41, - 0xb3, 0x7c, 0x66, 0xe8, 0x7d, 0x58, 0xcc, 0xa5, 0x4d, 0x13, 0xad, 0xd1, 0xb2, 0x76, 0x17, 0x4f, - 0xa9, 0xfc, 0x9e, 0x86, 0xe9, 0xb7, 0x79, 0x4e, 0xce, 0xd6, 0x12, 0xf5, 0xc1, 0x3e, 0xa0, 0xd4, - 0xc8, 0xe7, 0xb4, 0x2b, 0xdb, 0xa1, 0x14, 0xe7, 0x90, 0xf2, 0x72, 0xed, 0x57, 0xbb, 0xdc, 0xaf, - 0x2c, 0x80, 0xe3, 0x33, 0x5f, 0x10, 0xab, 0xf5, 0x6a, 0x62, 0xbd, 0x09, 0xad, 0x48, 0x04, 0xf4, - 0xac, 0xa6, 0x73, 0x4f, 0x04, 0xb4, 0x68, 0x3a, 0x91, 0x59, 0x3d, 0x27, 0x52, 0xfb, 0x79, 0x91, - 0xf6, 0x9e, 0x56, 0xa1, 0x59, 0xba, 0xa0, 0x77, 0xa0, 0x21, 0x19, 0x0f, 0x27, 0xd4, 0x70, 0xea, - 0xcd, 0x89, 0xef, 0xec, 0x69, 0xe4, 0x6e, 0x05, 0x1b, 0x1f, 0xf4, 0x36, 0xd4, 0x75, 0x73, 0x37, - 0xe4, 0x5e, 0x9b, 0xe7, 0x7c, 0x2f, 0x07, 0xee, 0x56, 0x70, 0xe1, 0xd1, 0x19, 0x40, 0xa3, 0x08, - 0x87, 0xde, 0x82, 0x5a, 0xce, 0x5b, 0x13, 0x38, 0xbf, 0x75, 0xf9, 0x44, 0x8c, 0xb2, 0xdd, 0x9f, - 0xbc, 0xc3, 0x3c, 0x1e, 0xd6, 0x0e, 0x9d, 0x87, 0x16, 0xd4, 0x75, 0x54, 0x74, 0x17, 0x9a, 0x23, - 0xa6, 0x48, 0x92, 0x90, 0xb2, 0xb6, 0x6e, 0x19, 0xa6, 0x18, 0x4a, 0xce, 0x6c, 0x06, 0x95, 0xb1, - 0x6e, 0x8b, 0x28, 0x26, 0xbe, 0x1a, 0x32, 0x35, 0xc8, 0xdd, 0xf0, 0x2c, 0x00, 0xba, 0x05, 0x30, - 0xab, 0x7a, 0xde, 0xf0, 0xec, 0xb3, 0xca, 0xde, 0x2a, 0xcb, 0x2e, 0x87, 0x75, 0xb0, 0x65, 0x1a, - 0xf5, 0x3e, 0xaf, 0x82, 0xbd, 0x43, 0x29, 0xca, 0xa0, 0x41, 0xa2, 0xbc, 0x77, 0x18, 0x61, 0xce, - 0xc6, 0x4c, 0x3e, 0xfb, 0x4e, 0x50, 0x61, 0x7c, 0xb8, 0xf3, 0xf8, 0xd7, 0x4b, 0x95, 0xef, 0x7e, - 0xbb, 0xd4, 0x0f, 0x99, 0x1a, 0xa7, 0x23, 0xc7, 0x17, 0x91, 0x5b, 0xce, 0x55, 0xfd, 0xb7, 0x29, - 0x83, 0x07, 0xae, 0xca, 0x62, 0x2a, 0xb5, 0x83, 0xfc, 0xfa, 0xd9, 0xa3, 0xab, 0x8b, 0x13, 0x1a, - 0x12, 0x3f, 0xf3, 0xf2, 0xe9, 0x29, 0xbf, 0x7d, 0xf6, 0xe8, 0xaa, 0x85, 0xcd, 0x81, 0x68, 0x1d, - 0x5a, 0x21, 0x91, 0xde, 0x84, 0x45, 0x4c, 0xe9, 0xeb, 0xa9, 0xe1, 0x66, 0x48, 0xe4, 0x87, 0xf9, - 0x1e, 0x39, 0x50, 0x8f, 0x49, 0x46, 0x93, 0xa2, 0x05, 0x0e, 0xdb, 0x3f, 0xff, 0xb0, 0xb9, 0x6a, - 0x98, 0x0d, 0x82, 0x20, 0xa1, 0x52, 0xee, 0xa9, 0x84, 0xf1, 0x10, 0x17, 0x30, 0xb4, 0x05, 0x0b, - 0x61, 0x42, 0xb8, 0x32, 0x3d, 0x71, 0x9e, 0x47, 0x09, 0xec, 0xfd, 0x68, 0x81, 0xbd, 0xcf, 0xe2, - 0xff, 0xb2, 0x06, 0xd7, 0xa0, 0xa1, 0x58, 0x1c, 0xd3, 0xa4, 0xe8, 0x92, 0x73, 0x58, 0x1b, 0xdc, - 0xad, 0x6a, 0xdb, 0xea, 0xfd, 0x64, 0xc1, 0xd2, 0x20, 0x9d, 0x16, 0x8f, 0x77, 0x9b, 0x28, 0x92, - 0xa7, 0x4f, 0x0a, 0xb8, 0x56, 0xd7, 0xdc, 0xf4, 0x0d, 0x10, 0xbd, 0x0b, 0xcd, 0x5c, 0xbe, 0x5e, - 0x20, 0x7c, 0xf3, 0x3a, 0x2e, 0xbf, 0xa4, 0x2b, 0x9d, 0x9c, 0x79, 0x78, 0x41, 0x9a, 0xd1, 0x5c, - 0xbe, 0x0a, 0xfb, 0x6f, 0xbe, 0x0a, 0xb4, 0x0c, 0xb6, 0x64, 0xa1, 0xbe, 0xa7, 0x45, 0x9c, 0x2f, - 0x87, 0xef, 0x3d, 0x3e, 0xec, 0x5a, 0x4f, 0x0e, 0xbb, 0xd6, 0xd3, 0xc3, 0xae, 0xf5, 0xf0, 0xa8, - 0x5b, 0x79, 0x72, 0xd4, 0xad, 0xfc, 0x72, 0xd4, 0xad, 0xdc, 0xbf, 0x72, 0x76, 0xa1, 0x5d, 0x35, - 0x1d, 0x35, 0x74, 0x83, 0xba, 0xf1, 0x67, 0x00, 0x00, 0x00, 0xff, 0xff, 0xb1, 0x48, 0xf7, 0x44, - 0x41, 0x0a, 0x00, 0x00, + // 1120 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x55, 0xc1, 0x6f, 0x1b, 0xc5, + 0x17, 0xf6, 0x7a, 0x6d, 0xc7, 0x7e, 0x4d, 0xda, 0x64, 0x54, 0xfd, 0xe4, 0x3a, 0xbf, 0x3a, 0xc1, + 0x55, 0xc1, 0xaa, 0xc8, 0x6e, 0x9b, 0x1e, 0x28, 0x15, 0x02, 0xec, 0x86, 0x28, 0x55, 0x29, 0x88, + 0x4d, 0x4e, 0xbd, 0xac, 0xc6, 0xbb, 0x93, 0xf5, 0xa8, 0xde, 0x99, 0x65, 0x67, 0x16, 0xbc, 0x47, + 0x2e, 0xdc, 0x90, 0x22, 0x2e, 0x48, 0x9c, 0x39, 0x20, 0x4e, 0x3d, 0x20, 0xfe, 0x86, 0x9c, 0x50, + 0xc5, 0x89, 0x53, 0x5b, 0x25, 0x87, 0xde, 0xf9, 0x07, 0x40, 0x3b, 0x3b, 0xbb, 0x49, 0xd3, 0xd4, + 0x29, 0x02, 0x89, 0x8b, 0x3d, 0xfb, 0xe6, 0x7b, 0x6f, 0xbe, 0x37, 0xf3, 0xbd, 0xf7, 0xa0, 0xe3, + 0x71, 0x11, 0x72, 0x61, 0xcb, 0xa9, 0xfd, 0xc5, 0x8d, 0x11, 0x91, 0xf8, 0x86, 0x2d, 0xa7, 0x56, + 0x14, 0x73, 0xc9, 0xd1, 0x52, 0xbe, 0x67, 0xc9, 0xa9, 0xa5, 0xf7, 0x3a, 0x4b, 0x38, 0xa4, 0x8c, + 0xdb, 0xea, 0x37, 0x47, 0x75, 0x2e, 0x06, 0x3c, 0xe0, 0x6a, 0x69, 0x67, 0x2b, 0x6d, 0x5d, 0xd3, + 0x71, 0xbd, 0x38, 0x8d, 0x24, 0xb7, 0xc3, 0x64, 0x22, 0xa9, 0xa0, 0x41, 0x79, 0x48, 0x61, 0xd0, + 0xf0, 0xae, 0x86, 0x8f, 0xb0, 0x20, 0x25, 0xc6, 0xe3, 0x94, 0xe9, 0xfd, 0xb7, 0x8e, 0x68, 0x0a, + 0x1a, 0x30, 0xca, 0x8e, 0x22, 0xe9, 0x6f, 0x0d, 0xbc, 0x14, 0x70, 0x1e, 0x4c, 0x88, 0xad, 0xbe, + 0x46, 0xc9, 0xae, 0x8d, 0x59, 0x5a, 0x6c, 0xe5, 0x31, 0xdc, 0x9c, 0xab, 0xce, 0x2d, 0xdf, 0x5a, + 0x39, 0xe9, 0x25, 0x69, 0x48, 0x84, 0xc4, 0x61, 0x94, 0x03, 0x7a, 0xdf, 0x18, 0x50, 0xdd, 0x99, + 0xa2, 0x35, 0xa8, 0x8d, 0xb8, 0x9f, 0xb6, 0x8d, 0x55, 0xa3, 0x7f, 0x6e, 0xfd, 0x92, 0xf5, 0xd2, + 0x05, 0x59, 0x3b, 0xd3, 0x21, 0xf7, 0x53, 0x47, 0xc1, 0xd0, 0x2d, 0x68, 0xe1, 0x44, 0x8e, 0x5d, + 0xca, 0x76, 0x79, 0xbb, 0xaa, 0x7c, 0x96, 0x4f, 0xf1, 0x19, 0x24, 0x72, 0x7c, 0x97, 0xed, 0x72, + 0xa7, 0x89, 0xf5, 0x0a, 0x75, 0x01, 0xb2, 0xbc, 0xb0, 0x4c, 0x62, 0x22, 0xda, 0xe6, 0xaa, 0xd9, + 0x9f, 0x77, 0x8e, 0x59, 0x7a, 0x0c, 0xea, 0x3b, 0x53, 0x07, 0x7f, 0x89, 0x2e, 0x03, 0x64, 0x47, + 0xb9, 0xa3, 0x54, 0x12, 0xa1, 0x78, 0xcd, 0x3b, 0xad, 0xcc, 0x32, 0xcc, 0x0c, 0xe8, 0x4d, 0xb8, + 0x50, 0x32, 0xd0, 0x98, 0xaa, 0xc2, 0x2c, 0x14, 0x47, 0xe5, 0xb8, 0xb3, 0xce, 0xfb, 0xd6, 0x80, + 0xb9, 0x6d, 0x1a, 0xb0, 0x0d, 0xee, 0xfd, 0x5b, 0x47, 0x5e, 0x82, 0xa6, 0x37, 0xc6, 0x94, 0xb9, + 0xd4, 0x6f, 0x9b, 0xab, 0x46, 0xbf, 0xe5, 0xcc, 0xa9, 0xef, 0xbb, 0x3e, 0xba, 0x0a, 0xe7, 0xb1, + 0xe7, 0xf1, 0x84, 0x49, 0x97, 0x25, 0xe1, 0x88, 0xc4, 0xed, 0xda, 0xaa, 0xd1, 0xaf, 0x39, 0x0b, + 0xda, 0xfa, 0x89, 0x32, 0xf6, 0xfe, 0x30, 0x60, 0x51, 0x93, 0xda, 0xa0, 0x31, 0xf1, 0xe4, 0x20, + 0x99, 0x9e, 0xc5, 0xee, 0x26, 0x40, 0x94, 0x8c, 0x26, 0xd4, 0x73, 0x1f, 0x92, 0x54, 0xbf, 0xc9, + 0x45, 0x2b, 0x7f, 0x7e, 0xab, 0x78, 0x7e, 0x6b, 0xc0, 0x52, 0xa7, 0x95, 0xe3, 0xee, 0x91, 0xf4, + 0x9f, 0x53, 0x45, 0x1d, 0x68, 0x0a, 0xf2, 0x79, 0x42, 0x98, 0x47, 0xda, 0x75, 0x05, 0x28, 0xbf, + 0xd1, 0xdb, 0x60, 0x4a, 0x1a, 0xb5, 0x1b, 0x8a, 0xcb, 0xff, 0x4e, 0xd3, 0x14, 0x8d, 0x86, 0xd5, + 0xb6, 0xe1, 0x64, 0xb0, 0xde, 0xd7, 0x26, 0x34, 0x72, 0x91, 0xa1, 0xeb, 0xd0, 0x0c, 0x89, 0x10, + 0x38, 0x50, 0x89, 0x9a, 0xaf, 0xcc, 0xa4, 0x44, 0x21, 0x04, 0xb5, 0x90, 0x84, 0xb9, 0x16, 0x5b, + 0x8e, 0x5a, 0x67, 0x19, 0x64, 0x6a, 0xe7, 0x89, 0x74, 0xc7, 0x84, 0x06, 0x63, 0xa9, 0x52, 0xac, + 0x39, 0x0b, 0xda, 0xba, 0xa5, 0x8c, 0xe8, 0xff, 0xd0, 0x4a, 0x18, 0x8f, 0x7d, 0x12, 0x13, 0x5f, + 0xe5, 0xd8, 0x74, 0x8e, 0x0c, 0xe8, 0x33, 0x58, 0x2a, 0x82, 0x94, 0xa5, 0xa3, 0x12, 0x3d, 0xb7, + 0xde, 0x79, 0x89, 0xd3, 0x4e, 0x81, 0x18, 0x36, 0xf7, 0x9f, 0xac, 0x18, 0x7b, 0x4f, 0x57, 0x0c, + 0x67, 0x51, 0xbb, 0x97, 0x7b, 0x68, 0x08, 0x4b, 0x64, 0x2a, 0x09, 0x13, 0x94, 0x33, 0x97, 0x47, + 0x92, 0x72, 0x26, 0xda, 0x7f, 0xce, 0xcd, 0xc8, 0x73, 0xb1, 0xc4, 0x7f, 0x9a, 0xc3, 0xd1, 0x03, + 0xe8, 0x32, 0xce, 0x5c, 0x2f, 0xa6, 0x92, 0x7a, 0x78, 0xe2, 0x9e, 0x12, 0xf0, 0xc2, 0x8c, 0x80, + 0xcb, 0x8c, 0xb3, 0x3b, 0xda, 0xf7, 0xa3, 0x13, 0xb1, 0x7b, 0x3f, 0x18, 0xd0, 0x2c, 0x2a, 0x17, + 0x7d, 0x08, 0xf3, 0x59, 0xb5, 0x90, 0x58, 0xc9, 0xbe, 0x78, 0x8e, 0xcb, 0xa7, 0x3c, 0xe6, 0xb6, + 0x82, 0xa9, 0x72, 0x3f, 0x27, 0xca, 0xb5, 0x40, 0x7d, 0x30, 0x77, 0x09, 0xd1, 0x8a, 0x3c, 0x4d, + 0x05, 0x9b, 0x84, 0x38, 0x19, 0xa4, 0xd0, 0x8b, 0xf9, 0x7a, 0x7a, 0xf9, 0xce, 0x00, 0x38, 0x3a, + 0xf3, 0x84, 0xfe, 0x8d, 0xd7, 0xd3, 0xff, 0x2d, 0x68, 0x85, 0xdc, 0x27, 0x67, 0xf5, 0xb1, 0xfb, + 0xdc, 0x27, 0x79, 0x1f, 0x0b, 0xf5, 0xea, 0x05, 0xdd, 0x9b, 0x2f, 0xea, 0xbe, 0xf7, 0xac, 0x0a, + 0xcd, 0xc2, 0x05, 0xbd, 0x07, 0x0d, 0x41, 0x59, 0x30, 0x21, 0x9a, 0x53, 0x6f, 0x46, 0x7c, 0x6b, + 0x5b, 0x21, 0xb7, 0x2a, 0x8e, 0xf6, 0x41, 0xef, 0x42, 0x5d, 0x0d, 0x14, 0x4d, 0xee, 0x8d, 0x59, + 0xce, 0xf7, 0x33, 0xe0, 0x56, 0xc5, 0xc9, 0x3d, 0x3a, 0x03, 0x68, 0xe4, 0xe1, 0xd0, 0x3b, 0x50, + 0xcb, 0x78, 0x2b, 0x02, 0xe7, 0xd7, 0xaf, 0x1c, 0x8b, 0x51, 0x8c, 0x98, 0xe3, 0x6f, 0x98, 0xc5, + 0x73, 0x94, 0x43, 0x67, 0xcf, 0x80, 0xba, 0x8a, 0x8a, 0xee, 0x41, 0x73, 0x44, 0x25, 0x8e, 0x63, + 0x5c, 0xdc, 0xad, 0x5d, 0x84, 0xc9, 0x07, 0xa1, 0x55, 0xce, 0xbd, 0x22, 0xd6, 0x1d, 0x1e, 0x46, + 0xd8, 0x93, 0x43, 0x2a, 0x07, 0x99, 0x9b, 0x53, 0x06, 0x40, 0xb7, 0x01, 0xca, 0x5b, 0xcf, 0x7a, + 0xa8, 0x79, 0xd6, 0xb5, 0xb7, 0x8a, 0x6b, 0x17, 0xc3, 0x3a, 0x98, 0x22, 0x09, 0x7b, 0x5f, 0x55, + 0xc1, 0xdc, 0x24, 0x04, 0xa5, 0xd0, 0xc0, 0x61, 0xd6, 0x8e, 0xb4, 0x30, 0xcb, 0xc9, 0x95, 0xcd, + 0xdb, 0x63, 0x54, 0x28, 0x1b, 0x6e, 0xee, 0x3f, 0x59, 0xa9, 0xfc, 0xf4, 0x74, 0xa5, 0x1f, 0x50, + 0x39, 0x4e, 0x46, 0x96, 0xc7, 0x43, 0xbb, 0x98, 0xe5, 0xea, 0x6f, 0x4d, 0xf8, 0x0f, 0x6d, 0x99, + 0x46, 0x44, 0x28, 0x07, 0xf1, 0xfd, 0xf3, 0x47, 0xd7, 0xe6, 0x27, 0x24, 0xc0, 0x5e, 0xea, 0x66, + 0x13, 0x5b, 0xfc, 0xf8, 0xfc, 0xd1, 0x35, 0xc3, 0xd1, 0x07, 0xa2, 0x65, 0x68, 0x05, 0x58, 0xb8, + 0x13, 0x1a, 0x52, 0xa9, 0x9e, 0xa7, 0xe6, 0x34, 0x03, 0x2c, 0x3e, 0xce, 0xbe, 0x91, 0x05, 0xf5, + 0x08, 0xa7, 0x24, 0xce, 0xbb, 0xea, 0xb0, 0xfd, 0xdb, 0xcf, 0x6b, 0x17, 0x35, 0xb3, 0x81, 0xef, + 0xc7, 0x44, 0x88, 0x6d, 0x19, 0x53, 0x16, 0x38, 0x39, 0x0c, 0xad, 0xc3, 0x5c, 0x10, 0x63, 0x26, + 0x75, 0x9b, 0x9d, 0xe5, 0x51, 0x00, 0x7b, 0xbf, 0x18, 0x60, 0xee, 0xd0, 0xe8, 0xbf, 0xbc, 0x83, + 0xeb, 0xd0, 0x90, 0x34, 0x8a, 0x48, 0x9c, 0x37, 0xde, 0x19, 0xac, 0x35, 0xee, 0x76, 0xb5, 0x6d, + 0xf4, 0x7e, 0x35, 0x60, 0x61, 0x90, 0x4c, 0xf3, 0xe2, 0xdd, 0xc0, 0x12, 0x67, 0xe9, 0xe3, 0x1c, + 0xae, 0xd4, 0x35, 0x33, 0x7d, 0x0d, 0x44, 0xef, 0x43, 0x33, 0x93, 0xaf, 0xeb, 0x73, 0x4f, 0x57, + 0xc7, 0x95, 0x57, 0x74, 0xa5, 0xe3, 0x63, 0xd4, 0x99, 0x13, 0x7a, 0xda, 0x17, 0x55, 0x61, 0xfe, + 0xcd, 0xaa, 0x40, 0x8b, 0x60, 0x0a, 0x1a, 0xa8, 0x77, 0x9a, 0x77, 0xb2, 0xe5, 0xf0, 0x83, 0xfd, + 0x83, 0xae, 0xf1, 0xf8, 0xa0, 0x6b, 0x3c, 0x3b, 0xe8, 0x1a, 0x7b, 0x87, 0xdd, 0xca, 0xe3, 0xc3, + 0x6e, 0xe5, 0xf7, 0xc3, 0x6e, 0xe5, 0xc1, 0xd5, 0xb3, 0x2f, 0xda, 0x96, 0xd3, 0x51, 0x43, 0x35, + 0xa8, 0x9b, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0xc4, 0xae, 0x24, 0xf8, 0xb5, 0x0a, 0x00, 0x00, } func (m *Tx) Marshal() (dAtA []byte, err error) { @@ -1389,6 +1405,16 @@ func (m *TxBody) MarshalToSizedBuffer(dAtA []byte) (int, error) { dAtA[i] = 0xfa } } + if m.TimeoutTimestamp != nil { + n5, err5 := github_com_cosmos_gogoproto_types.StdTimeMarshalTo(*m.TimeoutTimestamp, dAtA[i-github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.TimeoutTimestamp):]) + if err5 != nil { + return 0, err5 + } + i -= n5 + i = encodeVarintTx(dAtA, i, uint64(n5)) + i-- + dAtA[i] = 0x2a + } if m.Unordered { i-- if m.Unordered { @@ -1980,6 +2006,10 @@ func (m *TxBody) Size() (n int) { if m.Unordered { n += 2 } + if m.TimeoutTimestamp != nil { + l = github_com_cosmos_gogoproto_types.SizeOfStdTime(*m.TimeoutTimestamp) + n += 1 + l + sovTx(uint64(l)) + } if len(m.ExtensionOptions) > 0 { for _, e := range m.ExtensionOptions { l = e.Size() @@ -3013,6 +3043,42 @@ func (m *TxBody) Unmarshal(dAtA []byte) error { } } m.Unordered = bool(v != 0) + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowTx + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthTx + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthTx + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.TimeoutTimestamp == nil { + m.TimeoutTimestamp = new(time.Time) + } + if err := github_com_cosmos_gogoproto_types.StdTimeUnmarshal(m.TimeoutTimestamp, dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex case 1023: if wireType != 2 { return fmt.Errorf("proto: wrong wireType = %d for field ExtensionOptions", wireType) diff --git a/types/tx_msg.go b/types/tx_msg.go index 1f81dbbc0912..6e014f826574 100644 --- a/types/tx_msg.go +++ b/types/tx_msg.go @@ -4,6 +4,7 @@ import ( "encoding/json" fmt "fmt" strings "strings" + "time" "github.com/cosmos/gogoproto/proto" protov2 "google.golang.org/protobuf/proto" @@ -71,6 +72,14 @@ type ( GetMemo() string } + // TxWithTimeoutTimeStamp extends the Tx interface by allowing a transaction to + // set a timeout timestamp. + TxWithTimeoutTimeStamp interface { + Tx + + GetTimeoutTimeStamp() time.Time + } + // TxWithTimeoutHeight extends the Tx interface by allowing a transaction to // set a height timeout. TxWithTimeoutHeight interface { @@ -80,9 +89,9 @@ type ( } // TxWithUnordered extends the Tx interface by allowing a transaction to set - // the unordered field, which implicitly relies on TxWithTimeoutHeight. + // the unordered field, which implicitly relies on TxWithTimeoutTimeStamp. TxWithUnordered interface { - TxWithTimeoutHeight + TxWithTimeoutTimeStamp GetUnordered() bool } diff --git a/x/auth/ante/ante.go b/x/auth/ante/ante.go index 72e670ed2c1e..8e4af82fd7de 100644 --- a/x/auth/ante/ante.go +++ b/x/auth/ante/ante.go @@ -8,6 +8,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" "github.com/cosmos/cosmos-sdk/types/tx/signing" + "github.com/cosmos/cosmos-sdk/x/auth/ante/unorderedtx" "github.com/cosmos/cosmos-sdk/x/auth/types" ) @@ -20,6 +21,7 @@ type HandlerOptions struct { SignModeHandler *txsigning.HandlerMap SigGasConsumer func(meter storetypes.GasMeter, sig signing.SignatureV2, params types.Params) error TxFeeChecker TxFeeChecker + UnorderedTxManager *unorderedtx.Manager } // NewAnteHandler returns an AnteHandler that checks and increments sequence @@ -51,5 +53,9 @@ func NewAnteHandler(options HandlerOptions) (sdk.AnteHandler, error) { NewSigVerificationDecorator(options.AccountKeeper, options.SignModeHandler, options.SigGasConsumer), } + if options.UnorderedTxManager != nil { + anteDecorators = append(anteDecorators, NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, options.UnorderedTxManager, DefaultSha256GasCost)) + } + return sdk.ChainAnteDecorators(anteDecorators...), nil } diff --git a/x/auth/ante/ante_test.go b/x/auth/ante/ante_test.go index 8f9ec4940017..7588db63438a 100644 --- a/x/auth/ante/ante_test.go +++ b/x/auth/ante/ante_test.go @@ -6,6 +6,7 @@ import ( "fmt" "strings" "testing" + "time" "github.com/stretchr/testify/require" "go.uber.org/mock/gomock" @@ -1447,3 +1448,34 @@ func TestAnteHandlerReCheck(t *testing.T) { _, err = suite.anteHandler(suite.ctx, tx, false) require.NotNil(t, err, "antehandler on recheck did not fail once feePayer no longer has sufficient funds") } + +func TestAnteHandlerUnorderedTx(t *testing.T) { + suite := SetupTestSuite(t, false) + accs := suite.CreateTestAccounts(1) + msg := testdata.NewTestMsg(accs[0].acc.GetAddress()) + + // First send a normal sequential tx with sequence 0 + suite.bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), accs[0].acc.GetAddress(), authtypes.FeeCollectorName, testdata.NewTestFeeAmount()).Return(nil).AnyTimes() + + privs, accNums, accSeqs := []cryptotypes.PrivKey{accs[0].priv}, []uint64{1000}, []uint64{0} + _, err := suite.DeliverMsgs(t, privs, []sdk.Msg{msg}, testdata.NewTestFeeAmount(), testdata.NewTestGasLimit(), accNums, accSeqs, suite.ctx.ChainID(), false) + require.NoError(t, err) + + // we try to send another tx with the same sequence, it will fail + _, err = suite.DeliverMsgs(t, privs, []sdk.Msg{msg}, testdata.NewTestFeeAmount(), testdata.NewTestGasLimit(), accNums, accSeqs, suite.ctx.ChainID(), false) + require.Error(t, err) + + // now we'll still use the same sequence but because it's unordered, it will be ignored and accepted anyway + msgs := []sdk.Msg{msg} + require.NoError(t, suite.txBuilder.SetMsgs(msgs...)) + suite.txBuilder.SetFeeAmount(testdata.NewTestFeeAmount()) + suite.txBuilder.SetGasLimit(testdata.NewTestGasLimit()) + + tx, txErr := suite.CreateTestUnorderedTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT, true, time.Now().Add(time.Minute)) + require.NoError(t, txErr) + txBytes, err := suite.clientCtx.TxConfig.TxEncoder()(tx) + bytesCtx := suite.ctx.WithTxBytes(txBytes) + require.NoError(t, err) + _, err = suite.anteHandler(bytesCtx, tx, false) + require.NoError(t, err) +} diff --git a/x/auth/ante/basic.go b/x/auth/ante/basic.go index 46a2e27f0136..0137a9259cf1 100644 --- a/x/auth/ante/basic.go +++ b/x/auth/ante/basic.go @@ -1,6 +1,8 @@ package ante import ( + "time" + errorsmod "cosmossdk.io/errors" storetypes "cosmossdk.io/store/types" @@ -187,6 +189,7 @@ type ( sdk.Tx GetTimeoutHeight() uint64 + GetTimeoutTimeStamp() time.Time } ) @@ -213,5 +216,13 @@ func (txh TxTimeoutHeightDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simul ) } + timeoutTimestamp := timeoutTx.GetTimeoutTimeStamp() + blockTime := ctx.BlockHeader().Time + if !timeoutTimestamp.IsZero() && timeoutTimestamp.Unix() != 0 && timeoutTimestamp.Before(blockTime) { + return ctx, errorsmod.Wrapf( + sdkerrors.ErrTxTimeout, "block time: %s, timeout timestamp: %s", blockTime, timeoutTimestamp.String(), + ) + } + return next(ctx, tx, simulate) } diff --git a/x/auth/ante/basic_test.go b/x/auth/ante/basic_test.go index baac049acc6a..6bf20e08280e 100644 --- a/x/auth/ante/basic_test.go +++ b/x/auth/ante/basic_test.go @@ -3,6 +3,7 @@ package ante_test import ( "strings" "testing" + "time" "github.com/stretchr/testify/require" @@ -186,21 +187,30 @@ func TestTxHeightTimeoutDecorator(t *testing.T) { // keys and addresses priv1, _, addr1 := testdata.KeyTestPubAddr() + currentTime := time.Now() + // msg and signatures msg := testdata.NewTestMsg(addr1) feeAmount := testdata.NewTestFeeAmount() gasLimit := testdata.NewTestGasLimit() testCases := []struct { - name string - timeout uint64 - height int64 - expectedErr error + name string + timeout uint64 + height int64 + timeoutTimestamp time.Time + timestamp time.Time + expectedErr error }{ - {"default value", 0, 10, nil}, - {"no timeout (greater height)", 15, 10, nil}, - {"no timeout (same height)", 10, 10, nil}, - {"timeout (smaller height)", 9, 10, sdkerrors.ErrTxTimeoutHeight}, + {"default value", 0, 10, time.Time{}, time.Time{}, nil}, + {"no timeout (greater height)", 15, 10, time.Time{}, time.Time{}, nil}, + {"no timeout (same height)", 10, 10, time.Time{}, time.Time{}, nil}, + {"timeout (smaller height)", 9, 10, time.Time{}, time.Time{}, sdkerrors.ErrTxTimeoutHeight}, + {"no timeout (timeout after timestamp)", 0, 20, currentTime.Add(time.Minute), currentTime, nil}, + {"no timeout (current time)", 0, 20, currentTime, currentTime, nil}, + {"timeout before timestamp", 0, 20, currentTime, currentTime.Add(time.Minute), sdkerrors.ErrTxTimeout}, + {"tx contain both timeouts, timeout (timeout before timestamp)", 15, 10, currentTime, currentTime.Add(time.Minute), sdkerrors.ErrTxTimeout}, + {"tx contain both timeout, no timeout", 15, 10, currentTime.Add(time.Minute), currentTime, nil}, } for _, tc := range testCases { @@ -215,12 +225,13 @@ func TestTxHeightTimeoutDecorator(t *testing.T) { suite.txBuilder.SetGasLimit(gasLimit) suite.txBuilder.SetMemo(strings.Repeat("01234567890", 10)) suite.txBuilder.SetTimeoutHeight(tc.timeout) + suite.txBuilder.SetTimeoutTimestamp(tc.timeoutTimestamp) privs, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} tx, err := suite.CreateTestTx(suite.ctx, privs, accNums, accSeqs, suite.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT) require.NoError(t, err) - ctx := suite.ctx.WithBlockHeight(tc.height) + ctx := suite.ctx.WithBlockHeight(tc.height).WithBlockTime(tc.timestamp) _, err = antehandler(ctx, tx, true) require.ErrorIs(t, err, tc.expectedErr) }) diff --git a/x/auth/ante/sigverify.go b/x/auth/ante/sigverify.go index 1701d2e87340..c715ac7dc996 100644 --- a/x/auth/ante/sigverify.go +++ b/x/auth/ante/sigverify.go @@ -318,11 +318,28 @@ func (svd SigVerificationDecorator) consumeSignatureGas( return nil } -// verifySig will verify the signature of the provided signer account. -// it will assess: -// - the pub key is on the curve. -// - verify sig +// verifySig will verify the signature of the provided account. +// The following checks are performed: +// - For regular transactions (not unordered) , validates that the signature sequence matches the account sequence +// - Verifies the public key exists and is on the elliptic curve +// - In non-simulation mode and when signature verification is enabled, performs full signature validation: +// - Retrieves signer data (address, chain ID, account number, sequence) +// - Verifies the signature against the transaction data using the appropriate sign mode handler +// +// Signature verification is skipped during simulation, ReCheckTx, or when not in a signature verification context func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, simulate bool, tx sdk.Tx, acc sdk.AccountI, sig signing.SignatureV2) error { + unorderedTx, ok := tx.(sdk.TxWithUnordered) + isUnordered := ok && unorderedTx.GetUnordered() + // only check sequence if the tx is not unordered + if !isUnordered { + if sig.Sequence != acc.GetSequence() { + return errorsmod.Wrapf( + sdkerrors.ErrWrongSequence, + "account sequence mismatch: expected %d, got %d", acc.GetSequence(), sig.Sequence, + ) + } + } + // retrieve pubkey pubKey := acc.GetPubKey() if !simulate && pubKey == nil { @@ -333,13 +350,6 @@ func (svd SigVerificationDecorator) verifySig(ctx sdk.Context, simulate bool, tx return err } - if sig.Sequence != acc.GetSequence() { - return errorsmod.Wrapf( - sdkerrors.ErrWrongSequence, - "account sequence mismatch, expected %d, got %d", acc.GetSequence(), sig.Sequence, - ) - } - // we're in simulation mode, or in ReCheckTx, or context is not // on sig verify tx, then we do not need to verify the signatures // in the tx. diff --git a/x/auth/ante/sigverify_test.go b/x/auth/ante/sigverify_test.go index b64ea45bc65c..b072c02aca91 100644 --- a/x/auth/ante/sigverify_test.go +++ b/x/auth/ante/sigverify_test.go @@ -5,8 +5,8 @@ import ( "testing" banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" - "github.com/golang/mock/gomock" "github.com/stretchr/testify/require" + "go.uber.org/mock/gomock" "github.com/cosmos/cosmos-sdk/codec" "github.com/cosmos/cosmos-sdk/crypto/keys/ed25519" diff --git a/x/auth/ante/testutil_test.go b/x/auth/ante/testutil_test.go index ce7532e1bd6c..f04321a6e288 100644 --- a/x/auth/ante/testutil_test.go +++ b/x/auth/ante/testutil_test.go @@ -2,6 +2,7 @@ package ante_test import ( "testing" + "time" abci "github.com/cometbft/cometbft/abci/types" "github.com/stretchr/testify/require" @@ -257,3 +258,59 @@ func (suite *AnteTestSuite) CreateTestTx( return suite.txBuilder.GetTx(), nil } + +func (suite *AnteTestSuite) CreateTestUnorderedTx( + ctx sdk.Context, privs []cryptotypes.PrivKey, + accNums, accSeqs []uint64, + chainID string, signMode signing.SignMode, + unordered bool, unorderedTimeout time.Time, +) (xauthsigning.Tx, error) { + suite.txBuilder.SetUnordered(unordered) + suite.txBuilder.SetTimeoutTimestamp(unorderedTimeout) + + // First round: we gather all the signer infos. We use the "set empty + // signature" hack to do that. + var sigsV2 []signing.SignatureV2 + for i, priv := range privs { + sigV2 := signing.SignatureV2{ + PubKey: priv.PubKey(), + Data: &signing.SingleSignatureData{ + SignMode: signMode, + Signature: nil, + }, + Sequence: accSeqs[i], + } + + sigsV2 = append(sigsV2, sigV2) + } + err := suite.txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + // Second round: all signer infos are set, so each signer can sign. + sigsV2 = []signing.SignatureV2{} + for i, priv := range privs { + signerData := xauthsigning.SignerData{ + Address: sdk.AccAddress(priv.PubKey().Address()).String(), + ChainID: chainID, + AccountNumber: accNums[i], + Sequence: accSeqs[i], + PubKey: priv.PubKey(), + } + sigV2, err := tx.SignWithPrivKey( + ctx, signMode, signerData, + suite.txBuilder, priv, suite.clientCtx.TxConfig, accSeqs[i]) + if err != nil { + return nil, err + } + + sigsV2 = append(sigsV2, sigV2) + } + err = suite.txBuilder.SetSignatures(sigsV2...) + if err != nil { + return nil, err + } + + return suite.txBuilder.GetTx(), nil +} diff --git a/x/auth/ante/unordered.go b/x/auth/ante/unordered.go index 66fe13444e81..a97878959efa 100644 --- a/x/auth/ante/unordered.go +++ b/x/auth/ante/unordered.go @@ -1,20 +1,39 @@ package ante import ( + "bytes" "crypto/sha256" + "encoding/binary" + "fmt" + "sync" + "time" + + "github.com/cosmos/gogoproto/proto" errorsmod "cosmossdk.io/errors" sdk "github.com/cosmos/cosmos-sdk/types" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + "github.com/cosmos/cosmos-sdk/types/tx/signing" "github.com/cosmos/cosmos-sdk/x/auth/ante/unorderedtx" + authsigning "github.com/cosmos/cosmos-sdk/x/auth/signing" ) +// bufPool is a pool of bytes.Buffer objects to reduce memory allocations. +var bufPool = sync.Pool{ + New: func() interface{} { + return new(bytes.Buffer) + }, +} + +// DefaultSha256GasCost is the suggested default gas cost for Sha256 operations in unordered transaction handling. +const DefaultSha256GasCost = 25 + var _ sdk.AnteDecorator = (*UnorderedTxDecorator)(nil) // UnorderedTxDecorator defines an AnteHandler decorator that is responsible for // checking if a transaction is intended to be unordered and if so, evaluates -// the transaction accordingly. An unordered transaction will bypass having it's +// the transaction accordingly. An unordered transaction will bypass having its // nonce incremented, which allows fire-and-forget along with possible parallel // transaction processing, without having to deal with nonces. // @@ -26,49 +45,189 @@ var _ sdk.AnteDecorator = (*UnorderedTxDecorator)(nil) // chain to ensure that during DeliverTx, the transaction is added to the UnorderedTxManager. type UnorderedTxDecorator struct { // maxUnOrderedTTL defines the maximum TTL a transaction can define. - maxUnOrderedTTL uint64 - txManager *unorderedtx.Manager + maxTimeoutDuration time.Duration + txManager *unorderedtx.Manager + sha256GasCost uint64 } -func NewUnorderedTxDecorator(maxTTL uint64, m *unorderedtx.Manager) *UnorderedTxDecorator { +func NewUnorderedTxDecorator( + maxDuration time.Duration, + m *unorderedtx.Manager, + sha256GasCost uint64, +) *UnorderedTxDecorator { return &UnorderedTxDecorator{ - maxUnOrderedTTL: maxTTL, - txManager: m, + maxTimeoutDuration: maxDuration, + txManager: m, + sha256GasCost: sha256GasCost, + } +} + +func (d *UnorderedTxDecorator) AnteHandle( + ctx sdk.Context, + tx sdk.Tx, + _ bool, + next sdk.AnteHandler, +) (sdk.Context, error) { + if err := d.ValidateTx(ctx, tx); err != nil { + return ctx, err } + return next(ctx, tx, false) } -func (d *UnorderedTxDecorator) AnteHandle(ctx sdk.Context, tx sdk.Tx, simulate bool, next sdk.AnteHandler) (sdk.Context, error) { +func (d *UnorderedTxDecorator) ValidateTx(ctx sdk.Context, tx sdk.Tx) error { unorderedTx, ok := tx.(sdk.TxWithUnordered) if !ok || !unorderedTx.GetUnordered() { // If the transaction does not implement unordered capabilities or has the // unordered value as false, we bypass. - return next(ctx, tx, simulate) + return nil } - // TTL is defined as a specific block height at which this tx is no longer valid - ttl := unorderedTx.GetTimeoutHeight() - - if ttl == 0 { - return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction must have timeout_height set") + blockTime := ctx.BlockTime() + timeoutTimestamp := unorderedTx.GetTimeoutTimeStamp() + if timeoutTimestamp.IsZero() || timeoutTimestamp.Unix() == 0 { + return errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "unordered transaction must have timeout_timestamp set", + ) } - if ttl < uint64(ctx.BlockHeight()) { - return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "unordered transaction has a timeout_height that has already passed") + if timeoutTimestamp.Before(blockTime) { + return errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "unordered transaction has a timeout_timestamp that has already passed", + ) } - if ttl > uint64(ctx.BlockHeight())+d.maxUnOrderedTTL { - return ctx, errorsmod.Wrapf(sdkerrors.ErrInvalidRequest, "unordered tx ttl exceeds %d", d.maxUnOrderedTTL) + if timeoutTimestamp.After(blockTime.Add(d.maxTimeoutDuration)) { + return errorsmod.Wrapf( + sdkerrors.ErrInvalidRequest, + "unordered tx ttl exceeds %s", + d.maxTimeoutDuration.String(), + ) } - txHash := sha256.Sum256(ctx.TxBytes()) + // consume gas in all exec modes to avoid gas estimation discrepancies + ctx.GasMeter().ConsumeGas(d.sha256GasCost, "consume gas for calculating tx hash") + + // Avoid checking for duplicates and creating the identifier in simulation mode + // This is done to avoid sha256 computation in simulation mode + if ctx.ExecMode() == sdk.ExecModeSimulate { + return nil + } + + // calculate the tx hash + txHash, err := TxHashFromTimeout(uint64(timeoutTimestamp.Unix()), tx) + if err != nil { + return err + } // check for duplicates if d.txManager.Contains(txHash) { - return ctx, errorsmod.Wrap(sdkerrors.ErrInvalidRequest, "tx %X is duplicated") + return errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "tx %X is duplicated", + ) } - if ctx.ExecMode() == sdk.ExecModeFinalize { // a new tx included in the block, add the hash to the unordered tx manager - d.txManager.Add(txHash, ttl) + d.txManager.Add(txHash, timeoutTimestamp) + } + + return nil +} + +// TxHashFromTimeout returns a TxHash for an unordered transaction. +func TxHashFromTimeout(timeout uint64, tx sdk.Tx) (unorderedtx.TxHash, error) { + sigTx, ok := tx.(authsigning.Tx) + if !ok { + return unorderedtx.TxHash{}, errorsmod.Wrap(sdkerrors.ErrTxDecode, "invalid transaction type") + } + + if sigTx.GetFee().IsZero() { + return unorderedtx.TxHash{}, errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "unordered transaction must have a fee", + ) + } + + buf := bufPool.Get().(*bytes.Buffer) + // Make sure to reset the buffer + buf.Reset() + defer bufPool.Put(buf) + + // Add signatures to the transaction identifier + signatures, err := sigTx.GetSignaturesV2() + if err != nil { + return unorderedtx.TxHash{}, err + } + + for _, sig := range signatures { + if err := addSignatures(sig.Data, buf); err != nil { + return unorderedtx.TxHash{}, err + } + } + + // Use the buffer + for _, msg := range tx.GetMsgs() { + // loop through the messages and write them to the buffer + // encoding the msg to bytes makes it deterministic within the state machine. + // Malleability is not a concern here because the state machine will encode the transaction deterministically. + bz, err := proto.Marshal(msg) + if err != nil { + return unorderedtx.TxHash{}, errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "failed to marshal message", + ) + } + + if _, err := buf.Write(bz); err != nil { + return unorderedtx.TxHash{}, errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "failed to write message to buffer", + ) + } + } + + // write the timeout height to the buffer + if err := binary.Write(buf, binary.LittleEndian, timeout); err != nil { + return unorderedtx.TxHash{}, errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "failed to write timeout_height to buffer", + ) + } + + // write gas to the buffer + if err := binary.Write(buf, binary.LittleEndian, sigTx.GetGas()); err != nil { + return unorderedtx.TxHash{}, errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "failed to write unordered to buffer", + ) + } + + txHash := sha256.Sum256(buf.Bytes()) + + // Return the Buffer to the pool + return txHash, nil +} + +func addSignatures(sig signing.SignatureData, buf *bytes.Buffer) error { + switch data := sig.(type) { + case *signing.SingleSignatureData: + if _, err := buf.Write(data.Signature); err != nil { + return errorsmod.Wrap( + sdkerrors.ErrInvalidRequest, + "failed to write single signature to buffer", + ) + } + return nil + + case *signing.MultiSignatureData: + for _, sigdata := range data.Signatures { + if err := addSignatures(sigdata, buf); err != nil { + return err + } + } + default: + return fmt.Errorf("unexpected SignatureData %T", data) } - return next(ctx, tx, simulate) + return nil } diff --git a/x/auth/ante/unordered_test.go b/x/auth/ante/unordered_test.go index 02f7dcec2af1..99d7c90f09c5 100644 --- a/x/auth/ante/unordered_test.go +++ b/x/auth/ante/unordered_test.go @@ -1,11 +1,13 @@ package ante_test import ( - "crypto/sha256" "testing" + "time" "github.com/stretchr/testify/require" + storetypes "cosmossdk.io/store/types" + cryptotypes "github.com/cosmos/cosmos-sdk/crypto/types" "github.com/cosmos/cosmos-sdk/testutil/testdata" sdk "github.com/cosmos/cosmos-sdk/types" @@ -14,6 +16,8 @@ import ( "github.com/cosmos/cosmos-sdk/x/auth/ante/unorderedtx" ) +const gasConsumed = uint64(25) + func TestUnorderedTxDecorator_OrderedTx(t *testing.T) { txm := unorderedtx.NewManager(t.TempDir()) defer func() { @@ -22,10 +26,12 @@ func TestUnorderedTxDecorator_OrderedTx(t *testing.T) { txm.Start() - chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm)) + SetupTestSuite(t, false) + + chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, ante.DefaultSha256GasCost)) - tx, txBz := genUnorderedTx(t, false, 0) - ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100) + tx, txBz := genUnorderedTx(t, false, time.Time{}) + ctx := sdk.Context{}.WithTxBytes(txBz) _, err := chain(ctx, tx, false) require.NoError(t, err) @@ -39,10 +45,12 @@ func TestUnorderedTxDecorator_UnorderedTx_NoTTL(t *testing.T) { txm.Start() - chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm)) + SetupTestSuite(t, false) - tx, txBz := genUnorderedTx(t, true, 0) - ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100) + chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, ante.DefaultSha256GasCost)) + + tx, txBz := genUnorderedTx(t, true, time.Time{}) + ctx := sdk.Context{}.WithTxBytes(txBz) _, err := chain(ctx, tx, false) require.Error(t, err) @@ -56,11 +64,12 @@ func TestUnorderedTxDecorator_UnorderedTx_InvalidTTL(t *testing.T) { txm.Start() - chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm)) + SetupTestSuite(t, false) - tx, txBz := genUnorderedTx(t, true, 100+unorderedtx.DefaultMaxUnOrderedTTL+1) - ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100) + chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, ante.DefaultSha256GasCost)) + tx, txBz := genUnorderedTx(t, true, time.Now().Add(unorderedtx.DefaultMaxTimeoutDuration+time.Second)) + ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockTime(time.Now()) _, err := chain(ctx, tx, false) require.Error(t, err) } @@ -73,13 +82,16 @@ func TestUnorderedTxDecorator_UnorderedTx_AlreadyExists(t *testing.T) { txm.Start() - chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm)) + SetupTestSuite(t, false) + + chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, ante.DefaultSha256GasCost)) - tx, txBz := genUnorderedTx(t, true, 150) - ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100) + tx, txBz := genUnorderedTx(t, true, time.Now().Add(time.Minute)) + ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockTime(time.Now()).WithGasMeter(storetypes.NewGasMeter(gasConsumed)) - txHash := sha256.Sum256(txBz) - txm.Add(txHash, 150) + bz := [32]byte{} + copy(bz[:], txBz[:32]) + txm.Add(bz, time.Now().Add(time.Minute)) _, err := chain(ctx, tx, false) require.Error(t, err) @@ -93,10 +105,12 @@ func TestUnorderedTxDecorator_UnorderedTx_ValidCheckTx(t *testing.T) { txm.Start() - chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm)) + SetupTestSuite(t, false) - tx, txBz := genUnorderedTx(t, true, 150) - ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeCheck) + chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, ante.DefaultSha256GasCost)) + + tx, txBz := genUnorderedTx(t, true, time.Now().Add(time.Minute)) + ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockTime(time.Now()).WithExecMode(sdk.ExecModeCheck).WithGasMeter(storetypes.NewGasMeter(gasConsumed)) _, err := chain(ctx, tx, false) require.NoError(t, err) @@ -110,19 +124,23 @@ func TestUnorderedTxDecorator_UnorderedTx_ValidDeliverTx(t *testing.T) { txm.Start() - chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxUnOrderedTTL, txm)) + SetupTestSuite(t, false) + + chain := sdk.ChainAnteDecorators(ante.NewUnorderedTxDecorator(unorderedtx.DefaultMaxTimeoutDuration, txm, ante.DefaultSha256GasCost)) - tx, txBz := genUnorderedTx(t, true, 150) - ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockHeight(100).WithExecMode(sdk.ExecModeFinalize) + tx, txBz := genUnorderedTx(t, true, time.Now().Add(time.Minute)) + ctx := sdk.Context{}.WithTxBytes(txBz).WithBlockTime(time.Now()).WithExecMode(sdk.ExecModeFinalize).WithGasMeter(storetypes.NewGasMeter(gasConsumed)) _, err := chain(ctx, tx, false) require.NoError(t, err) - txHash := sha256.Sum256(txBz) - require.True(t, txm.Contains(txHash)) + bz := [32]byte{} + copy(bz[:], txBz[:32]) + + require.True(t, txm.Contains(bz)) } -func genUnorderedTx(t *testing.T, unordered bool, ttl uint64) (sdk.Tx, []byte) { +func genUnorderedTx(t *testing.T, unordered bool, timestamp time.Time) (sdk.Tx, []byte) { t.Helper() s := SetupTestSuite(t, true) @@ -140,14 +158,15 @@ func genUnorderedTx(t *testing.T, unordered bool, ttl uint64) (sdk.Tx, []byte) { s.txBuilder.SetFeeAmount(feeAmount) s.txBuilder.SetGasLimit(gasLimit) s.txBuilder.SetUnordered(unordered) - s.txBuilder.SetTimeoutHeight(ttl) + s.txBuilder.SetTimeoutTimestamp(timestamp) privKeys, accNums, accSeqs := []cryptotypes.PrivKey{priv1}, []uint64{0}, []uint64{0} tx, err := s.CreateTestTx(s.ctx, privKeys, accNums, accSeqs, s.ctx.ChainID(), signing.SignMode_SIGN_MODE_DIRECT) require.NoError(t, err) - txBz, err := s.encCfg.TxConfig.TxEncoder()(tx) + txBz, err := ante.TxHashFromTimeout(uint64(timestamp.Unix()), tx) + require.NoError(t, err) - return tx, txBz + return tx, txBz[:] } diff --git a/x/auth/ante/unorderedtx/manager.go b/x/auth/ante/unorderedtx/manager.go index 14fbe018b83b..d41399deca85 100644 --- a/x/auth/ante/unorderedtx/manager.go +++ b/x/auth/ante/unorderedtx/manager.go @@ -8,19 +8,18 @@ import ( "errors" "fmt" "io" + "maps" "os" "path/filepath" - "sort" + "slices" "sync" "time" - - "golang.org/x/exp/maps" ) const ( - // DefaultMaxUnOrderedTTL defines the default maximum TTL an un-ordered transaction + // DefaultMaxTimeoutDuration defines the default maximum duration an un-ordered transaction // can set. - DefaultMaxUnOrderedTTL = 1024 + DefaultMaxTimeoutDuration = time.Minute * 40 dirName = "unordered_txs" fileName = "data" @@ -32,8 +31,8 @@ type TxHash [32]byte // Manager contains the tx hash dictionary for duplicates checking, and expire // them when block production progresses. type Manager struct { - // blockCh defines a channel to receive newly committed block heights - blockCh chan uint64 + // blockTimeCh defines a channel to receive newly committed block time + blockTimeCh chan time.Time // doneCh allows us to ensure the purgeLoop has gracefully terminated prior to closing doneCh chan struct{} @@ -48,23 +47,26 @@ type Manager struct { dataDir string mu sync.RWMutex - // txHashes defines a map from tx hash -> TTL value, which is used for duplicate + + // txHashes defines a map from tx hash -> TTL value defined as block time, which is used for duplicate // checking and replay protection, as well as purging the map when the TTL is // expired. - txHashes map[TxHash]uint64 + txHashes map[TxHash]time.Time } func NewManager(dataDir string) *Manager { path := filepath.Join(dataDir, dirName) if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) { - _ = os.Mkdir(path, os.ModePerm) + if err = os.MkdirAll(path, os.ModePerm); err != nil { + panic(fmt.Errorf("failed to create unordered txs directory: %w", err)) + } } m := &Manager{ - dataDir: dataDir, - blockCh: make(chan uint64, 16), - doneCh: make(chan struct{}), - txHashes: make(map[TxHash]uint64), + dataDir: dataDir, + blockTimeCh: make(chan time.Time, 16), + doneCh: make(chan struct{}), + txHashes: make(map[TxHash]time.Time), } return m @@ -81,9 +83,9 @@ func (m *Manager) Start() { // It will free all necessary resources as well as writing all unexpired unordered // transactions along with their TTL values to file. func (m *Manager) Close() error { - close(m.blockCh) + close(m.blockTimeCh) <-m.doneCh - m.blockCh = nil + m.blockTimeCh = nil return m.flushToFile() } @@ -91,7 +93,6 @@ func (m *Manager) Close() error { func (m *Manager) Contains(hash TxHash) bool { m.mu.RLock() defer m.mu.RUnlock() - _, ok := m.txHashes[hash] return ok } @@ -103,11 +104,11 @@ func (m *Manager) Size() int { return len(m.txHashes) } -func (m *Manager) Add(txHash TxHash, ttl uint64) { +func (m *Manager) Add(txHash TxHash, timestamp time.Time) { m.mu.Lock() defer m.mu.Unlock() - m.txHashes[txHash] = ttl + m.txHashes[txHash] = timestamp } // OnInit must be called when a node starts up. Typically, this should be called @@ -145,33 +146,30 @@ func (m *Manager) OnInit() error { var txHash TxHash copy(txHash[:], buf[:txHashSize]) - m.Add(txHash, binary.BigEndian.Uint64(buf[txHashSize:])) + timeStamp := binary.BigEndian.Uint64(buf[txHashSize:]) + m.Add(txHash, time.Unix(int64(timeStamp), 0)) } return nil } -// OnNewBlock sends the latest block number to the background purge loop, which +// OnNewBlock sends the latest block time to the background purge loop, which // should be called in ABCI Commit event. -func (m *Manager) OnNewBlock(blockHeight uint64) { - m.blockCh <- blockHeight +func (m *Manager) OnNewBlock(blockTime time.Time) { + m.blockTimeCh <- blockTime } -func (m *Manager) exportSnapshot(height uint64, snapshotWriter func([]byte) error) error { +func (m *Manager) exportSnapshot(_ uint64, snapshotWriter func([]byte) error) error { var buf bytes.Buffer w := bufio.NewWriter(&buf) - keys := maps.Keys(m.txHashes) - sort.Slice(keys, func(i, j int) bool { return bytes.Compare(keys[i][:], keys[j][:]) < 0 }) - + keys := slices.SortedFunc(maps.Keys(m.txHashes), func(i, j TxHash) int { return bytes.Compare(i[:], j[:]) }) for _, txHash := range keys { - ttl := m.txHashes[txHash] - if height > ttl { - // skip expired txs that have yet to be purged - continue - } + timeoutTime := m.txHashes[txHash] - chunk := unorderedTxToBytes(txHash, ttl) + // right now we dont have access block time at this flow, so we would just include the expired txs + // and let it be purge during purge loop + chunk := unorderedTxToBytes(txHash, uint64(timeoutTime.Unix())) if _, err := w.Write(chunk); err != nil { return fmt.Errorf("failed to write unordered tx to buffer: %w", err) @@ -185,8 +183,8 @@ func (m *Manager) exportSnapshot(height uint64, snapshotWriter func([]byte) erro return snapshotWriter(buf.Bytes()) } -// flushToFile writes all unexpired unordered transactions along with their TTL -// to file, overwriting the existing file if it exists. +// flushToFile writes all unordered transactions (including expired if not pruned yet) +// along with their TTL to file, overwriting the existing file if it exists. func (m *Manager) flushToFile() error { f, err := os.Create(filepath.Join(m.dataDir, dirName, fileName)) if err != nil { @@ -195,8 +193,8 @@ func (m *Manager) flushToFile() error { defer f.Close() w := bufio.NewWriter(f) - for txHash, ttl := range m.txHashes { - chunk := unorderedTxToBytes(txHash, ttl) + for txHash, timestamp := range m.txHashes { + chunk := unorderedTxToBytes(txHash, uint64(timestamp.Unix())) if _, err = w.Write(chunk); err != nil { return fmt.Errorf("failed to write unordered tx to buffer: %w", err) @@ -210,14 +208,14 @@ func (m *Manager) flushToFile() error { return nil } -// expiredTxs returns expired tx hashes based on the provided block height. -func (m *Manager) expiredTxs(blockHeight uint64) []TxHash { +// expiredTxs returns expired tx hashes based on the provided block time. +func (m *Manager) expiredTxs(blockTime time.Time) []TxHash { m.mu.RLock() defer m.mu.RUnlock() var result []TxHash - for txHash, ttl := range m.txHashes { - if blockHeight > ttl { + for txHash, timestamp := range m.txHashes { + if blockTime.After(timestamp) { result = append(result, txHash) } } @@ -237,37 +235,40 @@ func (m *Manager) purge(txHashes []TxHash) { // purgeLoop removes expired tx hashes in the background func (m *Manager) purgeLoop() { for { - latestHeight, ok := m.batchReceive() + latestTime, ok := m.batchReceive() if !ok { // channel closed m.doneCh <- struct{}{} return } - hashes := m.expiredTxs(latestHeight) + hashes := m.expiredTxs(latestTime) if len(hashes) > 0 { m.purge(hashes) } } } -func (m *Manager) batchReceive() (uint64, bool) { +// batchReceive receives block time from the channel until the context is done +// or the channel is closed. +func (m *Manager) batchReceive() (time.Time, bool) { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - var latestHeight uint64 + var latestTime time.Time for { select { case <-ctx.Done(): - return latestHeight, true + return latestTime, true - case blockHeight, ok := <-m.blockCh: + case blockTime, ok := <-m.blockTimeCh: if !ok { // channel is closed - return 0, false + return time.Time{}, false } - if blockHeight > latestHeight { - latestHeight = blockHeight + + if blockTime.After(latestTime) { + latestTime = blockTime } } } @@ -277,7 +278,7 @@ func unorderedTxToBytes(txHash TxHash, ttl uint64) []byte { chunk := make([]byte, chunkSize) copy(chunk[:txHashSize], txHash[:]) - ttlBz := make([]byte, ttlSize) + ttlBz := make([]byte, timeoutSize) binary.BigEndian.PutUint64(ttlBz, ttl) copy(chunk[txHashSize:], ttlBz) diff --git a/x/auth/ante/unorderedtx/manager_test.go b/x/auth/ante/unorderedtx/manager_test.go index 132d02154657..271a2627d4ae 100644 --- a/x/auth/ante/unorderedtx/manager_test.go +++ b/x/auth/ante/unorderedtx/manager_test.go @@ -25,9 +25,9 @@ func TestUnorderedTxManager_SimpleSize(t *testing.T) { txm.Start() - txm.Add([32]byte{0xFF}, 100) - txm.Add([32]byte{0xAA}, 100) - txm.Add([32]byte{0xCC}, 100) + txm.Add(unorderedtx.TxHash{0xFF}, time.Now()) + txm.Add(unorderedtx.TxHash{0xAA}, time.Now()) + txm.Add(unorderedtx.TxHash{0xCC}, time.Now()) require.Equal(t, 3, txm.Size()) } @@ -41,13 +41,13 @@ func TestUnorderedTxManager_SimpleContains(t *testing.T) { txm.Start() for i := 0; i < 10; i++ { - txHash := [32]byte{byte(i)} - txm.Add(txHash, 100) + txHash := unorderedtx.TxHash{byte(i)} + txm.Add(txHash, time.Now()) require.True(t, txm.Contains(txHash)) } for i := 10; i < 20; i++ { - txHash := [32]byte{byte(i)} + txHash := unorderedtx.TxHash{byte(i)} require.False(t, txm.Contains(txHash)) } } @@ -70,7 +70,7 @@ func TestUnorderedTxManager_CloseInit(t *testing.T) { // add a handful of unordered txs for i := 0; i < 100; i++ { - txm.Add([32]byte{byte(i)}, 100) + txm.Add(unorderedtx.TxHash{byte(i)}, time.Now()) } // close the manager, which should flush all unexpired txs to file @@ -88,7 +88,7 @@ func TestUnorderedTxManager_CloseInit(t *testing.T) { require.Equal(t, 100, txm2.Size()) for i := 0; i < 100; i++ { - require.True(t, txm2.Contains([32]byte{byte(i)})) + require.True(t, txm2.Contains(unorderedtx.TxHash{byte(i)})) } } @@ -100,15 +100,17 @@ func TestUnorderedTxManager_Flow(t *testing.T) { txm.Start() + currentTime := time.Now() + // Seed the manager with a txs, some of which should eventually be purged and // the others will remain. Txs with TTL less than or equal to 50 should be purged. for i := 1; i <= 100; i++ { - txHash := [32]byte{byte(i)} + txHash := unorderedtx.TxHash{byte(i)} if i <= 50 { - txm.Add(txHash, uint64(i)) + txm.Add(txHash, currentTime.Add(time.Millisecond*500*time.Duration(i))) } else { - txm.Add(txHash, 100) + txm.Add(txHash, currentTime.Add(time.Hour)) } } @@ -118,19 +120,12 @@ func TestUnorderedTxManager_Flow(t *testing.T) { ticker := time.NewTicker(time.Millisecond * 500) defer ticker.Stop() - var ( - height uint64 = 1 - i = 101 - ) - for range ticker.C { - txm.OnNewBlock(height) - height++ + for t := range ticker.C { + txm.OnNewBlock(t) - if height > 51 { + if t.After(currentTime.Add(time.Millisecond * 500 * time.Duration(50))) { doneBlockCh <- true return - } else { - txm.Add([32]byte{byte(i)}, 50) } } }() diff --git a/x/auth/ante/unorderedtx/snapshotter.go b/x/auth/ante/unorderedtx/snapshotter.go index 5941a11a6888..4c855c9e3167 100644 --- a/x/auth/ante/unorderedtx/snapshotter.go +++ b/x/auth/ante/unorderedtx/snapshotter.go @@ -4,14 +4,15 @@ import ( "encoding/binary" "errors" "io" + "time" snapshot "cosmossdk.io/store/snapshots/types" ) const ( - txHashSize = 32 - ttlSize = 8 - chunkSize = txHashSize + ttlSize + txHashSize = 32 + timeoutSize = 8 + chunkSize = txHashSize + timeoutSize ) var _ snapshot.ExtensionSnapshotter = &Snapshotter{} @@ -78,11 +79,12 @@ func (s *Snapshotter) restore(height uint64, payloadReader snapshot.ExtensionPay var txHash TxHash copy(txHash[:], payload[i:i+txHashSize]) - ttl := binary.BigEndian.Uint64(payload[i+txHashSize : i+chunkSize]) + timestamp := binary.BigEndian.Uint64(payload[i+txHashSize : i+chunkSize]) - if height < ttl { - // only add unordered transactions that are still valid, i.e. unexpired - s.m.Add(txHash, ttl) + // add all txs, we don't care at this point if they are expired, + // we'll let the purge loop handle that + if timestamp != 0 { + s.m.Add(txHash, time.Unix(int64(timestamp), 0)) } i += chunkSize diff --git a/x/auth/ante/unorderedtx/snapshotter_test.go b/x/auth/ante/unorderedtx/snapshotter_test.go index bffd66ecf386..a912d69aea0c 100644 --- a/x/auth/ante/unorderedtx/snapshotter_test.go +++ b/x/auth/ante/unorderedtx/snapshotter_test.go @@ -2,6 +2,7 @@ package unorderedtx_test import ( "testing" + "time" "github.com/stretchr/testify/require" @@ -12,9 +13,11 @@ func TestSnapshotter(t *testing.T) { dataDir := t.TempDir() txm := unorderedtx.NewManager(dataDir) + currentTime := time.Now() + // add a handful of unordered txs for i := 0; i < 100; i++ { - txm.Add([32]byte{byte(i)}, 100) + txm.Add(unorderedtx.TxHash{byte(i)}, currentTime.Add(time.Second*100)) } var unorderedTxBz []byte @@ -36,21 +39,28 @@ func TestSnapshotter(t *testing.T) { err = s.RestoreExtension(50, 2, pr) require.Error(t, err) - // restore with height > ttl which should result in no unordered txs synced + // restore with timestamp > timeout time which should result in all unordered txs synced, + // even the ones that have timed out. txm2 := unorderedtx.NewManager(dataDir) s2 := unorderedtx.NewSnapshotter(txm2) - err = s2.RestoreExtension(200, unorderedtx.SnapshotFormat, pr) + err = s2.RestoreExtension(1, unorderedtx.SnapshotFormat, pr) require.NoError(t, err) - require.Empty(t, txm2.Size()) + require.Equal(t, 100, txm2.Size()) + + // start the manager and wait a bit for the background purge loop to run + txm2.Start() + txm2.OnNewBlock(currentTime.Add(time.Second * 200)) // blocks until channel is read in purge loop + // the loop runs every 5 seconds, so we need to wait for that + require.Eventually(t, func() bool { return txm2.Size() == 0 }, 6*time.Second, 500*time.Millisecond) - // restore with with height < ttl which should result in all unordered txs synced + // restore with timestamp < timeout time which should result in all unordered txs synced txm3 := unorderedtx.NewManager(dataDir) s3 := unorderedtx.NewSnapshotter(txm3) - err = s3.RestoreExtension(50, unorderedtx.SnapshotFormat, pr) + err = s3.RestoreExtension(uint64(currentTime.Add(time.Second*50).Unix()), unorderedtx.SnapshotFormat, pr) require.NoError(t, err) require.Equal(t, 100, txm3.Size()) for i := 0; i < 100; i++ { - require.True(t, txm3.Contains([32]byte{byte(i)})) + require.True(t, txm3.Contains(unorderedtx.TxHash{byte(i)})) } } diff --git a/x/auth/tx/builder.go b/x/auth/tx/builder.go index ffce977bd39b..13ac9812da80 100644 --- a/x/auth/tx/builder.go +++ b/x/auth/tx/builder.go @@ -3,6 +3,7 @@ package tx import ( "bytes" "fmt" + "time" "github.com/cosmos/gogoproto/proto" protov2 "google.golang.org/protobuf/proto" @@ -85,6 +86,18 @@ func (w *wrapper) GetMsgsV2() ([]protov2.Message, error) { return w.msgsV2, nil } +func (w *wrapper) SetTimeoutTimestamp(timestamp time.Time) { + w.tx.Body.TimeoutTimestamp = ×tamp +} + +func (w *wrapper) GetTimeoutTimeStamp() time.Time { + t := w.tx.Body.TimeoutTimestamp + if t == nil { + return time.Time{} + } + return *t +} + func (w *wrapper) ValidateBasic() error { if w.tx == nil { return fmt.Errorf("bad Tx") diff --git a/x/staking/types/staking.pb.go b/x/staking/types/staking.pb.go index dae487a8af20..b30d3498e254 100644 --- a/x/staking/types/staking.pb.go +++ b/x/staking/types/staking.pb.go @@ -1404,789 +1404,794 @@ func (this *Pool) Description() (desc *github_com_cosmos_gogoproto_protoc_gen_go func StakingDescription() (desc *github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet) { d := &github_com_cosmos_gogoproto_protoc_gen_gogo_descriptor.FileDescriptorSet{} var gzipped = []byte{ - // 12499 bytes of a gzipped FileDescriptorSet - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7d, 0x90, 0x64, 0xd7, - 0x55, 0x18, 0x3e, 0xaf, 0xbf, 0xfb, 0x74, 0x4f, 0xf7, 0x9b, 0x3b, 0xb3, 0xbb, 0xbd, 0xbd, 0xd2, + // 12584 bytes of a gzipped FileDescriptorSet + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0xbd, 0x7b, 0x90, 0x64, 0xd7, + 0x59, 0x18, 0x3e, 0xb7, 0xdf, 0xfd, 0x75, 0x4f, 0xf7, 0x9d, 0x33, 0xb3, 0xbb, 0xbd, 0xbd, 0xd2, 0xce, 0xa8, 0x65, 0x49, 0xab, 0x95, 0x34, 0xab, 0x1d, 0x69, 0x57, 0xda, 0x59, 0xcb, 0xfa, 0xf5, - 0xd7, 0xce, 0xf6, 0x6a, 0xa6, 0x7b, 0xf4, 0xba, 0x67, 0xa5, 0x15, 0xe0, 0xc7, 0x9b, 0xee, 0x3b, - 0x33, 0x4f, 0xdb, 0xfd, 0x5e, 0xbb, 0xdf, 0xeb, 0xd5, 0x8c, 0x7e, 0x55, 0x94, 0xc0, 0x86, 0x18, - 0x19, 0x13, 0x13, 0x28, 0x10, 0xd8, 0x6b, 0x6c, 0x08, 0x60, 0x08, 0x24, 0x60, 0x1c, 0x3e, 0x92, - 0x0a, 0x81, 0x7c, 0x82, 0x8b, 0x24, 0x86, 0xaa, 0x24, 0x24, 0x55, 0x28, 0xc1, 0xa6, 0x90, 0x30, - 0x26, 0x7c, 0x89, 0x84, 0x94, 0x2b, 0xe5, 0xd4, 0xfd, 0x7a, 0x1f, 0xfd, 0x31, 0xdd, 0xb3, 0x96, - 0x1d, 0x05, 0xf2, 0xcf, 0x4c, 0xdf, 0x7b, 0xcf, 0x39, 0xf7, 0xde, 0x73, 0xcf, 0x3d, 0xf7, 0x9c, - 0x73, 0x3f, 0x1e, 0xbc, 0xb1, 0x0d, 0x4b, 0xbb, 0xa6, 0xb9, 0xdb, 0xc6, 0xe7, 0xba, 0x3d, 0xd3, - 0x36, 0xb7, 0xfb, 0x3b, 0xe7, 0x5a, 0xd8, 0x6a, 0xf6, 0xf4, 0xae, 0x6d, 0xf6, 0x96, 0x69, 0x1e, - 0x4a, 0x33, 0x88, 0x65, 0x01, 0x91, 0xfb, 0xac, 0x04, 0x73, 0x57, 0xf4, 0x36, 0x2e, 0x39, 0x90, - 0x75, 0x6c, 0xa3, 0x27, 0x21, 0xb4, 0xa3, 0xb7, 0x71, 0x46, 0x5a, 0x0a, 0x9e, 0x49, 0xac, 0xbc, - 0x6b, 0x79, 0x00, 0x6b, 0xd9, 0x8f, 0xb1, 0x49, 0xb2, 0x15, 0x8a, 0x71, 0xf6, 0xff, 0x8f, 0xbd, - 0xf2, 0xa5, 0xcf, 0x7e, 0x45, 0x92, 0xbf, 0x95, 0xfc, 0xcd, 0x76, 0xd0, 0x4d, 0x96, 0x46, 0x8f, - 0x2f, 0x13, 0x3c, 0x4f, 0x7b, 0x6e, 0x9d, 0x27, 0x39, 0x2a, 0x41, 0x52, 0xdd, 0x6c, 0xd5, 0xc2, - 0xb6, 0x8a, 0xf7, 0x6d, 0x6c, 0x58, 0xba, 0x69, 0x64, 0x1f, 0x19, 0x81, 0x35, 0xd4, 0xda, 0xb2, - 0x00, 0xcf, 0xbd, 0x16, 0x86, 0xf9, 0x11, 0x4d, 0x43, 0x08, 0x42, 0x86, 0xd6, 0x21, 0xdd, 0x91, - 0xce, 0xc4, 0x15, 0xfa, 0x1b, 0x65, 0x20, 0xda, 0xd5, 0x9a, 0x37, 0xb5, 0x5d, 0x9c, 0x09, 0xd0, - 0x6c, 0x91, 0x44, 0xa7, 0x01, 0x5a, 0xb8, 0x8b, 0x8d, 0x16, 0x36, 0x9a, 0x07, 0x99, 0xe0, 0x52, - 0xf0, 0x4c, 0x5c, 0xf1, 0xe4, 0xa0, 0x87, 0x60, 0xae, 0xdb, 0xdf, 0x6e, 0xeb, 0x4d, 0xd5, 0x03, - 0x06, 0x4b, 0xc1, 0x33, 0x61, 0x45, 0x66, 0x05, 0x25, 0x17, 0xf8, 0x01, 0x48, 0xbf, 0x84, 0xb5, - 0x9b, 0x5e, 0xd0, 0x04, 0x05, 0x4d, 0x91, 0x6c, 0x0f, 0x60, 0x11, 0x92, 0x1d, 0x6c, 0x59, 0xda, - 0x2e, 0x56, 0xed, 0x83, 0x2e, 0xce, 0x84, 0x28, 0xeb, 0x97, 0x86, 0x58, 0x3f, 0xc8, 0xf6, 0x04, - 0xc7, 0x6a, 0x1c, 0x74, 0x31, 0xca, 0x43, 0x1c, 0x1b, 0xfd, 0x0e, 0xa3, 0x10, 0x1e, 0x33, 0x78, - 0x65, 0xa3, 0xdf, 0x19, 0xa4, 0x12, 0x23, 0x68, 0x9c, 0x44, 0xd4, 0xc2, 0xbd, 0x5b, 0x7a, 0x13, - 0x67, 0x22, 0x94, 0xc0, 0x03, 0x43, 0x04, 0xea, 0xac, 0x7c, 0x90, 0x86, 0xc0, 0x43, 0x45, 0x88, - 0x3b, 0x43, 0x98, 0x89, 0x52, 0x22, 0xf7, 0x8d, 0x10, 0x21, 0xdc, 0x6e, 0x0d, 0x92, 0x70, 0xf1, - 0xd0, 0x45, 0x88, 0x9a, 0x5d, 0x5b, 0x37, 0x0d, 0x2b, 0x13, 0x5b, 0x92, 0xce, 0x24, 0x56, 0xee, - 0x1a, 0x29, 0x85, 0x35, 0x06, 0xa3, 0x08, 0x60, 0x54, 0x01, 0xd9, 0x32, 0xfb, 0xbd, 0x26, 0x56, - 0x9b, 0x66, 0x0b, 0xab, 0xba, 0xb1, 0x63, 0x66, 0xe2, 0x94, 0xc0, 0xe2, 0x70, 0x47, 0x28, 0x60, - 0xd1, 0x6c, 0xe1, 0x8a, 0xb1, 0x63, 0x2a, 0x29, 0xcb, 0x97, 0x46, 0xc7, 0x21, 0x62, 0x1d, 0x18, - 0xb6, 0xb6, 0x9f, 0x49, 0x52, 0x09, 0xe1, 0x29, 0xb4, 0x02, 0x51, 0xdc, 0xd2, 0x49, 0x75, 0x99, - 0xd4, 0x92, 0x74, 0x26, 0xb5, 0x92, 0x19, 0xe6, 0x31, 0x2b, 0x57, 0x04, 0x60, 0xee, 0x97, 0x23, - 0x90, 0x9e, 0x46, 0x2c, 0x2f, 0x43, 0x78, 0x87, 0x70, 0x26, 0x13, 0x38, 0x0a, 0xdf, 0x18, 0x8e, - 0x9f, 0xf1, 0x91, 0x3b, 0x64, 0x7c, 0x1e, 0x12, 0x06, 0xb6, 0x6c, 0xdc, 0x62, 0x52, 0x14, 0x9c, - 0x52, 0x0e, 0x81, 0x21, 0x0d, 0x8b, 0x61, 0xe8, 0x8e, 0xc4, 0xf0, 0x79, 0x48, 0x3b, 0x4d, 0x52, - 0x7b, 0x9a, 0xb1, 0x2b, 0xe4, 0xf9, 0xdc, 0xa4, 0x96, 0x2c, 0x3b, 0xfa, 0x40, 0x21, 0x68, 0x4a, - 0x0a, 0xfb, 0xd2, 0xa8, 0x04, 0x60, 0x1a, 0xd8, 0xdc, 0x51, 0x5b, 0xb8, 0xd9, 0xce, 0xc4, 0xc6, - 0x70, 0xa9, 0x46, 0x40, 0x86, 0xb8, 0x64, 0xb2, 0xdc, 0x66, 0x1b, 0x5d, 0x72, 0xc5, 0x33, 0x3a, - 0x46, 0xba, 0x36, 0xd8, 0xc4, 0x1c, 0x92, 0xd0, 0x2d, 0x48, 0xf5, 0x30, 0x99, 0x2b, 0xb8, 0xc5, - 0x7b, 0x16, 0xa7, 0x8d, 0x58, 0x9e, 0xd8, 0x33, 0x85, 0xa3, 0xb1, 0x8e, 0xcd, 0xf6, 0xbc, 0x49, - 0x74, 0x2f, 0x38, 0x19, 0x2a, 0x15, 0x2b, 0xa0, 0x9a, 0x2b, 0x29, 0x32, 0xab, 0x5a, 0x07, 0x67, - 0x5f, 0x86, 0x94, 0x9f, 0x3d, 0x68, 0x01, 0xc2, 0x96, 0xad, 0xf5, 0x6c, 0x2a, 0x85, 0x61, 0x85, - 0x25, 0x90, 0x0c, 0x41, 0x6c, 0xb4, 0xa8, 0x66, 0x0c, 0x2b, 0xe4, 0x27, 0xfa, 0xff, 0xdc, 0x0e, - 0x07, 0x69, 0x87, 0xef, 0x1f, 0x1e, 0x51, 0x1f, 0xe5, 0xc1, 0x7e, 0x67, 0x9f, 0x80, 0x59, 0x5f, - 0x07, 0xa6, 0xad, 0x3a, 0xf7, 0x9b, 0x21, 0x38, 0x36, 0x92, 0x36, 0x7a, 0x1e, 0x16, 0xfa, 0x86, - 0x6e, 0xd8, 0xb8, 0xd7, 0xed, 0x61, 0x22, 0xb2, 0xac, 0xae, 0xcc, 0x1b, 0xd1, 0x31, 0x42, 0xb7, - 0xe5, 0x85, 0x66, 0x54, 0x94, 0xf9, 0xfe, 0x70, 0x26, 0xba, 0x01, 0x09, 0x22, 0x1f, 0x5a, 0x4f, - 0xa3, 0x04, 0xd9, 0x6c, 0x5c, 0x99, 0xae, 0xcb, 0xcb, 0x25, 0x17, 0xb3, 0x10, 0xfc, 0xa0, 0x14, - 0x50, 0xbc, 0xb4, 0xd0, 0x13, 0x10, 0xdb, 0xc1, 0x9a, 0xdd, 0xef, 0x61, 0x2b, 0xb3, 0x42, 0x59, - 0x79, 0x6a, 0x78, 0x92, 0x32, 0x80, 0x3a, 0xb6, 0x15, 0x07, 0x18, 0x75, 0x20, 0x79, 0x0b, 0xf7, - 0xf4, 0x1d, 0xbd, 0xc9, 0x1a, 0x15, 0xa4, 0xca, 0xe7, 0xc9, 0x29, 0x1b, 0x75, 0xdd, 0x83, 0x5a, - 0xb7, 0x35, 0x1b, 0xaf, 0xc2, 0x56, 0xf5, 0x7a, 0x59, 0xa9, 0x5c, 0xa9, 0x94, 0x4b, 0xac, 0x99, - 0x3e, 0xf2, 0xd9, 0xef, 0x93, 0x20, 0xe1, 0xe9, 0x09, 0x51, 0x87, 0x46, 0xbf, 0xb3, 0x8d, 0x7b, - 0x7c, 0xbc, 0x78, 0x0a, 0x9d, 0x82, 0xf8, 0x4e, 0xbf, 0xdd, 0x66, 0x42, 0xc7, 0xd6, 0xd2, 0x18, - 0xc9, 0x20, 0x02, 0x47, 0x74, 0x1c, 0x57, 0x23, 0x54, 0xc7, 0x91, 0xdf, 0x28, 0x0b, 0x31, 0x21, - 0x94, 0x99, 0xf0, 0x92, 0x74, 0x26, 0xa6, 0x38, 0x69, 0x56, 0xd6, 0xc5, 0x9a, 0x8d, 0x5b, 0x99, - 0x88, 0x28, 0x63, 0xe9, 0x6b, 0xa1, 0x58, 0x48, 0x0e, 0xe7, 0x1e, 0x87, 0xb9, 0xa1, 0xae, 0xa0, - 0x34, 0x24, 0x4a, 0xe5, 0xe2, 0x7a, 0x5e, 0xc9, 0x37, 0x2a, 0xb5, 0xaa, 0x3c, 0x83, 0x52, 0xe0, - 0xe9, 0x9d, 0x2c, 0x9d, 0x8d, 0xc7, 0xde, 0x8c, 0xca, 0xaf, 0xbc, 0xf2, 0xca, 0x2b, 0x81, 0xdc, - 0xaf, 0x45, 0x60, 0x61, 0x94, 0x12, 0x1c, 0xa9, 0x8f, 0xdd, 0x4e, 0x07, 0x7d, 0x9d, 0xce, 0x43, - 0xb8, 0xad, 0x6d, 0xe3, 0x76, 0x26, 0x44, 0x07, 0xe1, 0xa1, 0xa9, 0xd4, 0xec, 0xf2, 0x3a, 0x41, - 0x51, 0x18, 0x26, 0x7a, 0x0f, 0x67, 0x4d, 0x98, 0x52, 0x38, 0x3b, 0x1d, 0x05, 0xa2, 0x1c, 0x39, - 0x1b, 0x4f, 0x41, 0x9c, 0xfc, 0x67, 0x7c, 0x8f, 0x30, 0xbe, 0x93, 0x0c, 0xca, 0xf7, 0x2c, 0xc4, - 0xa8, 0xde, 0x6b, 0x61, 0x67, 0x4c, 0x44, 0x9a, 0x68, 0x8a, 0x16, 0xde, 0xd1, 0xfa, 0x6d, 0x5b, - 0xbd, 0xa5, 0xb5, 0xfb, 0x98, 0x6a, 0xb0, 0xb8, 0x92, 0xe4, 0x99, 0xd7, 0x49, 0x1e, 0x5a, 0x84, - 0x04, 0x53, 0x93, 0xba, 0xd1, 0xc2, 0xfb, 0x74, 0x09, 0x0d, 0x2b, 0x4c, 0x73, 0x56, 0x48, 0x0e, - 0xa9, 0xfe, 0x45, 0xcb, 0x34, 0x84, 0xae, 0xa1, 0x55, 0x90, 0x0c, 0x5a, 0xfd, 0x13, 0x83, 0xab, - 0xf7, 0xdd, 0xa3, 0xbb, 0x37, 0xa4, 0x1c, 0x1f, 0x80, 0x34, 0x85, 0x78, 0x8c, 0x4f, 0x65, 0xad, - 0x9d, 0x99, 0xa3, 0x62, 0x90, 0x62, 0xd9, 0x35, 0x9e, 0x9b, 0xfb, 0x85, 0x00, 0x84, 0xe8, 0x4a, - 0x91, 0x86, 0x44, 0xe3, 0xc6, 0x66, 0x59, 0x2d, 0xd5, 0xb6, 0x0a, 0xeb, 0x65, 0x59, 0x22, 0x43, - 0x4f, 0x33, 0xae, 0xac, 0xd7, 0xf2, 0x0d, 0x39, 0xe0, 0xa4, 0x2b, 0xd5, 0xc6, 0xc5, 0xc7, 0xe5, - 0xa0, 0x83, 0xb0, 0xc5, 0x32, 0x42, 0x5e, 0x80, 0xc7, 0x56, 0xe4, 0x30, 0x92, 0x21, 0xc9, 0x08, - 0x54, 0x9e, 0x2f, 0x97, 0x2e, 0x3e, 0x2e, 0x47, 0xfc, 0x39, 0x8f, 0xad, 0xc8, 0x51, 0x34, 0x0b, - 0x71, 0x9a, 0x53, 0xa8, 0xd5, 0xd6, 0xe5, 0x98, 0x43, 0xb3, 0xde, 0x50, 0x2a, 0xd5, 0x35, 0x39, - 0xee, 0xd0, 0x5c, 0x53, 0x6a, 0x5b, 0x9b, 0x32, 0x38, 0x14, 0x36, 0xca, 0xf5, 0x7a, 0x7e, 0xad, - 0x2c, 0x27, 0x1c, 0x88, 0xc2, 0x8d, 0x46, 0xb9, 0x2e, 0x27, 0x7d, 0xcd, 0x7a, 0x6c, 0x45, 0x9e, - 0x75, 0xaa, 0x28, 0x57, 0xb7, 0x36, 0xe4, 0x14, 0x9a, 0x83, 0x59, 0x56, 0x85, 0x68, 0x44, 0x7a, - 0x20, 0xeb, 0xe2, 0xe3, 0xb2, 0xec, 0x36, 0x84, 0x51, 0x99, 0xf3, 0x65, 0x5c, 0x7c, 0x5c, 0x46, - 0xb9, 0x22, 0x84, 0xa9, 0x18, 0x22, 0x04, 0xa9, 0xf5, 0x7c, 0xa1, 0xbc, 0xae, 0xd6, 0x36, 0xc9, - 0xa4, 0xc9, 0xaf, 0xcb, 0x92, 0x9b, 0xa7, 0x94, 0x37, 0xcb, 0xf9, 0x46, 0xb9, 0x24, 0x07, 0xbd, - 0x79, 0xcf, 0x6e, 0x55, 0x94, 0x72, 0x49, 0x0e, 0xe4, 0x9a, 0xb0, 0x30, 0x6a, 0x85, 0x1c, 0x39, - 0x85, 0x3c, 0xb2, 0x10, 0x18, 0x23, 0x0b, 0x94, 0xd6, 0xa0, 0x2c, 0xe4, 0xbe, 0x10, 0x80, 0xf9, - 0x11, 0x56, 0xc2, 0xc8, 0x4a, 0x9e, 0x86, 0x30, 0x93, 0x65, 0xa6, 0xa9, 0x1f, 0x1c, 0x69, 0x6e, - 0x50, 0xc9, 0x1e, 0xb2, 0x9d, 0x28, 0x9e, 0xd7, 0xde, 0x0c, 0x8e, 0xb1, 0x37, 0x09, 0x89, 0x21, - 0x81, 0xfd, 0xa6, 0xa1, 0xd5, 0x9c, 0x19, 0x3c, 0x17, 0xa7, 0x31, 0x78, 0x68, 0xde, 0xd1, 0x56, - 0xf5, 0xf0, 0x88, 0x55, 0xfd, 0x32, 0xcc, 0x0d, 0x11, 0x9a, 0x7a, 0x75, 0x7d, 0xbf, 0x04, 0x99, - 0x71, 0xcc, 0x99, 0xa0, 0x12, 0x03, 0x3e, 0x95, 0x78, 0x79, 0x90, 0x83, 0xf7, 0x8c, 0x1f, 0x84, - 0xa1, 0xb1, 0xfe, 0x09, 0x09, 0x8e, 0x8f, 0xf6, 0x2b, 0x46, 0xb6, 0xe1, 0x3d, 0x10, 0xe9, 0x60, - 0x7b, 0xcf, 0x14, 0x76, 0xf2, 0xfd, 0x23, 0xac, 0x2f, 0x52, 0x3c, 0x38, 0xd8, 0x1c, 0xcb, 0x6b, - 0xbe, 0x05, 0xc7, 0x39, 0x07, 0xac, 0x35, 0x43, 0x2d, 0xfd, 0xce, 0x00, 0x1c, 0x1b, 0x49, 0x7c, - 0x64, 0x43, 0xef, 0x06, 0xd0, 0x8d, 0x6e, 0xdf, 0x66, 0xb6, 0x30, 0xd3, 0xc4, 0x71, 0x9a, 0x43, - 0x95, 0x17, 0xd1, 0xb2, 0x7d, 0xdb, 0x29, 0x67, 0xab, 0x24, 0xb0, 0x2c, 0x0a, 0xf0, 0xa4, 0xdb, - 0xd0, 0x10, 0x6d, 0xe8, 0xe9, 0x31, 0x3d, 0x1d, 0x12, 0xcc, 0x47, 0x41, 0x6e, 0xb6, 0x75, 0x6c, - 0xd8, 0xaa, 0x65, 0xf7, 0xb0, 0xd6, 0xd1, 0x8d, 0x5d, 0xb6, 0xda, 0xae, 0x86, 0x77, 0xb4, 0xb6, - 0x85, 0x95, 0x34, 0x2b, 0xae, 0x8b, 0x52, 0x82, 0x41, 0x05, 0xa8, 0xe7, 0xc1, 0x88, 0xf8, 0x30, - 0x58, 0xb1, 0x83, 0x91, 0xfb, 0x99, 0x38, 0x24, 0x3c, 0x5e, 0x18, 0xba, 0x07, 0x92, 0x2f, 0x6a, - 0xb7, 0x34, 0x55, 0x78, 0xd6, 0x8c, 0x13, 0x09, 0x92, 0xb7, 0xc9, 0xbd, 0xeb, 0x47, 0x61, 0x81, - 0x82, 0x98, 0x7d, 0x1b, 0xf7, 0xd4, 0x66, 0x5b, 0xb3, 0x2c, 0xca, 0xb4, 0x18, 0x05, 0x45, 0xa4, - 0xac, 0x46, 0x8a, 0x8a, 0xa2, 0x04, 0x5d, 0x80, 0x79, 0x8a, 0xd1, 0xe9, 0xb7, 0x6d, 0xbd, 0xdb, - 0xc6, 0x34, 0x66, 0x60, 0xd1, 0x25, 0xc7, 0x69, 0xd9, 0x1c, 0x81, 0xd8, 0xe0, 0x00, 0xa4, 0x45, - 0x16, 0x2a, 0xc1, 0xdd, 0x14, 0x6d, 0x17, 0x1b, 0xb8, 0xa7, 0xd9, 0x58, 0xc5, 0xef, 0xeb, 0x6b, - 0x6d, 0x4b, 0xd5, 0x8c, 0x96, 0xba, 0xa7, 0x59, 0x7b, 0x99, 0x05, 0x42, 0xa0, 0x10, 0xc8, 0x48, - 0xca, 0x49, 0x02, 0xb8, 0xc6, 0xe1, 0xca, 0x14, 0x2c, 0x6f, 0xb4, 0xae, 0x6a, 0xd6, 0x1e, 0x5a, - 0x85, 0xe3, 0x94, 0x8a, 0x65, 0xf7, 0x74, 0x63, 0x57, 0x6d, 0xee, 0xe1, 0xe6, 0x4d, 0xb5, 0x6f, - 0xef, 0x3c, 0x99, 0x39, 0xe5, 0xad, 0x9f, 0xb6, 0xb0, 0x4e, 0x61, 0x8a, 0x04, 0x64, 0xcb, 0xde, - 0x79, 0x12, 0xd5, 0x21, 0x49, 0x06, 0xa3, 0xa3, 0xbf, 0x8c, 0xd5, 0x1d, 0xb3, 0x47, 0xd7, 0xd0, - 0xd4, 0x08, 0xd5, 0xe4, 0xe1, 0xe0, 0x72, 0x8d, 0x23, 0x6c, 0x98, 0x2d, 0xbc, 0x1a, 0xae, 0x6f, - 0x96, 0xcb, 0x25, 0x25, 0x21, 0xa8, 0x5c, 0x31, 0x7b, 0x44, 0xa0, 0x76, 0x4d, 0x87, 0xc1, 0x09, - 0x26, 0x50, 0xbb, 0xa6, 0x60, 0xef, 0x05, 0x98, 0x6f, 0x36, 0x59, 0x9f, 0xf5, 0xa6, 0xca, 0x3d, - 0x72, 0x2b, 0x23, 0xfb, 0x98, 0xd5, 0x6c, 0xae, 0x31, 0x00, 0x2e, 0xe3, 0x16, 0xba, 0x04, 0xc7, - 0x5c, 0x66, 0x79, 0x11, 0xe7, 0x86, 0x7a, 0x39, 0x88, 0x7a, 0x01, 0xe6, 0xbb, 0x07, 0xc3, 0x88, - 0xc8, 0x57, 0x63, 0xf7, 0x60, 0x10, 0xed, 0x3e, 0x1a, 0x65, 0xe9, 0xe1, 0x26, 0x35, 0xf5, 0x4e, - 0x78, 0xa1, 0x3d, 0x05, 0x68, 0x19, 0xe4, 0x66, 0x53, 0xc5, 0x86, 0xb6, 0xdd, 0xc6, 0xaa, 0xd6, - 0xc3, 0x86, 0x66, 0x65, 0x16, 0x29, 0x70, 0xc8, 0xee, 0xf5, 0xb1, 0x92, 0x6a, 0x36, 0xcb, 0xb4, - 0x30, 0x4f, 0xcb, 0xd0, 0x59, 0x98, 0x33, 0xb7, 0x5f, 0x6c, 0x32, 0xc1, 0x52, 0xbb, 0x3d, 0xbc, - 0xa3, 0xef, 0x67, 0xde, 0x45, 0xb9, 0x94, 0x26, 0x05, 0x54, 0xac, 0x36, 0x69, 0x36, 0x7a, 0x10, - 0xe4, 0xa6, 0xb5, 0xa7, 0xf5, 0xba, 0x54, 0xb3, 0x5a, 0x5d, 0xad, 0x89, 0x33, 0xf7, 0x31, 0x50, - 0x96, 0x5f, 0x15, 0xd9, 0x44, 0xb0, 0xad, 0x97, 0xf4, 0x1d, 0x5b, 0x50, 0x7c, 0x80, 0x09, 0x36, - 0xcd, 0xe3, 0xd4, 0xce, 0x80, 0xdc, 0xdd, 0xeb, 0xfa, 0x2b, 0x3e, 0x43, 0xc1, 0x52, 0xdd, 0xbd, - 0xae, 0xb7, 0xde, 0x7b, 0x61, 0x96, 0x40, 0xba, 0x95, 0x3e, 0xc8, 0xec, 0xaf, 0xee, 0x9e, 0xa7, - 0xc6, 0xc7, 0xe1, 0x38, 0x01, 0xea, 0x60, 0x5b, 0x6b, 0x69, 0xb6, 0xe6, 0x81, 0x7e, 0x98, 0x42, - 0x2f, 0x74, 0xf7, 0xba, 0x1b, 0xbc, 0xd0, 0xd7, 0xce, 0x5e, 0x7f, 0xfb, 0xc0, 0x91, 0x8f, 0x47, - 0x58, 0x3b, 0x49, 0x9e, 0x90, 0x90, 0x3b, 0x76, 0x3f, 0xbe, 0x66, 0xce, 0x56, 0x6e, 0x15, 0x92, - 0x5e, 0xb9, 0x47, 0x71, 0x60, 0x92, 0x2f, 0x4b, 0xc4, 0x08, 0x2a, 0xd6, 0x4a, 0xc4, 0x7c, 0x79, - 0xa1, 0x2c, 0x07, 0x88, 0x19, 0xb5, 0x5e, 0x69, 0x94, 0x55, 0x65, 0xab, 0xda, 0xa8, 0x6c, 0x94, - 0xe5, 0xa0, 0xc7, 0xb0, 0xbf, 0x16, 0x8a, 0x9d, 0x95, 0x1f, 0xba, 0x16, 0x8a, 0xdd, 0x2f, 0x3f, - 0x40, 0xd9, 0x33, 0x24, 0x94, 0xb9, 0xb7, 0x82, 0x90, 0xf2, 0xbb, 0xe5, 0xe8, 0xdd, 0x70, 0x42, - 0xc4, 0xdd, 0x2c, 0x6c, 0xab, 0x2f, 0xe9, 0x3d, 0x3a, 0x59, 0x3b, 0x1a, 0x5b, 0x38, 0x1d, 0xa1, - 0x5c, 0xe0, 0x50, 0x75, 0x6c, 0x3f, 0xa7, 0xf7, 0xc8, 0x54, 0xec, 0x68, 0x36, 0x5a, 0x87, 0x45, - 0xc3, 0x54, 0x2d, 0x5b, 0x33, 0x5a, 0x5a, 0xaf, 0xe5, 0x0d, 0x64, 0x6a, 0xcd, 0x26, 0xb6, 0x2c, - 0x93, 0x2d, 0x92, 0x0e, 0x95, 0xbb, 0x0c, 0xb3, 0xce, 0x81, 0xdd, 0xd5, 0x23, 0xcf, 0x41, 0x07, - 0xe6, 0x44, 0x70, 0xdc, 0x9c, 0x38, 0x05, 0xf1, 0x8e, 0xd6, 0x55, 0xb1, 0x61, 0xf7, 0x0e, 0xa8, - 0xed, 0x1e, 0x53, 0x62, 0x1d, 0xad, 0x5b, 0x26, 0x69, 0x74, 0x1d, 0xee, 0x77, 0x41, 0xd5, 0x36, - 0xde, 0xd5, 0x9a, 0x07, 0x2a, 0x35, 0xd4, 0x69, 0x8c, 0x48, 0x6d, 0x9a, 0xc6, 0x4e, 0x5b, 0x6f, - 0xda, 0x16, 0xd5, 0x1d, 0x4c, 0xff, 0xe5, 0x5c, 0x8c, 0x75, 0x8a, 0x70, 0xcd, 0x32, 0x0d, 0x6a, - 0x9f, 0x17, 0x05, 0xb4, 0x4f, 0x6c, 0x92, 0xef, 0x08, 0xb1, 0xf1, 0x0f, 0x7d, 0x48, 0x0e, 0x5f, - 0x0b, 0xc5, 0xc2, 0x72, 0xe4, 0x5a, 0x28, 0x16, 0x91, 0xa3, 0xd7, 0x42, 0xb1, 0x98, 0x1c, 0xbf, - 0x16, 0x8a, 0xc5, 0x65, 0xc8, 0xdd, 0x9e, 0x85, 0xa4, 0xd7, 0xdd, 0x20, 0xde, 0x5b, 0x93, 0x2e, - 0xb8, 0x12, 0x55, 0xc9, 0xf7, 0x1e, 0xea, 0x9c, 0x2c, 0x17, 0xc9, 0x4a, 0xbc, 0x1a, 0x61, 0xb6, - 0xbd, 0xc2, 0x30, 0x89, 0x15, 0x44, 0x26, 0x19, 0x66, 0xb6, 0x54, 0x4c, 0xe1, 0x29, 0xb4, 0x06, - 0x91, 0x17, 0x2d, 0x4a, 0x3b, 0x42, 0x69, 0xbf, 0xeb, 0x70, 0xda, 0xd7, 0xea, 0x94, 0x78, 0xfc, - 0x5a, 0x5d, 0xad, 0xd6, 0x94, 0x8d, 0xfc, 0xba, 0xc2, 0xd1, 0xd1, 0x49, 0x08, 0xb5, 0xb5, 0x97, - 0x0f, 0xfc, 0x6b, 0x36, 0xcd, 0x42, 0xcb, 0x90, 0xee, 0x1b, 0xcc, 0x57, 0x27, 0x63, 0x4c, 0xa0, - 0xd2, 0x5e, 0xa8, 0x94, 0x5b, 0xba, 0x4e, 0xe0, 0xa7, 0x94, 0xab, 0x93, 0x10, 0x7a, 0x09, 0x6b, - 0x37, 0xfd, 0x2b, 0x2b, 0xcd, 0x42, 0x67, 0x20, 0xd9, 0xc2, 0xdb, 0xfd, 0x5d, 0xb5, 0x87, 0x5b, - 0x5a, 0xd3, 0xf6, 0xaf, 0x27, 0x09, 0x5a, 0xa4, 0xd0, 0x12, 0xf4, 0x0c, 0xc4, 0xc9, 0x18, 0x19, - 0x74, 0x8c, 0xe7, 0x28, 0x0b, 0x1e, 0x39, 0x9c, 0x05, 0x7c, 0x88, 0x05, 0x92, 0xe2, 0xe2, 0xa3, - 0xab, 0x10, 0xb5, 0xb5, 0xde, 0x2e, 0xb6, 0xad, 0xcc, 0xfc, 0x52, 0xf0, 0x4c, 0x6a, 0x44, 0x8c, - 0x6c, 0x04, 0xa9, 0x06, 0x45, 0xa1, 0x9e, 0xb2, 0x40, 0x47, 0xcf, 0x81, 0xcc, 0x43, 0xb1, 0x2a, - 0x77, 0x73, 0xad, 0xcc, 0x02, 0x15, 0xc0, 0x87, 0x0f, 0x27, 0xc9, 0x23, 0xb9, 0x25, 0x86, 0xa4, - 0xa4, 0xb1, 0x2f, 0xed, 0x9f, 0x17, 0xc7, 0x8e, 0x32, 0x2f, 0xb6, 0x20, 0xcd, 0x7f, 0xab, 0x56, - 0xbf, 0xdb, 0x35, 0x7b, 0x76, 0xe6, 0x38, 0xc5, 0x9f, 0xd0, 0x20, 0x41, 0x8c, 0xe1, 0x28, 0xa9, - 0x1d, 0x5f, 0xfa, 0x6b, 0x37, 0xdd, 0xb2, 0x2f, 0x40, 0xca, 0xcf, 0x0c, 0x6f, 0x20, 0x3c, 0x38, - 0x65, 0x20, 0x9c, 0xb8, 0x25, 0xc2, 0x51, 0x23, 0x4b, 0x13, 0x4b, 0x64, 0xbf, 0x3f, 0x00, 0x29, - 0x7f, 0xc7, 0xd0, 0x1a, 0x20, 0x31, 0x62, 0xba, 0x61, 0xf7, 0xcc, 0x56, 0xbf, 0x89, 0x5b, 0x7c, - 0xc2, 0x8e, 0xaf, 0x67, 0x8e, 0xe3, 0x54, 0x1c, 0x14, 0x2f, 0x21, 0xcf, 0x2c, 0x08, 0x4c, 0x49, - 0xa8, 0xe4, 0xce, 0x8f, 0x73, 0x30, 0x2f, 0x08, 0x10, 0x62, 0x2f, 0x69, 0x3d, 0x83, 0x98, 0xc8, - 0xcc, 0x68, 0x47, 0x9e, 0xa2, 0xe7, 0x58, 0x09, 0xca, 0x83, 0x10, 0x17, 0xb5, 0x87, 0x3b, 0xe6, - 0x2d, 0xdc, 0xe2, 0xe1, 0xa2, 0xf1, 0xd5, 0xa6, 0x38, 0x82, 0xc2, 0xe0, 0x73, 0xe7, 0x20, 0x4c, - 0xd5, 0x0f, 0x02, 0xe0, 0x0a, 0x48, 0x9e, 0x41, 0x31, 0x08, 0x15, 0x6b, 0x0a, 0x59, 0x1e, 0x65, - 0x48, 0xb2, 0x5c, 0x75, 0xb3, 0x52, 0x2e, 0x96, 0xe5, 0x40, 0xee, 0x02, 0x44, 0x98, 0x4e, 0x21, - 0x4b, 0xa7, 0xa3, 0x55, 0xe4, 0x19, 0x9e, 0xe4, 0x34, 0x24, 0x51, 0xba, 0xb5, 0x51, 0x28, 0x2b, - 0x72, 0x20, 0xb7, 0x05, 0xe9, 0x81, 0x79, 0x88, 0x8e, 0xc1, 0x9c, 0x52, 0x6e, 0x94, 0xab, 0x8d, - 0x4a, 0xad, 0xaa, 0x6e, 0x55, 0x9f, 0xa9, 0xd6, 0x9e, 0xab, 0xca, 0x33, 0xfe, 0x6c, 0xb1, 0x0e, - 0x4b, 0x68, 0x01, 0x64, 0x37, 0xbb, 0x5e, 0xdb, 0x52, 0x68, 0x6b, 0xbe, 0x2b, 0x00, 0xf2, 0xe0, - 0xa4, 0x44, 0x27, 0x60, 0xbe, 0x91, 0x57, 0xd6, 0xca, 0x0d, 0x95, 0x05, 0x3c, 0x1c, 0xd2, 0x0b, - 0x20, 0x7b, 0x0b, 0xae, 0x54, 0x68, 0x3c, 0x67, 0x11, 0x4e, 0x79, 0x73, 0xcb, 0xcf, 0x37, 0xca, - 0xd5, 0x3a, 0xad, 0x3c, 0x5f, 0x5d, 0x23, 0x46, 0xc1, 0x00, 0x3d, 0x11, 0x62, 0x09, 0x92, 0xa6, - 0xfa, 0xe9, 0x95, 0xd7, 0x4b, 0x72, 0x68, 0x30, 0xbb, 0x56, 0x2d, 0xd7, 0xae, 0xc8, 0xe1, 0xc1, - 0xda, 0x69, 0xd8, 0x25, 0x82, 0xb2, 0x70, 0x7c, 0x30, 0x57, 0x2d, 0x57, 0x1b, 0xca, 0x0d, 0x39, - 0x3a, 0x58, 0x71, 0xbd, 0xac, 0x5c, 0xaf, 0x14, 0xcb, 0x72, 0x0c, 0x1d, 0x07, 0xe4, 0x6f, 0x51, - 0xe3, 0x6a, 0xad, 0x24, 0xc7, 0x47, 0xad, 0x58, 0x48, 0x9e, 0xcf, 0xfd, 0xb4, 0x04, 0x49, 0x6f, - 0x08, 0xc4, 0xa7, 0x54, 0xa4, 0x77, 0xda, 0x62, 0x9b, 0xfb, 0xad, 0x00, 0x24, 0x3c, 0xb1, 0x10, - 0xe2, 0xc4, 0x6a, 0xed, 0xb6, 0xf9, 0x92, 0xaa, 0xb5, 0x75, 0xcd, 0xe2, 0xeb, 0x21, 0xd0, 0xac, - 0x3c, 0xc9, 0x99, 0x76, 0xfd, 0x99, 0xde, 0x74, 0x89, 0xdc, 0xb1, 0xe9, 0x12, 0x7d, 0x07, 0x9a, - 0x2e, 0x61, 0x39, 0x92, 0xfb, 0x9d, 0x00, 0xc8, 0x83, 0xd1, 0x91, 0x01, 0xbe, 0x49, 0xe3, 0xf8, - 0xe6, 0xed, 0x5f, 0xe0, 0x28, 0xfd, 0x1b, 0x5c, 0xd5, 0x83, 0x63, 0x57, 0xf5, 0x11, 0x8b, 0x55, - 0xe8, 0x9d, 0xbc, 0x58, 0x79, 0xc5, 0xf5, 0xdf, 0x4b, 0x90, 0xf2, 0x07, 0x73, 0x7c, 0x1c, 0xcb, - 0x1d, 0x85, 0x63, 0xfe, 0x11, 0xb9, 0x67, 0xdc, 0x88, 0x7c, 0x5d, 0xfa, 0xf5, 0x83, 0x41, 0x98, - 0xf5, 0xc5, 0x7e, 0xa6, 0x6d, 0xdd, 0xfb, 0x60, 0x4e, 0x6f, 0xe1, 0x4e, 0xd7, 0xb4, 0xb1, 0xd1, - 0x3c, 0x50, 0xdb, 0xf8, 0x16, 0x6e, 0x53, 0x36, 0xa4, 0x46, 0xec, 0xae, 0xfa, 0x6a, 0x58, 0xae, - 0xb8, 0x78, 0xeb, 0x04, 0x6d, 0x75, 0xbe, 0x52, 0x2a, 0x6f, 0x6c, 0xd6, 0x1a, 0xe5, 0x6a, 0xf1, - 0x86, 0xd0, 0xe4, 0x8a, 0xac, 0x0f, 0x80, 0xf9, 0x18, 0x7e, 0xef, 0x3b, 0xc3, 0xe9, 0xdc, 0x04, - 0x79, 0xb0, 0x37, 0x44, 0xa1, 0x8f, 0xe8, 0x8f, 0x3c, 0x83, 0xe6, 0x21, 0x5d, 0xad, 0xa9, 0xf5, - 0x4a, 0xa9, 0xac, 0x96, 0xaf, 0x5c, 0x29, 0x17, 0x1b, 0x75, 0xb6, 0xd1, 0xe0, 0x40, 0x37, 0xe4, - 0x80, 0x77, 0x6c, 0x7e, 0x28, 0x08, 0xf3, 0x23, 0x5a, 0x82, 0xf2, 0x3c, 0x44, 0xc8, 0xa2, 0x96, - 0x8f, 0x4c, 0xd3, 0xfa, 0x65, 0xe2, 0xdd, 0x6f, 0x6a, 0x3d, 0x9b, 0x47, 0x14, 0x1f, 0x04, 0xc2, - 0x5e, 0xc3, 0x26, 0xe6, 0x7d, 0x8f, 0x6f, 0xe0, 0x30, 0x13, 0x24, 0xed, 0xe6, 0xb3, 0x3d, 0x9c, - 0x87, 0x01, 0x75, 0x4d, 0x4b, 0xb7, 0xf5, 0x5b, 0x98, 0xd8, 0x50, 0x1c, 0x98, 0x4c, 0xdc, 0x90, - 0x22, 0x8b, 0x92, 0x8a, 0x61, 0x3b, 0xd0, 0x06, 0xde, 0xd5, 0x06, 0xa0, 0x89, 0xfb, 0x11, 0x54, - 0x64, 0x51, 0xe2, 0x40, 0xdf, 0x03, 0xc9, 0x96, 0xd9, 0xdf, 0x6e, 0x63, 0x0e, 0x47, 0x54, 0xb2, - 0xa4, 0x24, 0x58, 0x9e, 0x03, 0xc2, 0xc3, 0x66, 0xee, 0x36, 0x53, 0x52, 0x49, 0xb0, 0x3c, 0x06, - 0xf2, 0x00, 0xa4, 0xb5, 0xdd, 0xdd, 0x1e, 0x21, 0x2e, 0x08, 0xb1, 0x40, 0x60, 0xca, 0xc9, 0xa6, - 0x80, 0xd9, 0x6b, 0x10, 0x13, 0x7c, 0x20, 0xfe, 0x2f, 0xe1, 0x84, 0xda, 0x65, 0xd1, 0xed, 0xc0, - 0x99, 0xb8, 0x12, 0x33, 0x44, 0xe1, 0x3d, 0x90, 0xd4, 0x2d, 0xf7, 0x08, 0x51, 0x26, 0xb0, 0x14, - 0x38, 0x13, 0x53, 0x12, 0xba, 0xe5, 0x1e, 0x13, 0xfa, 0x99, 0x04, 0x80, 0x2b, 0x6c, 0xe8, 0x7b, - 0x24, 0x48, 0xb1, 0x05, 0xa6, 0xdb, 0xc3, 0x16, 0x36, 0x9a, 0xc2, 0x2d, 0x7c, 0xf0, 0x10, 0x11, - 0x65, 0x6a, 0x6e, 0x93, 0x23, 0x14, 0x9e, 0xfe, 0xa0, 0x24, 0xbd, 0x26, 0x85, 0x5e, 0x93, 0xa4, - 0x1f, 0x91, 0x66, 0x51, 0xac, 0xfc, 0xfc, 0xe6, 0x7a, 0xa5, 0x58, 0x69, 0x64, 0x3e, 0x10, 0xa5, - 0xe9, 0xca, 0x06, 0x4f, 0xbf, 0x11, 0xf5, 0x97, 0xbf, 0x19, 0xfd, 0xb4, 0x14, 0x8c, 0xbd, 0x19, - 0x55, 0x66, 0x77, 0xbc, 0xf4, 0x50, 0xdb, 0x7b, 0x82, 0x22, 0x30, 0xce, 0x91, 0x74, 0x5b, 0x53, - 0xe6, 0xe7, 0x26, 0x0a, 0x0f, 0xd2, 0x86, 0x44, 0x68, 0x43, 0x12, 0x28, 0x52, 0x5c, 0xaf, 0xd5, - 0xcb, 0x25, 0xda, 0x8c, 0x38, 0x0a, 0xd5, 0x36, 0xcb, 0xd5, 0xcc, 0x1b, 0xa2, 0x4a, 0xf7, 0xb0, - 0xc5, 0x6b, 0x12, 0x9c, 0x10, 0xbb, 0xac, 0x7c, 0xad, 0xc5, 0x46, 0xd3, 0x6c, 0x09, 0xeb, 0x36, - 0xb5, 0x72, 0xfe, 0xb0, 0xca, 0x15, 0x8e, 0x4a, 0x59, 0x52, 0xe6, 0x88, 0x85, 0x47, 0x86, 0x58, - 0x92, 0xaf, 0x96, 0x78, 0x5b, 0x12, 0x28, 0xb2, 0x99, 0x2f, 0x3e, 0x53, 0x2e, 0xb9, 0xad, 0x39, - 0xd6, 0x1b, 0x45, 0x05, 0x7d, 0x0b, 0xa4, 0xfb, 0xf6, 0xce, 0x93, 0x44, 0x36, 0xf4, 0x16, 0xdb, - 0xf6, 0x0e, 0x8d, 0xdb, 0x2f, 0x75, 0x5b, 0xb4, 0x65, 0xef, 0x3c, 0x79, 0xdd, 0xc1, 0xe0, 0x4c, - 0x61, 0x4d, 0x89, 0xa3, 0x50, 0xb5, 0x56, 0x2d, 0x8b, 0x66, 0xd0, 0x2d, 0xe2, 0x1b, 0x6e, 0x33, - 0x52, 0x7d, 0x1f, 0x2a, 0xfa, 0x16, 0x90, 0x45, 0x78, 0xc8, 0x61, 0x49, 0x78, 0xdc, 0x96, 0xaf, - 0xdb, 0x00, 0x1e, 0x64, 0x72, 0x98, 0x71, 0xbf, 0xa7, 0x05, 0x0b, 0x28, 0xbd, 0x5e, 0xae, 0xae, - 0x35, 0xae, 0xaa, 0x9b, 0x4a, 0x99, 0xee, 0xdc, 0x65, 0x3e, 0x20, 0xaa, 0x4f, 0x77, 0xfc, 0x88, - 0xe8, 0xdb, 0x24, 0x48, 0x30, 0x13, 0x88, 0xc5, 0xa4, 0x58, 0x50, 0xe1, 0xfe, 0xc3, 0xea, 0xa6, - 0x16, 0x10, 0x85, 0x2e, 0x5c, 0xa2, 0xd5, 0x06, 0x85, 0x40, 0x9c, 0x40, 0x68, 0xbd, 0xbc, 0x96, - 0x2f, 0xde, 0x50, 0x0b, 0xe5, 0x7a, 0x83, 0x68, 0xb2, 0x9a, 0xc2, 0x64, 0x14, 0x50, 0x38, 0xbf, - 0xbe, 0x5e, 0x7b, 0xce, 0x65, 0x04, 0xbc, 0xe8, 0x90, 0xc9, 0x7d, 0x23, 0xcc, 0xfa, 0xc4, 0x9d, - 0x18, 0xc5, 0xd4, 0x98, 0x26, 0x3d, 0xa8, 0x97, 0xab, 0x45, 0xaf, 0x11, 0x9f, 0x04, 0x47, 0xbc, - 0x65, 0x89, 0xa4, 0x84, 0xf0, 0xcb, 0x01, 0xa2, 0x46, 0x79, 0x03, 0x9c, 0xbd, 0xc4, 0x60, 0xee, - 0x09, 0x88, 0x09, 0xf1, 0x25, 0xa6, 0x39, 0xb5, 0xb0, 0x07, 0x1c, 0x83, 0x18, 0x50, 0xd9, 0x95, - 0x25, 0xe2, 0x06, 0x31, 0x99, 0x96, 0x03, 0xb9, 0xeb, 0x70, 0x6c, 0xa4, 0xe8, 0xa1, 0x7b, 0x61, - 0x51, 0xec, 0x5f, 0x32, 0xa3, 0x5f, 0x2d, 0x57, 0x8b, 0xb5, 0x12, 0x71, 0x93, 0x5c, 0x9a, 0x00, - 0x5c, 0x06, 0x59, 0x2b, 0x85, 0x7c, 0xca, 0x81, 0x5c, 0x05, 0x52, 0x7e, 0x01, 0x42, 0xa7, 0xe0, - 0xc4, 0x56, 0xe3, 0xca, 0x93, 0xea, 0xf5, 0xfc, 0x7a, 0xa5, 0x94, 0x1f, 0x70, 0x88, 0x00, 0xb8, - 0x14, 0xc9, 0x01, 0xd2, 0x50, 0x22, 0x5d, 0x72, 0x30, 0x17, 0x8a, 0x49, 0xb2, 0x94, 0xab, 0x43, - 0x7a, 0x40, 0x14, 0xd0, 0x5d, 0x90, 0xe1, 0x1e, 0xca, 0xa8, 0x56, 0x51, 0x0e, 0xf9, 0x84, 0x83, - 0xf9, 0x6a, 0xa5, 0xf2, 0x7a, 0x65, 0xa3, 0xd2, 0xa0, 0xed, 0xbb, 0x0a, 0xe0, 0x8e, 0x31, 0x59, - 0xb3, 0xae, 0xd5, 0x6b, 0x55, 0xf5, 0x0a, 0x71, 0xf4, 0x1a, 0x1e, 0x52, 0x71, 0x60, 0x63, 0x2a, - 0x4b, 0xc4, 0x1f, 0x19, 0x1e, 0x78, 0x39, 0x70, 0xf6, 0x43, 0x12, 0x59, 0xb2, 0x3e, 0x54, 0xcd, - 0x7e, 0x9b, 0x84, 0xee, 0x8e, 0xbd, 0x19, 0x45, 0xd1, 0xe5, 0xee, 0xf6, 0x72, 0xb3, 0xdb, 0xcd, - 0xa6, 0xc9, 0x8f, 0x62, 0xb7, 0x7b, 0x45, 0x2c, 0xc4, 0x8b, 0xb1, 0x3f, 0x8c, 0xa2, 0x18, 0xc9, - 0x7d, 0x51, 0xbb, 0xa5, 0x65, 0x65, 0xf2, 0xeb, 0x9a, 0x76, 0x4b, 0x73, 0x00, 0x4e, 0xc5, 0xbe, - 0x18, 0x45, 0x11, 0x92, 0xbd, 0x6b, 0x66, 0x53, 0xe4, 0xff, 0x9a, 0xe9, 0x14, 0xde, 0x1b, 0xfb, - 0x8e, 0x2a, 0x02, 0x92, 0x49, 0x25, 0xf6, 0x7c, 0x16, 0x91, 0xdf, 0x74, 0xdb, 0xec, 0xbc, 0x00, + 0x6b, 0x77, 0x7a, 0x35, 0xd3, 0x3d, 0xba, 0xdd, 0xb3, 0xd2, 0x0a, 0xf0, 0xe5, 0x4e, 0xf7, 0x99, + 0x99, 0xab, 0xed, 0xbe, 0xb7, 0xdd, 0xf7, 0xf6, 0x6a, 0x46, 0xbf, 0x2a, 0x4a, 0x60, 0xc3, 0xcf, + 0xc8, 0x98, 0x9f, 0xf9, 0x41, 0x81, 0xc0, 0x5e, 0x63, 0xc3, 0x0f, 0x30, 0x04, 0x12, 0xb0, 0x1d, + 0x1e, 0x49, 0x85, 0x47, 0x9e, 0xe0, 0x90, 0xc4, 0x50, 0x95, 0x84, 0xa4, 0x0a, 0x25, 0xd8, 0x14, + 0x12, 0xc6, 0x84, 0x97, 0x48, 0x48, 0xb9, 0x52, 0x4e, 0x9d, 0xd7, 0x7d, 0xf4, 0x63, 0xba, 0x67, + 0x2d, 0x13, 0x05, 0xf2, 0xcf, 0xee, 0xdc, 0x73, 0xbe, 0xef, 0x3b, 0xe7, 0x7c, 0xe7, 0x3b, 0xdf, + 0xeb, 0x3c, 0x1a, 0xde, 0xd8, 0x86, 0xa5, 0x5d, 0xd3, 0xdc, 0x6d, 0xe3, 0x73, 0xdd, 0x9e, 0x69, + 0x9b, 0xdb, 0xfd, 0x9d, 0x73, 0x2d, 0x6c, 0x35, 0x7b, 0x7a, 0xd7, 0x36, 0x7b, 0xcb, 0xb4, 0x0c, + 0xa5, 0x19, 0xc4, 0xb2, 0x80, 0xc8, 0x7d, 0x4e, 0x82, 0xb9, 0x2b, 0x7a, 0x1b, 0x97, 0x1c, 0xc8, + 0x3a, 0xb6, 0xd1, 0x93, 0x10, 0xda, 0xd1, 0xdb, 0x38, 0x23, 0x2d, 0x05, 0xcf, 0x24, 0x56, 0xde, + 0xb5, 0x3c, 0x80, 0xb5, 0xec, 0xc7, 0xd8, 0x24, 0xc5, 0x0a, 0xc5, 0x38, 0xfb, 0x7f, 0xc7, 0x5e, + 0xf9, 0xf2, 0xe7, 0xbe, 0x2a, 0xc9, 0xdf, 0x4a, 0xfe, 0xcd, 0x76, 0xd0, 0x4d, 0xf6, 0x8d, 0x1e, + 0x5f, 0x26, 0x78, 0x9e, 0xfe, 0xdc, 0x3a, 0x4f, 0x4a, 0x54, 0x82, 0xa4, 0xba, 0xc5, 0xaa, 0x85, + 0x6d, 0x15, 0xef, 0xdb, 0xd8, 0xb0, 0x74, 0xd3, 0xc8, 0x3e, 0x32, 0x02, 0x6b, 0xa8, 0xb7, 0x65, + 0x01, 0x9e, 0x7b, 0x2d, 0x0c, 0xf3, 0x23, 0xba, 0x86, 0x10, 0x84, 0x0c, 0xad, 0x43, 0x86, 0x23, + 0x9d, 0x89, 0x2b, 0xf4, 0x6f, 0x94, 0x81, 0x68, 0x57, 0x6b, 0xde, 0xd4, 0x76, 0x71, 0x26, 0x40, + 0x8b, 0xc5, 0x27, 0x3a, 0x0d, 0xd0, 0xc2, 0x5d, 0x6c, 0xb4, 0xb0, 0xd1, 0x3c, 0xc8, 0x04, 0x97, + 0x82, 0x67, 0xe2, 0x8a, 0xa7, 0x04, 0x3d, 0x04, 0x73, 0xdd, 0xfe, 0x76, 0x5b, 0x6f, 0xaa, 0x1e, + 0x30, 0x58, 0x0a, 0x9e, 0x09, 0x2b, 0x32, 0xab, 0x28, 0xb9, 0xc0, 0x0f, 0x40, 0xfa, 0x25, 0xac, + 0xdd, 0xf4, 0x82, 0x26, 0x28, 0x68, 0x8a, 0x14, 0x7b, 0x00, 0x8b, 0x90, 0xec, 0x60, 0xcb, 0xd2, + 0x76, 0xb1, 0x6a, 0x1f, 0x74, 0x71, 0x26, 0x44, 0x59, 0xbf, 0x34, 0xc4, 0xfa, 0x41, 0xb6, 0x27, + 0x38, 0x56, 0xe3, 0xa0, 0x8b, 0x51, 0x1e, 0xe2, 0xd8, 0xe8, 0x77, 0x18, 0x85, 0xf0, 0x98, 0xc9, + 0x2b, 0x1b, 0xfd, 0xce, 0x20, 0x95, 0x18, 0x41, 0xe3, 0x24, 0xa2, 0x16, 0xee, 0xdd, 0xd2, 0x9b, + 0x38, 0x13, 0xa1, 0x04, 0x1e, 0x18, 0x22, 0x50, 0x67, 0xf5, 0x83, 0x34, 0x04, 0x1e, 0x2a, 0x42, + 0xdc, 0x99, 0xc2, 0x4c, 0x94, 0x12, 0xb9, 0x6f, 0x84, 0x08, 0xe1, 0x76, 0x6b, 0x90, 0x84, 0x8b, + 0x87, 0x2e, 0x42, 0xd4, 0xec, 0xda, 0xba, 0x69, 0x58, 0x99, 0xd8, 0x92, 0x74, 0x26, 0xb1, 0x72, + 0xd7, 0x48, 0x29, 0xac, 0x31, 0x18, 0x45, 0x00, 0xa3, 0x0a, 0xc8, 0x96, 0xd9, 0xef, 0x35, 0xb1, + 0xda, 0x34, 0x5b, 0x58, 0xd5, 0x8d, 0x1d, 0x33, 0x13, 0xa7, 0x04, 0x16, 0x87, 0x07, 0x42, 0x01, + 0x8b, 0x66, 0x0b, 0x57, 0x8c, 0x1d, 0x53, 0x49, 0x59, 0xbe, 0x6f, 0x74, 0x1c, 0x22, 0xd6, 0x81, + 0x61, 0x6b, 0xfb, 0x99, 0x24, 0x95, 0x10, 0xfe, 0x85, 0x56, 0x20, 0x8a, 0x5b, 0x3a, 0x69, 0x2e, + 0x93, 0x5a, 0x92, 0xce, 0xa4, 0x56, 0x32, 0xc3, 0x3c, 0x66, 0xf5, 0x8a, 0x00, 0xcc, 0xfd, 0x52, + 0x04, 0xd2, 0xd3, 0x88, 0xe5, 0x65, 0x08, 0xef, 0x10, 0xce, 0x64, 0x02, 0x47, 0xe1, 0x1b, 0xc3, + 0xf1, 0x33, 0x3e, 0x72, 0x87, 0x8c, 0xcf, 0x43, 0xc2, 0xc0, 0x96, 0x8d, 0x5b, 0x4c, 0x8a, 0x82, + 0x53, 0xca, 0x21, 0x30, 0xa4, 0x61, 0x31, 0x0c, 0xdd, 0x91, 0x18, 0x3e, 0x0f, 0x69, 0xa7, 0x4b, + 0x6a, 0x4f, 0x33, 0x76, 0x85, 0x3c, 0x9f, 0x9b, 0xd4, 0x93, 0x65, 0x47, 0x1f, 0x28, 0x04, 0x4d, + 0x49, 0x61, 0xdf, 0x37, 0x2a, 0x01, 0x98, 0x06, 0x36, 0x77, 0xd4, 0x16, 0x6e, 0xb6, 0x33, 0xb1, + 0x31, 0x5c, 0xaa, 0x11, 0x90, 0x21, 0x2e, 0x99, 0xac, 0xb4, 0xd9, 0x46, 0x97, 0x5c, 0xf1, 0x8c, + 0x8e, 0x91, 0xae, 0x0d, 0xb6, 0x30, 0x87, 0x24, 0x74, 0x0b, 0x52, 0x3d, 0x4c, 0xd6, 0x0a, 0x6e, + 0xf1, 0x91, 0xc5, 0x69, 0x27, 0x96, 0x27, 0x8e, 0x4c, 0xe1, 0x68, 0x6c, 0x60, 0xb3, 0x3d, 0xef, + 0x27, 0xba, 0x17, 0x9c, 0x02, 0x95, 0x8a, 0x15, 0x50, 0xcd, 0x95, 0x14, 0x85, 0x55, 0xad, 0x83, + 0xb3, 0x2f, 0x43, 0xca, 0xcf, 0x1e, 0xb4, 0x00, 0x61, 0xcb, 0xd6, 0x7a, 0x36, 0x95, 0xc2, 0xb0, + 0xc2, 0x3e, 0x90, 0x0c, 0x41, 0x6c, 0xb4, 0xa8, 0x66, 0x0c, 0x2b, 0xe4, 0x4f, 0xf4, 0x7f, 0xb9, + 0x03, 0x0e, 0xd2, 0x01, 0xdf, 0x3f, 0x3c, 0xa3, 0x3e, 0xca, 0x83, 0xe3, 0xce, 0x3e, 0x01, 0xb3, + 0xbe, 0x01, 0x4c, 0xdb, 0x74, 0xee, 0x37, 0x43, 0x70, 0x6c, 0x24, 0x6d, 0xf4, 0x3c, 0x2c, 0xf4, + 0x0d, 0xdd, 0xb0, 0x71, 0xaf, 0xdb, 0xc3, 0x44, 0x64, 0x59, 0x5b, 0x99, 0x37, 0xa2, 0x63, 0x84, + 0x6e, 0xcb, 0x0b, 0xcd, 0xa8, 0x28, 0xf3, 0xfd, 0xe1, 0x42, 0x74, 0x03, 0x12, 0x44, 0x3e, 0xb4, + 0x9e, 0x46, 0x09, 0xb2, 0xd5, 0xb8, 0x32, 0xdd, 0x90, 0x97, 0x4b, 0x2e, 0x66, 0x21, 0xf8, 0x41, + 0x29, 0xa0, 0x78, 0x69, 0xa1, 0x27, 0x20, 0xb6, 0x83, 0x35, 0xbb, 0xdf, 0xc3, 0x56, 0x66, 0x85, + 0xb2, 0xf2, 0xd4, 0xf0, 0x22, 0x65, 0x00, 0x75, 0x6c, 0x2b, 0x0e, 0x30, 0xea, 0x40, 0xf2, 0x16, + 0xee, 0xe9, 0x3b, 0x7a, 0x93, 0x75, 0x2a, 0x48, 0x95, 0xcf, 0x93, 0x53, 0x76, 0xea, 0xba, 0x07, + 0xb5, 0x6e, 0x6b, 0x36, 0x5e, 0x85, 0xad, 0xea, 0xf5, 0xb2, 0x52, 0xb9, 0x52, 0x29, 0x97, 0x58, + 0x37, 0x7d, 0xe4, 0xb3, 0xdf, 0x27, 0x41, 0xc2, 0x33, 0x12, 0xa2, 0x0e, 0x8d, 0x7e, 0x67, 0x1b, + 0xf7, 0xf8, 0x7c, 0xf1, 0x2f, 0x74, 0x0a, 0xe2, 0x3b, 0xfd, 0x76, 0x9b, 0x09, 0x1d, 0xb3, 0xa5, + 0x31, 0x52, 0x40, 0x04, 0x8e, 0xe8, 0x38, 0xae, 0x46, 0xa8, 0x8e, 0x23, 0x7f, 0xa3, 0x2c, 0xc4, + 0x84, 0x50, 0x66, 0xc2, 0x4b, 0xd2, 0x99, 0x98, 0xe2, 0x7c, 0xb3, 0xba, 0x2e, 0xd6, 0x6c, 0xdc, + 0xca, 0x44, 0x44, 0x1d, 0xfb, 0xbe, 0x16, 0x8a, 0x85, 0xe4, 0x70, 0xee, 0x71, 0x98, 0x1b, 0x1a, + 0x0a, 0x4a, 0x43, 0xa2, 0x54, 0x2e, 0xae, 0xe7, 0x95, 0x7c, 0xa3, 0x52, 0xab, 0xca, 0x33, 0x28, + 0x05, 0x9e, 0xd1, 0xc9, 0xd2, 0xd9, 0x78, 0xec, 0xcd, 0xa8, 0xfc, 0xca, 0x2b, 0xaf, 0xbc, 0x12, + 0xc8, 0xfd, 0x5a, 0x04, 0x16, 0x46, 0x29, 0xc1, 0x91, 0xfa, 0xd8, 0x1d, 0x74, 0xd0, 0x37, 0xe8, + 0x3c, 0x84, 0xdb, 0xda, 0x36, 0x6e, 0x67, 0x42, 0x74, 0x12, 0x1e, 0x9a, 0x4a, 0xcd, 0x2e, 0xaf, + 0x13, 0x14, 0x85, 0x61, 0xa2, 0xf7, 0x70, 0xd6, 0x84, 0x29, 0x85, 0xb3, 0xd3, 0x51, 0x20, 0xca, + 0x91, 0xb3, 0xf1, 0x14, 0xc4, 0xc9, 0xff, 0x8c, 0xef, 0x11, 0xc6, 0x77, 0x52, 0x40, 0xf9, 0x9e, + 0x85, 0x18, 0xd5, 0x7b, 0x2d, 0xec, 0xcc, 0x89, 0xf8, 0x26, 0x9a, 0xa2, 0x85, 0x77, 0xb4, 0x7e, + 0xdb, 0x56, 0x6f, 0x69, 0xed, 0x3e, 0xa6, 0x1a, 0x2c, 0xae, 0x24, 0x79, 0xe1, 0x75, 0x52, 0x86, + 0x16, 0x21, 0xc1, 0xd4, 0xa4, 0x6e, 0xb4, 0xf0, 0x3e, 0x35, 0xa1, 0x61, 0x85, 0x69, 0xce, 0x0a, + 0x29, 0x21, 0xcd, 0xbf, 0x68, 0x99, 0x86, 0xd0, 0x35, 0xb4, 0x09, 0x52, 0x40, 0x9b, 0x7f, 0x62, + 0xd0, 0x7a, 0xdf, 0x3d, 0x7a, 0x78, 0x43, 0xca, 0xf1, 0x01, 0x48, 0x53, 0x88, 0xc7, 0xf8, 0x52, + 0xd6, 0xda, 0x99, 0x39, 0x2a, 0x06, 0x29, 0x56, 0x5c, 0xe3, 0xa5, 0xb9, 0x9f, 0x0f, 0x40, 0x88, + 0x5a, 0x8a, 0x34, 0x24, 0x1a, 0x37, 0x36, 0xcb, 0x6a, 0xa9, 0xb6, 0x55, 0x58, 0x2f, 0xcb, 0x12, + 0x99, 0x7a, 0x5a, 0x70, 0x65, 0xbd, 0x96, 0x6f, 0xc8, 0x01, 0xe7, 0xbb, 0x52, 0x6d, 0x5c, 0x7c, + 0x5c, 0x0e, 0x3a, 0x08, 0x5b, 0xac, 0x20, 0xe4, 0x05, 0x78, 0x6c, 0x45, 0x0e, 0x23, 0x19, 0x92, + 0x8c, 0x40, 0xe5, 0xf9, 0x72, 0xe9, 0xe2, 0xe3, 0x72, 0xc4, 0x5f, 0xf2, 0xd8, 0x8a, 0x1c, 0x45, + 0xb3, 0x10, 0xa7, 0x25, 0x85, 0x5a, 0x6d, 0x5d, 0x8e, 0x39, 0x34, 0xeb, 0x0d, 0xa5, 0x52, 0xbd, + 0x2a, 0xc7, 0x1d, 0x9a, 0x57, 0x95, 0xda, 0xd6, 0xa6, 0x0c, 0x0e, 0x85, 0x8d, 0x72, 0xbd, 0x9e, + 0xbf, 0x5a, 0x96, 0x13, 0x0e, 0x44, 0xe1, 0x46, 0xa3, 0x5c, 0x97, 0x93, 0xbe, 0x6e, 0x3d, 0xb6, + 0x22, 0xcf, 0x3a, 0x4d, 0x94, 0xab, 0x5b, 0x1b, 0x72, 0x0a, 0xcd, 0xc1, 0x2c, 0x6b, 0x42, 0x74, + 0x22, 0x3d, 0x50, 0x74, 0xf1, 0x71, 0x59, 0x76, 0x3b, 0xc2, 0xa8, 0xcc, 0xf9, 0x0a, 0x2e, 0x3e, + 0x2e, 0xa3, 0x5c, 0x11, 0xc2, 0x54, 0x0c, 0x11, 0x82, 0xd4, 0x7a, 0xbe, 0x50, 0x5e, 0x57, 0x6b, + 0x9b, 0x64, 0xd1, 0xe4, 0xd7, 0x65, 0xc9, 0x2d, 0x53, 0xca, 0x9b, 0xe5, 0x7c, 0xa3, 0x5c, 0x92, + 0x83, 0xde, 0xb2, 0x67, 0xb7, 0x2a, 0x4a, 0xb9, 0x24, 0x07, 0x72, 0x4d, 0x58, 0x18, 0x65, 0x21, + 0x47, 0x2e, 0x21, 0x8f, 0x2c, 0x04, 0xc6, 0xc8, 0x02, 0xa5, 0x35, 0x28, 0x0b, 0xb9, 0x2f, 0x06, + 0x60, 0x7e, 0x84, 0x97, 0x30, 0xb2, 0x91, 0xa7, 0x21, 0xcc, 0x64, 0x99, 0x69, 0xea, 0x07, 0x47, + 0xba, 0x1b, 0x54, 0xb2, 0x87, 0x7c, 0x27, 0x8a, 0xe7, 0xf5, 0x37, 0x83, 0x63, 0xfc, 0x4d, 0x42, + 0x62, 0x48, 0x60, 0xbf, 0x69, 0xc8, 0x9a, 0x33, 0x87, 0xe7, 0xe2, 0x34, 0x0e, 0x0f, 0x2d, 0x3b, + 0x9a, 0x55, 0x0f, 0x8f, 0xb0, 0xea, 0x97, 0x61, 0x6e, 0x88, 0xd0, 0xd4, 0xd6, 0xf5, 0xfd, 0x12, + 0x64, 0xc6, 0x31, 0x67, 0x82, 0x4a, 0x0c, 0xf8, 0x54, 0xe2, 0xe5, 0x41, 0x0e, 0xde, 0x33, 0x7e, + 0x12, 0x86, 0xe6, 0xfa, 0x27, 0x24, 0x38, 0x3e, 0x3a, 0xae, 0x18, 0xd9, 0x87, 0xf7, 0x40, 0xa4, + 0x83, 0xed, 0x3d, 0x53, 0xf8, 0xc9, 0xf7, 0x8f, 0xf0, 0xbe, 0x48, 0xf5, 0xe0, 0x64, 0x73, 0x2c, + 0xaf, 0xfb, 0x16, 0x1c, 0x17, 0x1c, 0xb0, 0xde, 0x0c, 0xf5, 0xf4, 0x3b, 0x03, 0x70, 0x6c, 0x24, + 0xf1, 0x91, 0x1d, 0xbd, 0x1b, 0x40, 0x37, 0xba, 0x7d, 0x9b, 0xf9, 0xc2, 0x4c, 0x13, 0xc7, 0x69, + 0x09, 0x55, 0x5e, 0x44, 0xcb, 0xf6, 0x6d, 0xa7, 0x9e, 0x59, 0x49, 0x60, 0x45, 0x14, 0xe0, 0x49, + 0xb7, 0xa3, 0x21, 0xda, 0xd1, 0xd3, 0x63, 0x46, 0x3a, 0x24, 0x98, 0x8f, 0x82, 0xdc, 0x6c, 0xeb, + 0xd8, 0xb0, 0x55, 0xcb, 0xee, 0x61, 0xad, 0xa3, 0x1b, 0xbb, 0xcc, 0xda, 0xae, 0x86, 0x77, 0xb4, + 0xb6, 0x85, 0x95, 0x34, 0xab, 0xae, 0x8b, 0x5a, 0x82, 0x41, 0x05, 0xa8, 0xe7, 0xc1, 0x88, 0xf8, + 0x30, 0x58, 0xb5, 0x83, 0x91, 0xfb, 0x99, 0x38, 0x24, 0x3c, 0x51, 0x18, 0xba, 0x07, 0x92, 0x2f, + 0x6a, 0xb7, 0x34, 0x55, 0x44, 0xd6, 0x8c, 0x13, 0x09, 0x52, 0xb6, 0xc9, 0xa3, 0xeb, 0x47, 0x61, + 0x81, 0x82, 0x98, 0x7d, 0x1b, 0xf7, 0xd4, 0x66, 0x5b, 0xb3, 0x2c, 0xca, 0xb4, 0x18, 0x05, 0x45, + 0xa4, 0xae, 0x46, 0xaa, 0x8a, 0xa2, 0x06, 0x5d, 0x80, 0x79, 0x8a, 0xd1, 0xe9, 0xb7, 0x6d, 0xbd, + 0xdb, 0xc6, 0x34, 0x67, 0x60, 0x51, 0x93, 0xe3, 0xf4, 0x6c, 0x8e, 0x40, 0x6c, 0x70, 0x00, 0xd2, + 0x23, 0x0b, 0x95, 0xe0, 0x6e, 0x8a, 0xb6, 0x8b, 0x0d, 0xdc, 0xd3, 0x6c, 0xac, 0xe2, 0xf7, 0xf5, + 0xb5, 0xb6, 0xa5, 0x6a, 0x46, 0x4b, 0xdd, 0xd3, 0xac, 0xbd, 0xcc, 0x02, 0x21, 0x50, 0x08, 0x64, + 0x24, 0xe5, 0x24, 0x01, 0xbc, 0xca, 0xe1, 0xca, 0x14, 0x2c, 0x6f, 0xb4, 0xd6, 0x34, 0x6b, 0x0f, + 0xad, 0xc2, 0x71, 0x4a, 0xc5, 0xb2, 0x7b, 0xba, 0xb1, 0xab, 0x36, 0xf7, 0x70, 0xf3, 0xa6, 0xda, + 0xb7, 0x77, 0x9e, 0xcc, 0x9c, 0xf2, 0xb6, 0x4f, 0x7b, 0x58, 0xa7, 0x30, 0x45, 0x02, 0xb2, 0x65, + 0xef, 0x3c, 0x89, 0xea, 0x90, 0x24, 0x93, 0xd1, 0xd1, 0x5f, 0xc6, 0xea, 0x8e, 0xd9, 0xa3, 0x36, + 0x34, 0x35, 0x42, 0x35, 0x79, 0x38, 0xb8, 0x5c, 0xe3, 0x08, 0x1b, 0x66, 0x0b, 0xaf, 0x86, 0xeb, + 0x9b, 0xe5, 0x72, 0x49, 0x49, 0x08, 0x2a, 0x57, 0xcc, 0x1e, 0x11, 0xa8, 0x5d, 0xd3, 0x61, 0x70, + 0x82, 0x09, 0xd4, 0xae, 0x29, 0xd8, 0x7b, 0x01, 0xe6, 0x9b, 0x4d, 0x36, 0x66, 0xbd, 0xa9, 0xf2, + 0x88, 0xdc, 0xca, 0xc8, 0x3e, 0x66, 0x35, 0x9b, 0x57, 0x19, 0x00, 0x97, 0x71, 0x0b, 0x5d, 0x82, + 0x63, 0x2e, 0xb3, 0xbc, 0x88, 0x73, 0x43, 0xa3, 0x1c, 0x44, 0xbd, 0x00, 0xf3, 0xdd, 0x83, 0x61, + 0x44, 0xe4, 0x6b, 0xb1, 0x7b, 0x30, 0x88, 0x76, 0x1f, 0xcd, 0xb2, 0xf4, 0x70, 0x93, 0xba, 0x7a, + 0x27, 0xbc, 0xd0, 0x9e, 0x0a, 0xb4, 0x0c, 0x72, 0xb3, 0xa9, 0x62, 0x43, 0xdb, 0x6e, 0x63, 0x55, + 0xeb, 0x61, 0x43, 0xb3, 0x32, 0x8b, 0x14, 0x38, 0x64, 0xf7, 0xfa, 0x58, 0x49, 0x35, 0x9b, 0x65, + 0x5a, 0x99, 0xa7, 0x75, 0xe8, 0x2c, 0xcc, 0x99, 0xdb, 0x2f, 0x36, 0x99, 0x60, 0xa9, 0xdd, 0x1e, + 0xde, 0xd1, 0xf7, 0x33, 0xef, 0xa2, 0x5c, 0x4a, 0x93, 0x0a, 0x2a, 0x56, 0x9b, 0xb4, 0x18, 0x3d, + 0x08, 0x72, 0xd3, 0xda, 0xd3, 0x7a, 0x5d, 0xaa, 0x59, 0xad, 0xae, 0xd6, 0xc4, 0x99, 0xfb, 0x18, + 0x28, 0x2b, 0xaf, 0x8a, 0x62, 0x22, 0xd8, 0xd6, 0x4b, 0xfa, 0x8e, 0x2d, 0x28, 0x3e, 0xc0, 0x04, + 0x9b, 0x96, 0x71, 0x6a, 0x67, 0x40, 0xee, 0xee, 0x75, 0xfd, 0x0d, 0x9f, 0xa1, 0x60, 0xa9, 0xee, + 0x5e, 0xd7, 0xdb, 0xee, 0xbd, 0x30, 0x4b, 0x20, 0xdd, 0x46, 0x1f, 0x64, 0xfe, 0x57, 0x77, 0xcf, + 0xd3, 0xe2, 0xe3, 0x70, 0x9c, 0x00, 0x75, 0xb0, 0xad, 0xb5, 0x34, 0x5b, 0xf3, 0x40, 0x3f, 0x4c, + 0xa1, 0x17, 0xba, 0x7b, 0xdd, 0x0d, 0x5e, 0xe9, 0xeb, 0x67, 0xaf, 0xbf, 0x7d, 0xe0, 0xc8, 0xc7, + 0x23, 0xac, 0x9f, 0xa4, 0x4c, 0x48, 0xc8, 0x1d, 0x87, 0x1f, 0x5f, 0xb7, 0x60, 0x2b, 0xb7, 0x0a, + 0x49, 0xaf, 0xdc, 0xa3, 0x38, 0x30, 0xc9, 0x97, 0x25, 0xe2, 0x04, 0x15, 0x6b, 0x25, 0xe2, 0xbe, + 0xbc, 0x50, 0x96, 0x03, 0xc4, 0x8d, 0x5a, 0xaf, 0x34, 0xca, 0xaa, 0xb2, 0x55, 0x6d, 0x54, 0x36, + 0xca, 0x72, 0xd0, 0xe3, 0xd8, 0x5f, 0x0b, 0xc5, 0xce, 0xca, 0x0f, 0x5d, 0x0b, 0xc5, 0xee, 0x97, + 0x1f, 0xa0, 0xec, 0x19, 0x12, 0xca, 0xdc, 0x5b, 0x41, 0x48, 0xf9, 0xc3, 0x72, 0xf4, 0x6e, 0x38, + 0x21, 0xf2, 0x6e, 0x16, 0xb6, 0xd5, 0x97, 0xf4, 0x1e, 0x5d, 0xac, 0x1d, 0x8d, 0x19, 0x4e, 0x47, + 0x28, 0x17, 0x38, 0x54, 0x1d, 0xdb, 0xcf, 0xe9, 0x3d, 0xb2, 0x14, 0x3b, 0x9a, 0x8d, 0xd6, 0x61, + 0xd1, 0x30, 0x55, 0xcb, 0xd6, 0x8c, 0x96, 0xd6, 0x6b, 0x79, 0x13, 0x99, 0x5a, 0xb3, 0x89, 0x2d, + 0xcb, 0x64, 0x46, 0xd2, 0xa1, 0x72, 0x97, 0x61, 0xd6, 0x39, 0xb0, 0x6b, 0x3d, 0xf2, 0x1c, 0x74, + 0x60, 0x4d, 0x04, 0xc7, 0xad, 0x89, 0x53, 0x10, 0xef, 0x68, 0x5d, 0x15, 0x1b, 0x76, 0xef, 0x80, + 0xfa, 0xee, 0x31, 0x25, 0xd6, 0xd1, 0xba, 0x65, 0xf2, 0x8d, 0xae, 0xc3, 0xfd, 0x2e, 0xa8, 0xda, + 0xc6, 0xbb, 0x5a, 0xf3, 0x40, 0xa5, 0x8e, 0x3a, 0xcd, 0x11, 0xa9, 0x4d, 0xd3, 0xd8, 0x69, 0xeb, + 0x4d, 0xdb, 0xa2, 0xba, 0x83, 0xe9, 0xbf, 0x9c, 0x8b, 0xb1, 0x4e, 0x11, 0xae, 0x59, 0xa6, 0x41, + 0xfd, 0xf3, 0xa2, 0x80, 0xf6, 0x89, 0x4d, 0xf2, 0x1d, 0x21, 0x36, 0xfe, 0xa9, 0x0f, 0xc9, 0xe1, + 0x6b, 0xa1, 0x58, 0x58, 0x8e, 0x5c, 0x0b, 0xc5, 0x22, 0x72, 0xf4, 0x5a, 0x28, 0x16, 0x93, 0xe3, + 0xd7, 0x42, 0xb1, 0xb8, 0x0c, 0xb9, 0xdb, 0xb3, 0x90, 0xf4, 0x86, 0x1b, 0x24, 0x7a, 0x6b, 0x52, + 0x83, 0x2b, 0x51, 0x95, 0x7c, 0xef, 0xa1, 0xc1, 0xc9, 0x72, 0x91, 0x58, 0xe2, 0xd5, 0x08, 0xf3, + 0xed, 0x15, 0x86, 0x49, 0xbc, 0x20, 0xb2, 0xc8, 0x30, 0xf3, 0xa5, 0x62, 0x0a, 0xff, 0x42, 0x57, + 0x21, 0xf2, 0xa2, 0x45, 0x69, 0x47, 0x28, 0xed, 0x77, 0x1d, 0x4e, 0xfb, 0x5a, 0x9d, 0x12, 0x8f, + 0x5f, 0xab, 0xab, 0xd5, 0x9a, 0xb2, 0x91, 0x5f, 0x57, 0x38, 0x3a, 0x3a, 0x09, 0xa1, 0xb6, 0xf6, + 0xf2, 0x81, 0xdf, 0x66, 0xd3, 0x22, 0xb4, 0x0c, 0xe9, 0xbe, 0xc1, 0x62, 0x75, 0x32, 0xc7, 0x04, + 0x2a, 0xed, 0x85, 0x4a, 0xb9, 0xb5, 0xeb, 0x04, 0x7e, 0x4a, 0xb9, 0x3a, 0x09, 0xa1, 0x97, 0xb0, + 0x76, 0xd3, 0x6f, 0x59, 0x69, 0x11, 0x3a, 0x03, 0xc9, 0x16, 0xde, 0xee, 0xef, 0xaa, 0x3d, 0xdc, + 0xd2, 0x9a, 0xb6, 0xdf, 0x9e, 0x24, 0x68, 0x95, 0x42, 0x6b, 0xd0, 0x33, 0x10, 0x27, 0x73, 0x64, + 0xd0, 0x39, 0x9e, 0xa3, 0x2c, 0x78, 0xe4, 0x70, 0x16, 0xf0, 0x29, 0x16, 0x48, 0x8a, 0x8b, 0x8f, + 0xd6, 0x20, 0x6a, 0x6b, 0xbd, 0x5d, 0x6c, 0x5b, 0x99, 0xf9, 0xa5, 0xe0, 0x99, 0xd4, 0x88, 0x1c, + 0xd9, 0x08, 0x52, 0x0d, 0x8a, 0x42, 0x23, 0x65, 0x81, 0x8e, 0x9e, 0x03, 0x99, 0xa7, 0x62, 0x55, + 0x1e, 0xe6, 0x5a, 0x99, 0x05, 0x2a, 0x80, 0x0f, 0x1f, 0x4e, 0x92, 0x67, 0x72, 0x4b, 0x0c, 0x49, + 0x49, 0x63, 0xdf, 0xb7, 0x7f, 0x5d, 0x1c, 0x3b, 0xca, 0xba, 0xd8, 0x82, 0x34, 0xff, 0x5b, 0xb5, + 0xfa, 0xdd, 0xae, 0xd9, 0xb3, 0x33, 0xc7, 0x29, 0xfe, 0x84, 0x0e, 0x09, 0x62, 0x0c, 0x47, 0x49, + 0xed, 0xf8, 0xbe, 0xbf, 0x7e, 0xcb, 0x2d, 0xfb, 0x02, 0xa4, 0xfc, 0xcc, 0xf0, 0x26, 0xc2, 0x83, + 0x53, 0x26, 0xc2, 0x49, 0x58, 0x22, 0x02, 0x35, 0x62, 0x9a, 0xd8, 0x47, 0xf6, 0xfb, 0x03, 0x90, + 0xf2, 0x0f, 0x0c, 0x5d, 0x05, 0x24, 0x66, 0x4c, 0x37, 0xec, 0x9e, 0xd9, 0xea, 0x37, 0x71, 0x8b, + 0x2f, 0xd8, 0xf1, 0xed, 0xcc, 0x71, 0x9c, 0x8a, 0x83, 0xe2, 0x25, 0xe4, 0x59, 0x05, 0x81, 0x29, + 0x09, 0x95, 0xdc, 0xf5, 0x71, 0x0e, 0xe6, 0x05, 0x01, 0x42, 0xec, 0x25, 0xad, 0x67, 0x10, 0x17, + 0x99, 0x39, 0xed, 0xc8, 0x53, 0xf5, 0x1c, 0xab, 0x41, 0x79, 0x10, 0xe2, 0xa2, 0xf6, 0x70, 0xc7, + 0xbc, 0x85, 0x5b, 0x3c, 0x5d, 0x34, 0xbe, 0xd9, 0x14, 0x47, 0x50, 0x18, 0x7c, 0xee, 0x1c, 0x84, + 0xa9, 0xfa, 0x41, 0x00, 0x5c, 0x01, 0xc9, 0x33, 0x28, 0x06, 0xa1, 0x62, 0x4d, 0x21, 0xe6, 0x51, + 0x86, 0x24, 0x2b, 0x55, 0x37, 0x2b, 0xe5, 0x62, 0x59, 0x0e, 0xe4, 0x2e, 0x40, 0x84, 0xe9, 0x14, + 0x62, 0x3a, 0x1d, 0xad, 0x22, 0xcf, 0xf0, 0x4f, 0x4e, 0x43, 0x12, 0xb5, 0x5b, 0x1b, 0x85, 0xb2, + 0x22, 0x07, 0x72, 0x5b, 0x90, 0x1e, 0x58, 0x87, 0xe8, 0x18, 0xcc, 0x29, 0xe5, 0x46, 0xb9, 0xda, + 0xa8, 0xd4, 0xaa, 0xea, 0x56, 0xf5, 0x99, 0x6a, 0xed, 0xb9, 0xaa, 0x3c, 0xe3, 0x2f, 0x16, 0x76, + 0x58, 0x42, 0x0b, 0x20, 0xbb, 0xc5, 0xf5, 0xda, 0x96, 0x42, 0x7b, 0xf3, 0x5d, 0x01, 0x90, 0x07, + 0x17, 0x25, 0x3a, 0x01, 0xf3, 0x8d, 0xbc, 0x72, 0xb5, 0xdc, 0x50, 0x59, 0xc2, 0xc3, 0x21, 0xbd, + 0x00, 0xb2, 0xb7, 0xe2, 0x4a, 0x85, 0xe6, 0x73, 0x16, 0xe1, 0x94, 0xb7, 0xb4, 0xfc, 0x7c, 0xa3, + 0x5c, 0xad, 0xd3, 0xc6, 0xf3, 0xd5, 0xab, 0xc4, 0x29, 0x18, 0xa0, 0x27, 0x52, 0x2c, 0x41, 0xd2, + 0x55, 0x3f, 0xbd, 0xf2, 0x7a, 0x49, 0x0e, 0x0d, 0x16, 0xd7, 0xaa, 0xe5, 0xda, 0x15, 0x39, 0x3c, + 0xd8, 0x3a, 0x4d, 0xbb, 0x44, 0x50, 0x16, 0x8e, 0x0f, 0x96, 0xaa, 0xe5, 0x6a, 0x43, 0xb9, 0x21, + 0x47, 0x07, 0x1b, 0xae, 0x97, 0x95, 0xeb, 0x95, 0x62, 0x59, 0x8e, 0xa1, 0xe3, 0x80, 0xfc, 0x3d, + 0x6a, 0xac, 0xd5, 0x4a, 0x72, 0x7c, 0x94, 0xc5, 0x42, 0xf2, 0x7c, 0xee, 0xa7, 0x25, 0x48, 0x7a, + 0x53, 0x20, 0x3e, 0xa5, 0x22, 0xbd, 0xd3, 0x8c, 0x6d, 0xee, 0xb7, 0x02, 0x90, 0xf0, 0xe4, 0x42, + 0x48, 0x10, 0xab, 0xb5, 0xdb, 0xe6, 0x4b, 0xaa, 0xd6, 0xd6, 0x35, 0x8b, 0xdb, 0x43, 0xa0, 0x45, + 0x79, 0x52, 0x32, 0xad, 0xfd, 0x99, 0xde, 0x75, 0x89, 0xdc, 0xb1, 0xeb, 0x12, 0x7d, 0x07, 0xba, + 0x2e, 0x61, 0x39, 0x92, 0xfb, 0x9d, 0x00, 0xc8, 0x83, 0xd9, 0x91, 0x01, 0xbe, 0x49, 0xe3, 0xf8, + 0xe6, 0x1d, 0x5f, 0xe0, 0x28, 0xe3, 0x1b, 0xb4, 0xea, 0xc1, 0xb1, 0x56, 0x7d, 0x84, 0xb1, 0x0a, + 0xbd, 0x93, 0x8d, 0x95, 0x57, 0x5c, 0xff, 0xad, 0x04, 0x29, 0x7f, 0x32, 0xc7, 0xc7, 0xb1, 0xdc, + 0x51, 0x38, 0xe6, 0x9f, 0x91, 0x7b, 0xc6, 0xcd, 0xc8, 0x5f, 0xcb, 0xb8, 0x7e, 0x30, 0x08, 0xb3, + 0xbe, 0xdc, 0xcf, 0xb4, 0xbd, 0x7b, 0x1f, 0xcc, 0xe9, 0x2d, 0xdc, 0xe9, 0x9a, 0x36, 0x36, 0x9a, + 0x07, 0x6a, 0x1b, 0xdf, 0xc2, 0x6d, 0xca, 0x86, 0xd4, 0x88, 0xdd, 0x55, 0x5f, 0x0b, 0xcb, 0x15, + 0x17, 0x6f, 0x9d, 0xa0, 0xad, 0xce, 0x57, 0x4a, 0xe5, 0x8d, 0xcd, 0x5a, 0xa3, 0x5c, 0x2d, 0xde, + 0x10, 0x9a, 0x5c, 0x91, 0xf5, 0x01, 0x30, 0x1f, 0xc3, 0xef, 0x7d, 0x67, 0x04, 0x9d, 0x9b, 0x20, + 0x0f, 0x8e, 0x86, 0x28, 0xf4, 0x11, 0xe3, 0x91, 0x67, 0xd0, 0x3c, 0xa4, 0xab, 0x35, 0xb5, 0x5e, + 0x29, 0x95, 0xd5, 0xf2, 0x95, 0x2b, 0xe5, 0x62, 0xa3, 0xce, 0x36, 0x1a, 0x1c, 0xe8, 0x86, 0x1c, + 0xf0, 0xce, 0xcd, 0x0f, 0x05, 0x61, 0x7e, 0x44, 0x4f, 0x50, 0x9e, 0xa7, 0x08, 0x59, 0xd6, 0xf2, + 0x91, 0x69, 0x7a, 0xbf, 0x4c, 0xa2, 0xfb, 0x4d, 0xad, 0x67, 0xf3, 0x8c, 0xe2, 0x83, 0x40, 0xd8, + 0x6b, 0xd8, 0xc4, 0xbd, 0xef, 0xf1, 0x0d, 0x1c, 0xe6, 0x82, 0xa4, 0xdd, 0x72, 0xb6, 0x87, 0xf3, + 0x30, 0xa0, 0xae, 0x69, 0xe9, 0xb6, 0x7e, 0x0b, 0x13, 0x1f, 0x8a, 0x03, 0x93, 0x85, 0x1b, 0x52, + 0x64, 0x51, 0x53, 0x31, 0x6c, 0x07, 0xda, 0xc0, 0xbb, 0xda, 0x00, 0x34, 0x09, 0x3f, 0x82, 0x8a, + 0x2c, 0x6a, 0x1c, 0xe8, 0x7b, 0x20, 0xd9, 0x32, 0xfb, 0xdb, 0x6d, 0xcc, 0xe1, 0x88, 0x4a, 0x96, + 0x94, 0x04, 0x2b, 0x73, 0x40, 0x78, 0xda, 0xcc, 0xdd, 0x66, 0x4a, 0x2a, 0x09, 0x56, 0xc6, 0x40, + 0x1e, 0x80, 0xb4, 0xb6, 0xbb, 0xdb, 0x23, 0xc4, 0x05, 0x21, 0x96, 0x08, 0x4c, 0x39, 0xc5, 0x14, + 0x30, 0x7b, 0x0d, 0x62, 0x82, 0x0f, 0x24, 0xfe, 0x25, 0x9c, 0x50, 0xbb, 0x2c, 0xbb, 0x1d, 0x38, + 0x13, 0x57, 0x62, 0x86, 0xa8, 0xbc, 0x07, 0x92, 0xba, 0xe5, 0x1e, 0x21, 0xca, 0x04, 0x96, 0x02, + 0x67, 0x62, 0x4a, 0x42, 0xb7, 0xdc, 0x63, 0x42, 0x3f, 0x93, 0x00, 0x70, 0x85, 0x0d, 0x7d, 0x8f, + 0x04, 0x29, 0x66, 0x60, 0xba, 0x3d, 0x6c, 0x61, 0xa3, 0x29, 0xc2, 0xc2, 0x07, 0x0f, 0x11, 0x51, + 0xa6, 0xe6, 0x36, 0x39, 0x42, 0xe1, 0xe9, 0x0f, 0x4a, 0xd2, 0x6b, 0x52, 0xe8, 0x35, 0x49, 0xfa, + 0x11, 0x69, 0x16, 0xc5, 0xca, 0xcf, 0x6f, 0xae, 0x57, 0x8a, 0x95, 0x46, 0xe6, 0x03, 0x51, 0xfa, + 0x5d, 0xd9, 0xe0, 0xdf, 0x6f, 0x44, 0xfd, 0xf5, 0x6f, 0x46, 0x3f, 0x2d, 0x05, 0x63, 0x6f, 0x46, + 0x95, 0xd9, 0x1d, 0x2f, 0x3d, 0xd4, 0xf6, 0x9e, 0xa0, 0x08, 0x8c, 0x0b, 0x24, 0xdd, 0xde, 0x94, + 0xf9, 0xb9, 0x89, 0xc2, 0x83, 0xb4, 0x23, 0x11, 0xda, 0x91, 0x04, 0x8a, 0x14, 0xd7, 0x6b, 0xf5, + 0x72, 0x89, 0x76, 0x23, 0x8e, 0x42, 0xb5, 0xcd, 0x72, 0x35, 0xf3, 0x86, 0x68, 0xd2, 0x3d, 0x6c, + 0xf1, 0x9a, 0x04, 0x27, 0xc4, 0x2e, 0x2b, 0xb7, 0xb5, 0xd8, 0x68, 0x9a, 0x2d, 0xe1, 0xdd, 0xa6, + 0x56, 0xce, 0x1f, 0xd6, 0xb8, 0xc2, 0x51, 0x29, 0x4b, 0xca, 0x1c, 0xb1, 0xf0, 0xc8, 0x10, 0x4b, + 0xf2, 0xd5, 0x12, 0xef, 0x4b, 0x02, 0x45, 0x36, 0xf3, 0xc5, 0x67, 0xca, 0x25, 0xb7, 0x37, 0xc7, + 0x7a, 0xa3, 0xa8, 0xa0, 0x6f, 0x81, 0x74, 0xdf, 0xde, 0x79, 0x92, 0xc8, 0x86, 0xde, 0x62, 0xdb, + 0xde, 0xa1, 0x71, 0xfb, 0xa5, 0x6e, 0x8f, 0xb6, 0xec, 0x9d, 0x27, 0xaf, 0x3b, 0x18, 0x9c, 0x29, + 0xac, 0x2b, 0x71, 0x14, 0xaa, 0xd6, 0xaa, 0x65, 0xd1, 0x0d, 0xba, 0x45, 0x7c, 0xc3, 0xed, 0x46, + 0xaa, 0xef, 0x43, 0x45, 0xdf, 0x02, 0xb2, 0x48, 0x0f, 0x39, 0x2c, 0x09, 0x8f, 0xdb, 0xf2, 0x75, + 0x3b, 0xc0, 0x93, 0x4c, 0x0e, 0x33, 0xee, 0xf7, 0xf4, 0x60, 0x01, 0xa5, 0xd7, 0xcb, 0xd5, 0xab, + 0x8d, 0x35, 0x75, 0x53, 0x29, 0xd3, 0x9d, 0xbb, 0xcc, 0x07, 0x44, 0xf3, 0xe9, 0x8e, 0x1f, 0x11, + 0x7d, 0x9b, 0x04, 0x09, 0xe6, 0x02, 0xb1, 0x9c, 0x14, 0x4b, 0x2a, 0xdc, 0x7f, 0x58, 0xdb, 0xd4, + 0x03, 0xa2, 0xd0, 0x85, 0x4b, 0xb4, 0xd9, 0xa0, 0x10, 0x88, 0x13, 0x08, 0xad, 0x97, 0xaf, 0xe6, + 0x8b, 0x37, 0xd4, 0x42, 0xb9, 0xde, 0x20, 0x9a, 0xac, 0xa6, 0x30, 0x19, 0x05, 0x14, 0xce, 0xaf, + 0xaf, 0xd7, 0x9e, 0x73, 0x19, 0x01, 0x2f, 0x3a, 0x64, 0x72, 0xdf, 0x08, 0xb3, 0x3e, 0x71, 0x27, + 0x4e, 0x31, 0x75, 0xa6, 0xc9, 0x08, 0xea, 0xe5, 0x6a, 0xd1, 0xeb, 0xc4, 0x27, 0xc1, 0x11, 0x6f, + 0x59, 0x22, 0x5f, 0x42, 0xf8, 0xe5, 0x00, 0x51, 0xa3, 0xbc, 0x03, 0xce, 0x5e, 0x62, 0x30, 0xf7, + 0x04, 0xc4, 0x84, 0xf8, 0x12, 0xd7, 0x9c, 0x7a, 0xd8, 0x03, 0x81, 0x41, 0x0c, 0xa8, 0xec, 0xca, + 0x12, 0x09, 0x83, 0x98, 0x4c, 0xcb, 0x81, 0xdc, 0x75, 0x38, 0x36, 0x52, 0xf4, 0xd0, 0xbd, 0xb0, + 0x28, 0xf6, 0x2f, 0x99, 0xd3, 0xaf, 0x96, 0xab, 0xc5, 0x5a, 0x89, 0x84, 0x49, 0x2e, 0x4d, 0x00, + 0x2e, 0x83, 0xac, 0x97, 0x42, 0x3e, 0xe5, 0x40, 0xae, 0x02, 0x29, 0xbf, 0x00, 0xa1, 0x53, 0x70, + 0x62, 0xab, 0x71, 0xe5, 0x49, 0xf5, 0x7a, 0x7e, 0xbd, 0x52, 0xca, 0x0f, 0x04, 0x44, 0x00, 0x5c, + 0x8a, 0xe4, 0x00, 0xe9, 0x28, 0x91, 0x2e, 0x39, 0x98, 0x0b, 0xc5, 0x24, 0x59, 0xca, 0xd5, 0x21, + 0x3d, 0x20, 0x0a, 0xe8, 0x2e, 0xc8, 0xf0, 0x08, 0x65, 0x54, 0xaf, 0x28, 0x87, 0x7c, 0xc2, 0xc1, + 0x62, 0xb5, 0x52, 0x79, 0xbd, 0xb2, 0x51, 0x69, 0xd0, 0xfe, 0xad, 0x01, 0xb8, 0x73, 0x4c, 0x6c, + 0xd6, 0xb5, 0x7a, 0xad, 0xaa, 0x5e, 0x21, 0x81, 0x5e, 0xc3, 0x43, 0x2a, 0x0e, 0x6c, 0x4e, 0x65, + 0x89, 0xc4, 0x23, 0xc3, 0x13, 0x2f, 0x07, 0xce, 0x7e, 0x48, 0x22, 0x26, 0xeb, 0x43, 0xd5, 0xec, + 0xb7, 0x49, 0xe8, 0xee, 0xd8, 0x9b, 0x51, 0x14, 0x5d, 0xee, 0x6e, 0x2f, 0x37, 0xbb, 0xdd, 0x6c, + 0x9a, 0xfc, 0x51, 0xec, 0x76, 0xaf, 0x08, 0x43, 0xbc, 0x18, 0xfb, 0xc3, 0x28, 0x8a, 0x91, 0xd2, + 0x17, 0xb5, 0x5b, 0x5a, 0x56, 0x26, 0x7f, 0x5d, 0xd3, 0x6e, 0x69, 0x0e, 0xc0, 0xa9, 0xd8, 0x97, + 0xa2, 0x28, 0x42, 0x8a, 0x77, 0xcd, 0x6c, 0x8a, 0xfc, 0x7f, 0xd5, 0x74, 0x2a, 0xef, 0x8d, 0x7d, + 0x47, 0x15, 0x01, 0x29, 0xa4, 0x12, 0x7b, 0x3e, 0x8b, 0xc8, 0xdf, 0x74, 0xdb, 0xec, 0xbc, 0x00, 0x3a, 0x1b, 0x89, 0x7d, 0xa8, 0x2a, 0x7f, 0xa4, 0x7a, 0x36, 0x12, 0xfb, 0x48, 0x55, 0xfe, 0x9e, 0xea, 0xb5, 0x48, 0xec, 0x8d, 0xa8, 0xfc, 0x66, 0x34, 0xf7, 0x27, 0x41, 0x40, 0xae, 0x7c, 0x3b, - 0x91, 0x97, 0xe7, 0x21, 0xe6, 0x84, 0x72, 0xd8, 0x41, 0xd5, 0x77, 0x1f, 0x32, 0x2d, 0x04, 0x9a, - 0x27, 0x6b, 0x20, 0xb4, 0xe3, 0x50, 0x23, 0x7e, 0x7b, 0x47, 0x37, 0xf4, 0x4e, 0xbf, 0xa3, 0x8a, - 0xf8, 0xc6, 0x44, 0xbf, 0x9d, 0x23, 0xf0, 0x34, 0x25, 0xa1, 0xed, 0xfb, 0x48, 0x84, 0x27, 0x92, - 0x60, 0x08, 0x3c, 0x9d, 0xfd, 0x2b, 0x09, 0x32, 0xe3, 0x1a, 0x7b, 0x47, 0xa1, 0x97, 0x2a, 0x2c, - 0x98, 0xb7, 0x70, 0xaf, 0xa7, 0xb7, 0xe8, 0x6e, 0x8a, 0x63, 0x90, 0x85, 0x26, 0x1b, 0x64, 0xf3, - 0x1e, 0x44, 0x67, 0x50, 0x0b, 0x64, 0xdd, 0xdc, 0x27, 0x4b, 0x86, 0xa0, 0x14, 0x9e, 0x4c, 0x69, - 0x96, 0xa2, 0x08, 0x1a, 0xd7, 0xc8, 0x34, 0x21, 0x3e, 0x50, 0x40, 0x0e, 0xba, 0x56, 0x5f, 0xee, - 0xe3, 0x41, 0x48, 0xf9, 0x0f, 0x67, 0xa2, 0x12, 0xc4, 0xda, 0x26, 0x3f, 0xf8, 0xc4, 0x46, 0xfb, - 0xcc, 0x84, 0xf3, 0x9c, 0xcb, 0xeb, 0x1c, 0x5e, 0x71, 0x30, 0xb3, 0xff, 0x56, 0x82, 0x98, 0xc8, - 0x46, 0xc7, 0x21, 0xd4, 0xd5, 0xec, 0x3d, 0x4a, 0x2e, 0x5c, 0x08, 0xc8, 0x92, 0x42, 0xd3, 0x24, - 0xdf, 0xea, 0x6a, 0xec, 0xd0, 0x17, 0xcf, 0x27, 0x69, 0x62, 0x79, 0xb5, 0xb1, 0xd6, 0xa2, 0xfb, - 0x80, 0x66, 0xa7, 0x83, 0x0d, 0xdb, 0x12, 0x96, 0x17, 0xcf, 0x2f, 0xf2, 0x6c, 0xf4, 0x10, 0xcc, - 0xd9, 0x3d, 0x4d, 0x6f, 0xfb, 0x60, 0x43, 0x14, 0x56, 0x16, 0x05, 0x0e, 0xf0, 0x2a, 0x9c, 0x14, - 0x74, 0x5b, 0xd8, 0xd6, 0x9a, 0x7b, 0xb8, 0xe5, 0x22, 0x45, 0xe8, 0x7e, 0xff, 0x09, 0x0e, 0x50, - 0xe2, 0xe5, 0x02, 0xf7, 0x6c, 0xdf, 0x77, 0xde, 0x7a, 0x17, 0x61, 0x7e, 0xde, 0xfa, 0xfc, 0x98, - 0xf3, 0xd6, 0x83, 0x67, 0x63, 0x3d, 0x87, 0xad, 0xcf, 0x8e, 0x40, 0xf1, 0x73, 0xd4, 0x35, 0xa1, - 0x3e, 0x17, 0x80, 0x39, 0xb1, 0x61, 0xda, 0x72, 0xc6, 0x68, 0x03, 0x40, 0x33, 0x0c, 0xd3, 0xf6, - 0x8e, 0xd2, 0xb0, 0x8d, 0x3b, 0x84, 0xb7, 0x9c, 0x77, 0x90, 0x14, 0x0f, 0x81, 0xec, 0x1f, 0x49, - 0x00, 0x6e, 0xd1, 0xd8, 0xe1, 0x5a, 0x84, 0x04, 0xef, 0x15, 0x3d, 0xb3, 0xce, 0xe2, 0x8a, 0xc0, - 0xb2, 0xae, 0xe8, 0x6d, 0x7a, 0x12, 0x62, 0x1b, 0xef, 0xea, 0x06, 0x3f, 0xc2, 0xc5, 0x12, 0xe2, - 0x24, 0x44, 0xc8, 0x3d, 0xe2, 0xa8, 0x40, 0xcc, 0xc2, 0x1d, 0xcd, 0xb0, 0xf5, 0x26, 0x9f, 0xac, - 0x17, 0x8f, 0xd4, 0xf8, 0xe5, 0x3a, 0xc7, 0x56, 0x1c, 0x3a, 0xb9, 0x33, 0x10, 0x13, 0xb9, 0xce, - 0xe2, 0x30, 0x83, 0xa2, 0x10, 0xac, 0x97, 0xc9, 0xf2, 0x48, 0x75, 0x74, 0x25, 0x5f, 0x97, 0x03, - 0x67, 0x7f, 0x22, 0x00, 0x51, 0xa1, 0x3d, 0xe6, 0x21, 0x5d, 0x2e, 0x55, 0x06, 0xd6, 0x99, 0x79, - 0x48, 0x89, 0x4c, 0xa6, 0xcc, 0xe5, 0x0f, 0x44, 0xbd, 0x99, 0x9b, 0x4a, 0xad, 0x51, 0x5b, 0x91, - 0xff, 0x60, 0x38, 0xf3, 0x31, 0xf9, 0x8d, 0x28, 0x9a, 0x83, 0xa4, 0xc8, 0x5c, 0x79, 0x74, 0xe5, - 0x31, 0xf9, 0xcd, 0xc1, 0xac, 0xc7, 0xe5, 0x3f, 0xa4, 0x21, 0x2d, 0x91, 0x75, 0x5e, 0x6d, 0x90, - 0xc5, 0xa2, 0x56, 0x5d, 0xbf, 0x21, 0x4b, 0xde, 0x82, 0x15, 0x4f, 0x41, 0x00, 0xdd, 0x0d, 0x27, - 0x44, 0xc1, 0xa5, 0x4b, 0x97, 0x2e, 0x3d, 0xe1, 0x29, 0xbc, 0xfd, 0xe1, 0xc8, 0x60, 0xf1, 0x93, - 0x9e, 0xe2, 0x8f, 0x0f, 0x17, 0x5f, 0xf2, 0x14, 0xff, 0xf0, 0x87, 0x23, 0x68, 0x1e, 0x12, 0xa2, - 0x78, 0x23, 0xff, 0xbc, 0xfc, 0x95, 0xaf, 0x7c, 0xe5, 0x2b, 0xd1, 0xc2, 0xb7, 0xc0, 0x7c, 0xd3, - 0xec, 0x0c, 0x0e, 0x4d, 0x41, 0x1e, 0x38, 0x8f, 0x61, 0x5d, 0x95, 0x5e, 0x78, 0x84, 0x03, 0xed, - 0x9a, 0x6d, 0xcd, 0xd8, 0x5d, 0x36, 0x7b, 0xbb, 0xee, 0xe5, 0x08, 0x62, 0x5b, 0x5b, 0x9e, 0x2b, - 0x12, 0xdd, 0xed, 0xbf, 0x92, 0xa4, 0x1f, 0x09, 0x04, 0xd7, 0x36, 0x0b, 0x3f, 0x15, 0xc8, 0xae, - 0x31, 0xc4, 0x4d, 0x31, 0xf0, 0x0a, 0xde, 0x69, 0xe3, 0x26, 0x19, 0x1d, 0xf8, 0xe3, 0x87, 0x60, - 0x61, 0xd7, 0xdc, 0x35, 0x29, 0xa5, 0x73, 0xe4, 0x17, 0xbf, 0x5d, 0x11, 0x77, 0x72, 0xb3, 0x13, - 0xaf, 0x62, 0xac, 0x56, 0x61, 0x9e, 0x03, 0xab, 0xd4, 0xd4, 0x67, 0x5b, 0xc6, 0xe8, 0xd0, 0x63, - 0x47, 0x99, 0x9f, 0xfb, 0x7d, 0x1a, 0xa3, 0x51, 0xe6, 0x38, 0x2a, 0x29, 0x63, 0xbb, 0xca, 0xab, - 0x0a, 0x1c, 0xf3, 0xd1, 0x63, 0x6e, 0x16, 0xee, 0x4d, 0xa0, 0xf8, 0x2f, 0x39, 0xc5, 0x79, 0x0f, - 0xc5, 0x3a, 0x47, 0x5d, 0x2d, 0xc2, 0xec, 0x51, 0x68, 0xfd, 0x2b, 0x4e, 0x2b, 0x89, 0xbd, 0x44, - 0xd6, 0x20, 0x4d, 0x89, 0x34, 0xfb, 0x96, 0x6d, 0x76, 0xa8, 0x0f, 0x7b, 0x38, 0x99, 0x7f, 0xfd, - 0xfb, 0x4c, 0xab, 0xa6, 0x08, 0x5a, 0xd1, 0xc1, 0x5a, 0x5d, 0x05, 0xea, 0xb2, 0xb4, 0x70, 0xb3, - 0x3d, 0x81, 0xc2, 0xaf, 0xf3, 0x86, 0x38, 0xf0, 0xab, 0xd7, 0x61, 0x81, 0xfc, 0xa6, 0x2e, 0xa6, - 0xb7, 0x25, 0x93, 0xcf, 0x28, 0x65, 0x7e, 0xeb, 0xfd, 0x4c, 0x71, 0xcf, 0x3b, 0x04, 0x3c, 0x6d, - 0xf2, 0x8c, 0xe2, 0x2e, 0xb6, 0x6d, 0xdc, 0xb3, 0x54, 0xad, 0x3d, 0xaa, 0x79, 0x9e, 0x43, 0x1e, - 0x99, 0x1f, 0xfc, 0x92, 0x7f, 0x14, 0xd7, 0x18, 0x66, 0xbe, 0xdd, 0x5e, 0xdd, 0x82, 0x13, 0x23, - 0xa4, 0x62, 0x0a, 0x9a, 0x3f, 0xc4, 0x69, 0x2e, 0x0c, 0x49, 0x06, 0x21, 0xbb, 0x09, 0x22, 0xdf, - 0x19, 0xcb, 0x29, 0x68, 0x7e, 0x94, 0xd3, 0x44, 0x1c, 0x57, 0x0c, 0x29, 0xa1, 0x78, 0x0d, 0xe6, - 0x6e, 0xe1, 0xde, 0xb6, 0x69, 0xf1, 0x83, 0x35, 0x53, 0x90, 0xfb, 0x18, 0x27, 0x97, 0xe6, 0x88, - 0xf4, 0xa4, 0x0d, 0xa1, 0x75, 0x09, 0x62, 0x3b, 0x5a, 0x13, 0x4f, 0x41, 0xe2, 0x36, 0x27, 0x11, - 0x25, 0xf0, 0x04, 0x35, 0x0f, 0xc9, 0x5d, 0x93, 0x47, 0x19, 0x26, 0xa3, 0x7f, 0x9c, 0xa3, 0x27, - 0x04, 0x0e, 0x27, 0xd1, 0x35, 0xbb, 0xfd, 0xb6, 0x66, 0x4f, 0xd3, 0x82, 0x1f, 0x16, 0x24, 0x04, - 0x0e, 0x27, 0x71, 0x04, 0xb6, 0x7e, 0x42, 0x90, 0xb0, 0x3c, 0xfc, 0x7c, 0x1a, 0x12, 0xa6, 0xd1, - 0x3e, 0x30, 0x8d, 0x69, 0x1a, 0xf1, 0x49, 0x4e, 0x01, 0x38, 0x0a, 0x21, 0x70, 0x19, 0xe2, 0xd3, - 0x0e, 0xc4, 0x8f, 0x7d, 0x49, 0x4c, 0x0f, 0x31, 0x02, 0x6b, 0x90, 0x16, 0x0a, 0x4a, 0x37, 0x8d, - 0x29, 0x48, 0xfc, 0x38, 0x27, 0x91, 0xf2, 0xa0, 0xf1, 0x6e, 0xd8, 0xd8, 0xb2, 0x77, 0xf1, 0x34, - 0x44, 0x7e, 0x42, 0x74, 0x83, 0xa3, 0x70, 0x56, 0x6e, 0x63, 0xa3, 0xb9, 0x37, 0x1d, 0x85, 0x4f, - 0x09, 0x56, 0x0a, 0x1c, 0x42, 0xa2, 0x08, 0xb3, 0x1d, 0xad, 0x67, 0xed, 0x69, 0xed, 0xa9, 0x86, - 0xe3, 0x27, 0x39, 0x8d, 0xa4, 0x83, 0xc4, 0x39, 0xd2, 0x37, 0x8e, 0x42, 0xe6, 0xa7, 0x04, 0x47, - 0x3c, 0x68, 0x7c, 0xea, 0x59, 0x36, 0x35, 0xb8, 0x8f, 0x42, 0xed, 0xef, 0x89, 0xa9, 0xc7, 0x70, - 0x37, 0xbc, 0x14, 0x2f, 0x43, 0xdc, 0xd2, 0x5f, 0x9e, 0x8a, 0xcc, 0x4f, 0x8b, 0x91, 0xa6, 0x08, - 0x04, 0xf9, 0x06, 0x9c, 0x1c, 0xb9, 0x4c, 0x4c, 0x41, 0xec, 0x67, 0x38, 0xb1, 0xe3, 0x23, 0x96, - 0x0a, 0xae, 0x12, 0x8e, 0x4a, 0xf2, 0xef, 0x0b, 0x95, 0x80, 0x07, 0x68, 0x6d, 0xc2, 0x42, 0xdf, - 0xb0, 0xb4, 0x9d, 0xa3, 0x71, 0xed, 0x1f, 0x08, 0xae, 0x31, 0x5c, 0x1f, 0xd7, 0x1a, 0x70, 0x9c, - 0x53, 0x3c, 0xda, 0xb8, 0xfe, 0xac, 0x50, 0xac, 0x0c, 0x7b, 0xcb, 0x3f, 0xba, 0xdf, 0x00, 0x59, - 0x87, 0x9d, 0xc2, 0x3a, 0xb6, 0xd4, 0x8e, 0xd6, 0x9d, 0x82, 0xf2, 0xcf, 0x71, 0xca, 0x42, 0xe3, - 0x3b, 0xe6, 0xb5, 0xb5, 0xa1, 0x75, 0x09, 0xf1, 0xe7, 0x21, 0x23, 0x88, 0xf7, 0x8d, 0x1e, 0x6e, - 0x9a, 0xbb, 0x86, 0xfe, 0x32, 0x6e, 0x4d, 0x41, 0xfa, 0xd3, 0x03, 0x43, 0xb5, 0xe5, 0x41, 0x27, - 0x94, 0x2b, 0x20, 0x3b, 0xb6, 0x8a, 0xaa, 0x77, 0xe8, 0x66, 0xcc, 0xe1, 0x14, 0x7f, 0x5e, 0x8c, - 0x94, 0x83, 0x57, 0xa1, 0x68, 0xab, 0x65, 0x60, 0x47, 0xf3, 0xa7, 0x15, 0xc9, 0xcf, 0x70, 0x42, - 0xb3, 0x2e, 0x16, 0x57, 0x1c, 0x4d, 0xb3, 0xd3, 0xd5, 0x7a, 0xd3, 0xe8, 0xbf, 0x7f, 0x28, 0x14, - 0x07, 0x47, 0xe1, 0x8a, 0x83, 0x58, 0x74, 0x64, 0xb5, 0x9f, 0x82, 0xc2, 0x2f, 0x08, 0xc5, 0x21, - 0x70, 0x38, 0x09, 0x61, 0x30, 0x4c, 0x41, 0xe2, 0x17, 0x05, 0x09, 0x81, 0x43, 0x48, 0x3c, 0xeb, - 0x2e, 0xb4, 0x3d, 0xbc, 0xab, 0x5b, 0x36, 0xbf, 0x3c, 0x73, 0x38, 0xa9, 0x5f, 0xfa, 0x92, 0xdf, - 0x08, 0x53, 0x3c, 0xa8, 0x44, 0x13, 0xf1, 0xa8, 0x20, 0x8d, 0x7a, 0x4f, 0x6e, 0xd8, 0x2f, 0x0b, - 0x4d, 0xe4, 0x41, 0x23, 0x6d, 0xf3, 0x58, 0x88, 0x84, 0xed, 0x4d, 0xe2, 0x49, 0x4e, 0x41, 0xee, - 0x1f, 0x0d, 0x34, 0xae, 0x2e, 0x70, 0x09, 0x4d, 0x8f, 0xfd, 0xd3, 0x37, 0x6e, 0xe2, 0x83, 0xa9, - 0xa4, 0xf3, 0x1f, 0x0f, 0xd8, 0x3f, 0x5b, 0x0c, 0x93, 0xe9, 0x90, 0xf4, 0x80, 0x3d, 0x85, 0x26, - 0xdd, 0xac, 0xcb, 0x7c, 0xeb, 0x5b, 0xbc, 0xbf, 0x7e, 0x73, 0x6a, 0x75, 0x9d, 0x08, 0xb9, 0xdf, - 0xe8, 0x99, 0x4c, 0xec, 0xfd, 0x6f, 0x39, 0x72, 0xee, 0xb3, 0x79, 0x56, 0xaf, 0xc0, 0xac, 0xcf, - 0xe0, 0x99, 0x4c, 0xea, 0x03, 0x9c, 0x54, 0xd2, 0x6b, 0xef, 0xac, 0x5e, 0x80, 0x10, 0x31, 0x5e, - 0x26, 0xa3, 0x7f, 0x3b, 0x47, 0xa7, 0xe0, 0xab, 0x4f, 0x41, 0x4c, 0x18, 0x2d, 0x93, 0x51, 0xbf, - 0x83, 0xa3, 0x3a, 0x28, 0x04, 0x5d, 0x18, 0x2c, 0x93, 0xd1, 0xff, 0x96, 0x40, 0x17, 0x28, 0x04, - 0x7d, 0x7a, 0x16, 0xfe, 0xea, 0x87, 0x42, 0x7c, 0xd1, 0x11, 0xbc, 0xbb, 0x0c, 0x51, 0x6e, 0xa9, - 0x4c, 0xc6, 0xfe, 0x4e, 0x5e, 0xb9, 0xc0, 0x58, 0x7d, 0x02, 0xc2, 0x53, 0x32, 0xfc, 0xc3, 0x1c, - 0x95, 0xc1, 0xaf, 0x16, 0x21, 0xe1, 0xb1, 0x4e, 0x26, 0xa3, 0x7f, 0x37, 0x47, 0xf7, 0x62, 0x91, - 0xa6, 0x73, 0xeb, 0x64, 0x32, 0x81, 0xbf, 0x2d, 0x9a, 0xce, 0x31, 0x08, 0xdb, 0x84, 0x61, 0x32, - 0x19, 0xfb, 0x23, 0x82, 0xeb, 0x02, 0x65, 0xf5, 0x69, 0x88, 0x3b, 0x8b, 0xcd, 0x64, 0xfc, 0xef, - 0xe1, 0xf8, 0x2e, 0x0e, 0xe1, 0x80, 0x67, 0xb1, 0x9b, 0x4c, 0xe2, 0xef, 0x08, 0x0e, 0x78, 0xb0, - 0xc8, 0x34, 0x1a, 0x34, 0x60, 0x26, 0x53, 0xfa, 0x5e, 0x31, 0x8d, 0x06, 0xec, 0x17, 0x32, 0x9a, - 0x54, 0xe7, 0x4f, 0x26, 0xf1, 0x7d, 0x62, 0x34, 0x29, 0x3c, 0x69, 0xc6, 0xa0, 0x45, 0x30, 0x99, - 0xc6, 0x0f, 0x88, 0x66, 0x0c, 0x18, 0x04, 0xab, 0x9b, 0x80, 0x86, 0xad, 0x81, 0xc9, 0xf4, 0x5e, - 0xe3, 0xf4, 0xe6, 0x86, 0x8c, 0x81, 0xd5, 0xe7, 0xe0, 0xf8, 0x68, 0x4b, 0x60, 0x32, 0xd5, 0x1f, - 0x7c, 0x6b, 0xc0, 0x77, 0xf3, 0x1a, 0x02, 0xab, 0x0d, 0x77, 0x49, 0xf1, 0x5a, 0x01, 0x93, 0xc9, - 0xfe, 0xd0, 0x5b, 0x7e, 0xc5, 0xed, 0x35, 0x02, 0x56, 0xf3, 0x00, 0xee, 0x02, 0x3c, 0x99, 0xd6, - 0xc7, 0x38, 0x2d, 0x0f, 0x12, 0x99, 0x1a, 0x7c, 0xfd, 0x9d, 0x8c, 0x7f, 0x5b, 0x4c, 0x0d, 0x8e, - 0x41, 0xa6, 0x86, 0x58, 0x7a, 0x27, 0x63, 0x7f, 0x5c, 0x4c, 0x0d, 0x81, 0x42, 0x24, 0xdb, 0xb3, - 0xba, 0x4d, 0xa6, 0xf0, 0x49, 0x21, 0xd9, 0x1e, 0xac, 0xd5, 0x2a, 0xcc, 0x0d, 0x2d, 0x88, 0x93, - 0x49, 0xfd, 0x08, 0x27, 0x25, 0x0f, 0xae, 0x87, 0xde, 0xc5, 0x8b, 0x2f, 0x86, 0x93, 0xa9, 0xfd, - 0xe8, 0xc0, 0xe2, 0xc5, 0xd7, 0xc2, 0xd5, 0xcb, 0x10, 0x33, 0xfa, 0xed, 0x36, 0x99, 0x3c, 0xe8, - 0xf0, 0xcb, 0x93, 0x99, 0x3f, 0xfc, 0x32, 0xe7, 0x8e, 0x40, 0x58, 0xbd, 0x00, 0x61, 0xdc, 0xd9, - 0xc6, 0xad, 0x49, 0x98, 0x5f, 0xfc, 0xb2, 0x50, 0x98, 0x04, 0x7a, 0xf5, 0x69, 0x00, 0x16, 0x1a, - 0xa1, 0x07, 0x90, 0x27, 0xe0, 0xfe, 0xd1, 0x97, 0xf9, 0x6d, 0x25, 0x17, 0xc5, 0x25, 0xc0, 0xee, - 0x3e, 0x1d, 0x4e, 0xe0, 0x4b, 0x7e, 0x02, 0x74, 0x44, 0x2e, 0x41, 0xf4, 0x45, 0xcb, 0x34, 0x6c, - 0x6d, 0x77, 0x12, 0xf6, 0x1f, 0x73, 0x6c, 0x01, 0x4f, 0x18, 0xd6, 0x31, 0x7b, 0xd8, 0xd6, 0x76, - 0xad, 0x49, 0xb8, 0xff, 0x8d, 0xe3, 0x3a, 0x08, 0x04, 0xb9, 0xa9, 0x59, 0xf6, 0x34, 0xfd, 0xfe, - 0x13, 0x81, 0x2c, 0x10, 0x48, 0xa3, 0xc9, 0xef, 0x9b, 0xf8, 0x60, 0x12, 0xee, 0x9f, 0x8a, 0x46, - 0x73, 0xf8, 0xd5, 0xa7, 0x20, 0x4e, 0x7e, 0xb2, 0x2b, 0x88, 0x13, 0x90, 0xff, 0x8c, 0x23, 0xbb, - 0x18, 0xa4, 0x66, 0xcb, 0x6e, 0xd9, 0xfa, 0x64, 0x66, 0xff, 0x39, 0x1f, 0x69, 0x01, 0xbf, 0x9a, - 0x87, 0x84, 0x65, 0xb7, 0x5a, 0x7d, 0x6e, 0x9f, 0x4e, 0x40, 0xff, 0x8b, 0x2f, 0x3b, 0x21, 0x0b, - 0x07, 0x87, 0x8c, 0xf6, 0x4b, 0x37, 0xed, 0xae, 0x49, 0x8f, 0xac, 0x4c, 0xa2, 0xf0, 0x16, 0xa7, - 0xe0, 0x41, 0x59, 0x2d, 0x42, 0x92, 0xf4, 0x45, 0xec, 0xfc, 0x4f, 0x22, 0xf1, 0x97, 0x9c, 0x01, - 0x3e, 0xa4, 0xc2, 0x37, 0xff, 0xfa, 0xe7, 0x4f, 0x4b, 0x9f, 0xfb, 0xfc, 0x69, 0xe9, 0xbf, 0x7e, - 0xfe, 0xb4, 0xf4, 0x91, 0x2f, 0x9c, 0x9e, 0xf9, 0xdc, 0x17, 0x4e, 0xcf, 0xfc, 0xce, 0x17, 0x4e, - 0xcf, 0x8c, 0x8e, 0x12, 0xc3, 0x9a, 0xb9, 0x66, 0xb2, 0xf8, 0xf0, 0x0b, 0xf7, 0xed, 0xea, 0xf6, - 0x5e, 0x7f, 0x7b, 0xb9, 0x69, 0x76, 0xce, 0x35, 0x4d, 0xab, 0x63, 0x5a, 0xe7, 0xfc, 0x71, 0x5d, - 0xfa, 0x0b, 0xfe, 0x97, 0x44, 0x7c, 0x66, 0x7f, 0x38, 0x57, 0x33, 0x0e, 0xc6, 0x3d, 0xa9, 0x73, - 0x11, 0x82, 0x79, 0xe3, 0x00, 0x9d, 0x64, 0x0a, 0x4e, 0xed, 0xf7, 0xda, 0xfc, 0x1e, 0x5c, 0x94, - 0xa4, 0xb7, 0x7a, 0x6d, 0xff, 0x19, 0xe8, 0x24, 0x3f, 0x03, 0x5d, 0xf8, 0x6e, 0xe9, 0x68, 0x3d, - 0x89, 0xe5, 0x8d, 0x03, 0xda, 0x91, 0x4d, 0xe9, 0x85, 0x87, 0x27, 0xc6, 0xb9, 0x6f, 0x1a, 0xe6, - 0x4b, 0x06, 0x69, 0x76, 0x77, 0x5b, 0xc4, 0xb8, 0x4f, 0x0f, 0xc6, 0xb8, 0x9f, 0xc3, 0xed, 0xf6, - 0x33, 0x04, 0xae, 0x41, 0x50, 0xb6, 0x23, 0xec, 0xca, 0x35, 0x7c, 0x6f, 0x00, 0x4e, 0x0f, 0x85, - 0xb3, 0xb9, 0x10, 0x8c, 0x63, 0xc2, 0x2a, 0xc4, 0x4a, 0x42, 0xb6, 0x32, 0x10, 0xb5, 0x70, 0xd3, - 0x34, 0x5a, 0xec, 0x30, 0x6b, 0x50, 0x11, 0x49, 0xc2, 0x08, 0x43, 0x33, 0x4c, 0x8b, 0xdf, 0x24, - 0x65, 0x89, 0xc2, 0x47, 0x8f, 0xc8, 0x88, 0x59, 0x51, 0x93, 0xe0, 0xc6, 0xf9, 0x29, 0xb9, 0x21, - 0x3a, 0xe1, 0x8b, 0xfc, 0x4f, 0xcb, 0x95, 0x1f, 0x08, 0xc0, 0xe2, 0x20, 0x57, 0xc8, 0xcc, 0xb2, - 0x6c, 0xad, 0xd3, 0x1d, 0xc7, 0x96, 0xcb, 0x10, 0x6f, 0x08, 0x98, 0x23, 0xf3, 0xe5, 0xf6, 0x11, - 0xf9, 0x92, 0x72, 0xaa, 0x12, 0x8c, 0x59, 0x99, 0x92, 0x31, 0x4e, 0x3f, 0xee, 0x88, 0x33, 0xff, - 0x33, 0x02, 0x27, 0xd9, 0x74, 0x52, 0xd9, 0x54, 0x62, 0x09, 0xce, 0x93, 0xa4, 0xb7, 0x68, 0xf2, - 0x3e, 0x49, 0xee, 0x19, 0x98, 0xaf, 0x10, 0x6d, 0x41, 0xbc, 0x20, 0x77, 0x87, 0x67, 0xe4, 0x65, - 0xdb, 0x25, 0x9f, 0xc1, 0xcf, 0x77, 0x02, 0xbd, 0x59, 0xb9, 0x6f, 0x95, 0x40, 0xae, 0x37, 0xb5, - 0xb6, 0xd6, 0xfb, 0x6a, 0x49, 0xa1, 0x27, 0x00, 0xd8, 0x51, 0x29, 0xe7, 0x99, 0x9c, 0xd4, 0x4a, - 0x66, 0xd9, 0xdb, 0xb9, 0x65, 0x56, 0x13, 0xbd, 0x88, 0x12, 0xa7, 0xb0, 0xe4, 0xe7, 0xd9, 0xe7, - 0x01, 0xdc, 0x02, 0x74, 0x0a, 0x4e, 0xd4, 0x8b, 0xf9, 0xf5, 0xbc, 0x22, 0xce, 0xbc, 0xd4, 0x37, - 0xcb, 0x45, 0xf6, 0x6a, 0xc5, 0x0c, 0x3a, 0x0e, 0xc8, 0x5b, 0xe8, 0x1c, 0xde, 0x3f, 0x06, 0x73, - 0xde, 0x7c, 0xf6, 0x84, 0x40, 0x80, 0x58, 0x8a, 0x7a, 0xa7, 0xdb, 0xc6, 0x74, 0x6b, 0x58, 0xd5, - 0x05, 0xd7, 0x26, 0x1b, 0x21, 0xbf, 0xf1, 0x1f, 0xd8, 0xb5, 0xf2, 0x79, 0x17, 0xdd, 0xe1, 0xf9, - 0xea, 0x3a, 0xcc, 0x69, 0xcd, 0x26, 0xee, 0xfa, 0x48, 0x4e, 0x50, 0xd5, 0x84, 0x20, 0xdd, 0xec, - 0xe6, 0x98, 0x2e, 0xb5, 0x27, 0x20, 0x62, 0xd1, 0xde, 0x4f, 0x22, 0xf1, 0x59, 0x4e, 0x82, 0x83, - 0xaf, 0x1a, 0x30, 0xc7, 0x5e, 0x51, 0xc1, 0x9e, 0x66, 0x1c, 0x1e, 0x67, 0xf8, 0x27, 0x3f, 0xff, - 0x28, 0xdd, 0x83, 0xbe, 0xc7, 0x3f, 0x2c, 0x23, 0xc4, 0x49, 0x91, 0x39, 0x6d, 0xb7, 0xa1, 0x18, - 0x52, 0xa2, 0x3e, 0xde, 0xe0, 0xc3, 0x2b, 0xfb, 0x15, 0x5e, 0xd9, 0xe9, 0x51, 0x32, 0xe0, 0xa9, - 0x69, 0x96, 0x53, 0x65, 0x05, 0x85, 0xf2, 0xb8, 0x39, 0xfd, 0xc2, 0x43, 0xc3, 0xab, 0x13, 0xfb, - 0xf7, 0x08, 0xa5, 0x7c, 0xd9, 0x5b, 0x8d, 0x33, 0xf7, 0x3e, 0x1a, 0x82, 0x39, 0xad, 0xa3, 0x1b, - 0xe6, 0x39, 0xfa, 0x97, 0xcf, 0xb9, 0x30, 0x4d, 0x4c, 0xb1, 0x29, 0x79, 0x91, 0x4d, 0x85, 0xc9, - 0x12, 0xf3, 0x67, 0xdf, 0xf5, 0xe3, 0x61, 0x77, 0xba, 0xac, 0x6e, 0x0c, 0x1f, 0x93, 0x9b, 0x4c, - 0xe3, 0xcf, 0x05, 0x8d, 0xc1, 0x53, 0x6f, 0xab, 0xef, 0x86, 0x98, 0x43, 0x66, 0x92, 0x65, 0x22, - 0x88, 0x38, 0x18, 0xc4, 0x2e, 0x61, 0x33, 0x73, 0x1a, 0x2b, 0xf4, 0x2d, 0x81, 0xcf, 0x66, 0x68, - 0x95, 0xf4, 0x66, 0x0d, 0x52, 0x2d, 0xd3, 0xb0, 0x55, 0xb3, 0xa3, 0xdb, 0xb8, 0xd3, 0xb5, 0x27, - 0xda, 0x75, 0x7f, 0xc9, 0x88, 0xc4, 0x94, 0x59, 0x82, 0x57, 0x13, 0x68, 0xa4, 0x25, 0xec, 0x11, - 0x95, 0x69, 0x5a, 0xf2, 0xdf, 0x9d, 0x96, 0x50, 0x1c, 0xd2, 0x92, 0x3b, 0x92, 0x0e, 0xab, 0x75, - 0x93, 0x2b, 0x73, 0x7b, 0x9f, 0x49, 0x81, 0x23, 0x1d, 0xff, 0x3c, 0x04, 0xa7, 0x39, 0xf0, 0xb6, - 0x66, 0xe1, 0x73, 0xb7, 0xce, 0x6f, 0x63, 0x5b, 0x3b, 0x7f, 0xae, 0x69, 0xea, 0x62, 0x25, 0x9f, - 0xe7, 0xca, 0x9a, 0x94, 0x2f, 0xf3, 0xf2, 0xec, 0xc8, 0xed, 0xee, 0xec, 0x78, 0x25, 0x9f, 0x1d, - 0x96, 0xc1, 0x5c, 0x1b, 0x42, 0x45, 0x53, 0xa7, 0x17, 0xc0, 0x5a, 0xd8, 0x30, 0x3b, 0x5c, 0xdd, - 0xb2, 0x04, 0xba, 0x0a, 0x11, 0xad, 0x63, 0xf6, 0x0d, 0x9b, 0xa9, 0xda, 0xc2, 0xa3, 0xbf, 0xfe, - 0xfa, 0xe2, 0xcc, 0x7f, 0x7e, 0x7d, 0xf1, 0x18, 0x23, 0x6b, 0xb5, 0x6e, 0x2e, 0xeb, 0xe6, 0xb9, - 0x8e, 0x66, 0xef, 0x91, 0xe9, 0xfb, 0xdb, 0x9f, 0x79, 0x04, 0x78, 0x7d, 0x15, 0xc3, 0xfe, 0xd4, + 0x99, 0x97, 0xe7, 0x21, 0xe6, 0xa4, 0x72, 0xd8, 0x41, 0xd5, 0x77, 0x1f, 0xb2, 0x2c, 0x04, 0x9a, + 0xa7, 0x68, 0x20, 0xb5, 0xe3, 0x50, 0x23, 0x71, 0x7b, 0x47, 0x37, 0xf4, 0x4e, 0xbf, 0xa3, 0x8a, + 0xfc, 0xc6, 0xc4, 0xb8, 0x9d, 0x23, 0xf0, 0x6f, 0x4a, 0x42, 0xdb, 0xf7, 0x91, 0x08, 0x4f, 0x24, + 0xc1, 0x10, 0xf8, 0x77, 0xf6, 0xaf, 0x24, 0xc8, 0x8c, 0xeb, 0xec, 0x1d, 0xa5, 0x5e, 0xaa, 0xb0, + 0x60, 0xde, 0xc2, 0xbd, 0x9e, 0xde, 0xa2, 0xbb, 0x29, 0x8e, 0x43, 0x16, 0x9a, 0xec, 0x90, 0xcd, + 0x7b, 0x10, 0x9d, 0x49, 0x2d, 0x10, 0xbb, 0xb9, 0x4f, 0x4c, 0x86, 0xa0, 0x14, 0x9e, 0x4c, 0x69, + 0x96, 0xa2, 0x08, 0x1a, 0xd7, 0xc8, 0x32, 0x21, 0x31, 0x50, 0x40, 0x0e, 0xba, 0x5e, 0x5f, 0xee, + 0xe3, 0x41, 0x48, 0xf9, 0x0f, 0x67, 0xa2, 0x12, 0xc4, 0xda, 0x26, 0x3f, 0xf8, 0xc4, 0x66, 0xfb, + 0xcc, 0x84, 0xf3, 0x9c, 0xcb, 0xeb, 0x1c, 0x5e, 0x71, 0x30, 0xb3, 0xff, 0x5a, 0x82, 0x98, 0x28, + 0x46, 0xc7, 0x21, 0xd4, 0xd5, 0xec, 0x3d, 0x4a, 0x2e, 0x5c, 0x08, 0xc8, 0x92, 0x42, 0xbf, 0x49, + 0xb9, 0xd5, 0xd5, 0xd8, 0xa1, 0x2f, 0x5e, 0x4e, 0xbe, 0x89, 0xe7, 0xd5, 0xc6, 0x5a, 0x8b, 0xee, + 0x03, 0x9a, 0x9d, 0x0e, 0x36, 0x6c, 0x4b, 0x78, 0x5e, 0xbc, 0xbc, 0xc8, 0x8b, 0xd1, 0x43, 0x30, + 0x67, 0xf7, 0x34, 0xbd, 0xed, 0x83, 0x0d, 0x51, 0x58, 0x59, 0x54, 0x38, 0xc0, 0xab, 0x70, 0x52, + 0xd0, 0x6d, 0x61, 0x5b, 0x6b, 0xee, 0xe1, 0x96, 0x8b, 0x14, 0xa1, 0xfb, 0xfd, 0x27, 0x38, 0x40, + 0x89, 0xd7, 0x0b, 0xdc, 0xb3, 0x7d, 0xdf, 0x79, 0xeb, 0x5d, 0x84, 0xf9, 0x79, 0xeb, 0xf3, 0x63, + 0xce, 0x5b, 0x0f, 0x9e, 0x8d, 0xf5, 0x1c, 0xb6, 0x3e, 0x3b, 0x02, 0xc5, 0xcf, 0x51, 0xd7, 0x85, + 0xfa, 0x7c, 0x00, 0xe6, 0xc4, 0x86, 0x69, 0xcb, 0x99, 0xa3, 0x0d, 0x00, 0xcd, 0x30, 0x4c, 0xdb, + 0x3b, 0x4b, 0xc3, 0x3e, 0xee, 0x10, 0xde, 0x72, 0xde, 0x41, 0x52, 0x3c, 0x04, 0xb2, 0x7f, 0x24, + 0x01, 0xb8, 0x55, 0x63, 0xa7, 0x6b, 0x11, 0x12, 0x7c, 0x54, 0xf4, 0xcc, 0x3a, 0xcb, 0x2b, 0x02, + 0x2b, 0xba, 0xa2, 0xb7, 0xe9, 0x49, 0x88, 0x6d, 0xbc, 0xab, 0x1b, 0xfc, 0x08, 0x17, 0xfb, 0x10, + 0x27, 0x21, 0x42, 0xee, 0x11, 0x47, 0x05, 0x62, 0x16, 0xee, 0x68, 0x86, 0xad, 0x37, 0xf9, 0x62, + 0xbd, 0x78, 0xa4, 0xce, 0x2f, 0xd7, 0x39, 0xb6, 0xe2, 0xd0, 0xc9, 0x9d, 0x81, 0x98, 0x28, 0x75, + 0x8c, 0xc3, 0x0c, 0x8a, 0x42, 0xb0, 0x5e, 0x26, 0xe6, 0x91, 0xea, 0xe8, 0x4a, 0xbe, 0x2e, 0x07, + 0xce, 0xfe, 0x44, 0x00, 0xa2, 0x42, 0x7b, 0xcc, 0x43, 0xba, 0x5c, 0xaa, 0x0c, 0xd8, 0x99, 0x79, + 0x48, 0x89, 0x42, 0xa6, 0xcc, 0xe5, 0x0f, 0x44, 0xbd, 0x85, 0x9b, 0x4a, 0xad, 0x51, 0x5b, 0x91, + 0xff, 0x60, 0xb8, 0xf0, 0x31, 0xf9, 0x8d, 0x28, 0x9a, 0x83, 0xa4, 0x28, 0x5c, 0x79, 0x74, 0xe5, + 0x31, 0xf9, 0xcd, 0xc1, 0xa2, 0xc7, 0xe5, 0x3f, 0xa4, 0x29, 0x2d, 0x51, 0x74, 0x5e, 0x6d, 0x10, + 0x63, 0x51, 0xab, 0xae, 0xdf, 0x90, 0x25, 0x6f, 0xc5, 0x8a, 0xa7, 0x22, 0x80, 0xee, 0x86, 0x13, + 0xa2, 0xe2, 0xd2, 0xa5, 0x4b, 0x97, 0x9e, 0xf0, 0x54, 0xde, 0xfe, 0x70, 0x64, 0xb0, 0xfa, 0x49, + 0x4f, 0xf5, 0xc7, 0x87, 0xab, 0x2f, 0x79, 0xaa, 0x7f, 0xf8, 0xc3, 0x11, 0x34, 0x0f, 0x09, 0x51, + 0xbd, 0x91, 0x7f, 0x5e, 0xfe, 0xea, 0x57, 0xbf, 0xfa, 0xd5, 0x68, 0xe1, 0x5b, 0x60, 0xbe, 0x69, + 0x76, 0x06, 0xa7, 0xa6, 0x20, 0x0f, 0x9c, 0xc7, 0xb0, 0xd6, 0xa4, 0x17, 0x1e, 0xe1, 0x40, 0xbb, + 0x66, 0x5b, 0x33, 0x76, 0x97, 0xcd, 0xde, 0xae, 0x7b, 0x39, 0x82, 0xf8, 0xd6, 0x96, 0xe7, 0x8a, + 0x44, 0x77, 0xfb, 0xaf, 0x24, 0xe9, 0x47, 0x02, 0xc1, 0xab, 0x9b, 0x85, 0x9f, 0x0a, 0x64, 0xaf, + 0x32, 0xc4, 0x4d, 0x31, 0xf1, 0x0a, 0xde, 0x69, 0xe3, 0x26, 0x99, 0x1d, 0xf8, 0xe3, 0x87, 0x60, + 0x61, 0xd7, 0xdc, 0x35, 0x29, 0xa5, 0x73, 0xe4, 0x2f, 0x7e, 0xbb, 0x22, 0xee, 0x94, 0x66, 0x27, + 0x5e, 0xc5, 0x58, 0xad, 0xc2, 0x3c, 0x07, 0x56, 0xa9, 0xab, 0xcf, 0xb6, 0x8c, 0xd1, 0xa1, 0xc7, + 0x8e, 0x32, 0x3f, 0xf7, 0xfb, 0x34, 0x47, 0xa3, 0xcc, 0x71, 0x54, 0x52, 0xc7, 0x76, 0x95, 0x57, + 0x15, 0x38, 0xe6, 0xa3, 0xc7, 0xc2, 0x2c, 0xdc, 0x9b, 0x40, 0xf1, 0x9f, 0x71, 0x8a, 0xf3, 0x1e, + 0x8a, 0x75, 0x8e, 0xba, 0x5a, 0x84, 0xd9, 0xa3, 0xd0, 0xfa, 0xe7, 0x9c, 0x56, 0x12, 0x7b, 0x89, + 0x5c, 0x85, 0x34, 0x25, 0xd2, 0xec, 0x5b, 0xb6, 0xd9, 0xa1, 0x31, 0xec, 0xe1, 0x64, 0xfe, 0xc5, + 0xef, 0x33, 0xad, 0x9a, 0x22, 0x68, 0x45, 0x07, 0x6b, 0x75, 0x15, 0x68, 0xc8, 0xd2, 0xc2, 0xcd, + 0xf6, 0x04, 0x0a, 0xbf, 0xce, 0x3b, 0xe2, 0xc0, 0xaf, 0x5e, 0x87, 0x05, 0xf2, 0x37, 0x0d, 0x31, + 0xbd, 0x3d, 0x99, 0x7c, 0x46, 0x29, 0xf3, 0x5b, 0xef, 0x67, 0x8a, 0x7b, 0xde, 0x21, 0xe0, 0xe9, + 0x93, 0x67, 0x16, 0x77, 0xb1, 0x6d, 0xe3, 0x9e, 0xa5, 0x6a, 0xed, 0x51, 0xdd, 0xf3, 0x1c, 0xf2, + 0xc8, 0xfc, 0xe0, 0x97, 0xfd, 0xb3, 0x78, 0x95, 0x61, 0xe6, 0xdb, 0xed, 0xd5, 0x2d, 0x38, 0x31, + 0x42, 0x2a, 0xa6, 0xa0, 0xf9, 0x43, 0x9c, 0xe6, 0xc2, 0x90, 0x64, 0x10, 0xb2, 0x9b, 0x20, 0xca, + 0x9d, 0xb9, 0x9c, 0x82, 0xe6, 0x47, 0x39, 0x4d, 0xc4, 0x71, 0xc5, 0x94, 0x12, 0x8a, 0xd7, 0x60, + 0xee, 0x16, 0xee, 0x6d, 0x9b, 0x16, 0x3f, 0x58, 0x33, 0x05, 0xb9, 0x8f, 0x71, 0x72, 0x69, 0x8e, + 0x48, 0x4f, 0xda, 0x10, 0x5a, 0x97, 0x20, 0xb6, 0xa3, 0x35, 0xf1, 0x14, 0x24, 0x6e, 0x73, 0x12, + 0x51, 0x02, 0x4f, 0x50, 0xf3, 0x90, 0xdc, 0x35, 0x79, 0x96, 0x61, 0x32, 0xfa, 0xc7, 0x39, 0x7a, + 0x42, 0xe0, 0x70, 0x12, 0x5d, 0xb3, 0xdb, 0x6f, 0x6b, 0xf6, 0x34, 0x3d, 0xf8, 0x61, 0x41, 0x42, + 0xe0, 0x70, 0x12, 0x47, 0x60, 0xeb, 0x27, 0x04, 0x09, 0xcb, 0xc3, 0xcf, 0xa7, 0x21, 0x61, 0x1a, + 0xed, 0x03, 0xd3, 0x98, 0xa6, 0x13, 0x9f, 0xe4, 0x14, 0x80, 0xa3, 0x10, 0x02, 0x97, 0x21, 0x3e, + 0xed, 0x44, 0xfc, 0xd8, 0x97, 0xc5, 0xf2, 0x10, 0x33, 0x70, 0x15, 0xd2, 0x42, 0x41, 0xe9, 0xa6, + 0x31, 0x05, 0x89, 0x1f, 0xe7, 0x24, 0x52, 0x1e, 0x34, 0x3e, 0x0c, 0x1b, 0x5b, 0xf6, 0x2e, 0x9e, + 0x86, 0xc8, 0x4f, 0x88, 0x61, 0x70, 0x14, 0xce, 0xca, 0x6d, 0x6c, 0x34, 0xf7, 0xa6, 0xa3, 0xf0, + 0x29, 0xc1, 0x4a, 0x81, 0x43, 0x48, 0x14, 0x61, 0xb6, 0xa3, 0xf5, 0xac, 0x3d, 0xad, 0x3d, 0xd5, + 0x74, 0xfc, 0x24, 0xa7, 0x91, 0x74, 0x90, 0x38, 0x47, 0xfa, 0xc6, 0x51, 0xc8, 0xfc, 0x94, 0xe0, + 0x88, 0x07, 0x8d, 0x2f, 0x3d, 0xcb, 0xa6, 0x0e, 0xf7, 0x51, 0xa8, 0xfd, 0x1d, 0xb1, 0xf4, 0x18, + 0xee, 0x86, 0x97, 0xe2, 0x65, 0x88, 0x5b, 0xfa, 0xcb, 0x53, 0x91, 0xf9, 0x69, 0x31, 0xd3, 0x14, + 0x81, 0x20, 0xdf, 0x80, 0x93, 0x23, 0xcd, 0xc4, 0x14, 0xc4, 0x7e, 0x86, 0x13, 0x3b, 0x3e, 0xc2, + 0x54, 0x70, 0x95, 0x70, 0x54, 0x92, 0x7f, 0x57, 0xa8, 0x04, 0x3c, 0x40, 0x6b, 0x13, 0x16, 0xfa, + 0x86, 0xa5, 0xed, 0x1c, 0x8d, 0x6b, 0x7f, 0x4f, 0x70, 0x8d, 0xe1, 0xfa, 0xb8, 0xd6, 0x80, 0xe3, + 0x9c, 0xe2, 0xd1, 0xe6, 0xf5, 0x67, 0x85, 0x62, 0x65, 0xd8, 0x5b, 0xfe, 0xd9, 0xfd, 0x06, 0xc8, + 0x3a, 0xec, 0x14, 0xde, 0xb1, 0xa5, 0x76, 0xb4, 0xee, 0x14, 0x94, 0x7f, 0x8e, 0x53, 0x16, 0x1a, + 0xdf, 0x71, 0xaf, 0xad, 0x0d, 0xad, 0x4b, 0x88, 0x3f, 0x0f, 0x19, 0x41, 0xbc, 0x6f, 0xf4, 0x70, + 0xd3, 0xdc, 0x35, 0xf4, 0x97, 0x71, 0x6b, 0x0a, 0xd2, 0x9f, 0x1e, 0x98, 0xaa, 0x2d, 0x0f, 0x3a, + 0xa1, 0x5c, 0x01, 0xd9, 0xf1, 0x55, 0x54, 0xbd, 0x43, 0x37, 0x63, 0x0e, 0xa7, 0xf8, 0x19, 0x31, + 0x53, 0x0e, 0x5e, 0x85, 0xa2, 0xad, 0x96, 0x81, 0x1d, 0xcd, 0x9f, 0x56, 0x24, 0x3f, 0xcb, 0x09, + 0xcd, 0xba, 0x58, 0x5c, 0x71, 0x34, 0xcd, 0x4e, 0x57, 0xeb, 0x4d, 0xa3, 0xff, 0xfe, 0xbe, 0x50, + 0x1c, 0x1c, 0x85, 0x2b, 0x0e, 0xe2, 0xd1, 0x11, 0x6b, 0x3f, 0x05, 0x85, 0x9f, 0x17, 0x8a, 0x43, + 0xe0, 0x70, 0x12, 0xc2, 0x61, 0x98, 0x82, 0xc4, 0x2f, 0x08, 0x12, 0x02, 0x87, 0x90, 0x78, 0xd6, + 0x35, 0xb4, 0x3d, 0xbc, 0xab, 0x5b, 0x36, 0xbf, 0x3c, 0x73, 0x38, 0xa9, 0x5f, 0xfc, 0xb2, 0xdf, + 0x09, 0x53, 0x3c, 0xa8, 0x44, 0x13, 0xf1, 0xac, 0x20, 0xcd, 0x7a, 0x4f, 0xee, 0xd8, 0x2f, 0x09, + 0x4d, 0xe4, 0x41, 0x23, 0x7d, 0xf3, 0x78, 0x88, 0x84, 0xed, 0x4d, 0x12, 0x49, 0x4e, 0x41, 0xee, + 0x1f, 0x0c, 0x74, 0xae, 0x2e, 0x70, 0x09, 0x4d, 0x8f, 0xff, 0xd3, 0x37, 0x6e, 0xe2, 0x83, 0xa9, + 0xa4, 0xf3, 0x1f, 0x0e, 0xf8, 0x3f, 0x5b, 0x0c, 0x93, 0xe9, 0x90, 0xf4, 0x80, 0x3f, 0x85, 0x26, + 0xdd, 0xac, 0xcb, 0x7c, 0xeb, 0x5b, 0x7c, 0xbc, 0x7e, 0x77, 0x6a, 0x75, 0x9d, 0x08, 0xb9, 0xdf, + 0xe9, 0x99, 0x4c, 0xec, 0xfd, 0x6f, 0x39, 0x72, 0xee, 0xf3, 0x79, 0x56, 0xaf, 0xc0, 0xac, 0xcf, + 0xe1, 0x99, 0x4c, 0xea, 0x03, 0x9c, 0x54, 0xd2, 0xeb, 0xef, 0xac, 0x5e, 0x80, 0x10, 0x71, 0x5e, + 0x26, 0xa3, 0x7f, 0x3b, 0x47, 0xa7, 0xe0, 0xab, 0x4f, 0x41, 0x4c, 0x38, 0x2d, 0x93, 0x51, 0xbf, + 0x83, 0xa3, 0x3a, 0x28, 0x04, 0x5d, 0x38, 0x2c, 0x93, 0xd1, 0xff, 0x1f, 0x81, 0x2e, 0x50, 0x08, + 0xfa, 0xf4, 0x2c, 0xfc, 0xd5, 0x0f, 0x85, 0xb8, 0xd1, 0x11, 0xbc, 0xbb, 0x0c, 0x51, 0xee, 0xa9, + 0x4c, 0xc6, 0xfe, 0x4e, 0xde, 0xb8, 0xc0, 0x58, 0x7d, 0x02, 0xc2, 0x53, 0x32, 0xfc, 0xc3, 0x1c, + 0x95, 0xc1, 0xaf, 0x16, 0x21, 0xe1, 0xf1, 0x4e, 0x26, 0xa3, 0x7f, 0x37, 0x47, 0xf7, 0x62, 0x91, + 0xae, 0x73, 0xef, 0x64, 0x32, 0x81, 0xff, 0x57, 0x74, 0x9d, 0x63, 0x10, 0xb6, 0x09, 0xc7, 0x64, + 0x32, 0xf6, 0x47, 0x04, 0xd7, 0x05, 0xca, 0xea, 0xd3, 0x10, 0x77, 0x8c, 0xcd, 0x64, 0xfc, 0xef, + 0xe1, 0xf8, 0x2e, 0x0e, 0xe1, 0x80, 0xc7, 0xd8, 0x4d, 0x26, 0xf1, 0xff, 0x09, 0x0e, 0x78, 0xb0, + 0xc8, 0x32, 0x1a, 0x74, 0x60, 0x26, 0x53, 0xfa, 0x5e, 0xb1, 0x8c, 0x06, 0xfc, 0x17, 0x32, 0x9b, + 0x54, 0xe7, 0x4f, 0x26, 0xf1, 0x7d, 0x62, 0x36, 0x29, 0x3c, 0xe9, 0xc6, 0xa0, 0x47, 0x30, 0x99, + 0xc6, 0x0f, 0x88, 0x6e, 0x0c, 0x38, 0x04, 0xab, 0x9b, 0x80, 0x86, 0xbd, 0x81, 0xc9, 0xf4, 0x5e, + 0xe3, 0xf4, 0xe6, 0x86, 0x9c, 0x81, 0xd5, 0xe7, 0xe0, 0xf8, 0x68, 0x4f, 0x60, 0x32, 0xd5, 0x1f, + 0x7c, 0x6b, 0x20, 0x76, 0xf3, 0x3a, 0x02, 0xab, 0x0d, 0xd7, 0xa4, 0x78, 0xbd, 0x80, 0xc9, 0x64, + 0x7f, 0xe8, 0x2d, 0xbf, 0xe2, 0xf6, 0x3a, 0x01, 0xab, 0x79, 0x00, 0xd7, 0x00, 0x4f, 0xa6, 0xf5, + 0x31, 0x4e, 0xcb, 0x83, 0x44, 0x96, 0x06, 0xb7, 0xbf, 0x93, 0xf1, 0x6f, 0x8b, 0xa5, 0xc1, 0x31, + 0xc8, 0xd2, 0x10, 0xa6, 0x77, 0x32, 0xf6, 0xc7, 0xc5, 0xd2, 0x10, 0x28, 0x44, 0xb2, 0x3d, 0xd6, + 0x6d, 0x32, 0x85, 0x4f, 0x0a, 0xc9, 0xf6, 0x60, 0xad, 0x56, 0x61, 0x6e, 0xc8, 0x20, 0x4e, 0x26, + 0xf5, 0x23, 0x9c, 0x94, 0x3c, 0x68, 0x0f, 0xbd, 0xc6, 0x8b, 0x1b, 0xc3, 0xc9, 0xd4, 0x7e, 0x74, + 0xc0, 0x78, 0x71, 0x5b, 0xb8, 0x7a, 0x19, 0x62, 0x46, 0xbf, 0xdd, 0x26, 0x8b, 0x07, 0x1d, 0x7e, + 0x79, 0x32, 0xf3, 0x87, 0x5f, 0xe1, 0xdc, 0x11, 0x08, 0xab, 0x17, 0x20, 0x8c, 0x3b, 0xdb, 0xb8, + 0x35, 0x09, 0xf3, 0x4b, 0x5f, 0x11, 0x0a, 0x93, 0x40, 0xaf, 0x3e, 0x0d, 0xc0, 0x52, 0x23, 0xf4, + 0x00, 0xf2, 0x04, 0xdc, 0x3f, 0xfa, 0x0a, 0xbf, 0xad, 0xe4, 0xa2, 0xb8, 0x04, 0xd8, 0xdd, 0xa7, + 0xc3, 0x09, 0x7c, 0xd9, 0x4f, 0x80, 0xce, 0xc8, 0x25, 0x88, 0xbe, 0x68, 0x99, 0x86, 0xad, 0xed, + 0x4e, 0xc2, 0xfe, 0x63, 0x8e, 0x2d, 0xe0, 0x09, 0xc3, 0x3a, 0x66, 0x0f, 0xdb, 0xda, 0xae, 0x35, + 0x09, 0xf7, 0xbf, 0x70, 0x5c, 0x07, 0x81, 0x20, 0x37, 0x35, 0xcb, 0x9e, 0x66, 0xdc, 0x7f, 0x22, + 0x90, 0x05, 0x02, 0xe9, 0x34, 0xf9, 0xfb, 0x26, 0x3e, 0x98, 0x84, 0xfb, 0xa7, 0xa2, 0xd3, 0x1c, + 0x7e, 0xf5, 0x29, 0x88, 0x93, 0x3f, 0xd9, 0x15, 0xc4, 0x09, 0xc8, 0x7f, 0xc6, 0x91, 0x5d, 0x0c, + 0xd2, 0xb2, 0x65, 0xb7, 0x6c, 0x7d, 0x32, 0xb3, 0xff, 0x9c, 0xcf, 0xb4, 0x80, 0x5f, 0xcd, 0x43, + 0xc2, 0xb2, 0x5b, 0xad, 0x3e, 0xf7, 0x4f, 0x27, 0xa0, 0xff, 0xc5, 0x57, 0x9c, 0x94, 0x85, 0x83, + 0x43, 0x66, 0xfb, 0xa5, 0x9b, 0x76, 0xd7, 0xa4, 0x47, 0x56, 0x26, 0x51, 0x78, 0x8b, 0x53, 0xf0, + 0xa0, 0xac, 0x16, 0x21, 0x49, 0xc6, 0x22, 0x76, 0xfe, 0x27, 0x91, 0xf8, 0x4b, 0xce, 0x00, 0x1f, + 0x52, 0xe1, 0x9b, 0x7f, 0xfd, 0x0b, 0xa7, 0xa5, 0xcf, 0x7f, 0xe1, 0xb4, 0xf4, 0x9f, 0xbf, 0x70, + 0x5a, 0xfa, 0xc8, 0x17, 0x4f, 0xcf, 0x7c, 0xfe, 0x8b, 0xa7, 0x67, 0x7e, 0xe7, 0x8b, 0xa7, 0x67, + 0x46, 0x67, 0x89, 0xe1, 0xaa, 0x79, 0xd5, 0x64, 0xf9, 0xe1, 0x17, 0xee, 0xdb, 0xd5, 0xed, 0xbd, + 0xfe, 0xf6, 0x72, 0xd3, 0xec, 0x9c, 0x6b, 0x9a, 0x56, 0xc7, 0xb4, 0xce, 0xf9, 0xf3, 0xba, 0xf4, + 0x2f, 0xf8, 0x1f, 0x12, 0x89, 0x99, 0xfd, 0xe9, 0x5c, 0xcd, 0x38, 0x18, 0xf7, 0xa4, 0xce, 0x45, + 0x08, 0xe6, 0x8d, 0x03, 0x74, 0x92, 0x29, 0x38, 0xb5, 0xdf, 0x6b, 0xf3, 0x7b, 0x70, 0x51, 0xf2, + 0xbd, 0xd5, 0x6b, 0xfb, 0xcf, 0x40, 0x27, 0xf9, 0x19, 0xe8, 0xc2, 0x77, 0x4b, 0x47, 0x1b, 0x49, + 0x2c, 0x6f, 0x1c, 0xd0, 0x81, 0x6c, 0x4a, 0x2f, 0x3c, 0x3c, 0x31, 0xcf, 0x7d, 0xd3, 0x30, 0x5f, + 0x32, 0x48, 0xb7, 0xbb, 0xdb, 0x22, 0xc7, 0x7d, 0x7a, 0x30, 0xc7, 0xfd, 0x1c, 0x6e, 0xb7, 0x9f, + 0x21, 0x70, 0x0d, 0x82, 0xb2, 0x1d, 0x61, 0x57, 0xae, 0xe1, 0x7b, 0x03, 0x70, 0x7a, 0x28, 0x9d, + 0xcd, 0x85, 0x60, 0x1c, 0x13, 0x56, 0x21, 0x56, 0x12, 0xb2, 0x95, 0x81, 0xa8, 0x85, 0x9b, 0xa6, + 0xd1, 0x62, 0x87, 0x59, 0x83, 0x8a, 0xf8, 0x24, 0x8c, 0x30, 0x34, 0xc3, 0xb4, 0xf8, 0x4d, 0x52, + 0xf6, 0x51, 0xf8, 0xe8, 0x11, 0x19, 0x31, 0x2b, 0x5a, 0x12, 0xdc, 0x38, 0x3f, 0x25, 0x37, 0xc4, + 0x20, 0x7c, 0x99, 0xff, 0x69, 0xb9, 0xf2, 0x03, 0x01, 0x58, 0x1c, 0xe4, 0x0a, 0x59, 0x59, 0x96, + 0xad, 0x75, 0xba, 0xe3, 0xd8, 0x72, 0x19, 0xe2, 0x0d, 0x01, 0x73, 0x64, 0xbe, 0xdc, 0x3e, 0x22, + 0x5f, 0x52, 0x4e, 0x53, 0x82, 0x31, 0x2b, 0x53, 0x32, 0xc6, 0x19, 0xc7, 0x1d, 0x71, 0xe6, 0xa3, + 0x71, 0x38, 0xc9, 0x96, 0x93, 0xca, 0x96, 0x12, 0xfb, 0xe0, 0x3c, 0x49, 0x7a, 0xab, 0x26, 0xef, + 0x93, 0xe4, 0x9e, 0x81, 0xf9, 0x0a, 0xd1, 0x16, 0x24, 0x0a, 0x72, 0x77, 0x78, 0x46, 0x5e, 0xb6, + 0x5d, 0xf2, 0x39, 0xfc, 0x7c, 0x27, 0xd0, 0x5b, 0x94, 0xfb, 0x56, 0x09, 0xe4, 0x7a, 0x53, 0x6b, + 0x6b, 0xbd, 0xaf, 0x95, 0x14, 0x7a, 0x02, 0x80, 0x1d, 0x95, 0x72, 0x9e, 0xc9, 0x49, 0xad, 0x64, + 0x96, 0xbd, 0x83, 0x5b, 0x66, 0x2d, 0xd1, 0x8b, 0x28, 0x71, 0x0a, 0x4b, 0xfe, 0x3c, 0xfb, 0x3c, + 0x80, 0x5b, 0x81, 0x4e, 0xc1, 0x89, 0x7a, 0x31, 0xbf, 0x9e, 0x57, 0xc4, 0x99, 0x97, 0xfa, 0x66, + 0xb9, 0xc8, 0x5e, 0xad, 0x98, 0x41, 0xc7, 0x01, 0x79, 0x2b, 0x9d, 0xc3, 0xfb, 0xc7, 0x60, 0xce, + 0x5b, 0xce, 0x9e, 0x10, 0x08, 0xac, 0xae, 0x41, 0x9a, 0xdd, 0x6f, 0x56, 0xb5, 0x56, 0x0b, 0xb7, + 0x54, 0xdd, 0x40, 0x13, 0xae, 0x0b, 0x67, 0x7e, 0xe3, 0xdf, 0x85, 0xe9, 0xd0, 0x66, 0x19, 0x62, + 0x9e, 0xe0, 0x55, 0x0c, 0xe2, 0x73, 0xea, 0x9d, 0x6e, 0x1b, 0xd3, 0x4d, 0x66, 0x55, 0x17, 0xfc, + 0x9f, 0xec, 0xce, 0x10, 0x7a, 0xc1, 0x33, 0x71, 0x65, 0xde, 0x45, 0x77, 0x66, 0x6f, 0xf5, 0x19, + 0xf7, 0x30, 0x95, 0xd3, 0xc1, 0x89, 0x14, 0x3f, 0xc7, 0x7b, 0x28, 0xb2, 0x19, 0xa2, 0x8b, 0xeb, + 0x30, 0xa7, 0x35, 0x9b, 0xb8, 0xeb, 0xeb, 0xdf, 0x04, 0x0b, 0x22, 0x46, 0x2b, 0x73, 0x4c, 0xb7, + 0x6b, 0x4f, 0x40, 0xc4, 0xa2, 0x93, 0x32, 0x89, 0x84, 0xe8, 0x0e, 0x07, 0x5f, 0x2d, 0x8b, 0xc3, + 0x83, 0xce, 0x88, 0x26, 0x10, 0xf8, 0x97, 0x9c, 0x40, 0x92, 0xa2, 0x89, 0xd1, 0x18, 0x30, 0xc7, + 0xde, 0x88, 0xc1, 0x9e, 0xd1, 0x1c, 0x9e, 0x45, 0xf9, 0x47, 0x9f, 0x79, 0x94, 0xee, 0xb0, 0xdf, + 0xe3, 0x17, 0xba, 0x11, 0x8b, 0x45, 0x91, 0x39, 0x6d, 0x77, 0xbc, 0x18, 0x52, 0xa2, 0x3d, 0x3e, + 0xee, 0xc3, 0x1b, 0xfb, 0x65, 0xde, 0xd8, 0xe9, 0x51, 0x12, 0xee, 0x69, 0x69, 0x96, 0x53, 0x65, + 0x15, 0xab, 0x05, 0x98, 0xa5, 0x2f, 0xbc, 0x39, 0xcc, 0x39, 0xbc, 0x95, 0x5f, 0xf9, 0xcc, 0xa3, + 0x6c, 0xa1, 0x11, 0x24, 0xce, 0x9a, 0x42, 0x79, 0x9c, 0xd6, 0x7b, 0xe1, 0xa1, 0x61, 0xfb, 0xcd, + 0xfe, 0x7b, 0x84, 0x52, 0xbf, 0xec, 0xed, 0xaa, 0xab, 0x9d, 0x42, 0x30, 0xa7, 0x75, 0x74, 0xc3, + 0x3c, 0x47, 0xff, 0xe5, 0x5a, 0x29, 0x4c, 0x3f, 0xa6, 0xd8, 0xb6, 0xbd, 0xc8, 0x94, 0xc5, 0x64, + 0xb9, 0xfd, 0xb3, 0xef, 0xfa, 0xf1, 0xb0, 0xab, 0x50, 0x56, 0x37, 0x86, 0x0f, 0x12, 0x4e, 0xa6, + 0xf1, 0xe7, 0x82, 0xc6, 0xe0, 0xb9, 0xc0, 0xd5, 0x77, 0x43, 0xcc, 0x21, 0x33, 0xc9, 0x77, 0x13, + 0x44, 0x1c, 0x0c, 0xe2, 0xb9, 0x31, 0xa1, 0x9d, 0xc6, 0x4f, 0x7f, 0x4b, 0xe0, 0x33, 0x1d, 0x56, + 0x25, 0xa3, 0xb9, 0x0a, 0xa9, 0x96, 0x69, 0xd8, 0xaa, 0xd9, 0xd1, 0x6d, 0xdc, 0xe9, 0xda, 0x13, + 0x3d, 0xdf, 0xbf, 0x64, 0x44, 0x62, 0xca, 0x2c, 0xc1, 0xab, 0x09, 0x34, 0xd2, 0x13, 0xf6, 0xcc, + 0xcc, 0x34, 0x3d, 0xf9, 0xaf, 0x4e, 0x4f, 0x28, 0x0e, 0xe9, 0xc9, 0x1d, 0x49, 0x87, 0xd5, 0xba, + 0xc9, 0xcd, 0x9d, 0xbd, 0xcf, 0xa4, 0xc0, 0x91, 0x8e, 0x7f, 0x12, 0x82, 0xd3, 0x1c, 0x78, 0x5b, + 0xb3, 0xf0, 0xb9, 0x5b, 0xe7, 0xb7, 0xb1, 0xad, 0x9d, 0x3f, 0xd7, 0x34, 0x75, 0xe1, 0xeb, 0xcc, + 0x73, 0x73, 0x46, 0xea, 0x97, 0x79, 0x7d, 0x76, 0xe4, 0x81, 0x80, 0xec, 0x78, 0x33, 0x98, 0x1d, + 0x96, 0xc1, 0x5c, 0x1b, 0x42, 0x45, 0x53, 0xa7, 0x57, 0xe4, 0x5a, 0xd8, 0x30, 0x3b, 0xdc, 0x20, + 0xb1, 0x0f, 0xb4, 0x06, 0x11, 0xad, 0x63, 0xf6, 0x0d, 0x9b, 0x19, 0xa3, 0xc2, 0xa3, 0xbf, 0xfe, + 0xfa, 0xe2, 0xcc, 0x7f, 0x7c, 0x7d, 0xf1, 0x18, 0x23, 0x6b, 0xb5, 0x6e, 0x2e, 0xeb, 0xe6, 0xb9, + 0x8e, 0x66, 0xef, 0x11, 0x15, 0xf0, 0xdb, 0x9f, 0x7d, 0x04, 0x78, 0x7b, 0x15, 0xc3, 0xfe, 0xd4, 0x1b, 0x3f, 0x7b, 0x56, 0x52, 0x38, 0xfe, 0x6a, 0xe8, 0xcd, 0x4f, 0x2c, 0x4a, 0xb9, 0x2e, 0x44, - 0x4b, 0xb8, 0x79, 0x48, 0x85, 0x95, 0x81, 0x0a, 0xcf, 0xf3, 0x0a, 0x4f, 0x0d, 0x57, 0xc8, 0x2e, - 0x96, 0x94, 0x70, 0xd3, 0x53, 0x6d, 0x09, 0x37, 0x07, 0x6a, 0xac, 0x40, 0xac, 0x62, 0xd8, 0xec, - 0x25, 0x88, 0xa7, 0x20, 0xa8, 0x1b, 0xec, 0x02, 0x71, 0xbc, 0xf0, 0xd0, 0x11, 0xba, 0xa2, 0x10, + 0x4b, 0xb8, 0x79, 0x48, 0x83, 0x95, 0x81, 0x06, 0xcf, 0xf3, 0x06, 0x4f, 0x0d, 0x37, 0xc8, 0xae, + 0xde, 0x94, 0x70, 0xd3, 0xd3, 0x6c, 0x09, 0x37, 0x07, 0x5a, 0xac, 0x40, 0xac, 0x62, 0xd8, 0xec, + 0xad, 0x8c, 0xa7, 0x20, 0xa8, 0x1b, 0xec, 0x8a, 0x75, 0xbc, 0xf0, 0xd0, 0x11, 0x86, 0xa2, 0x10, 0xbc, 0x5c, 0x0d, 0x62, 0x25, 0xdc, 0x64, 0xa4, 0x8a, 0x10, 0x6c, 0xe1, 0x26, 0x27, 0x75, 0x07, - 0x8d, 0x24, 0xd8, 0x85, 0xd2, 0xef, 0xfc, 0xde, 0xe9, 0x99, 0x57, 0x3e, 0x7f, 0x7a, 0x66, 0xac, - 0x38, 0xe5, 0x26, 0x8b, 0x93, 0x23, 0x45, 0x3f, 0x1e, 0x82, 0xbb, 0xe9, 0x53, 0x42, 0xbd, 0x8e, + 0x9d, 0x24, 0xd8, 0x85, 0xd2, 0xef, 0xfc, 0xde, 0xe9, 0x99, 0x57, 0xbe, 0x70, 0x7a, 0x66, 0xac, + 0x38, 0xe5, 0x26, 0x8b, 0x93, 0x23, 0x45, 0x3f, 0x1e, 0x82, 0xbb, 0xe9, 0x63, 0x4b, 0xbd, 0x8e, 0x6e, 0xd8, 0xe7, 0x9a, 0xbd, 0x83, 0xae, 0x6d, 0x12, 0xa5, 0x62, 0xee, 0x70, 0x21, 0x9a, 0x73, - 0x8b, 0x97, 0x59, 0xf1, 0x68, 0x11, 0xca, 0xed, 0x40, 0x78, 0x93, 0xe0, 0x91, 0x41, 0xb2, 0x4d, - 0x5b, 0x6b, 0x73, 0x4b, 0x88, 0x25, 0x48, 0x2e, 0x7b, 0x7e, 0x28, 0xc0, 0x72, 0x75, 0xf1, 0xf2, - 0x50, 0x1b, 0x6b, 0x3b, 0xec, 0x15, 0x87, 0x20, 0x35, 0xa1, 0x63, 0x24, 0x83, 0x3e, 0xd8, 0xb0, - 0x00, 0x61, 0xad, 0xcf, 0x4e, 0x5b, 0x05, 0x89, 0x6d, 0x4d, 0x13, 0xb9, 0x67, 0x20, 0xca, 0xf7, - 0xf4, 0x91, 0x0c, 0xc1, 0x9b, 0xf8, 0x80, 0xd6, 0x93, 0x54, 0xc8, 0x4f, 0xb4, 0x0c, 0x61, 0xda, - 0x78, 0x7e, 0x79, 0x26, 0xb3, 0x3c, 0xd4, 0xfa, 0x65, 0xda, 0x48, 0x85, 0x81, 0xe5, 0xae, 0x41, - 0xac, 0x64, 0x12, 0xc9, 0xf6, 0x53, 0x8b, 0x33, 0x6a, 0xb4, 0xcd, 0xdd, 0xbe, 0x2d, 0x2e, 0x38, - 0xd2, 0x04, 0x3a, 0x0e, 0x11, 0xf6, 0xaa, 0x07, 0x3f, 0x31, 0xc6, 0x53, 0xb9, 0x22, 0x44, 0x29, - 0xed, 0x5a, 0xd7, 0x79, 0x2a, 0x4b, 0xf2, 0x3c, 0x95, 0xc5, 0xc9, 0x07, 0xdc, 0xc6, 0x22, 0x08, - 0xb5, 0x34, 0x5b, 0xe3, 0xfd, 0xa6, 0xbf, 0x73, 0xef, 0x81, 0x18, 0x27, 0x62, 0xa1, 0x15, 0x08, - 0x9a, 0x5d, 0x71, 0x20, 0x32, 0x3b, 0xae, 0x2b, 0xb5, 0x6e, 0x21, 0x44, 0x64, 0x49, 0x21, 0xc0, - 0x85, 0xea, 0x58, 0xb1, 0x78, 0xdc, 0x27, 0x16, 0x1d, 0x6c, 0x6f, 0xef, 0xd8, 0xee, 0x0f, 0x36, - 0x9c, 0x43, 0xa2, 0xe0, 0x08, 0xca, 0xed, 0x00, 0x9c, 0xf6, 0x94, 0xde, 0xc2, 0x3d, 0x4b, 0x37, - 0x0d, 0x26, 0x4d, 0x5c, 0x52, 0x90, 0xa7, 0x81, 0xbc, 0x7c, 0x8c, 0xa8, 0x3c, 0x05, 0xc1, 0x7c, - 0xb7, 0x8b, 0xb2, 0x10, 0xa3, 0xe9, 0xa6, 0xc9, 0x64, 0x25, 0xa4, 0x38, 0x69, 0x52, 0x66, 0x99, - 0x3b, 0xf6, 0x4b, 0x5a, 0xcf, 0x79, 0xf4, 0x4a, 0xa4, 0x73, 0x97, 0x20, 0x5e, 0x34, 0x0d, 0x0b, - 0x1b, 0x56, 0x9f, 0xda, 0xd7, 0xdb, 0x6d, 0xb3, 0x79, 0x93, 0x53, 0x60, 0x09, 0xc2, 0x6c, 0xad, - 0xdb, 0xa5, 0x98, 0x21, 0x85, 0xfc, 0x64, 0x33, 0xbb, 0x50, 0x1b, 0xcb, 0x9e, 0x0b, 0x47, 0x63, - 0x0f, 0xef, 0xa0, 0x6b, 0x28, 0x4b, 0x70, 0xd7, 0xf0, 0x44, 0xba, 0x89, 0x0f, 0xac, 0xa3, 0xce, - 0xa3, 0xe7, 0x21, 0xbe, 0x49, 0x9f, 0x1e, 0x7d, 0x06, 0x1f, 0xa0, 0x2c, 0x44, 0x71, 0x6b, 0xe5, - 0xc2, 0x85, 0xf3, 0x97, 0x98, 0x94, 0x5f, 0x9d, 0x51, 0x44, 0x06, 0x3a, 0x0d, 0x71, 0x0b, 0x37, - 0xbb, 0x2b, 0x17, 0x2e, 0xde, 0x3c, 0xcf, 0xc4, 0xea, 0xea, 0x8c, 0xe2, 0x66, 0xad, 0xc6, 0x48, - 0x8f, 0xdf, 0xfc, 0xe4, 0xa2, 0x54, 0x08, 0x43, 0xd0, 0xea, 0x77, 0xbe, 0x66, 0xb2, 0xf1, 0xa7, - 0x11, 0x58, 0xf2, 0x94, 0xb2, 0x05, 0x8b, 0x9f, 0xf2, 0x77, 0x9e, 0xab, 0x95, 0x3d, 0xfd, 0xa7, - 0x10, 0x63, 0x56, 0xa2, 0x43, 0xb9, 0x98, 0xfb, 0xb4, 0x04, 0xc9, 0xeb, 0x82, 0x72, 0x1d, 0xdb, - 0xe8, 0x32, 0x80, 0x53, 0x93, 0x98, 0x2a, 0xa7, 0x96, 0x07, 0xeb, 0x5a, 0x76, 0x70, 0x14, 0x0f, - 0x38, 0x7a, 0x82, 0x0a, 0x60, 0xd7, 0xb4, 0xf8, 0x03, 0x48, 0x13, 0x50, 0x1d, 0x60, 0xf4, 0x30, - 0x20, 0xaa, 0xd5, 0xd4, 0x5b, 0xa6, 0xad, 0x1b, 0xbb, 0x6a, 0xd7, 0x7c, 0x89, 0x3f, 0x2b, 0x17, - 0x54, 0x64, 0x5a, 0x72, 0x9d, 0x16, 0x6c, 0x92, 0x7c, 0xd2, 0xe8, 0xb8, 0x43, 0x85, 0xb8, 0x8a, - 0x5a, 0xab, 0xd5, 0xc3, 0x96, 0xc5, 0x15, 0x97, 0x48, 0xa2, 0xcb, 0x10, 0xed, 0xf6, 0xb7, 0x55, - 0xa1, 0x25, 0x12, 0x2b, 0x77, 0x8d, 0x9a, 0xf3, 0x42, 0x36, 0xf8, 0xac, 0x8f, 0x74, 0xfb, 0xdb, - 0x44, 0x52, 0xee, 0x81, 0xe4, 0x88, 0xc6, 0x24, 0x6e, 0xb9, 0xed, 0xa0, 0xaf, 0xdd, 0xf2, 0x1e, - 0xa8, 0xdd, 0x9e, 0x6e, 0xf6, 0x74, 0xfb, 0x80, 0x1e, 0x9a, 0x0c, 0x2a, 0xb2, 0x28, 0xd8, 0xe4, - 0xf9, 0xb9, 0x9b, 0x90, 0xae, 0x53, 0x17, 0xc2, 0x6d, 0xf9, 0x05, 0xb7, 0x7d, 0xd2, 0xe4, 0xf6, - 0x8d, 0x6d, 0x59, 0x60, 0xa8, 0x65, 0x67, 0xff, 0xa3, 0x04, 0x89, 0x02, 0x99, 0xb8, 0x95, 0xd2, - 0x95, 0xb6, 0xb6, 0x8b, 0xce, 0xc3, 0xb1, 0xc2, 0x7a, 0xad, 0xf8, 0x8c, 0x5a, 0x29, 0xa9, 0x57, - 0xd6, 0xf3, 0x9e, 0x53, 0xf5, 0xd9, 0xe3, 0xaf, 0xde, 0x5e, 0x42, 0x1e, 0xd8, 0x2d, 0x83, 0xfa, - 0xb9, 0xe8, 0x1c, 0x2c, 0xf8, 0x51, 0xf2, 0x85, 0x7a, 0xb9, 0xda, 0x90, 0xa5, 0xec, 0xb1, 0x57, - 0x6f, 0x2f, 0xcd, 0x79, 0x30, 0xf2, 0xdb, 0x16, 0x36, 0xec, 0x61, 0x84, 0x62, 0x6d, 0x63, 0xa3, - 0xd2, 0x90, 0x03, 0x43, 0x08, 0x45, 0xb3, 0xd3, 0xd1, 0x6d, 0xf4, 0x20, 0xcc, 0xf9, 0x11, 0xaa, - 0x95, 0x75, 0x39, 0x98, 0x45, 0xaf, 0xde, 0x5e, 0x4a, 0x79, 0xa0, 0xab, 0x7a, 0x3b, 0x1b, 0xfb, - 0xe0, 0x8f, 0x9e, 0x9e, 0xf9, 0xd4, 0xdf, 0x3d, 0x2d, 0x15, 0x36, 0xc6, 0xce, 0xb9, 0xc7, 0x8e, - 0x36, 0xe7, 0xfc, 0xeb, 0xf6, 0x97, 0xef, 0xf2, 0xa9, 0x1b, 0x6e, 0x23, 0x7a, 0x94, 0xf1, 0xb4, - 0xd3, 0x6d, 0x52, 0xdc, 0x23, 0x7b, 0xb8, 0x79, 0x90, 0x9d, 0xb0, 0x28, 0x64, 0x27, 0x2a, 0x86, - 0xdc, 0x25, 0x98, 0xdd, 0xd4, 0x7a, 0x76, 0x1d, 0xdb, 0x57, 0xb1, 0xd6, 0xc2, 0x3d, 0xbf, 0xfd, - 0x30, 0x2b, 0xec, 0x07, 0x04, 0x21, 0x6a, 0x24, 0xb0, 0xf5, 0x93, 0xfe, 0xce, 0xed, 0x41, 0x88, - 0x5e, 0x14, 0x73, 0x6c, 0x0b, 0x8e, 0xc1, 0x6c, 0x0b, 0xb2, 0x32, 0x1c, 0xd8, 0xfc, 0x22, 0x6d, - 0x52, 0x61, 0x09, 0xf4, 0xb8, 0xb0, 0x10, 0x82, 0x87, 0x5b, 0x08, 0x7c, 0x7a, 0x71, 0x3b, 0xa1, - 0x0d, 0x51, 0x3e, 0xc4, 0x4e, 0x43, 0x24, 0xb7, 0x21, 0x68, 0x03, 0xd2, 0x5d, 0xad, 0x67, 0xd3, - 0x67, 0x67, 0xf6, 0x68, 0x2f, 0xf8, 0x0c, 0x5e, 0x1c, 0xd6, 0x27, 0xbe, 0xce, 0xf2, 0x5a, 0x66, - 0xbb, 0xde, 0xcc, 0xdc, 0x1f, 0x84, 0x20, 0xc2, 0x99, 0xf1, 0x14, 0x44, 0x39, 0x5b, 0xf9, 0x9c, - 0xbb, 0x7b, 0x79, 0x78, 0x99, 0x5d, 0x76, 0x96, 0x43, 0x4e, 0x4f, 0xe0, 0xa0, 0xfb, 0x21, 0xd6, - 0xdc, 0xd3, 0x74, 0x43, 0xd5, 0x5b, 0xdc, 0x38, 0x4e, 0x7c, 0xfe, 0xf5, 0xc5, 0x68, 0x91, 0xe4, - 0x55, 0x4a, 0x4a, 0x94, 0x16, 0x56, 0x5a, 0xc4, 0xa6, 0xd9, 0xc3, 0xfa, 0xee, 0x9e, 0xcd, 0xf5, - 0x06, 0x4f, 0xa1, 0x27, 0x21, 0x44, 0x04, 0x82, 0xdf, 0x2b, 0xc8, 0x0e, 0x79, 0x3d, 0x4e, 0x58, - 0xaa, 0x10, 0x23, 0x15, 0x7f, 0xe4, 0xbf, 0x2c, 0x4a, 0x0a, 0xc5, 0x40, 0x45, 0x98, 0x6d, 0x6b, - 0x96, 0xad, 0xd2, 0xf5, 0x98, 0x54, 0xcf, 0x2e, 0x14, 0x9c, 0x1c, 0x66, 0x08, 0x67, 0x2c, 0x6f, - 0x7a, 0x82, 0x60, 0xb1, 0xac, 0x16, 0x3a, 0x03, 0x32, 0x25, 0xd2, 0xa4, 0x33, 0x90, 0x59, 0x89, - 0x11, 0xca, 0xf7, 0x14, 0xc9, 0x67, 0x13, 0x93, 0xda, 0x8a, 0xa7, 0x20, 0x4e, 0xdf, 0x56, 0xa2, - 0x20, 0xec, 0x76, 0x62, 0x8c, 0x64, 0xd0, 0xc2, 0x07, 0x20, 0xed, 0x6a, 0x7d, 0x06, 0x12, 0x63, - 0x54, 0xdc, 0x6c, 0x0a, 0xf8, 0x28, 0x2c, 0x18, 0x78, 0xdf, 0x56, 0x07, 0xa1, 0xe3, 0x14, 0x1a, - 0x91, 0xb2, 0xeb, 0x7e, 0x8c, 0xfb, 0x20, 0xd5, 0x14, 0xcc, 0x67, 0xb0, 0x40, 0x61, 0x67, 0x9d, - 0x5c, 0x0a, 0x76, 0x12, 0x62, 0x5a, 0xb7, 0xcb, 0x00, 0x12, 0x5c, 0xeb, 0x77, 0xbb, 0xb4, 0xe8, - 0x2c, 0xcc, 0xd1, 0x3e, 0xf6, 0xb0, 0xd5, 0x6f, 0xdb, 0x9c, 0x48, 0x92, 0xc2, 0xa4, 0x49, 0x81, - 0xc2, 0xf2, 0x29, 0xec, 0xbd, 0x30, 0x8b, 0x6f, 0xe9, 0x2d, 0x6c, 0x34, 0x31, 0x83, 0x9b, 0xa5, - 0x70, 0x49, 0x91, 0x49, 0x81, 0x1e, 0x04, 0x47, 0x9b, 0xab, 0x62, 0xa5, 0x49, 0x31, 0x7a, 0x22, - 0x3f, 0xcf, 0xb2, 0x73, 0x19, 0x08, 0x95, 0x34, 0x5b, 0x23, 0xe6, 0x92, 0xbd, 0xcf, 0x96, 0xcf, - 0xa4, 0x42, 0x7e, 0xe6, 0x7e, 0x31, 0x08, 0xa1, 0xeb, 0xa6, 0x8d, 0xd1, 0x63, 0x1e, 0x53, 0x36, - 0x35, 0x4a, 0x9e, 0xeb, 0xfa, 0xae, 0x81, 0x5b, 0x1b, 0xd6, 0xae, 0xe7, 0x3d, 0x53, 0x57, 0x9c, - 0x02, 0x3e, 0x71, 0x5a, 0x80, 0x70, 0xcf, 0xec, 0x1b, 0x2d, 0x71, 0x7c, 0x9f, 0x26, 0x50, 0x19, - 0x62, 0x8e, 0x94, 0x84, 0x26, 0x49, 0x49, 0x9a, 0x48, 0x09, 0x91, 0x61, 0x9e, 0xa1, 0x44, 0xb7, - 0xb9, 0xb0, 0x14, 0x20, 0xee, 0x28, 0x2f, 0x2e, 0x6d, 0xd3, 0x09, 0xac, 0x8b, 0x46, 0x96, 0x48, - 0x67, 0xec, 0x1d, 0xe6, 0x31, 0x89, 0x93, 0x9d, 0x02, 0xce, 0x3d, 0x9f, 0x58, 0xf1, 0xb7, 0x55, - 0xa3, 0xb4, 0x5f, 0xae, 0x58, 0xb1, 0xf7, 0x55, 0xef, 0x82, 0xb8, 0xa5, 0xef, 0x1a, 0xf4, 0x46, - 0x0c, 0x97, 0x3c, 0x37, 0x83, 0x94, 0xba, 0x77, 0x5c, 0x99, 0xa4, 0x79, 0xde, 0xf0, 0x3e, 0x07, - 0xf3, 0xee, 0xeb, 0xd9, 0x2e, 0x15, 0x26, 0x65, 0xc8, 0x29, 0xaa, 0x8b, 0x92, 0xdc, 0xaf, 0x4a, - 0x10, 0xe1, 0x2b, 0x96, 0x3b, 0x0c, 0xd2, 0xe8, 0x61, 0x08, 0x8c, 0x1b, 0x86, 0xe0, 0x9d, 0x0f, - 0x43, 0x1e, 0xc0, 0x69, 0xa6, 0xc5, 0x5f, 0xd0, 0x1c, 0x61, 0x56, 0xb1, 0x26, 0xd6, 0xf5, 0x5d, - 0x3e, 0xef, 0x3d, 0x48, 0xb9, 0xdf, 0x95, 0x88, 0x85, 0xcf, 0xcb, 0x51, 0x1e, 0x66, 0x45, 0xbb, - 0xd4, 0x9d, 0xb6, 0xb6, 0xcb, 0x45, 0xf1, 0xee, 0xb1, 0x8d, 0x23, 0xab, 0xb0, 0x92, 0xe0, 0xed, - 0xa1, 0xf6, 0xc4, 0xc8, 0x61, 0x0d, 0x8c, 0x19, 0x56, 0x9f, 0x1c, 0x05, 0xef, 0x4c, 0x8e, 0x7c, - 0x23, 0x1e, 0x1a, 0x18, 0xf1, 0xdc, 0xef, 0x49, 0xfc, 0xed, 0xee, 0x16, 0xbb, 0xfe, 0xf3, 0x7f, - 0x6a, 0xa8, 0x5e, 0xe0, 0xb2, 0xd5, 0xc2, 0x2d, 0x75, 0x68, 0xcc, 0xee, 0x1d, 0xa6, 0xe8, 0x6f, - 0xb3, 0x3b, 0x76, 0x48, 0x50, 0xa9, 0xbb, 0x63, 0xf8, 0x99, 0x00, 0xcc, 0x0d, 0xc1, 0xff, 0xf5, - 0x1b, 0x4b, 0xff, 0xec, 0x0d, 0x4f, 0x39, 0x7b, 0x23, 0x63, 0x67, 0xef, 0xcf, 0x07, 0x68, 0x00, - 0xa0, 0x6b, 0x5a, 0x5a, 0xfb, 0xeb, 0xa1, 0x7b, 0x4f, 0x41, 0xbc, 0x6b, 0xb6, 0x55, 0x56, 0xc2, - 0x2e, 0x50, 0xc5, 0xba, 0x66, 0x5b, 0x19, 0x12, 0xb3, 0xf0, 0xdb, 0xa4, 0x98, 0x23, 0x6f, 0xc3, - 0x20, 0x44, 0x07, 0x27, 0x54, 0x0f, 0x92, 0x8c, 0x15, 0xdc, 0x6a, 0x7a, 0x94, 0xf0, 0x80, 0x9a, - 0x61, 0xd2, 0xb0, 0x95, 0xc7, 0x9a, 0xcd, 0x20, 0x15, 0x0e, 0x47, 0x30, 0x98, 0x91, 0x31, 0x2a, - 0x72, 0xe4, 0xd5, 0x58, 0x0a, 0x87, 0xcb, 0x7d, 0xbf, 0x04, 0xb0, 0x4e, 0x38, 0x4b, 0xfb, 0x4b, - 0xec, 0x1d, 0x8b, 0x36, 0x41, 0xf5, 0xd5, 0x7c, 0x7a, 0xdc, 0xa0, 0xf1, 0xfa, 0x93, 0x96, 0xb7, - 0xdd, 0x45, 0x98, 0x75, 0x65, 0xdb, 0xc2, 0xa2, 0x31, 0xa7, 0x0f, 0xf1, 0x4a, 0xeb, 0xd8, 0x56, - 0x92, 0xb7, 0x3c, 0xa9, 0xdc, 0x3f, 0x93, 0x20, 0x4e, 0xdb, 0xb4, 0x81, 0x6d, 0xcd, 0x37, 0x86, - 0xd2, 0x9d, 0x8f, 0xe1, 0xdd, 0x00, 0x8c, 0x8c, 0xa5, 0xbf, 0x8c, 0xb9, 0x64, 0xc5, 0x69, 0x4e, - 0x5d, 0x7f, 0x19, 0xa3, 0x8b, 0x0e, 0xc3, 0x83, 0x87, 0x33, 0x5c, 0x78, 0xad, 0x9c, 0xed, 0x27, - 0x20, 0x4a, 0xdf, 0x46, 0xd8, 0xb7, 0xb8, 0x23, 0x1a, 0x31, 0xfa, 0x9d, 0xc6, 0xbe, 0x95, 0x7b, - 0x11, 0xa2, 0x8d, 0x7d, 0x16, 0x4f, 0x3c, 0x05, 0xf1, 0x9e, 0x69, 0x72, 0xeb, 0x8f, 0x59, 0xdd, - 0x31, 0x92, 0x41, 0x8d, 0x1d, 0x11, 0x43, 0x0b, 0xb8, 0x31, 0x34, 0x37, 0x08, 0x18, 0x9c, 0x2a, - 0x08, 0x48, 0xbc, 0xcf, 0x59, 0xdf, 0x4c, 0x42, 0x0f, 0xc3, 0x89, 0x7a, 0x65, 0xad, 0x5a, 0x2e, - 0xa9, 0x1b, 0xf5, 0xb5, 0x81, 0x1b, 0xec, 0xd9, 0xf4, 0xab, 0xb7, 0x97, 0x12, 0xdc, 0xed, 0x1c, - 0x07, 0xbd, 0xa9, 0x94, 0xaf, 0xd7, 0x1a, 0x65, 0x59, 0x62, 0xd0, 0x9b, 0x3d, 0x7c, 0xcb, 0xb4, - 0xd9, 0x87, 0x5d, 0x1e, 0x85, 0x93, 0x23, 0xa0, 0x1d, 0xe7, 0x73, 0xee, 0xd5, 0xdb, 0x4b, 0xb3, - 0x9b, 0x3d, 0xcc, 0xa4, 0x8c, 0x62, 0x2c, 0x43, 0x66, 0x18, 0xa3, 0xb6, 0x59, 0xab, 0xe7, 0xd7, - 0xe5, 0xa5, 0xac, 0xfc, 0xea, 0xed, 0xa5, 0xa4, 0x50, 0x19, 0x04, 0xfe, 0x6b, 0xef, 0x7d, 0x7e, - 0x67, 0xcc, 0x17, 0x35, 0x66, 0x7e, 0x5d, 0x57, 0xeb, 0x69, 0x9d, 0xa3, 0xba, 0x9f, 0x13, 0x0e, - 0x23, 0xe4, 0x3e, 0x1d, 0x80, 0xb4, 0xe3, 0xdc, 0x6c, 0xd2, 0x1a, 0xd0, 0x63, 0xde, 0x88, 0x5f, - 0x62, 0xec, 0xda, 0xc1, 0xa0, 0x45, 0x40, 0xf0, 0xdd, 0x10, 0x13, 0x46, 0x32, 0x9f, 0x54, 0x4b, - 0x23, 0xd6, 0x37, 0x0e, 0xc1, 0x51, 0x1d, 0x0c, 0xf4, 0x34, 0xc4, 0x9d, 0x29, 0xe6, 0xbc, 0x88, - 0x3d, 0x7e, 0x4e, 0x72, 0x7c, 0x17, 0x07, 0x5d, 0x72, 0xdd, 0xb8, 0xd0, 0x38, 0xc7, 0xf0, 0x3a, - 0x03, 0xe0, 0xc8, 0x8e, 0x0b, 0xf7, 0x28, 0x84, 0xb4, 0xed, 0xa6, 0xce, 0x15, 0xf0, 0x5d, 0xc3, - 0x78, 0xf9, 0x42, 0xb1, 0xc2, 0x91, 0x28, 0x64, 0xae, 0xc2, 0x83, 0x29, 0x9c, 0x5f, 0xf4, 0x8d, - 0xd1, 0x7d, 0x95, 0xf9, 0xc2, 0xcc, 0xba, 0x88, 0x75, 0xb4, 0xfd, 0x02, 0x75, 0x87, 0x4f, 0x40, - 0x94, 0x14, 0xee, 0xf2, 0xc7, 0xbe, 0x82, 0x4a, 0xa4, 0xa3, 0xed, 0xaf, 0x69, 0xd6, 0xb5, 0x50, - 0x2c, 0x28, 0x87, 0x72, 0x3f, 0x49, 0x2c, 0x15, 0x1f, 0x57, 0xd0, 0x43, 0x80, 0x08, 0x86, 0xb6, - 0x8b, 0x55, 0x32, 0x75, 0x29, 0x7b, 0x05, 0xdd, 0x74, 0x47, 0xdb, 0xcf, 0xef, 0xe2, 0x6a, 0xbf, - 0x43, 0x1b, 0x60, 0xa1, 0x0d, 0x90, 0x05, 0xb0, 0x18, 0x59, 0xce, 0xfe, 0x93, 0xc3, 0x9f, 0x48, - 0xe1, 0x00, 0x6c, 0x01, 0x78, 0x8d, 0x2c, 0x00, 0x29, 0x46, 0xcf, 0x39, 0x7e, 0xe2, 0xeb, 0x4a, - 0xd0, 0xdf, 0x95, 0xdc, 0xd3, 0x90, 0x1e, 0x18, 0x01, 0x94, 0x83, 0x59, 0x1e, 0xb1, 0xa2, 0x5b, - 0xfb, 0xcc, 0xc3, 0x89, 0x2b, 0x09, 0x16, 0x99, 0xa2, 0x47, 0x1d, 0x56, 0x63, 0xbf, 0xf4, 0x89, - 0x45, 0x89, 0x6e, 0xfb, 0x3c, 0x04, 0xb3, 0xbe, 0x31, 0x10, 0x51, 0x64, 0xc9, 0x8d, 0x22, 0xbb, - 0xc0, 0x2f, 0x40, 0x92, 0x28, 0x20, 0xdc, 0xe2, 0xb0, 0xf7, 0x43, 0x9a, 0x29, 0xc8, 0x41, 0x5e, - 0x33, 0x83, 0x67, 0x43, 0x30, 0x3c, 0x27, 0x2c, 0x20, 0x3f, 0xdb, 0x13, 0x02, 0x6a, 0x4d, 0xb3, - 0x72, 0x35, 0x00, 0x77, 0x50, 0x51, 0x1e, 0xee, 0x26, 0xca, 0xc3, 0x7b, 0x14, 0x95, 0x3f, 0xa2, - 0xec, 0xb3, 0x18, 0xb3, 0x04, 0xc8, 0x3d, 0x6e, 0xca, 0x9e, 0x52, 0xbe, 0x4a, 0x21, 0x0a, 0xcf, - 0x7e, 0xea, 0xf3, 0xa7, 0xa5, 0xaf, 0x8d, 0x2e, 0xf8, 0x4f, 0x37, 0xe0, 0x94, 0xa7, 0x90, 0x08, - 0xa0, 0x2f, 0x10, 0x95, 0xf6, 0xc8, 0x2b, 0x29, 0x9c, 0x14, 0x50, 0x3a, 0x34, 0xfe, 0x9b, 0x3d, - 0x5c, 0xed, 0x4c, 0x8e, 0x36, 0x4d, 0x8e, 0x77, 0x8d, 0x0e, 0xca, 0xff, 0xd3, 0x38, 0x44, 0x15, - 0xfc, 0xbe, 0x3e, 0xb6, 0x6c, 0xb4, 0x02, 0x21, 0xdc, 0xdc, 0x33, 0x47, 0xc5, 0x40, 0x49, 0x07, - 0x97, 0x39, 0x5c, 0xb9, 0xb9, 0x67, 0x5e, 0x9d, 0x51, 0x28, 0x2c, 0xba, 0x00, 0xe1, 0x9d, 0x76, - 0x9f, 0x87, 0xaf, 0x06, 0x74, 0x96, 0x17, 0xe9, 0x0a, 0x01, 0xba, 0x3a, 0xa3, 0x30, 0x68, 0x52, - 0x15, 0xfd, 0xea, 0x55, 0xf0, 0xf0, 0xaa, 0x2a, 0xc6, 0x0e, 0xad, 0x8a, 0xc0, 0xa2, 0x02, 0x80, - 0x6e, 0xe8, 0xb6, 0x4a, 0x43, 0x3b, 0x5c, 0x6b, 0xdc, 0x33, 0x1e, 0x53, 0xb7, 0x69, 0x30, 0xe8, - 0xea, 0x8c, 0x12, 0xd7, 0x45, 0x82, 0x34, 0xf7, 0x7d, 0x7d, 0xdc, 0x3b, 0xe0, 0xd6, 0xda, 0xd8, - 0xe6, 0x3e, 0x4b, 0x80, 0x48, 0x73, 0x29, 0x34, 0x51, 0xb2, 0xec, 0x55, 0x75, 0x7b, 0x9f, 0x7f, - 0x2b, 0x64, 0x71, 0x1c, 0x26, 0x7d, 0x5a, 0xbd, 0xb1, 0x7f, 0x75, 0x46, 0x89, 0x36, 0xd9, 0x4f, - 0xf4, 0xa4, 0x63, 0x82, 0x25, 0x86, 0xad, 0x1e, 0x1f, 0x2e, 0x0b, 0xfb, 0xcc, 0x08, 0x53, 0x0c, - 0x55, 0x21, 0xd5, 0xd6, 0x2d, 0x5b, 0xb5, 0x0c, 0xad, 0x6b, 0xed, 0x99, 0xb6, 0x78, 0xd6, 0xf8, - 0xbe, 0x71, 0x14, 0xd6, 0x75, 0xcb, 0xae, 0x0b, 0xe0, 0xab, 0x33, 0xca, 0x6c, 0xdb, 0x9b, 0x41, - 0xe8, 0x99, 0x3b, 0x3b, 0xb8, 0xe7, 0x10, 0xa4, 0x71, 0x96, 0x43, 0xe8, 0xd5, 0x08, 0xb4, 0xc0, - 0x27, 0xf4, 0x4c, 0x6f, 0x06, 0xfa, 0x06, 0x98, 0x6f, 0x9b, 0x5a, 0xcb, 0x21, 0xa7, 0x36, 0xf7, - 0xfa, 0xc6, 0x4d, 0x1a, 0x94, 0x49, 0xac, 0x3c, 0x38, 0xb6, 0x91, 0xa6, 0xd6, 0x12, 0x24, 0x8a, - 0x04, 0xe1, 0xea, 0x8c, 0x32, 0xd7, 0x1e, 0xcc, 0x44, 0xef, 0x85, 0x05, 0xad, 0xdb, 0x6d, 0x1f, - 0x0c, 0x52, 0x4f, 0x53, 0xea, 0x67, 0xc7, 0x51, 0xcf, 0x13, 0x9c, 0x41, 0xf2, 0x48, 0x1b, 0xca, - 0x45, 0x0d, 0x90, 0xbb, 0x3d, 0x4c, 0x6f, 0x73, 0x75, 0xb9, 0x95, 0x41, 0xdf, 0x0c, 0x4e, 0xac, - 0x3c, 0x30, 0x8e, 0xf6, 0x26, 0x83, 0x17, 0x46, 0xc9, 0xd5, 0x19, 0x25, 0xdd, 0xf5, 0x67, 0x31, - 0xaa, 0x66, 0x13, 0xd3, 0x07, 0xd6, 0x39, 0xd5, 0xb9, 0x49, 0x54, 0x29, 0xbc, 0x9f, 0xaa, 0x2f, - 0x0b, 0x95, 0x21, 0xc1, 0x5c, 0x51, 0x95, 0x28, 0x43, 0xfa, 0x70, 0x7d, 0x62, 0x25, 0x37, 0x76, - 0x86, 0x52, 0xd0, 0xeb, 0xa6, 0x8d, 0xaf, 0xce, 0x28, 0x80, 0x9d, 0x14, 0xd2, 0xe0, 0x18, 0x7d, - 0x74, 0xf9, 0x40, 0xf5, 0x2b, 0xde, 0xcc, 0x3c, 0x25, 0xf8, 0xd0, 0x38, 0x82, 0xf4, 0x63, 0x46, - 0x07, 0xd7, 0xbd, 0x7a, 0xf8, 0xea, 0x8c, 0x32, 0x7f, 0x6b, 0x38, 0x9b, 0x88, 0xd8, 0x8e, 0x6e, - 0x68, 0x6d, 0xfd, 0x65, 0xcc, 0x96, 0x50, 0xfa, 0x0d, 0x83, 0x43, 0x44, 0xec, 0x0a, 0x87, 0xa6, - 0x0b, 0x2b, 0x11, 0xb1, 0x1d, 0x6f, 0x46, 0x21, 0xca, 0xcf, 0xa1, 0x3a, 0x8f, 0x91, 0x46, 0xe5, - 0x18, 0x7b, 0x32, 0xfb, 0x5a, 0x28, 0x06, 0x72, 0x22, 0xf7, 0x00, 0x24, 0x3c, 0x8a, 0x09, 0x65, - 0x20, 0xca, 0x4f, 0xea, 0x88, 0x13, 0xad, 0x3c, 0x99, 0x4b, 0x41, 0xd2, 0xab, 0x8c, 0x72, 0x1f, - 0x91, 0x1c, 0x4c, 0xfa, 0x32, 0x48, 0xc6, 0x1f, 0x91, 0x8e, 0xbb, 0x96, 0xca, 0xbd, 0x62, 0x69, - 0x13, 0xe5, 0x6c, 0xfb, 0x35, 0x49, 0x33, 0xf9, 0xca, 0x8a, 0x16, 0x21, 0xd1, 0x5d, 0xe9, 0x3a, - 0x20, 0x41, 0x0a, 0x02, 0xdd, 0x95, 0xae, 0x00, 0xb8, 0x07, 0x92, 0xa4, 0xdf, 0xaa, 0xd7, 0x5e, - 0x8a, 0x2b, 0x09, 0x92, 0xc7, 0x41, 0x72, 0xbf, 0x19, 0x00, 0x79, 0x50, 0x81, 0x39, 0xa1, 0x6a, - 0xe9, 0xc8, 0xa1, 0xea, 0x93, 0x83, 0x41, 0x72, 0x37, 0x2e, 0xbe, 0x0e, 0xb2, 0x1b, 0xde, 0x65, - 0x4b, 0xcd, 0x78, 0xfb, 0x6f, 0xc0, 0x50, 0x55, 0xd2, 0xcd, 0x01, 0xcb, 0xf5, 0x8a, 0x6f, 0xb3, - 0x52, 0x7c, 0x16, 0x72, 0x70, 0xc0, 0x1d, 0x23, 0x66, 0xab, 0xdb, 0xd2, 0x6c, 0x2c, 0xe2, 0x63, - 0x9e, 0x7d, 0xcb, 0xfb, 0x21, 0xad, 0x75, 0xbb, 0xaa, 0x65, 0x6b, 0x36, 0xe6, 0xb6, 0x06, 0x8b, - 0x3c, 0xcc, 0x6a, 0xdd, 0x2e, 0xfd, 0x8a, 0x16, 0xb3, 0x35, 0xee, 0x83, 0x14, 0xd1, 0xe9, 0xba, - 0xd6, 0x16, 0xa6, 0x42, 0x84, 0x99, 0x24, 0x3c, 0x97, 0x59, 0x07, 0xb9, 0x96, 0x33, 0xe2, 0x54, - 0x9f, 0x3b, 0x3e, 0x95, 0xe4, 0xf1, 0xa9, 0x10, 0x7f, 0xb1, 0x85, 0xf1, 0x47, 0x3c, 0xae, 0x33, - 0x7a, 0xd3, 0x60, 0x81, 0xfa, 0x5f, 0xb7, 0x58, 0xb0, 0x24, 0xa6, 0xb0, 0x44, 0x4e, 0x81, 0x94, - 0x5f, 0xf7, 0xa3, 0x14, 0x04, 0xec, 0x7d, 0x5e, 0x4b, 0xc0, 0xde, 0x27, 0x96, 0xae, 0xe7, 0x91, - 0xbc, 0xe1, 0xd5, 0x8e, 0xe3, 0xb9, 0xb1, 0x8e, 0x5c, 0x1a, 0x66, 0x7d, 0x6b, 0x42, 0xee, 0x38, - 0x2c, 0x8c, 0x52, 0xf1, 0xb9, 0x3d, 0x27, 0xdf, 0xa7, 0xaa, 0xd1, 0x05, 0x88, 0x39, 0x3a, 0x7e, - 0x84, 0x77, 0x4c, 0xab, 0x15, 0xc0, 0x8a, 0x03, 0xea, 0x0b, 0xe7, 0x07, 0x7c, 0xe1, 0xfc, 0xdc, - 0x37, 0x43, 0x66, 0x9c, 0xfe, 0x1e, 0x08, 0xf2, 0x85, 0x1c, 0x86, 0x1d, 0x87, 0x08, 0x7f, 0x13, - 0x2e, 0x40, 0x37, 0xb0, 0x78, 0x8a, 0x30, 0x92, 0xe9, 0xf2, 0x20, 0xdb, 0xd7, 0xa2, 0x89, 0x9c, - 0x0a, 0x27, 0xc7, 0xea, 0xf0, 0xf1, 0x5b, 0x61, 0x8c, 0x10, 0xdf, 0x0a, 0x6b, 0x8a, 0xe6, 0x58, - 0xb4, 0xaf, 0xe2, 0x20, 0x0b, 0x4b, 0xe5, 0x5e, 0x0b, 0xc2, 0xf1, 0xd1, 0x9a, 0x1c, 0x2d, 0x41, - 0x92, 0xd8, 0xad, 0xb6, 0xdf, 0xc4, 0x85, 0x8e, 0xb6, 0xdf, 0xe0, 0xf6, 0x2d, 0xdf, 0x4a, 0x08, - 0x38, 0x5b, 0x09, 0x68, 0x0b, 0xe6, 0xda, 0x66, 0x53, 0x6b, 0xab, 0x9e, 0xad, 0x1c, 0x3e, 0x89, - 0xee, 0x1d, 0x62, 0xb6, 0x3f, 0x64, 0x48, 0x14, 0x0e, 0x97, 0xff, 0x34, 0xa5, 0xb1, 0xee, 0xec, - 0xfa, 0xa0, 0x12, 0x24, 0x3a, 0xba, 0xb5, 0x8d, 0xf7, 0xb4, 0x5b, 0xba, 0xd9, 0xe3, 0xb3, 0x69, - 0x58, 0x68, 0x36, 0x5c, 0x18, 0xb1, 0xc3, 0xe4, 0x41, 0xf3, 0x0c, 0x49, 0x78, 0xe4, 0xc6, 0x57, - 0xe4, 0xc8, 0xda, 0x64, 0xdc, 0x1e, 0x52, 0x74, 0xec, 0x1e, 0xd2, 0xa8, 0x0d, 0x9b, 0xd8, 0xe8, - 0x0d, 0x9b, 0x0f, 0x7a, 0x87, 0xc6, 0xbf, 0xf6, 0x0d, 0xed, 0xe1, 0xa0, 0x3a, 0x2c, 0x70, 0xfc, - 0x96, 0x8f, 0xf7, 0x23, 0x8e, 0x3a, 0xb0, 0xf9, 0x35, 0xc8, 0x73, 0x24, 0xd0, 0xc7, 0xb3, 0x3d, - 0x78, 0x67, 0x6c, 0x17, 0x9b, 0xa8, 0x21, 0xcf, 0x26, 0xea, 0xff, 0x65, 0x43, 0xf1, 0xfe, 0x20, - 0xcc, 0x0d, 0x19, 0x12, 0x23, 0x77, 0x87, 0xc7, 0x45, 0x64, 0x45, 0xc7, 0x82, 0x47, 0xee, 0x18, - 0x1f, 0xeb, 0xd0, 0xe4, 0xb1, 0x0e, 0xbf, 0x8d, 0x63, 0x1d, 0xb9, 0xb3, 0xb1, 0xfe, 0x9a, 0x8e, - 0xc2, 0xc7, 0x24, 0xc8, 0x8e, 0xb7, 0xbe, 0x46, 0x0e, 0xc7, 0x91, 0x36, 0x10, 0xc6, 0xad, 0x71, - 0xf7, 0x41, 0x6a, 0xc0, 0x36, 0x64, 0xa2, 0x3c, 0xeb, 0xf3, 0xc2, 0x73, 0x1f, 0x08, 0x3a, 0x0b, - 0x8f, 0xcf, 0x80, 0x1b, 0x31, 0x5b, 0x9f, 0x85, 0xf9, 0x16, 0x6e, 0xea, 0xad, 0x3b, 0x9d, 0xac, - 0x73, 0x1c, 0xfb, 0xff, 0xcd, 0xd5, 0x61, 0x29, 0xf9, 0x3e, 0x80, 0x98, 0x82, 0xad, 0x2e, 0xb1, - 0xc7, 0x50, 0x01, 0xe2, 0x78, 0xbf, 0x89, 0xbb, 0xb6, 0x7b, 0xa8, 0x62, 0x94, 0x8b, 0xc0, 0xa0, - 0xcb, 0x02, 0x92, 0x38, 0xc8, 0x0e, 0x1a, 0x7a, 0x8c, 0xc7, 0x00, 0xc6, 0xbb, 0xf3, 0x1c, 0xdd, - 0x1b, 0x04, 0xb8, 0x28, 0x82, 0x00, 0xc1, 0xb1, 0xfe, 0x2d, 0xc3, 0x1a, 0x88, 0x02, 0x3c, 0xc6, - 0xa3, 0x00, 0xa1, 0x09, 0x95, 0xf9, 0xc2, 0x00, 0x45, 0x5f, 0x18, 0x20, 0x32, 0xa1, 0x9b, 0x63, - 0xe2, 0x00, 0x17, 0x45, 0x1c, 0x20, 0x3a, 0xa1, 0xc5, 0x03, 0x81, 0x80, 0xa7, 0x3c, 0x81, 0x80, - 0xf8, 0x70, 0xb4, 0xd5, 0x87, 0x3a, 0x22, 0x12, 0x70, 0xc9, 0x89, 0x04, 0x24, 0xc7, 0x46, 0x11, - 0x38, 0xf2, 0x60, 0x28, 0xa0, 0x36, 0x14, 0x0a, 0x98, 0xe5, 0x9f, 0x38, 0x1e, 0x47, 0x62, 0x42, - 0x2c, 0xa0, 0x36, 0x14, 0x0b, 0x48, 0x4d, 0x20, 0x38, 0x21, 0x18, 0xf0, 0x8d, 0xa3, 0x83, 0x01, - 0xe3, 0xdd, 0x75, 0xde, 0xcc, 0xe9, 0xa2, 0x01, 0xea, 0x98, 0x68, 0x80, 0x3c, 0xd6, 0x73, 0x65, - 0xe4, 0xa7, 0x0e, 0x07, 0x6c, 0x8d, 0x08, 0x07, 0x30, 0xc7, 0xfd, 0xcc, 0x58, 0xe2, 0x53, 0xc4, - 0x03, 0xb6, 0x46, 0xc4, 0x03, 0xd0, 0x44, 0xb2, 0x13, 0x03, 0x02, 0x57, 0xfc, 0x01, 0x81, 0xf9, - 0x31, 0x56, 0xa7, 0x3b, 0xdb, 0xc7, 0x44, 0x04, 0xb6, 0xc7, 0x45, 0x04, 0x16, 0xf8, 0xa7, 0x13, - 0xc6, 0x51, 0x3c, 0x42, 0x48, 0xa0, 0x36, 0x14, 0x12, 0x38, 0x36, 0x41, 0xd2, 0xa6, 0x8f, 0x09, - 0xb0, 0x8f, 0x69, 0xb1, 0xcf, 0x68, 0x81, 0x9c, 0xb8, 0x16, 0x8a, 0x25, 0xe4, 0x64, 0xee, 0x41, - 0x62, 0xc1, 0x0c, 0xe8, 0x39, 0xe2, 0x2b, 0xe0, 0x5e, 0xcf, 0xec, 0x89, 0x3b, 0x16, 0x34, 0x91, - 0x3b, 0x43, 0x7c, 0x44, 0x57, 0xa7, 0x1d, 0x12, 0x3f, 0xa0, 0x3e, 0x99, 0x47, 0x8f, 0xe5, 0x7e, - 0x49, 0x72, 0x71, 0x69, 0x04, 0xc1, 0xeb, 0x5f, 0xc6, 0xb9, 0x7f, 0xe9, 0x89, 0x2a, 0x04, 0xfc, - 0x51, 0x85, 0x45, 0x48, 0x10, 0x5f, 0x6b, 0x20, 0x60, 0xa0, 0x75, 0x9d, 0x80, 0x81, 0x38, 0x40, - 0xc5, 0x62, 0x0f, 0x7c, 0x59, 0x62, 0xbb, 0x89, 0x69, 0xe7, 0x30, 0x19, 0x73, 0x75, 0xd1, 0x23, - 0x30, 0xef, 0x81, 0x75, 0x7c, 0x38, 0xe6, 0x3d, 0xcb, 0x0e, 0x74, 0x9e, 0x3b, 0x73, 0xff, 0x42, - 0x72, 0x39, 0xe4, 0x46, 0x1a, 0x46, 0x05, 0x05, 0xa4, 0xb7, 0x29, 0x28, 0x10, 0xb8, 0xe3, 0xa0, - 0x80, 0xd7, 0x27, 0x0d, 0xfa, 0x7d, 0xd2, 0xff, 0x21, 0xb9, 0x63, 0xe2, 0xb8, 0xf8, 0x4d, 0xb3, - 0x85, 0xb9, 0x97, 0x48, 0x7f, 0x13, 0x93, 0xa4, 0x6d, 0x8a, 0x6f, 0x20, 0x91, 0x9f, 0x04, 0xca, - 0x59, 0x78, 0xe2, 0x7c, 0x5d, 0x71, 0x1c, 0xcc, 0xb0, 0xf7, 0x1e, 0x07, 0xbf, 0xdc, 0x10, 0x71, - 0x2f, 0x37, 0x38, 0x17, 0xa3, 0xa3, 0x9e, 0x8b, 0xd1, 0xe8, 0x49, 0x88, 0xd3, 0x60, 0xbf, 0x6a, - 0x76, 0xc5, 0xe7, 0xa4, 0x4f, 0x8d, 0xbf, 0xd8, 0x60, 0xd1, 0x23, 0xd7, 0xec, 0x32, 0x84, 0x6b, - 0x71, 0xc4, 0x7d, 0x16, 0xc7, 0x5d, 0x10, 0x27, 0xad, 0x67, 0xdf, 0x53, 0x04, 0x7e, 0xab, 0x5e, - 0x64, 0xe4, 0x7e, 0x2a, 0x00, 0xe9, 0x81, 0x85, 0x66, 0x64, 0xdf, 0x47, 0x6d, 0x23, 0x4f, 0xc7, - 0x8f, 0xd3, 0x00, 0xbb, 0x9a, 0xa5, 0xbe, 0xa4, 0x19, 0x36, 0xff, 0x06, 0x7a, 0x50, 0xf1, 0xe4, - 0xa0, 0x2c, 0xc4, 0x48, 0xaa, 0x6f, 0xf1, 0xaf, 0xa0, 0x07, 0x15, 0x27, 0x8d, 0xae, 0x42, 0x04, - 0xdf, 0xa2, 0x4f, 0x03, 0xb3, 0x4f, 0x60, 0x1c, 0x1f, 0x76, 0x87, 0x49, 0x71, 0x21, 0x43, 0x06, - 0xfb, 0x8b, 0xaf, 0x2f, 0xca, 0x0c, 0xfa, 0x61, 0xe7, 0x32, 0x9b, 0xc2, 0xf1, 0xfd, 0x5c, 0x88, - 0x0d, 0x70, 0x81, 0xc6, 0x01, 0x93, 0xc2, 0xbd, 0x27, 0x3c, 0x65, 0x67, 0xbc, 0x95, 0xd9, 0x0e, - 0xee, 0x74, 0x4d, 0xb3, 0xad, 0xb2, 0x39, 0x9e, 0x87, 0x94, 0x7f, 0x5d, 0x65, 0x9f, 0x2c, 0xb6, - 0x35, 0xdd, 0x50, 0x7d, 0x46, 0x70, 0x92, 0x65, 0xb2, 0x39, 0xe5, 0x7d, 0xf7, 0x39, 0xb7, 0x09, - 0xc7, 0x46, 0xae, 0xab, 0xe8, 0x09, 0x88, 0xbb, 0x4b, 0x32, 0x3b, 0xa6, 0x7f, 0x48, 0xa4, 0xc5, - 0x85, 0xcd, 0xfd, 0x8a, 0xe4, 0x92, 0xf4, 0xc7, 0x6e, 0xca, 0x10, 0x61, 0x67, 0x26, 0xf9, 0xf9, - 0x98, 0x47, 0xa6, 0x5b, 0x91, 0x97, 0xd9, 0x81, 0x4a, 0x85, 0x23, 0xe7, 0xde, 0x0b, 0x11, 0x96, - 0x83, 0x12, 0x10, 0xf5, 0x3d, 0x05, 0x9f, 0x2f, 0x16, 0xcb, 0x9b, 0xe2, 0x69, 0xdf, 0x02, 0x7d, - 0x66, 0x9d, 0x64, 0x2b, 0xe5, 0x6b, 0xe5, 0x62, 0x43, 0x0e, 0xa2, 0x39, 0x98, 0x65, 0xbf, 0xf9, - 0x83, 0xed, 0x72, 0xc8, 0x93, 0x55, 0x2f, 0x57, 0x4b, 0x65, 0x45, 0x0e, 0xe7, 0xce, 0xc3, 0xc9, - 0xb1, 0x6b, 0xb8, 0x1b, 0x98, 0x91, 0x3c, 0x81, 0x99, 0xdc, 0x6b, 0x01, 0xe2, 0xd4, 0x8c, 0x5b, - 0x98, 0xd1, 0xb5, 0x81, 0x8e, 0xaf, 0x1c, 0x61, 0x55, 0x1f, 0xe8, 0x3d, 0xf1, 0x63, 0x7a, 0x78, - 0x07, 0xdb, 0xcd, 0x3d, 0x66, 0x28, 0x30, 0x0d, 0x34, 0xab, 0xcc, 0xf2, 0x5c, 0x8a, 0x64, 0x31, - 0xb0, 0x17, 0x71, 0xd3, 0x56, 0x99, 0x10, 0x59, 0xd4, 0x99, 0x88, 0x13, 0x30, 0x92, 0x5b, 0x67, - 0x99, 0xb9, 0x6f, 0x3e, 0x12, 0x2f, 0xe3, 0x10, 0x56, 0xca, 0x0d, 0xe5, 0x06, 0xfb, 0x30, 0x39, - 0xfd, 0xa9, 0xd6, 0xab, 0xf9, 0xcd, 0xfa, 0xd5, 0x1a, 0xe1, 0xe5, 0x3c, 0xa4, 0x05, 0x2f, 0x45, - 0x66, 0x38, 0xf7, 0x10, 0x9c, 0x18, 0x63, 0x55, 0x8c, 0x38, 0xc4, 0xfa, 0x49, 0xc9, 0x0b, 0xed, - 0xb7, 0x0c, 0x6a, 0x10, 0xb1, 0x6c, 0xcd, 0xee, 0x5b, 0x9c, 0x89, 0x4f, 0x4c, 0x6b, 0x66, 0x2c, - 0x8b, 0x1f, 0x75, 0x8a, 0xae, 0x70, 0x32, 0xb9, 0x0b, 0x90, 0xf2, 0x97, 0x8c, 0xe7, 0x81, 0x2b, - 0x44, 0x81, 0xdc, 0x65, 0x40, 0xc3, 0xd6, 0xc7, 0x08, 0xf7, 0x52, 0x1a, 0xe5, 0x5e, 0xfe, 0x98, - 0x04, 0xa7, 0x0e, 0xb1, 0x34, 0xd0, 0xb3, 0x03, 0x9d, 0xbc, 0x74, 0x14, 0x3b, 0x65, 0x99, 0xe5, - 0x0d, 0x74, 0xf3, 0x31, 0x48, 0x7a, 0xf3, 0xa7, 0xeb, 0xe4, 0x17, 0x03, 0xee, 0x24, 0xf6, 0xfb, - 0xc1, 0xae, 0x0a, 0x94, 0xbe, 0x4a, 0x15, 0xf8, 0x6e, 0x00, 0x7b, 0x5f, 0x9c, 0xa2, 0xe6, 0xeb, - 0xe8, 0xdd, 0x23, 0xe2, 0x8b, 0xb8, 0xd9, 0xd8, 0xe7, 0x93, 0x20, 0x6e, 0xf3, 0x5f, 0x16, 0xaa, - 0x7b, 0x83, 0x02, 0x7d, 0xba, 0xc6, 0x5a, 0xdc, 0x61, 0x9e, 0x76, 0x31, 0x76, 0x83, 0x07, 0x2c, - 0xdb, 0x42, 0x37, 0xe0, 0xc4, 0x80, 0xa1, 0xe0, 0x90, 0x0e, 0x4d, 0x6b, 0x2f, 0x1c, 0xf3, 0xdb, - 0x0b, 0x82, 0xb4, 0x77, 0xb5, 0x0f, 0xfb, 0x57, 0xfb, 0x1b, 0x00, 0x6e, 0x70, 0xc0, 0x3d, 0xf6, - 0x27, 0x79, 0x8f, 0xfd, 0x5d, 0x80, 0x30, 0x91, 0x24, 0xc1, 0xa7, 0x61, 0x55, 0x4c, 0x24, 0xc1, - 0x13, 0x5c, 0x60, 0xd0, 0x39, 0x1d, 0xd0, 0x70, 0x80, 0x76, 0x4c, 0x15, 0x4f, 0xf9, 0xab, 0xb8, - 0x67, 0x6c, 0xa8, 0x77, 0x74, 0x55, 0x2f, 0x43, 0x98, 0x8e, 0xfc, 0xc8, 0xbb, 0x94, 0xdf, 0x04, - 0xa0, 0xd9, 0x76, 0x4f, 0xdf, 0xee, 0xbb, 0x15, 0x2c, 0x8e, 0x96, 0x9c, 0xbc, 0x80, 0x2b, 0xdc, - 0xc5, 0x45, 0x68, 0xc1, 0x45, 0xf5, 0x88, 0x91, 0x87, 0x60, 0xae, 0x0a, 0x29, 0x3f, 0xee, 0xe8, - 0xbb, 0xa1, 0xc3, 0x1f, 0xbf, 0x74, 0xad, 0x23, 0xfe, 0x18, 0x13, 0x4d, 0xe4, 0x5e, 0x09, 0x40, - 0xd2, 0x2b, 0x78, 0x7f, 0xf3, 0x4c, 0x90, 0xdc, 0xb7, 0x4b, 0x10, 0x73, 0xba, 0x7f, 0xc8, 0x61, - 0x67, 0xf7, 0x8e, 0xb0, 0xb3, 0x79, 0xc1, 0xb6, 0x89, 0x82, 0xce, 0x36, 0xd1, 0x65, 0x67, 0xf9, - 0x1b, 0x17, 0x10, 0xf1, 0xf2, 0x5a, 0x1c, 0x38, 0xe4, 0xab, 0xfd, 0xe5, 0xe9, 0xae, 0xe2, 0x2d, - 0x40, 0xd8, 0x7b, 0x8d, 0x8e, 0x25, 0x72, 0x2d, 0xcf, 0x09, 0x23, 0x36, 0x11, 0xbd, 0x77, 0xf6, - 0xa4, 0x23, 0xdf, 0xd9, 0x73, 0x6a, 0x09, 0x78, 0x6b, 0xf9, 0x5e, 0x09, 0x62, 0x62, 0x4e, 0xa0, - 0xf7, 0x78, 0x4f, 0x9e, 0x89, 0xad, 0xcd, 0xb1, 0xfa, 0x88, 0xd3, 0xf7, 0x1c, 0x3c, 0x1b, 0x3a, - 0x70, 0x1d, 0x3c, 0xea, 0x81, 0x6b, 0x6e, 0xd9, 0xfd, 0x85, 0x04, 0xf2, 0xe0, 0x8c, 0xfd, 0xaa, - 0x5b, 0x37, 0xbc, 0xcc, 0x05, 0x47, 0x2c, 0x73, 0xe3, 0x4e, 0x51, 0x87, 0xc6, 0x9d, 0xa2, 0x1e, - 0xee, 0x75, 0xf8, 0x0e, 0x7b, 0xfd, 0xfe, 0x00, 0x24, 0x3c, 0xe1, 0x51, 0xf4, 0xb8, 0xef, 0x44, - 0xf6, 0xd2, 0x61, 0xa1, 0x54, 0xcf, 0x91, 0x6c, 0x1f, 0x9b, 0x02, 0x47, 0x67, 0xd3, 0xdb, 0x7f, - 0x3b, 0x6b, 0xf4, 0x05, 0xd6, 0xf0, 0x98, 0x0b, 0xac, 0xdf, 0x26, 0x41, 0xcc, 0x31, 0xbb, 0x8f, - 0xba, 0x89, 0x79, 0x1c, 0x22, 0xdc, 0xb2, 0x64, 0xbb, 0x98, 0x3c, 0x35, 0x32, 0xac, 0x9c, 0x85, - 0x98, 0xf8, 0x4a, 0x3e, 0x5f, 0xd5, 0x9c, 0xf4, 0xd9, 0x4b, 0x90, 0xf0, 0x6c, 0x00, 0x13, 0xd5, - 0x58, 0x2d, 0x3f, 0x27, 0xcf, 0x64, 0xa3, 0xaf, 0xde, 0x5e, 0x0a, 0x56, 0xf1, 0x4b, 0x64, 0x36, - 0x2b, 0xe5, 0xe2, 0xd5, 0x72, 0xf1, 0x19, 0x59, 0xca, 0x26, 0x5e, 0xbd, 0xbd, 0x14, 0x55, 0x30, - 0x8d, 0x28, 0x9e, 0x7d, 0x06, 0xd2, 0x03, 0x03, 0xe3, 0x37, 0x5b, 0x10, 0xa4, 0x4a, 0x5b, 0x9b, - 0xeb, 0x95, 0x62, 0xbe, 0x51, 0x56, 0xd9, 0xb9, 0x5d, 0x74, 0x02, 0xe6, 0xd7, 0x2b, 0x6b, 0x57, - 0x1b, 0x6a, 0x71, 0xbd, 0x52, 0xae, 0x36, 0xd4, 0x7c, 0xa3, 0x91, 0x2f, 0x3e, 0x23, 0x07, 0x56, - 0x6e, 0x27, 0x20, 0x94, 0x2f, 0x14, 0x2b, 0xa8, 0x08, 0x21, 0x1a, 0x0a, 0x39, 0xf4, 0x04, 0x58, - 0xf6, 0xf0, 0xd8, 0x30, 0xba, 0x02, 0x61, 0x1a, 0x25, 0x41, 0x87, 0x1f, 0x09, 0xcb, 0x4e, 0x08, - 0x16, 0x93, 0xc6, 0xd0, 0x19, 0x79, 0xe8, 0x19, 0xb1, 0xec, 0xe1, 0xb1, 0x63, 0xb4, 0x0e, 0x51, - 0xe1, 0x24, 0x4f, 0x3a, 0xb8, 0x95, 0x9d, 0x18, 0xd0, 0x25, 0x5d, 0x63, 0xc1, 0x86, 0xc3, 0x8f, - 0x8f, 0x65, 0x27, 0x44, 0x95, 0x51, 0xc5, 0xb9, 0xcf, 0x34, 0xe1, 0x44, 0x58, 0x76, 0x52, 0x9c, - 0x18, 0x29, 0x10, 0x77, 0xc3, 0x38, 0x93, 0x0f, 0xc5, 0x65, 0xa7, 0x08, 0x98, 0xa3, 0xf7, 0xc2, - 0xac, 0xdf, 0xd5, 0x9d, 0xee, 0xd4, 0x59, 0x76, 0xca, 0x88, 0x34, 0xa1, 0xef, 0xf7, 0x7b, 0xa7, - 0x3b, 0x85, 0x96, 0x9d, 0x32, 0x40, 0x8d, 0x5e, 0x84, 0xb9, 0x61, 0xbf, 0x74, 0xfa, 0x43, 0x69, - 0xd9, 0x23, 0x84, 0xac, 0x51, 0x07, 0xd0, 0x08, 0x7f, 0xf6, 0x08, 0x67, 0xd4, 0xb2, 0x47, 0x89, - 0x60, 0xa3, 0x16, 0xa4, 0x07, 0x9d, 0xc4, 0x69, 0xcf, 0xac, 0x65, 0xa7, 0x8e, 0x66, 0xb3, 0x5a, - 0xfc, 0xce, 0xe5, 0xb4, 0x67, 0xd8, 0xb2, 0x53, 0x07, 0xb7, 0xd1, 0x16, 0x80, 0xc7, 0x3f, 0x9c, - 0xe2, 0x4c, 0x5b, 0x76, 0x9a, 0x30, 0x37, 0xea, 0xc2, 0xfc, 0x28, 0xc7, 0xf1, 0x28, 0x47, 0xdc, - 0xb2, 0x47, 0x8a, 0x7e, 0x13, 0x79, 0xf6, 0xbb, 0x80, 0xd3, 0x1d, 0x79, 0xcb, 0x4e, 0x19, 0x06, - 0x2f, 0xe4, 0xc7, 0x9e, 0x73, 0x7e, 0xe0, 0xd0, 0x73, 0xce, 0xee, 0xc9, 0x65, 0xe7, 0x6c, 0xf3, - 0xbf, 0x3b, 0x07, 0xef, 0xe2, 0x2f, 0xe8, 0x58, 0xb6, 0x76, 0x53, 0x37, 0x76, 0x9d, 0x67, 0x96, - 0x78, 0x9a, 0x1f, 0x72, 0x3e, 0xce, 0x5f, 0xe9, 0x11, 0xb9, 0x13, 0x1e, 0x5b, 0x1a, 0xfb, 0x02, - 0xe5, 0xa4, 0xfb, 0x10, 0x93, 0x8f, 0x2f, 0x1f, 0xf2, 0x90, 0xd3, 0x84, 0xe7, 0xa2, 0x46, 0x3c, - 0xf4, 0x94, 0x3d, 0xf4, 0x8d, 0x81, 0xec, 0x61, 0xe7, 0xbe, 0x89, 0x15, 0x9b, 0xba, 0xaa, 0x5b, - 0xb6, 0xd9, 0xd3, 0x9b, 0x5a, 0x9b, 0x2e, 0x2f, 0x97, 0xa7, 0xbd, 0x95, 0x55, 0x88, 0x13, 0x73, - 0x85, 0xbf, 0x05, 0xc5, 0x6f, 0x0a, 0x95, 0x20, 0x72, 0x4b, 0x6b, 0xb3, 0x3b, 0x51, 0xde, 0x87, - 0xe0, 0x06, 0x79, 0xee, 0xb1, 0xa3, 0xbc, 0x54, 0x18, 0x6e, 0xee, 0xfb, 0xe9, 0x7d, 0x92, 0x4e, - 0x47, 0xb7, 0x88, 0x2c, 0x2a, 0xd4, 0x95, 0xbe, 0x06, 0xa1, 0x9e, 0x66, 0x73, 0x07, 0xb3, 0x70, - 0xf1, 0xc8, 0xef, 0x32, 0xb1, 0x1a, 0x28, 0x0d, 0xf4, 0x2c, 0xc4, 0x3a, 0xda, 0xbe, 0x4a, 0xe9, - 0x05, 0xbe, 0x2a, 0x7a, 0xd1, 0x8e, 0xb6, 0x4f, 0xda, 0x87, 0xde, 0x4b, 0x3f, 0x3f, 0xa8, 0x36, - 0xf7, 0x34, 0x63, 0x17, 0x33, 0xca, 0xc1, 0xaf, 0x8a, 0xf2, 0x6c, 0x47, 0xdb, 0x2f, 0x52, 0x6a, - 0x84, 0x3e, 0x7f, 0xf2, 0xea, 0xd7, 0x24, 0x1e, 0x35, 0xa0, 0x8c, 0x41, 0x1a, 0xc8, 0x4d, 0x27, - 0x45, 0x2b, 0x15, 0x5b, 0x1c, 0x0f, 0x8c, 0xe3, 0xfb, 0x00, 0x5b, 0x0b, 0xb3, 0xa4, 0x79, 0x9f, - 0x7b, 0x7d, 0x51, 0x62, 0xb5, 0xa6, 0x9b, 0x43, 0x6c, 0x4f, 0xb0, 0x60, 0x88, 0x4a, 0x6d, 0xd8, - 0xc0, 0x44, 0x1b, 0x76, 0x56, 0xd8, 0xb0, 0x8c, 0x20, 0x30, 0x6c, 0x52, 0xce, 0xfb, 0xf0, 0x29, - 0x09, 0x12, 0x25, 0xcf, 0xb3, 0x8e, 0x19, 0x88, 0x76, 0x4c, 0x43, 0xbf, 0x89, 0x7b, 0xce, 0x1e, - 0x15, 0x4b, 0x12, 0x3b, 0x93, 0x7d, 0x60, 0xd9, 0x3e, 0x10, 0xaf, 0x0b, 0x89, 0x34, 0xc1, 0x7a, - 0x09, 0x6f, 0x5b, 0xba, 0xe0, 0xb3, 0x22, 0x92, 0xe8, 0x41, 0x90, 0x2d, 0xdc, 0xec, 0xf7, 0x74, - 0xfb, 0x40, 0x6d, 0x9a, 0x86, 0xad, 0x35, 0x6d, 0xee, 0x87, 0xa7, 0x45, 0x7e, 0x91, 0x65, 0x13, - 0x22, 0x2d, 0x6c, 0x6b, 0x7a, 0x9b, 0x9d, 0xcc, 0x8c, 0x2b, 0x22, 0xc9, 0x9b, 0xfa, 0x6a, 0xd4, - 0xeb, 0x87, 0x16, 0x41, 0x36, 0xbb, 0xb8, 0xe7, 0x3b, 0x90, 0xc2, 0xa4, 0x31, 0xf3, 0xdb, 0x9f, - 0x79, 0x64, 0x81, 0x33, 0x9c, 0x1f, 0x66, 0x60, 0x5f, 0x31, 0x50, 0xd2, 0x02, 0x43, 0x9c, 0x54, - 0xb9, 0xe1, 0xdb, 0x95, 0xea, 0x6f, 0xbb, 0xcf, 0xc8, 0x2c, 0x0c, 0x31, 0x35, 0x6f, 0x1c, 0x14, - 0x32, 0x9f, 0x75, 0x49, 0xbb, 0x7e, 0xea, 0x33, 0xf8, 0xc0, 0xbb, 0x45, 0x45, 0xc9, 0x10, 0x13, - 0xfe, 0x45, 0x4d, 0x6f, 0x8b, 0x0f, 0xfe, 0x2b, 0x3c, 0x85, 0x56, 0x9d, 0xf0, 0x22, 0xfb, 0xa6, - 0x66, 0x6e, 0x9c, 0x6c, 0x14, 0x4c, 0xa3, 0xe5, 0x8f, 0x23, 0xa2, 0x22, 0x44, 0x6c, 0xf3, 0x26, - 0x36, 0x38, 0x83, 0x8e, 0xf6, 0xb4, 0x1a, 0x47, 0x45, 0xdf, 0x08, 0x72, 0x0b, 0xb7, 0xf1, 0x2e, - 0xbb, 0x2f, 0xb9, 0xa7, 0xf5, 0x30, 0xbb, 0xad, 0x7f, 0x47, 0xcf, 0xab, 0xa5, 0x1d, 0x52, 0x75, - 0x4a, 0x09, 0x6d, 0xfa, 0x1f, 0x0e, 0x8d, 0xf2, 0xcd, 0xe3, 0x31, 0x7d, 0xf4, 0x48, 0x9e, 0x57, - 0xf3, 0xf8, 0x1e, 0x1a, 0x7d, 0x10, 0xe4, 0xbe, 0xb1, 0x6d, 0x1a, 0xf4, 0x03, 0x91, 0xdc, 0x8b, - 0x8a, 0xb1, 0x9d, 0x4a, 0x27, 0x9f, 0xef, 0x54, 0x6e, 0x42, 0xca, 0x05, 0xa5, 0x33, 0x24, 0x7e, - 0xd4, 0x19, 0x32, 0xeb, 0x10, 0x20, 0x20, 0x68, 0x03, 0xc0, 0x9d, 0x83, 0x74, 0xab, 0x2c, 0x31, - 0x7e, 0xc4, 0xdc, 0xd9, 0xec, 0xed, 0x8c, 0x87, 0x00, 0xfa, 0x06, 0x98, 0xef, 0xe8, 0x86, 0x6a, - 0xe1, 0xf6, 0x8e, 0xca, 0x39, 0x47, 0xe8, 0x26, 0x8e, 0x3e, 0x9a, 0x73, 0x1d, 0xdd, 0xa8, 0xe3, - 0xf6, 0x4e, 0xc9, 0xa1, 0x82, 0xde, 0x0d, 0xa7, 0xdc, 0xde, 0x9b, 0x86, 0xba, 0x67, 0xb6, 0x5b, - 0x6a, 0x0f, 0xef, 0xa8, 0x4d, 0xfa, 0xce, 0x5f, 0x92, 0xf2, 0xec, 0x84, 0x03, 0x52, 0x33, 0xae, - 0x9a, 0xed, 0x96, 0x82, 0x77, 0x8a, 0xa4, 0x18, 0xdd, 0x0b, 0x6e, 0xd7, 0x55, 0xbd, 0x65, 0x65, - 0x66, 0x97, 0x82, 0x67, 0x42, 0x4a, 0xd2, 0xc9, 0xac, 0xb4, 0xac, 0xd5, 0xd8, 0x07, 0x3f, 0xb1, - 0x38, 0xf3, 0xe6, 0x27, 0x16, 0x67, 0x72, 0x57, 0xe8, 0x9b, 0x52, 0x7c, 0x1e, 0x61, 0x0b, 0x5d, - 0x84, 0xb8, 0x26, 0x12, 0xec, 0xc6, 0xd8, 0x21, 0xf3, 0xd0, 0x05, 0xcd, 0xfd, 0xa4, 0x04, 0x91, - 0xd2, 0xf5, 0x4d, 0x4d, 0xef, 0xa1, 0x32, 0xcc, 0xb9, 0x82, 0x39, 0xed, 0x94, 0x76, 0x65, 0x59, - 0xcc, 0xe9, 0xea, 0xb8, 0xa3, 0x6a, 0xf1, 0xc2, 0x3d, 0xbf, 0xfd, 0x99, 0x47, 0xee, 0xe6, 0x64, - 0xae, 0x0f, 0x9c, 0x5a, 0x13, 0xf4, 0x06, 0x4f, 0xb3, 0x79, 0xfa, 0x7c, 0x0d, 0xa2, 0xac, 0xa9, - 0x16, 0x7a, 0x1a, 0xc2, 0x5d, 0xf2, 0x83, 0x47, 0xe0, 0x4f, 0x8f, 0x15, 0x70, 0x0a, 0xef, 0x15, - 0x07, 0x86, 0x97, 0xfb, 0x50, 0x00, 0xa0, 0x74, 0xfd, 0x7a, 0xa3, 0xa7, 0x77, 0xdb, 0xd8, 0x7e, - 0xbb, 0xfa, 0xbe, 0x05, 0xc7, 0x3c, 0x77, 0xa1, 0x7b, 0xcd, 0xa3, 0xf7, 0x7f, 0xde, 0xbd, 0x16, - 0xdd, 0x6b, 0x8e, 0x24, 0xdb, 0xb2, 0x6c, 0x87, 0x6c, 0xf0, 0xe8, 0x64, 0x4b, 0x96, 0x3d, 0xcc, - 0xd9, 0xe7, 0x21, 0xe1, 0x32, 0xc3, 0x42, 0x15, 0x88, 0xd9, 0xfc, 0x37, 0x67, 0x70, 0x6e, 0x3c, - 0x83, 0x05, 0x9a, 0x97, 0xc9, 0x0e, 0x7a, 0xee, 0xaf, 0x24, 0x00, 0xcf, 0x1c, 0x79, 0x67, 0xca, - 0x18, 0x71, 0xd7, 0xb9, 0x26, 0x0e, 0xde, 0xf1, 0x6b, 0x9c, 0x8c, 0x80, 0x87, 0xa9, 0x1f, 0x0e, - 0xc0, 0xfc, 0x96, 0x98, 0xbd, 0xef, 0x7c, 0x1e, 0x6c, 0x41, 0x14, 0x1b, 0x76, 0x4f, 0x77, 0xf6, - 0x90, 0x1e, 0x1d, 0x37, 0xe6, 0x23, 0x3a, 0x55, 0x36, 0xec, 0xde, 0x81, 0x57, 0x02, 0x04, 0x2d, - 0x0f, 0x3f, 0x3e, 0x1a, 0x84, 0xcc, 0x38, 0x54, 0xf4, 0x00, 0xa4, 0x9b, 0x3d, 0x4c, 0x33, 0xfc, - 0x57, 0x44, 0x53, 0x22, 0x9b, 0xaf, 0x31, 0x0a, 0x10, 0xab, 0x8c, 0x08, 0x17, 0x01, 0xbd, 0x33, - 0x33, 0x2c, 0xe5, 0x52, 0xa0, 0xab, 0x4c, 0x03, 0xd2, 0xe2, 0xce, 0xc9, 0xb6, 0xd6, 0xd6, 0x8c, - 0xa6, 0x30, 0x57, 0x8f, 0xb4, 0x24, 0x88, 0x7b, 0x2b, 0x05, 0x46, 0x02, 0x95, 0x21, 0x2a, 0xa8, - 0x85, 0x8e, 0x4e, 0x4d, 0xe0, 0xa2, 0x7b, 0x20, 0xe9, 0x5d, 0x18, 0xa8, 0xe9, 0x11, 0x52, 0x12, - 0x9e, 0x75, 0x61, 0xd2, 0xca, 0x13, 0x39, 0x74, 0xe5, 0xe1, 0xd6, 0xdd, 0x0f, 0xd3, 0xa3, 0xe1, - 0xad, 0xbf, 0xfe, 0xc3, 0xb2, 0x09, 0xc0, 0xa6, 0x2a, 0xd1, 0xa4, 0x7c, 0x64, 0xee, 0x60, 0xbe, - 0xc7, 0x19, 0x91, 0x92, 0x65, 0x7f, 0xbd, 0x46, 0xe8, 0x77, 0x03, 0x90, 0xf4, 0x8e, 0xd0, 0xdf, - 0xc8, 0x45, 0x0b, 0x55, 0x5d, 0x35, 0xc5, 0xae, 0xcf, 0x3c, 0x38, 0x4e, 0x4d, 0x0d, 0x49, 0xf3, - 0x04, 0xfd, 0xf4, 0xb1, 0x20, 0x44, 0xf8, 0xf9, 0xb6, 0xda, 0x90, 0x21, 0x2b, 0x4d, 0x7a, 0x00, - 0x60, 0x56, 0x3c, 0x00, 0x30, 0xd2, 0x8e, 0xbd, 0x0f, 0x52, 0xc4, 0x21, 0xf6, 0x1d, 0x9a, 0x93, - 0xce, 0xcc, 0x52, 0xbf, 0xd6, 0x3d, 0x22, 0x8e, 0x16, 0x21, 0x41, 0xc0, 0x5c, 0x3d, 0x4c, 0x60, - 0xa0, 0xa3, 0xed, 0x97, 0x59, 0x0e, 0x7a, 0x04, 0xd0, 0x9e, 0x13, 0xa0, 0x50, 0x5d, 0x46, 0x10, - 0xb8, 0x39, 0xb7, 0x44, 0x80, 0xdf, 0x0d, 0x40, 0x5a, 0xa1, 0xb2, 0x07, 0xa8, 0xf9, 0xf3, 0xde, - 0x24, 0xa7, 0x44, 0x1f, 0xa1, 0xfe, 0x80, 0xc4, 0xec, 0xe1, 0x01, 0xb7, 0x99, 0xbb, 0x23, 0x8d, - 0x29, 0x26, 0xc5, 0x9f, 0xbf, 0xbe, 0x98, 0x3d, 0xd0, 0x3a, 0xed, 0xd5, 0xdc, 0x08, 0x3a, 0xb9, - 0x51, 0x9e, 0x3c, 0x31, 0x9c, 0xfd, 0x6e, 0xf7, 0xea, 0xbb, 0x88, 0x78, 0xbf, 0xfa, 0xc6, 0xcf, - 0x9e, 0x3d, 0xe5, 0x79, 0xf3, 0x79, 0xdf, 0x09, 0x5f, 0xb1, 0x31, 0x21, 0x96, 0x2a, 0x72, 0x57, - 0x0d, 0xe7, 0x64, 0xfc, 0x06, 0x80, 0xc7, 0x92, 0x97, 0x0e, 0xf7, 0x10, 0x5c, 0x7c, 0x9f, 0x87, - 0xe0, 0x99, 0x53, 0xef, 0x71, 0x95, 0xb6, 0x78, 0xf3, 0x61, 0xc4, 0x8b, 0xe4, 0xcb, 0x45, 0x53, - 0xf7, 0x91, 0x10, 0x48, 0x74, 0xaa, 0xce, 0xe4, 0xfe, 0x8d, 0x04, 0x27, 0x87, 0xc4, 0xcf, 0x69, - 0x72, 0x13, 0x50, 0xcf, 0x53, 0x48, 0x87, 0x51, 0x6c, 0xc5, 0xde, 0x99, 0x34, 0xcf, 0xf5, 0x86, - 0x34, 0xf7, 0xdb, 0xb3, 0xfa, 0x70, 0xd5, 0xf3, 0x1b, 0x12, 0x2c, 0x78, 0x1b, 0xe0, 0x74, 0xa5, - 0x0e, 0x49, 0x6f, 0xd5, 0xbc, 0x13, 0xef, 0x9a, 0xa6, 0x13, 0xde, 0xf6, 0xfb, 0x88, 0xa0, 0xeb, - 0xee, 0x14, 0x67, 0x71, 0xb3, 0xf3, 0x53, 0x33, 0x45, 0x34, 0x6c, 0xe4, 0x54, 0x67, 0x63, 0xf3, - 0x47, 0x12, 0x84, 0x36, 0x4d, 0xb3, 0x8d, 0xde, 0x07, 0x73, 0x86, 0x69, 0xab, 0x64, 0x3a, 0xe0, - 0x96, 0xca, 0x1d, 0x7b, 0xa6, 0x3e, 0xcb, 0x87, 0xf2, 0xea, 0x8b, 0xaf, 0x2f, 0x0e, 0x63, 0x8e, - 0x7a, 0x13, 0x3e, 0x6d, 0x98, 0x76, 0x81, 0x02, 0x35, 0x98, 0xef, 0xbf, 0x03, 0xb3, 0xfe, 0xea, - 0x98, 0x8a, 0xcd, 0x4f, 0xaa, 0x6e, 0x76, 0x62, 0x55, 0xc9, 0x6d, 0x4f, 0x3d, 0xec, 0x19, 0xe5, - 0x3f, 0x25, 0x23, 0x77, 0x03, 0xe4, 0xeb, 0x83, 0x47, 0x7c, 0xca, 0x10, 0x15, 0x47, 0x7a, 0xa4, - 0x29, 0x4f, 0x0b, 0x79, 0xd9, 0xc9, 0x71, 0xcf, 0xfe, 0x82, 0x04, 0xe0, 0x06, 0x49, 0xd0, 0xc3, - 0x70, 0xa2, 0x50, 0xab, 0x96, 0xd4, 0x7a, 0x23, 0xdf, 0xd8, 0xaa, 0xfb, 0xbf, 0x24, 0x22, 0xde, - 0x1f, 0xb2, 0xba, 0xb8, 0xa9, 0xef, 0xe8, 0xb8, 0x85, 0xee, 0x87, 0x05, 0x3f, 0x34, 0x49, 0x95, - 0x4b, 0xb2, 0x94, 0x4d, 0xbe, 0x7a, 0x7b, 0x29, 0xc6, 0xec, 0x44, 0xdc, 0x42, 0x67, 0xe0, 0xd8, - 0x30, 0x5c, 0xa5, 0xba, 0x26, 0x07, 0xb2, 0xb3, 0xaf, 0xde, 0x5e, 0x8a, 0x3b, 0x06, 0x25, 0xca, - 0x01, 0xf2, 0x42, 0x72, 0x7a, 0xc1, 0x2c, 0xbc, 0x7a, 0x7b, 0x29, 0xc2, 0x46, 0x21, 0x1b, 0xfa, - 0xe0, 0x8f, 0x9e, 0x9e, 0x39, 0xfb, 0x4d, 0x00, 0x15, 0x63, 0xa7, 0xa7, 0xd1, 0xcf, 0xe9, 0xa3, - 0x2c, 0x1c, 0xaf, 0x54, 0xaf, 0x28, 0xf9, 0x22, 0xfd, 0xcc, 0xbf, 0xff, 0x03, 0x28, 0xfe, 0xb2, - 0x52, 0x6d, 0xab, 0xb0, 0x5e, 0x56, 0xeb, 0x95, 0xb5, 0x2a, 0xdb, 0x6c, 0xf5, 0x95, 0x3d, 0x57, - 0x6d, 0x54, 0x36, 0xca, 0x72, 0xa0, 0x70, 0x65, 0x6c, 0x30, 0xff, 0xe1, 0x43, 0x5f, 0xb9, 0x77, - 0x35, 0x9e, 0x2f, 0xa2, 0xff, 0xbf, 0x03, 0x00, 0x00, 0xff, 0xff, 0x82, 0xc8, 0xcb, 0x92, 0x5a, - 0xb1, 0x00, 0x00, + 0xab, 0x97, 0x59, 0xf5, 0x68, 0x11, 0xca, 0xed, 0x40, 0x78, 0x93, 0xe0, 0x91, 0x49, 0xb2, 0x4d, + 0x5b, 0x6b, 0x73, 0x5f, 0x91, 0x7d, 0x90, 0x52, 0xf6, 0x40, 0x53, 0x80, 0x95, 0xea, 0xe2, 0x6d, + 0xa6, 0x36, 0xd6, 0x76, 0xd8, 0x3b, 0x17, 0x41, 0x1a, 0x64, 0xc4, 0x48, 0x01, 0x7d, 0xd2, 0x62, + 0x01, 0xc2, 0x5a, 0x9f, 0x9d, 0x47, 0x0b, 0x92, 0xe8, 0x83, 0x7e, 0xe4, 0x9e, 0x81, 0x28, 0x3f, + 0xf5, 0x80, 0x64, 0x08, 0xde, 0xc4, 0x07, 0xb4, 0x9d, 0xa4, 0x42, 0xfe, 0x44, 0xcb, 0x10, 0xa6, + 0x9d, 0xe7, 0xd7, 0x8b, 0x32, 0xcb, 0x43, 0xbd, 0x5f, 0xa6, 0x9d, 0x54, 0x18, 0x58, 0xee, 0x1a, + 0xc4, 0x4a, 0x26, 0x91, 0x6c, 0x3f, 0xb5, 0x38, 0xa3, 0x46, 0xfb, 0xdc, 0xed, 0xdb, 0xe2, 0x0a, + 0x28, 0xfd, 0x40, 0xc7, 0x21, 0xc2, 0xde, 0x3d, 0xe1, 0x67, 0xea, 0xf8, 0x57, 0xae, 0x08, 0x51, + 0x4a, 0xbb, 0xd6, 0x75, 0x1e, 0x13, 0x93, 0x3c, 0x8f, 0x89, 0x71, 0xf2, 0x01, 0xb7, 0xb3, 0x08, + 0x42, 0x2d, 0xcd, 0xd6, 0xf8, 0xb8, 0xe9, 0xdf, 0xb9, 0xf7, 0x40, 0x8c, 0x13, 0xb1, 0xd0, 0x0a, + 0x04, 0xcd, 0xae, 0x38, 0x32, 0x9a, 0x1d, 0x37, 0x94, 0x5a, 0xb7, 0x10, 0x22, 0xb2, 0xa4, 0x10, + 0xe0, 0x42, 0x75, 0xac, 0x58, 0x3c, 0xee, 0x13, 0x8b, 0x0e, 0xb6, 0xb7, 0x77, 0x6c, 0xf7, 0x0f, + 0x36, 0x9d, 0x43, 0xa2, 0xe0, 0x08, 0xca, 0xed, 0x00, 0x9c, 0xf6, 0xd4, 0xde, 0xc2, 0x3d, 0x4b, + 0x37, 0x0d, 0x26, 0x4d, 0x5c, 0x52, 0x90, 0xa7, 0x83, 0xbc, 0x7e, 0x8c, 0xa8, 0x3c, 0x05, 0xc1, + 0x7c, 0xb7, 0x8b, 0xb2, 0x10, 0xa3, 0xdf, 0x4d, 0x93, 0xc9, 0x4a, 0x48, 0x71, 0xbe, 0x49, 0x9d, + 0x65, 0xee, 0xd8, 0x2f, 0x69, 0x3d, 0xe7, 0x59, 0x30, 0xf1, 0x9d, 0xbb, 0x04, 0xf1, 0xa2, 0x69, + 0x58, 0xd8, 0xb0, 0xfa, 0x34, 0x02, 0xd9, 0x6e, 0x9b, 0xcd, 0x9b, 0x9c, 0x02, 0xfb, 0x20, 0xcc, + 0xd6, 0xba, 0x5d, 0x8a, 0x19, 0x52, 0xc8, 0x9f, 0x6c, 0x65, 0x17, 0x6a, 0x63, 0xd9, 0x73, 0xe1, + 0x68, 0xec, 0xe1, 0x03, 0x74, 0xf8, 0xf3, 0xdf, 0x25, 0xb8, 0x6b, 0x78, 0x21, 0xdd, 0xc4, 0x07, + 0xd6, 0x51, 0xd7, 0xd1, 0xf3, 0x10, 0xdf, 0xa4, 0x8f, 0xb3, 0x3e, 0x83, 0x0f, 0x50, 0x16, 0xa2, + 0xb8, 0xb5, 0x72, 0xe1, 0xc2, 0xf9, 0x4b, 0x4c, 0xca, 0xd7, 0x66, 0x14, 0x51, 0x80, 0x4e, 0x43, + 0xdc, 0xc2, 0xcd, 0xee, 0xca, 0x85, 0x8b, 0x37, 0xcf, 0x33, 0xb1, 0x5a, 0x9b, 0x51, 0xdc, 0xa2, + 0xd5, 0x18, 0x19, 0xf1, 0x9b, 0x9f, 0x5c, 0x94, 0x0a, 0x61, 0x08, 0x5a, 0xfd, 0xce, 0xd7, 0x4d, + 0x36, 0xfe, 0x34, 0x02, 0x4b, 0x9e, 0x5a, 0x66, 0xb0, 0xf8, 0x3d, 0x08, 0xe7, 0x41, 0x5f, 0xd9, + 0x33, 0x7e, 0x0a, 0x31, 0xc6, 0x12, 0x1d, 0xca, 0xc5, 0xdc, 0xa7, 0x25, 0x48, 0x5e, 0x17, 0x94, + 0xeb, 0xd8, 0x46, 0x97, 0x01, 0x9c, 0x96, 0xc4, 0x52, 0x39, 0xb5, 0x3c, 0xd8, 0xd6, 0xb2, 0x83, + 0xa3, 0x78, 0xc0, 0xd1, 0x13, 0x54, 0x00, 0xbb, 0xa6, 0xc5, 0x9f, 0x88, 0x9a, 0x80, 0xea, 0x00, + 0xa3, 0x87, 0x01, 0x51, 0xad, 0xa6, 0xde, 0x32, 0x6d, 0xdd, 0xd8, 0x55, 0xbb, 0xe6, 0x4b, 0xfc, + 0xe1, 0xbd, 0xa0, 0x22, 0xd3, 0x9a, 0xeb, 0xb4, 0x62, 0x93, 0x94, 0x93, 0x4e, 0xc7, 0x1d, 0x2a, + 0x24, 0x98, 0xd6, 0x5a, 0xad, 0x1e, 0xb6, 0x2c, 0xae, 0xb8, 0xc4, 0x27, 0xba, 0x0c, 0xd1, 0x6e, + 0x7f, 0x5b, 0x15, 0x5a, 0x22, 0xb1, 0x72, 0xd7, 0xa8, 0x35, 0x2f, 0x64, 0x83, 0xaf, 0xfa, 0x48, + 0xb7, 0xbf, 0x4d, 0x24, 0xe5, 0x1e, 0x48, 0x8e, 0xe8, 0x4c, 0xe2, 0x96, 0xdb, 0x0f, 0xfa, 0x1e, + 0x30, 0x1f, 0x81, 0xda, 0xed, 0xe9, 0x66, 0x4f, 0xb7, 0x0f, 0xe8, 0xb1, 0xd2, 0xa0, 0x22, 0x8b, + 0x8a, 0x4d, 0x5e, 0x9e, 0xbb, 0x09, 0xe9, 0x3a, 0x0d, 0x8d, 0xdc, 0x9e, 0x5f, 0x70, 0xfb, 0x27, + 0x4d, 0xee, 0xdf, 0xd8, 0x9e, 0x05, 0x86, 0x7a, 0x76, 0xf6, 0xdf, 0x4b, 0x90, 0x28, 0x90, 0x85, + 0x5b, 0x29, 0x5d, 0x69, 0x6b, 0xbb, 0xe8, 0x3c, 0x1c, 0x2b, 0xac, 0xd7, 0x8a, 0xcf, 0xa8, 0x95, + 0x92, 0x7a, 0x65, 0x3d, 0xef, 0xb9, 0x77, 0x90, 0x3d, 0xfe, 0xea, 0xed, 0x25, 0xe4, 0x81, 0xdd, + 0x32, 0x68, 0x26, 0x00, 0x9d, 0x83, 0x05, 0x3f, 0x4a, 0xbe, 0x50, 0x2f, 0x57, 0x1b, 0xb2, 0x94, + 0x3d, 0xf6, 0xea, 0xed, 0xa5, 0x39, 0x0f, 0x46, 0x7e, 0xdb, 0xc2, 0x86, 0x3d, 0x8c, 0x50, 0xac, + 0x6d, 0x6c, 0x54, 0x1a, 0x72, 0x60, 0x08, 0xa1, 0x68, 0x76, 0x3a, 0xba, 0x8d, 0x1e, 0x84, 0x39, + 0x3f, 0x42, 0xb5, 0xb2, 0x2e, 0x07, 0xb3, 0xe8, 0xd5, 0xdb, 0x4b, 0x29, 0x0f, 0x74, 0x55, 0x6f, + 0x67, 0x63, 0x1f, 0xfc, 0xd1, 0xd3, 0x33, 0x9f, 0xfa, 0xff, 0x4f, 0x4b, 0x85, 0x8d, 0xb1, 0x6b, + 0xee, 0xb1, 0xa3, 0xad, 0x39, 0xbf, 0xdd, 0xfe, 0xca, 0x5d, 0x3e, 0x75, 0xc3, 0x7d, 0x44, 0x8f, + 0x32, 0x9e, 0x76, 0xb9, 0x4d, 0xca, 0x0c, 0x65, 0x0f, 0x77, 0x0f, 0xb2, 0x13, 0x8c, 0x42, 0x76, + 0xa2, 0x62, 0xc8, 0x5d, 0x82, 0xd9, 0x4d, 0xad, 0x67, 0xd7, 0xb1, 0xbd, 0x86, 0xb5, 0x16, 0xee, + 0xf9, 0xfd, 0x87, 0x59, 0xe1, 0x3f, 0x20, 0x08, 0x51, 0x27, 0x81, 0xd9, 0x4f, 0xfa, 0x77, 0x6e, + 0x0f, 0x42, 0xf4, 0x2a, 0x9d, 0xe3, 0x5b, 0x70, 0x0c, 0xe6, 0x5b, 0x10, 0xcb, 0x70, 0x60, 0xf3, + 0xab, 0xc6, 0x49, 0x85, 0x7d, 0xa0, 0xc7, 0x85, 0x87, 0x10, 0x3c, 0xdc, 0x43, 0xe0, 0xcb, 0x8b, + 0xfb, 0x09, 0x6d, 0x88, 0xf2, 0x29, 0x76, 0x3a, 0x22, 0xb9, 0x1d, 0x41, 0x1b, 0x90, 0xee, 0x6a, + 0x3d, 0x9b, 0x3e, 0xcc, 0xb3, 0x47, 0x47, 0xc1, 0x57, 0xf0, 0xe2, 0xb0, 0x3e, 0xf1, 0x0d, 0x96, + 0xb7, 0x32, 0xdb, 0xf5, 0x16, 0xe6, 0xfe, 0x20, 0x04, 0x11, 0xce, 0x8c, 0xa7, 0x20, 0xca, 0xd9, + 0xca, 0xd7, 0xdc, 0xdd, 0xcb, 0xc3, 0x66, 0x76, 0xd9, 0x31, 0x87, 0x9c, 0x9e, 0xc0, 0x41, 0xf7, + 0x43, 0xac, 0xb9, 0xa7, 0xe9, 0x86, 0xaa, 0xb7, 0xb8, 0x73, 0x9c, 0xf8, 0xc2, 0xeb, 0x8b, 0xd1, + 0x22, 0x29, 0xab, 0x94, 0x94, 0x28, 0xad, 0xac, 0xb4, 0x88, 0x4f, 0xb3, 0x87, 0xf5, 0xdd, 0x3d, + 0x9b, 0xeb, 0x0d, 0xfe, 0x85, 0x9e, 0x84, 0x10, 0x11, 0x08, 0x7e, 0xf3, 0x22, 0x3b, 0x14, 0xf5, + 0x38, 0x89, 0xbb, 0x42, 0x8c, 0x34, 0xfc, 0x91, 0xff, 0xb4, 0x28, 0x29, 0x14, 0x03, 0x15, 0x61, + 0xb6, 0xad, 0x59, 0xb6, 0x4a, 0xed, 0x31, 0x69, 0x9e, 0x5d, 0xb9, 0x38, 0x39, 0xcc, 0x10, 0xce, + 0x58, 0xde, 0xf5, 0x04, 0xc1, 0x62, 0x45, 0x2d, 0x74, 0x06, 0x64, 0x4a, 0xa4, 0x49, 0x57, 0x20, + 0xf3, 0x12, 0x23, 0x94, 0xef, 0x29, 0x52, 0xce, 0x16, 0x26, 0xf5, 0x15, 0x4f, 0x41, 0x9c, 0xbe, + 0x3e, 0x45, 0x41, 0xd8, 0xfd, 0xcd, 0x18, 0x29, 0xa0, 0x95, 0x0f, 0x40, 0xda, 0xd5, 0xfa, 0x0c, + 0x24, 0xc6, 0xa8, 0xb8, 0xc5, 0x14, 0xf0, 0x51, 0x58, 0x30, 0xf0, 0xbe, 0xad, 0x0e, 0x42, 0xc7, + 0x29, 0x34, 0x22, 0x75, 0xd7, 0xfd, 0x18, 0xf7, 0x41, 0xaa, 0x29, 0x98, 0xcf, 0x60, 0x81, 0xc2, + 0xce, 0x3a, 0xa5, 0x14, 0xec, 0x24, 0xc4, 0xb4, 0x6e, 0x97, 0x01, 0x24, 0xb8, 0xd6, 0xef, 0x76, + 0x69, 0xd5, 0x59, 0x98, 0xa3, 0x63, 0xec, 0x61, 0xab, 0xdf, 0xb6, 0x39, 0x91, 0x24, 0x85, 0x49, + 0x93, 0x0a, 0x85, 0x95, 0x53, 0xd8, 0x7b, 0x61, 0x16, 0xdf, 0xd2, 0x5b, 0xd8, 0x68, 0x62, 0x06, + 0x37, 0x4b, 0xe1, 0x92, 0xa2, 0x90, 0x02, 0x3d, 0x08, 0x8e, 0x36, 0x57, 0x85, 0xa5, 0x49, 0x31, + 0x7a, 0xa2, 0x3c, 0xcf, 0x8a, 0x73, 0x19, 0x08, 0x95, 0x34, 0x5b, 0x23, 0xee, 0x92, 0xbd, 0xcf, + 0xcc, 0x67, 0x52, 0x21, 0x7f, 0xe6, 0x7e, 0x21, 0x08, 0xa1, 0xeb, 0xa6, 0x8d, 0xd1, 0x63, 0x1e, + 0x57, 0x36, 0x35, 0x4a, 0x9e, 0xeb, 0xfa, 0xae, 0x81, 0x5b, 0x1b, 0xd6, 0xae, 0xe7, 0xc5, 0x57, + 0x57, 0x9c, 0x02, 0x3e, 0x71, 0x5a, 0x80, 0x70, 0xcf, 0xec, 0x1b, 0x2d, 0x71, 0xc1, 0x81, 0x7e, + 0xa0, 0x32, 0xc4, 0x1c, 0x29, 0x09, 0x4d, 0x92, 0x92, 0x34, 0x91, 0x12, 0x22, 0xc3, 0xbc, 0x40, + 0x89, 0x6e, 0x73, 0x61, 0x29, 0x40, 0xdc, 0x51, 0x5e, 0x5c, 0xda, 0xa6, 0x13, 0x58, 0x17, 0x8d, + 0x98, 0x48, 0x67, 0xee, 0x1d, 0xe6, 0x31, 0x89, 0x93, 0x9d, 0x0a, 0xce, 0x3d, 0x9f, 0x58, 0xf1, + 0xd7, 0x67, 0xa3, 0x74, 0x5c, 0xae, 0x58, 0xb1, 0x17, 0x68, 0xef, 0x82, 0xb8, 0xa5, 0xef, 0x1a, + 0xf4, 0xce, 0x10, 0x97, 0x3c, 0xb7, 0x80, 0xd4, 0xba, 0xb7, 0x80, 0x99, 0xa4, 0x79, 0x5e, 0x39, + 0x3f, 0x07, 0xf3, 0xee, 0xfb, 0xe2, 0x2e, 0x15, 0x26, 0x65, 0xc8, 0xa9, 0xaa, 0x8b, 0x9a, 0xdc, + 0xaf, 0x4a, 0x10, 0xe1, 0x16, 0xcb, 0x9d, 0x06, 0x69, 0xf4, 0x34, 0x04, 0xc6, 0x4d, 0x43, 0xf0, + 0xce, 0xa7, 0x21, 0x0f, 0xe0, 0x74, 0xd3, 0xe2, 0x6f, 0x8c, 0x8e, 0x70, 0xab, 0x58, 0x17, 0xeb, + 0xfa, 0x2e, 0x5f, 0xf7, 0x1e, 0xa4, 0xdc, 0xef, 0x4a, 0xc4, 0xc3, 0xe7, 0xf5, 0x28, 0x0f, 0xb3, + 0xa2, 0x5f, 0xea, 0x4e, 0x5b, 0xdb, 0xe5, 0xa2, 0x78, 0xf7, 0xd8, 0xce, 0x11, 0x2b, 0xac, 0x24, + 0x78, 0x7f, 0xa8, 0x3f, 0x31, 0x72, 0x5a, 0x03, 0x63, 0xa6, 0xd5, 0x27, 0x47, 0xc1, 0x3b, 0x93, + 0x23, 0xdf, 0x8c, 0x87, 0x06, 0x66, 0x3c, 0xf7, 0x7b, 0x12, 0x7f, 0xdd, 0xbc, 0xc5, 0x2e, 0x48, + 0xfd, 0xaf, 0x9a, 0xaa, 0x17, 0xb8, 0x6c, 0xb5, 0x70, 0x4b, 0x1d, 0x9a, 0xb3, 0x7b, 0x87, 0x29, + 0xfa, 0xfb, 0xec, 0xce, 0x1d, 0x12, 0x54, 0xea, 0xee, 0x1c, 0x7e, 0x36, 0x00, 0x73, 0x43, 0xf0, + 0x7f, 0xf3, 0xe6, 0xd2, 0xbf, 0x7a, 0xc3, 0x53, 0xae, 0xde, 0xc8, 0xd8, 0xd5, 0xfb, 0x99, 0x00, + 0x4d, 0x00, 0x74, 0x4d, 0x4b, 0x6b, 0xff, 0x75, 0xe8, 0xde, 0x53, 0x10, 0xef, 0x9a, 0x6d, 0x95, + 0xd5, 0xb0, 0x2b, 0x66, 0xb1, 0xae, 0xd9, 0x56, 0x86, 0xc4, 0x2c, 0xfc, 0x36, 0x29, 0xe6, 0xc8, + 0xdb, 0x30, 0x09, 0xd1, 0xc1, 0x05, 0xd5, 0x83, 0x24, 0x63, 0x05, 0xf7, 0x9a, 0x1e, 0x25, 0x3c, + 0xa0, 0x6e, 0x98, 0x34, 0xec, 0xe5, 0xb1, 0x6e, 0x33, 0x48, 0x85, 0xc3, 0x11, 0x0c, 0xe6, 0x64, + 0x8c, 0xca, 0x1c, 0x79, 0x35, 0x96, 0xc2, 0xe1, 0x72, 0xdf, 0x2f, 0x01, 0xac, 0x13, 0xce, 0xd2, + 0xf1, 0x12, 0x7f, 0xc7, 0xa2, 0x5d, 0x50, 0x7d, 0x2d, 0x9f, 0x1e, 0x37, 0x69, 0xbc, 0xfd, 0xa4, + 0xe5, 0xed, 0x77, 0x11, 0x66, 0x5d, 0xd9, 0xb6, 0xb0, 0xe8, 0xcc, 0xe9, 0x43, 0xa2, 0xd2, 0x3a, + 0xb6, 0x95, 0xe4, 0x2d, 0xcf, 0x57, 0xee, 0x1f, 0x4b, 0x10, 0xa7, 0x7d, 0xda, 0xc0, 0xb6, 0xe6, + 0x9b, 0x43, 0xe9, 0xce, 0xe7, 0xf0, 0x6e, 0x00, 0x46, 0xc6, 0xd2, 0x5f, 0xc6, 0x5c, 0xb2, 0xe2, + 0xb4, 0xa4, 0xae, 0xbf, 0x8c, 0xd1, 0x45, 0x87, 0xe1, 0xc1, 0xc3, 0x19, 0x2e, 0xa2, 0x56, 0xce, + 0xf6, 0x13, 0x10, 0xa5, 0xaf, 0x47, 0xec, 0x5b, 0x3c, 0x10, 0x8d, 0x18, 0xfd, 0x4e, 0x63, 0xdf, + 0xca, 0xbd, 0x08, 0xd1, 0xc6, 0x3e, 0xcb, 0x27, 0x9e, 0x82, 0x78, 0xcf, 0x34, 0xb9, 0xf7, 0xc7, + 0xbc, 0xee, 0x18, 0x29, 0xa0, 0xce, 0x8e, 0xc8, 0xa1, 0x05, 0xdc, 0x1c, 0x9a, 0x9b, 0x04, 0x0c, + 0x4e, 0x95, 0x04, 0x24, 0xd1, 0xe7, 0xac, 0x6f, 0x25, 0xa1, 0x87, 0xe1, 0x44, 0xbd, 0x72, 0xb5, + 0x5a, 0x2e, 0xa9, 0x1b, 0xf5, 0xab, 0x03, 0x77, 0xfc, 0xb3, 0xe9, 0x57, 0x6f, 0x2f, 0x25, 0x78, + 0xd8, 0x39, 0x0e, 0x7a, 0x53, 0x29, 0x5f, 0xaf, 0x35, 0xca, 0xb2, 0xc4, 0xa0, 0x37, 0x7b, 0xf8, + 0x96, 0x69, 0xb3, 0x9f, 0xbe, 0x79, 0x14, 0x4e, 0x8e, 0x80, 0x76, 0x82, 0xcf, 0xb9, 0x57, 0x6f, + 0x2f, 0xcd, 0x6e, 0xf6, 0x30, 0x93, 0x32, 0x8a, 0xb1, 0x0c, 0x99, 0x61, 0x8c, 0xda, 0x66, 0xad, + 0x9e, 0x5f, 0x97, 0x97, 0xb2, 0xf2, 0xab, 0xb7, 0x97, 0x92, 0x42, 0x65, 0x10, 0xf8, 0xaf, 0x7f, + 0xf4, 0xf9, 0x9d, 0x31, 0x5f, 0xd6, 0x98, 0xc5, 0x75, 0x5d, 0xad, 0xa7, 0x75, 0x8e, 0x1a, 0x7e, + 0x4e, 0x38, 0xae, 0x91, 0xfb, 0x74, 0x00, 0xd2, 0x4e, 0x70, 0xb3, 0x49, 0x5b, 0x40, 0x8f, 0x79, + 0x33, 0x7e, 0x89, 0xb1, 0xb6, 0x83, 0x41, 0x8b, 0x84, 0xe0, 0xbb, 0x21, 0x26, 0x9c, 0x64, 0xbe, + 0xa8, 0x96, 0x46, 0xd8, 0x37, 0x0e, 0xc1, 0x51, 0x1d, 0x0c, 0xf4, 0x34, 0xc4, 0x9d, 0x25, 0xe6, + 0xbc, 0x19, 0x3e, 0x7e, 0x4d, 0x72, 0x7c, 0x17, 0x07, 0x5d, 0x72, 0xc3, 0xb8, 0xd0, 0xb8, 0xc0, + 0xf0, 0x3a, 0x03, 0xe0, 0xc8, 0x4e, 0x08, 0xf7, 0x28, 0x84, 0xb4, 0xed, 0xa6, 0xce, 0x15, 0xf0, + 0x5d, 0xc3, 0x78, 0xf9, 0x42, 0xb1, 0xc2, 0x91, 0x28, 0x64, 0xae, 0xc2, 0x93, 0x29, 0x9c, 0x5f, + 0xf4, 0x15, 0xd6, 0x7d, 0x95, 0xc5, 0xc2, 0xcc, 0xbb, 0x88, 0x75, 0xb4, 0xfd, 0x02, 0x0d, 0x87, + 0x4f, 0x40, 0x94, 0x54, 0xee, 0xf2, 0xe7, 0xd0, 0x82, 0x4a, 0xa4, 0xa3, 0xed, 0x5f, 0xd5, 0xac, + 0x6b, 0xa1, 0x58, 0x50, 0x0e, 0xe5, 0x7e, 0x92, 0x78, 0x2a, 0x3e, 0xae, 0xa0, 0x87, 0x00, 0x11, + 0x0c, 0x6d, 0x17, 0xab, 0x64, 0xe9, 0x52, 0xf6, 0x0a, 0xba, 0xe9, 0x8e, 0xb6, 0x9f, 0xdf, 0xc5, + 0xd5, 0x7e, 0x87, 0x76, 0xc0, 0x42, 0x1b, 0x20, 0x0b, 0x60, 0x31, 0xb3, 0x9c, 0xfd, 0x27, 0x87, + 0x7f, 0x44, 0x86, 0x03, 0x30, 0x03, 0xf0, 0x1a, 0x31, 0x00, 0x29, 0x46, 0xcf, 0x39, 0xa0, 0xe3, + 0x1b, 0x4a, 0xd0, 0x3f, 0x94, 0xdc, 0xd3, 0x90, 0x1e, 0x98, 0x01, 0x94, 0x83, 0x59, 0x9e, 0xb1, + 0xa2, 0x87, 0x1f, 0x58, 0x84, 0x13, 0x57, 0x12, 0x2c, 0x33, 0x45, 0x0f, 0x83, 0xac, 0xc6, 0x7e, + 0xf1, 0x13, 0x8b, 0x12, 0xdd, 0xf6, 0x79, 0x08, 0x66, 0x7d, 0x73, 0x20, 0xb2, 0xc8, 0x92, 0x9b, + 0x45, 0x76, 0x81, 0x5f, 0x80, 0x24, 0x51, 0x40, 0xb8, 0xc5, 0x61, 0xef, 0x87, 0x34, 0x53, 0x90, + 0x83, 0xbc, 0x66, 0x0e, 0xcf, 0x86, 0x60, 0x78, 0x4e, 0x78, 0x40, 0x7e, 0xb6, 0x27, 0x04, 0xd4, + 0x55, 0xcd, 0xca, 0xd5, 0x00, 0xdc, 0x49, 0x45, 0x79, 0xb8, 0x9b, 0x28, 0x0f, 0xef, 0x61, 0x5d, + 0xfe, 0xcc, 0xb4, 0xcf, 0x63, 0xcc, 0x12, 0x20, 0xf7, 0x40, 0x2e, 0x7b, 0x6c, 0x7a, 0x8d, 0x42, + 0x14, 0x9e, 0xfd, 0xd4, 0x17, 0x4e, 0x4b, 0x5f, 0x1f, 0x5d, 0xf0, 0x1f, 0x6e, 0xc0, 0x29, 0x4f, + 0x25, 0x11, 0x40, 0x5f, 0x22, 0x2a, 0xed, 0x91, 0x57, 0x52, 0x39, 0x29, 0xa1, 0x74, 0x68, 0xfe, + 0x37, 0x7b, 0xb8, 0xda, 0x99, 0x9c, 0x6d, 0x9a, 0x9c, 0xef, 0x1a, 0x9d, 0x94, 0xff, 0x95, 0x38, + 0x44, 0x15, 0xfc, 0xbe, 0x3e, 0xb6, 0x6c, 0xb4, 0x02, 0x21, 0xdc, 0xdc, 0x33, 0x47, 0xe5, 0x40, + 0xc9, 0x00, 0x97, 0x39, 0x5c, 0xb9, 0xb9, 0x67, 0xae, 0xcd, 0x28, 0x14, 0x16, 0x5d, 0x80, 0xf0, + 0x4e, 0xbb, 0xcf, 0xd3, 0x57, 0x03, 0x3a, 0xcb, 0x8b, 0x74, 0x85, 0x00, 0xad, 0xcd, 0x28, 0x0c, + 0x9a, 0x34, 0x45, 0x7f, 0x17, 0x2c, 0x78, 0x78, 0x53, 0x15, 0x63, 0x87, 0x36, 0x45, 0x60, 0x51, + 0x01, 0x40, 0x37, 0x74, 0x5b, 0xa5, 0xa9, 0x1d, 0xae, 0x35, 0xee, 0x19, 0x8f, 0xa9, 0xdb, 0x34, + 0x19, 0xb4, 0x36, 0xa3, 0xc4, 0x75, 0xf1, 0x41, 0xba, 0xfb, 0xbe, 0x3e, 0xee, 0x1d, 0x70, 0x6f, + 0x6d, 0x6c, 0x77, 0x9f, 0x25, 0x40, 0xa4, 0xbb, 0x14, 0x9a, 0x28, 0x59, 0xf6, 0xee, 0xbc, 0xbd, + 0xcf, 0x7f, 0x4d, 0x65, 0x71, 0x1c, 0x26, 0x7d, 0x7c, 0xbe, 0xb1, 0xbf, 0x36, 0xa3, 0x44, 0x9b, + 0xec, 0x4f, 0xf4, 0xa4, 0xe3, 0x82, 0x25, 0x86, 0xbd, 0x1e, 0x1f, 0x2e, 0x4b, 0xfb, 0xcc, 0x08, + 0x57, 0x0c, 0x55, 0x21, 0xd5, 0xd6, 0x2d, 0x5b, 0xb5, 0x0c, 0xad, 0x6b, 0xed, 0x99, 0xb6, 0x78, + 0xf8, 0xf9, 0xbe, 0x71, 0x14, 0xd6, 0x75, 0xcb, 0xae, 0x0b, 0xe0, 0xb5, 0x19, 0x65, 0xb6, 0xed, + 0x2d, 0x20, 0xf4, 0xcc, 0x9d, 0x1d, 0xdc, 0x73, 0x08, 0xd2, 0x3c, 0xcb, 0x21, 0xf4, 0x6a, 0x04, + 0x5a, 0xe0, 0x13, 0x7a, 0xa6, 0xb7, 0x00, 0x7d, 0x03, 0xcc, 0xb7, 0x4d, 0xad, 0xe5, 0x90, 0x53, + 0x9b, 0x7b, 0x7d, 0xe3, 0x26, 0x4d, 0xca, 0x24, 0x56, 0x1e, 0x1c, 0xdb, 0x49, 0x53, 0x6b, 0x09, + 0x12, 0x45, 0x82, 0xb0, 0x36, 0xa3, 0xcc, 0xb5, 0x07, 0x0b, 0xd1, 0x7b, 0x61, 0x41, 0xeb, 0x76, + 0xdb, 0x07, 0x83, 0xd4, 0xd3, 0x94, 0xfa, 0xd9, 0x71, 0xd4, 0xf3, 0x04, 0x67, 0x90, 0x3c, 0xd2, + 0x86, 0x4a, 0x51, 0x03, 0xe4, 0x6e, 0x0f, 0xd3, 0xfb, 0x6e, 0x5d, 0xee, 0x65, 0xd0, 0x57, 0x95, + 0x13, 0x2b, 0x0f, 0x8c, 0xa3, 0xbd, 0xc9, 0xe0, 0x85, 0x53, 0xb2, 0x36, 0xa3, 0xa4, 0xbb, 0xfe, + 0x22, 0x46, 0xd5, 0x6c, 0x62, 0xfa, 0x04, 0x3d, 0xa7, 0x3a, 0x37, 0x89, 0x2a, 0x85, 0xf7, 0x53, + 0xf5, 0x15, 0xa1, 0x32, 0x24, 0x58, 0x28, 0xaa, 0x12, 0x65, 0x48, 0x9f, 0xf6, 0x4f, 0xac, 0xe4, + 0xc6, 0xae, 0x50, 0x0a, 0x7a, 0xdd, 0xb4, 0xf1, 0xda, 0x8c, 0x02, 0xd8, 0xf9, 0x42, 0x1a, 0x1c, + 0xa3, 0xcf, 0x52, 0x1f, 0xa8, 0x7e, 0xc5, 0x9b, 0x99, 0xa7, 0x04, 0x1f, 0x1a, 0x47, 0x90, 0xfe, + 0xdc, 0xd3, 0xc1, 0x75, 0xaf, 0x1e, 0x5e, 0x9b, 0x51, 0xe6, 0x6f, 0x0d, 0x17, 0x13, 0x11, 0xdb, + 0xd1, 0x0d, 0xad, 0xad, 0xbf, 0x8c, 0x99, 0x09, 0xa5, 0xbf, 0xf2, 0x70, 0x88, 0x88, 0x5d, 0xe1, + 0xd0, 0xd4, 0xb0, 0x12, 0x11, 0xdb, 0xf1, 0x16, 0x14, 0xa2, 0xfc, 0xa4, 0xae, 0xf3, 0x5c, 0x6b, + 0x54, 0x8e, 0xb1, 0x47, 0xc5, 0xaf, 0x85, 0x62, 0x20, 0x27, 0x72, 0x0f, 0x40, 0xc2, 0xa3, 0x98, + 0x50, 0x06, 0xa2, 0xfc, 0xa4, 0x8e, 0x38, 0xf3, 0xcb, 0x3f, 0x73, 0x29, 0x48, 0x7a, 0x95, 0x51, + 0xee, 0x23, 0x92, 0x83, 0x49, 0xdf, 0x4e, 0xc9, 0xf8, 0x33, 0xd2, 0x71, 0xd7, 0x53, 0xb9, 0x57, + 0x98, 0x36, 0x51, 0xcf, 0xb6, 0x5f, 0x93, 0xb4, 0x90, 0x5b, 0x56, 0xb4, 0x08, 0x89, 0xee, 0x4a, + 0xd7, 0x01, 0x09, 0x52, 0x10, 0xe8, 0xae, 0x74, 0x05, 0xc0, 0x3d, 0x90, 0x24, 0xe3, 0x56, 0xbd, + 0xfe, 0x52, 0x5c, 0x49, 0x90, 0x32, 0x0e, 0x92, 0xfb, 0xcd, 0x00, 0xc8, 0x83, 0x0a, 0xcc, 0x49, + 0x55, 0x4b, 0x47, 0x4e, 0x55, 0x9f, 0x1c, 0x4c, 0x92, 0xbb, 0x79, 0xf1, 0x75, 0x90, 0xdd, 0xf4, + 0x2e, 0x33, 0x35, 0xe3, 0xfd, 0xbf, 0x01, 0x47, 0x55, 0x49, 0x37, 0x07, 0x3c, 0xd7, 0x2b, 0xbe, + 0xcd, 0x4a, 0xf1, 0xc3, 0x99, 0x83, 0x13, 0xee, 0x38, 0x31, 0x5b, 0xdd, 0x96, 0x66, 0x63, 0x91, + 0x1f, 0xf3, 0xec, 0x5b, 0xde, 0x0f, 0x69, 0xad, 0xdb, 0x55, 0x2d, 0x5b, 0xb3, 0x31, 0xf7, 0x35, + 0x58, 0xe6, 0x61, 0x56, 0xeb, 0x76, 0xe9, 0xef, 0x8c, 0x31, 0x5f, 0xe3, 0x3e, 0x48, 0x11, 0x9d, + 0xae, 0x6b, 0x6d, 0xe1, 0x2a, 0x44, 0x98, 0x4b, 0xc2, 0x4b, 0x99, 0x77, 0x90, 0x6b, 0x39, 0x33, + 0x4e, 0xf5, 0xb9, 0x13, 0x53, 0x49, 0x9e, 0x98, 0x0a, 0xf1, 0x37, 0x6d, 0x18, 0x7f, 0xc4, 0xf3, + 0x43, 0xa3, 0x37, 0x0d, 0x16, 0x68, 0xfc, 0x75, 0x8b, 0x25, 0x4b, 0x62, 0x0a, 0xfb, 0xc8, 0x29, + 0x90, 0xf2, 0xeb, 0x7e, 0x94, 0x82, 0x80, 0xbd, 0xcf, 0x5b, 0x09, 0xd8, 0xfb, 0xc4, 0xd3, 0xf5, + 0x3c, 0x23, 0x38, 0x6c, 0xed, 0x38, 0x9e, 0x9b, 0xeb, 0xc8, 0xa5, 0x61, 0xd6, 0x67, 0x13, 0x72, + 0xc7, 0x61, 0x61, 0x94, 0x8a, 0xcf, 0xed, 0x39, 0xe5, 0x3e, 0x55, 0x8d, 0x2e, 0x40, 0xcc, 0xd1, + 0xf1, 0x23, 0xa2, 0x63, 0xda, 0xac, 0x00, 0x56, 0x1c, 0x50, 0x5f, 0x3a, 0x3f, 0xe0, 0x4b, 0xe7, + 0xe7, 0xbe, 0x19, 0x32, 0xe3, 0xf4, 0xf7, 0x40, 0x92, 0x2f, 0xe4, 0x30, 0xec, 0x38, 0x44, 0xf8, + 0xab, 0x79, 0x01, 0xba, 0x81, 0xc5, 0xbf, 0x08, 0x23, 0x99, 0x2e, 0x0f, 0xb2, 0x7d, 0x2d, 0xfa, + 0x91, 0x53, 0xe1, 0xe4, 0x58, 0x1d, 0x3e, 0x7e, 0x2b, 0x8c, 0x11, 0xe2, 0x5b, 0x61, 0x4d, 0xd1, + 0x1d, 0x8b, 0x8e, 0x55, 0x1c, 0x64, 0x61, 0x5f, 0xb9, 0xd7, 0x82, 0x70, 0x7c, 0xb4, 0x26, 0x47, + 0x4b, 0x90, 0x24, 0x7e, 0xab, 0xed, 0x77, 0x71, 0xa1, 0xa3, 0xed, 0x37, 0xb8, 0x7f, 0xcb, 0xb7, + 0x12, 0x02, 0xce, 0x56, 0x02, 0xda, 0x82, 0xb9, 0xb6, 0xd9, 0xd4, 0xda, 0xaa, 0x67, 0x2b, 0x87, + 0x2f, 0xa2, 0x7b, 0x87, 0x98, 0xed, 0x4f, 0x19, 0x12, 0x85, 0xc3, 0xe5, 0x3f, 0x4d, 0x69, 0xac, + 0x3b, 0xbb, 0x3e, 0xa8, 0x04, 0x89, 0x8e, 0x6e, 0x6d, 0xe3, 0x3d, 0xed, 0x96, 0x6e, 0xf6, 0xf8, + 0x6a, 0x1a, 0x16, 0x9a, 0x0d, 0x17, 0x46, 0xec, 0x30, 0x79, 0xd0, 0x3c, 0x53, 0x12, 0x1e, 0xb9, + 0xf1, 0x15, 0x39, 0xb2, 0x36, 0x19, 0xb7, 0x87, 0x14, 0x1d, 0xbb, 0x87, 0x34, 0x6a, 0xc3, 0x26, + 0x36, 0x7a, 0xc3, 0xe6, 0x83, 0xde, 0xa9, 0xf1, 0xdb, 0xbe, 0xa1, 0x3d, 0x1c, 0x54, 0x87, 0x05, + 0x8e, 0xdf, 0xf2, 0xf1, 0x7e, 0xc4, 0x51, 0x07, 0xb6, 0xbe, 0x06, 0x79, 0x8e, 0x04, 0xfa, 0x78, + 0xb6, 0x07, 0xef, 0x8c, 0xed, 0x62, 0x13, 0x35, 0xe4, 0xd9, 0x44, 0xfd, 0xdf, 0x6c, 0x2a, 0xde, + 0x1f, 0x84, 0xb9, 0x21, 0x47, 0x62, 0xe4, 0xee, 0xf0, 0xb8, 0x8c, 0xac, 0x18, 0x58, 0xf0, 0xc8, + 0x03, 0xe3, 0x73, 0x1d, 0x9a, 0x3c, 0xd7, 0xe1, 0xb7, 0x71, 0xae, 0x23, 0x77, 0x36, 0xd7, 0x5f, + 0xd7, 0x59, 0xf8, 0x98, 0x04, 0xd9, 0xf1, 0xde, 0xd7, 0xc8, 0xe9, 0x38, 0xd2, 0x06, 0xc2, 0x38, + 0x1b, 0x77, 0x1f, 0xa4, 0x06, 0x7c, 0x43, 0x26, 0xca, 0xb3, 0xbe, 0x28, 0x3c, 0xf7, 0x81, 0xa0, + 0x63, 0x78, 0x7c, 0x0e, 0xdc, 0x88, 0xd5, 0xfa, 0x2c, 0xcc, 0xb7, 0x70, 0x53, 0x6f, 0xdd, 0xe9, + 0x62, 0x9d, 0xe3, 0xd8, 0xff, 0x67, 0xad, 0x0e, 0x4b, 0xc9, 0xf7, 0x01, 0xc4, 0x14, 0x6c, 0x75, + 0x89, 0x3f, 0x86, 0x0a, 0x10, 0xc7, 0xfb, 0x4d, 0xdc, 0xb5, 0xdd, 0x43, 0x15, 0xa3, 0x42, 0x04, + 0x06, 0x5d, 0x16, 0x90, 0x24, 0x40, 0x76, 0xd0, 0xd0, 0x63, 0x3c, 0x07, 0x30, 0x3e, 0x9c, 0xe7, + 0xe8, 0xde, 0x24, 0xc0, 0x45, 0x91, 0x04, 0x08, 0x8e, 0x8d, 0x6f, 0x19, 0xd6, 0x40, 0x16, 0xe0, + 0x31, 0x9e, 0x05, 0x08, 0x4d, 0x68, 0xcc, 0x97, 0x06, 0x28, 0xfa, 0xd2, 0x00, 0x91, 0x09, 0xc3, + 0x1c, 0x93, 0x07, 0xb8, 0x28, 0xf2, 0x00, 0xd1, 0x09, 0x3d, 0x1e, 0x48, 0x04, 0x3c, 0xe5, 0x49, + 0x04, 0xc4, 0x87, 0xb3, 0xad, 0x3e, 0xd4, 0x11, 0x99, 0x80, 0x4b, 0x4e, 0x26, 0x20, 0x39, 0x36, + 0x8b, 0xc0, 0x91, 0x07, 0x53, 0x01, 0xb5, 0xa1, 0x54, 0xc0, 0x2c, 0xff, 0x11, 0xe8, 0x71, 0x24, + 0x26, 0xe4, 0x02, 0x6a, 0x43, 0xb9, 0x80, 0xd4, 0x04, 0x82, 0x13, 0x92, 0x01, 0xdf, 0x38, 0x3a, + 0x19, 0x30, 0x3e, 0x5c, 0xe7, 0xdd, 0x9c, 0x2e, 0x1b, 0xa0, 0x8e, 0xc9, 0x06, 0xc8, 0x63, 0x23, + 0x57, 0x46, 0x7e, 0xea, 0x74, 0xc0, 0xd6, 0x88, 0x74, 0x00, 0x0b, 0xdc, 0xcf, 0x8c, 0x25, 0x3e, + 0x45, 0x3e, 0x60, 0x6b, 0x44, 0x3e, 0x00, 0x4d, 0x24, 0x3b, 0x31, 0x21, 0x70, 0xc5, 0x9f, 0x10, + 0x98, 0x1f, 0xe3, 0x75, 0xba, 0xab, 0x7d, 0x4c, 0x46, 0x60, 0x7b, 0x5c, 0x46, 0x60, 0x81, 0xff, + 0xb8, 0xc4, 0x38, 0x8a, 0x47, 0x48, 0x09, 0xd4, 0x86, 0x52, 0x02, 0xc7, 0x26, 0x48, 0xda, 0xf4, + 0x39, 0x01, 0xf6, 0x73, 0x63, 0xec, 0x87, 0xc6, 0x40, 0x4e, 0x5c, 0x0b, 0xc5, 0x12, 0x72, 0x32, + 0xf7, 0x20, 0xf1, 0x60, 0x06, 0xf4, 0x1c, 0x89, 0x15, 0x70, 0xaf, 0x67, 0xf6, 0xc4, 0x1d, 0x0b, + 0xfa, 0x91, 0x3b, 0x43, 0x62, 0x44, 0x57, 0xa7, 0x1d, 0x92, 0x3f, 0xa0, 0x31, 0x99, 0x47, 0x8f, + 0xe5, 0x7e, 0x51, 0x72, 0x71, 0x69, 0x06, 0xc1, 0x1b, 0x5f, 0xc6, 0x79, 0x7c, 0xe9, 0xc9, 0x2a, + 0x04, 0xfc, 0x59, 0x85, 0x45, 0x48, 0x90, 0x58, 0x6b, 0x20, 0x61, 0xa0, 0x75, 0x9d, 0x84, 0x81, + 0x38, 0x40, 0xc5, 0x72, 0x0f, 0xdc, 0x2c, 0xb1, 0xdd, 0xc4, 0xb4, 0x73, 0x98, 0x8c, 0x85, 0xba, + 0xe8, 0x11, 0x98, 0xf7, 0xc0, 0x3a, 0x31, 0x1c, 0x8b, 0x9e, 0x65, 0x07, 0x3a, 0xcf, 0x83, 0xb9, + 0x7f, 0x2a, 0xb9, 0x1c, 0x72, 0x33, 0x0d, 0xa3, 0x92, 0x02, 0xd2, 0xdb, 0x94, 0x14, 0x08, 0xdc, + 0x71, 0x52, 0xc0, 0x1b, 0x93, 0x06, 0xfd, 0x31, 0xe9, 0x7f, 0x93, 0xdc, 0x39, 0x71, 0x42, 0xfc, + 0xa6, 0xd9, 0xc2, 0x3c, 0x4a, 0xa4, 0x7f, 0x13, 0x97, 0xa4, 0x6d, 0x8a, 0x5f, 0x89, 0x22, 0x7f, + 0x12, 0x28, 0xc7, 0xf0, 0xc4, 0xb9, 0x5d, 0x71, 0x02, 0xcc, 0xb0, 0xf7, 0x1e, 0x07, 0xbf, 0xdc, + 0x10, 0x71, 0x2f, 0x37, 0x38, 0x57, 0xc7, 0xa3, 0x9e, 0xab, 0xe3, 0xe8, 0x49, 0x88, 0xd3, 0x64, + 0xbf, 0x6a, 0x76, 0xc5, 0x0f, 0x6e, 0x9f, 0x1a, 0x7f, 0xb1, 0xc1, 0xa2, 0x47, 0xae, 0xd9, 0x65, + 0x08, 0xd7, 0xe3, 0x88, 0xfb, 0x3c, 0x8e, 0xbb, 0x20, 0x4e, 0x7a, 0xcf, 0x7e, 0x71, 0x12, 0xf8, + 0xbb, 0x03, 0xa2, 0x20, 0xf7, 0x53, 0x01, 0x48, 0x0f, 0x18, 0x9a, 0x91, 0x63, 0x1f, 0xb5, 0x8d, + 0x3c, 0x1d, 0x3f, 0x4e, 0x03, 0xec, 0x6a, 0x96, 0xfa, 0x92, 0x66, 0xd8, 0xfc, 0x57, 0xe2, 0x83, + 0x8a, 0xa7, 0x04, 0x65, 0x21, 0x46, 0xbe, 0xfa, 0x16, 0xff, 0x9d, 0xf8, 0xa0, 0xe2, 0x7c, 0xa3, + 0x35, 0x88, 0xe0, 0x5b, 0xf4, 0xf1, 0x64, 0xf6, 0x23, 0x21, 0xc7, 0x87, 0xc3, 0x61, 0x52, 0x5d, + 0xc8, 0x90, 0xc9, 0xfe, 0xd2, 0xeb, 0x8b, 0x32, 0x83, 0x7e, 0xd8, 0xb9, 0xcc, 0xa6, 0x70, 0x7c, + 0x3f, 0x17, 0x62, 0x03, 0x5c, 0xa0, 0x79, 0xc0, 0xa4, 0x08, 0xef, 0x09, 0x4f, 0xd9, 0x19, 0x6f, + 0x65, 0xb6, 0x83, 0x3b, 0x5d, 0xd3, 0x6c, 0xab, 0x6c, 0x8d, 0xe7, 0x21, 0xe5, 0xb7, 0xab, 0xec, + 0x47, 0x9d, 0x6d, 0x4d, 0x37, 0x54, 0x9f, 0x13, 0x9c, 0x64, 0x85, 0x6c, 0x4d, 0x79, 0x5f, 0xc6, + 0xce, 0x6d, 0xc2, 0xb1, 0x91, 0x76, 0x15, 0x3d, 0x01, 0x71, 0xd7, 0x24, 0xb3, 0x63, 0xfa, 0x87, + 0x64, 0x5a, 0x5c, 0xd8, 0xdc, 0x2f, 0x4b, 0x2e, 0x49, 0x7f, 0xee, 0xa6, 0x0c, 0x11, 0x76, 0x66, + 0x92, 0x9f, 0x8f, 0x79, 0x64, 0x3a, 0x8b, 0xbc, 0xcc, 0x0e, 0x54, 0x2a, 0x1c, 0x39, 0xf7, 0x5e, + 0x88, 0xb0, 0x12, 0x94, 0x80, 0xa8, 0xef, 0xb1, 0xfc, 0x7c, 0xb1, 0x58, 0xde, 0x14, 0x8f, 0x1f, + 0x17, 0xe8, 0x43, 0xf4, 0xa4, 0x58, 0x29, 0x5f, 0x2b, 0x17, 0x1b, 0x72, 0x10, 0xcd, 0xc1, 0x2c, + 0xfb, 0x9b, 0x3f, 0x69, 0x2f, 0x87, 0x3c, 0x45, 0xf5, 0x72, 0xb5, 0x54, 0x56, 0xe4, 0x70, 0xee, + 0x3c, 0x9c, 0x1c, 0x6b, 0xc3, 0xdd, 0xc4, 0x8c, 0xe4, 0x49, 0xcc, 0xe4, 0x5e, 0x0b, 0x90, 0xa0, + 0x66, 0x9c, 0x61, 0x46, 0xd7, 0x06, 0x06, 0xbe, 0x72, 0x04, 0xab, 0x3e, 0x30, 0x7a, 0x12, 0xc7, + 0xf4, 0xf0, 0x0e, 0xb6, 0x9b, 0x7b, 0xcc, 0x51, 0x60, 0x1a, 0x68, 0x56, 0x99, 0xe5, 0xa5, 0x14, + 0xc9, 0x62, 0x60, 0x2f, 0xe2, 0xa6, 0xad, 0x32, 0x21, 0xb2, 0x68, 0x30, 0x11, 0x27, 0x60, 0xa4, + 0xb4, 0xce, 0x0a, 0x73, 0xdf, 0x7c, 0x24, 0x5e, 0xc6, 0x21, 0xac, 0x94, 0x1b, 0xca, 0x0d, 0xf6, + 0xd3, 0xed, 0xf4, 0x4f, 0xb5, 0x5e, 0xcd, 0x6f, 0xd6, 0xd7, 0x6a, 0x84, 0x97, 0xf3, 0x90, 0x16, + 0xbc, 0x14, 0x85, 0xe1, 0xdc, 0x43, 0x70, 0x62, 0x8c, 0x57, 0x31, 0xe2, 0x10, 0xeb, 0x27, 0x25, + 0x2f, 0xb4, 0xdf, 0x33, 0xa8, 0x41, 0xc4, 0xb2, 0x35, 0xbb, 0x6f, 0x71, 0x26, 0x3e, 0x31, 0xad, + 0x9b, 0xb1, 0x2c, 0xfe, 0xa8, 0x53, 0x74, 0x85, 0x93, 0xc9, 0x5d, 0x80, 0x94, 0xbf, 0x66, 0x3c, + 0x0f, 0x5c, 0x21, 0x0a, 0xe4, 0x2e, 0x03, 0x1a, 0xf6, 0x3e, 0x46, 0x84, 0x97, 0xd2, 0xa8, 0xf0, + 0xf2, 0xc7, 0x24, 0x38, 0x75, 0x88, 0xa7, 0x81, 0x9e, 0x1d, 0x18, 0xe4, 0xa5, 0xa3, 0xf8, 0x29, + 0xcb, 0xac, 0x6c, 0x60, 0x98, 0x8f, 0x41, 0xd2, 0x5b, 0x3e, 0xdd, 0x20, 0xbf, 0x14, 0x70, 0x17, + 0xb1, 0x3f, 0x0e, 0x76, 0x55, 0xa0, 0xf4, 0x35, 0xaa, 0xc0, 0x77, 0x03, 0xd8, 0xfb, 0xe2, 0x14, + 0x35, 0xb7, 0xa3, 0x77, 0x8f, 0xc8, 0x2f, 0xe2, 0x66, 0x63, 0x9f, 0x2f, 0x82, 0xb8, 0xcd, 0xff, + 0xb2, 0x50, 0xdd, 0x9b, 0x14, 0xe8, 0x53, 0x1b, 0x6b, 0xf1, 0x80, 0x79, 0x5a, 0x63, 0xec, 0x26, + 0x0f, 0x58, 0xb1, 0x85, 0x6e, 0xc0, 0x89, 0x01, 0x47, 0xc1, 0x21, 0x1d, 0x9a, 0xd6, 0x5f, 0x38, + 0xe6, 0xf7, 0x17, 0x04, 0x69, 0xaf, 0xb5, 0x0f, 0xfb, 0xad, 0xfd, 0x0d, 0x00, 0x37, 0x39, 0xe0, + 0x1e, 0xfb, 0x93, 0xbc, 0xc7, 0xfe, 0x2e, 0x40, 0x98, 0x48, 0x92, 0xe0, 0xd3, 0xb0, 0x2a, 0x26, + 0x92, 0xe0, 0x49, 0x2e, 0x30, 0xe8, 0x9c, 0x0e, 0x68, 0x38, 0x41, 0x3b, 0xa6, 0x89, 0xa7, 0xfc, + 0x4d, 0xdc, 0x33, 0x36, 0xd5, 0x3b, 0xba, 0xa9, 0x97, 0x21, 0x4c, 0x67, 0x7e, 0xe4, 0x5d, 0xca, + 0x6f, 0x02, 0xd0, 0x6c, 0xbb, 0xa7, 0x6f, 0xf7, 0xdd, 0x06, 0x16, 0x47, 0x4b, 0x4e, 0x5e, 0xc0, + 0x15, 0xee, 0xe2, 0x22, 0xb4, 0xe0, 0xa2, 0x7a, 0xc4, 0xc8, 0x43, 0x30, 0x57, 0x85, 0x94, 0x1f, + 0x77, 0xf4, 0xdd, 0xd0, 0xe1, 0x9f, 0x07, 0x75, 0xbd, 0x23, 0xfe, 0x5c, 0x15, 0xfd, 0xc8, 0xbd, + 0x12, 0x80, 0xa4, 0x57, 0xf0, 0xfe, 0xf6, 0xb9, 0x20, 0xb9, 0x6f, 0x97, 0x20, 0xe6, 0x0c, 0xff, + 0x90, 0xc3, 0xce, 0xee, 0x1d, 0x61, 0x67, 0xf3, 0x82, 0x6d, 0x13, 0x05, 0x9d, 0x6d, 0xa2, 0xcb, + 0x8e, 0xf9, 0x1b, 0x97, 0x10, 0xf1, 0xf2, 0x5a, 0x1c, 0x38, 0xe4, 0xd6, 0xfe, 0xf2, 0x74, 0x57, + 0xf1, 0x16, 0x20, 0xec, 0xbd, 0x46, 0xc7, 0x3e, 0x72, 0x2d, 0xcf, 0x09, 0x23, 0xb6, 0x10, 0xbd, + 0x77, 0xf6, 0xa4, 0x23, 0xdf, 0xd9, 0x73, 0x5a, 0x09, 0x78, 0x5b, 0xf9, 0x5e, 0x09, 0x62, 0x62, + 0x4d, 0xa0, 0xf7, 0x78, 0x4f, 0x9e, 0x89, 0xad, 0xcd, 0xb1, 0xfa, 0x88, 0xd3, 0xf7, 0x1c, 0x3c, + 0x1b, 0x3a, 0x70, 0x1d, 0x3c, 0xea, 0x81, 0x6b, 0xee, 0xd9, 0xfd, 0x85, 0x04, 0xf2, 0xe0, 0x8a, + 0xfd, 0x9a, 0x7b, 0x37, 0x6c, 0xe6, 0x82, 0x23, 0xcc, 0xdc, 0xb8, 0x53, 0xd4, 0xa1, 0x71, 0xa7, + 0xa8, 0x87, 0x47, 0x1d, 0xbe, 0xc3, 0x51, 0xbf, 0x3f, 0x00, 0x09, 0x4f, 0x7a, 0x14, 0x3d, 0xee, + 0x3b, 0x91, 0xbd, 0x74, 0x58, 0x2a, 0xd5, 0x73, 0x24, 0xdb, 0xc7, 0xa6, 0xc0, 0xd1, 0xd9, 0xf4, + 0xf6, 0xdf, 0xce, 0x1a, 0x7d, 0x81, 0x35, 0x3c, 0xe6, 0x02, 0xeb, 0xb7, 0x49, 0x10, 0x73, 0xdc, + 0xee, 0xa3, 0x6e, 0x62, 0x1e, 0x87, 0x08, 0xf7, 0x2c, 0xd9, 0x2e, 0x26, 0xff, 0x1a, 0x99, 0x56, + 0xce, 0x42, 0xac, 0x83, 0x6d, 0x8d, 0xea, 0x41, 0x66, 0xd5, 0x9c, 0xef, 0xb3, 0x97, 0x20, 0xe1, + 0xd9, 0x00, 0x26, 0xaa, 0xb1, 0x5a, 0x7e, 0x4e, 0x9e, 0xc9, 0x46, 0x5f, 0xbd, 0xbd, 0x14, 0xac, + 0xe2, 0x97, 0xc8, 0x6a, 0x56, 0xca, 0xc5, 0xb5, 0x72, 0xf1, 0x19, 0x59, 0xca, 0x26, 0x5e, 0xbd, + 0xbd, 0x14, 0x55, 0x30, 0xcd, 0x28, 0x9e, 0x7d, 0x06, 0xd2, 0x03, 0x13, 0xe3, 0x77, 0x5b, 0x10, + 0xa4, 0x4a, 0x5b, 0x9b, 0xeb, 0x95, 0x62, 0xbe, 0x51, 0x56, 0xd9, 0xb9, 0x5d, 0x74, 0x02, 0xe6, + 0xd7, 0x2b, 0x57, 0xd7, 0x1a, 0x6a, 0x71, 0xbd, 0x52, 0xae, 0x36, 0xd4, 0x7c, 0xa3, 0x91, 0x2f, + 0x3e, 0x23, 0x07, 0x56, 0x6e, 0x27, 0x20, 0x94, 0x2f, 0x14, 0x2b, 0xa8, 0x08, 0x21, 0x9a, 0x0a, + 0x39, 0xf4, 0x04, 0x58, 0xf6, 0xf0, 0xdc, 0x30, 0xba, 0x02, 0x61, 0x9a, 0x25, 0x41, 0x87, 0x1f, + 0x09, 0xcb, 0x4e, 0x48, 0x16, 0x93, 0xce, 0xd0, 0x15, 0x79, 0xe8, 0x19, 0xb1, 0xec, 0xe1, 0xb9, + 0x63, 0xb4, 0x0e, 0x51, 0x11, 0x24, 0x4f, 0x3a, 0xb8, 0x95, 0x9d, 0x98, 0xd0, 0x25, 0x43, 0x63, + 0xc9, 0x86, 0xc3, 0x8f, 0x8f, 0x65, 0x27, 0x64, 0x95, 0x51, 0xc5, 0xb9, 0xcf, 0x34, 0xe1, 0x44, + 0x58, 0x76, 0x52, 0x9e, 0x18, 0x29, 0x10, 0x77, 0xd3, 0x38, 0x93, 0x0f, 0xc5, 0x65, 0xa7, 0x48, + 0x98, 0xa3, 0xf7, 0xc2, 0xac, 0x3f, 0xd4, 0x9d, 0xee, 0xd4, 0x59, 0x76, 0xca, 0x8c, 0x34, 0xa1, + 0xef, 0x8f, 0x7b, 0xa7, 0x3b, 0x85, 0x96, 0x9d, 0x32, 0x41, 0x8d, 0x5e, 0x84, 0xb9, 0xe1, 0xb8, + 0x74, 0xfa, 0x43, 0x69, 0xd9, 0x23, 0xa4, 0xac, 0x51, 0x07, 0xd0, 0x88, 0x78, 0xf6, 0x08, 0x67, + 0xd4, 0xb2, 0x47, 0xc9, 0x60, 0xa3, 0x16, 0xa4, 0x07, 0x83, 0xc4, 0x69, 0xcf, 0xac, 0x65, 0xa7, + 0xce, 0x66, 0xb3, 0x56, 0xfc, 0xc1, 0xe5, 0xb4, 0x67, 0xd8, 0xb2, 0x53, 0x27, 0xb7, 0xd1, 0x16, + 0x80, 0x27, 0x3e, 0x9c, 0xe2, 0x4c, 0x5b, 0x76, 0x9a, 0x34, 0x37, 0xea, 0xc2, 0xfc, 0xa8, 0xc0, + 0xf1, 0x28, 0x47, 0xdc, 0xb2, 0x47, 0xca, 0x7e, 0x13, 0x79, 0xf6, 0x87, 0x80, 0xd3, 0x1d, 0x79, + 0xcb, 0x4e, 0x99, 0x06, 0x2f, 0xe4, 0xc7, 0x9e, 0x73, 0x7e, 0xe0, 0xd0, 0x73, 0xce, 0xee, 0xc9, + 0x65, 0xe7, 0x6c, 0xf3, 0xbf, 0x39, 0x07, 0xef, 0xe2, 0x2f, 0xe8, 0x58, 0xb6, 0x76, 0x53, 0x37, + 0x76, 0x9d, 0x67, 0x96, 0xf8, 0x37, 0x3f, 0xe4, 0x7c, 0x9c, 0xbf, 0xd2, 0x23, 0x4a, 0x27, 0x3c, + 0xb6, 0x34, 0xf6, 0x8d, 0xce, 0x49, 0xf7, 0x21, 0x26, 0x1f, 0x5f, 0x3e, 0xe4, 0x21, 0xa7, 0x09, + 0xcf, 0x45, 0x8d, 0x78, 0xe8, 0x29, 0x7b, 0xe8, 0x1b, 0x03, 0xd9, 0xc3, 0xce, 0x7d, 0x13, 0x2f, + 0x36, 0xb5, 0xa6, 0x5b, 0xb6, 0xd9, 0xd3, 0x9b, 0x5a, 0x9b, 0x9a, 0x97, 0xcb, 0xd3, 0xde, 0xca, + 0x2a, 0xc4, 0x89, 0xbb, 0xc2, 0xdf, 0x82, 0xe2, 0x37, 0x85, 0x4a, 0x10, 0xb9, 0xa5, 0xb5, 0xd9, + 0x9d, 0x28, 0xef, 0x63, 0x72, 0x83, 0x3c, 0xf7, 0xf8, 0x51, 0x5e, 0x2a, 0x0c, 0x37, 0xf7, 0xfd, + 0xf4, 0x3e, 0x49, 0xa7, 0xa3, 0x5b, 0x44, 0x16, 0x15, 0x1a, 0x4a, 0x5f, 0x83, 0x50, 0x4f, 0xb3, + 0x79, 0x80, 0x59, 0xb8, 0x78, 0xe4, 0x77, 0x99, 0x58, 0x0b, 0x94, 0x06, 0x7a, 0x16, 0x62, 0x1d, + 0x6d, 0x5f, 0xa5, 0xf4, 0x02, 0x5f, 0x13, 0xbd, 0x68, 0x47, 0xdb, 0x27, 0xfd, 0x43, 0xef, 0xa5, + 0x3f, 0xd0, 0xa8, 0x36, 0xf7, 0x34, 0x63, 0x17, 0x33, 0xca, 0xc1, 0xaf, 0x89, 0xf2, 0x6c, 0x47, + 0xdb, 0x2f, 0x52, 0x6a, 0x84, 0x3e, 0x7f, 0xf2, 0xea, 0xd7, 0x24, 0x9e, 0x35, 0xa0, 0x8c, 0x41, + 0x1a, 0xc8, 0x4d, 0xe7, 0x8b, 0x36, 0x2a, 0xb6, 0x38, 0x1e, 0x18, 0xc7, 0xf7, 0x01, 0xb6, 0x16, + 0x66, 0x49, 0xf7, 0x3e, 0xff, 0xfa, 0xa2, 0xc4, 0x5a, 0x4d, 0x37, 0x87, 0xd8, 0x9e, 0x60, 0xc9, + 0x10, 0x95, 0xfa, 0xb0, 0x81, 0x89, 0x3e, 0xec, 0xac, 0xf0, 0x61, 0x19, 0x41, 0x60, 0xd8, 0xa4, + 0x9e, 0x8f, 0xe1, 0x53, 0x12, 0x24, 0x4a, 0x9e, 0x87, 0x2f, 0x33, 0x10, 0xed, 0x98, 0x86, 0x7e, + 0x13, 0xf7, 0x9c, 0x3d, 0x2a, 0xf6, 0x49, 0xfc, 0x4c, 0xf6, 0x13, 0xd4, 0xf6, 0x81, 0x78, 0x5d, + 0x48, 0x7c, 0x13, 0xac, 0x97, 0xf0, 0xb6, 0xa5, 0x0b, 0x3e, 0x2b, 0xe2, 0x13, 0x3d, 0x08, 0xb2, + 0x85, 0x9b, 0xfd, 0x9e, 0x6e, 0x1f, 0xa8, 0x4d, 0xd3, 0xb0, 0xb5, 0xa6, 0xcd, 0xe3, 0xf0, 0xb4, + 0x28, 0x2f, 0xb2, 0x62, 0x42, 0xa4, 0x85, 0x6d, 0x4d, 0x6f, 0xb3, 0x93, 0x99, 0x71, 0x45, 0x7c, + 0xf2, 0xae, 0xbe, 0x1a, 0xf5, 0xc6, 0xa1, 0x45, 0x90, 0xcd, 0x2e, 0xee, 0xf9, 0x0e, 0xa4, 0x30, + 0x69, 0xcc, 0xfc, 0xf6, 0x67, 0x1f, 0x59, 0xe0, 0x0c, 0xe7, 0x87, 0x19, 0xd8, 0xef, 0x3c, 0x28, + 0x69, 0x81, 0x21, 0x4e, 0xaa, 0xdc, 0xf0, 0xed, 0x4a, 0xf5, 0xb7, 0xdd, 0x67, 0x64, 0x16, 0x86, + 0x98, 0x9a, 0x37, 0x0e, 0x0a, 0x99, 0xcf, 0xb9, 0xa4, 0xdd, 0x38, 0xf5, 0x19, 0x7c, 0xe0, 0xdd, + 0xa2, 0xa2, 0x64, 0x88, 0x0b, 0xff, 0xa2, 0xa6, 0xb7, 0x71, 0x8b, 0xa7, 0x35, 0xf8, 0x17, 0x5a, + 0x75, 0xd2, 0x8b, 0xec, 0x57, 0x47, 0x73, 0xe3, 0x64, 0xa3, 0x60, 0x1a, 0x2d, 0x7f, 0x1e, 0x11, + 0x15, 0x21, 0x62, 0x9b, 0x37, 0xb1, 0xc1, 0x19, 0x74, 0xb4, 0xa7, 0xd5, 0x38, 0x2a, 0xfa, 0x46, + 0x90, 0x5b, 0xb8, 0x8d, 0x77, 0xd9, 0x7d, 0xc9, 0x3d, 0xad, 0x87, 0xd9, 0x6d, 0xfd, 0x3b, 0x7a, + 0x5e, 0x2d, 0xed, 0x90, 0xaa, 0x53, 0x4a, 0x68, 0xd3, 0xff, 0xb4, 0x6a, 0x94, 0x6f, 0x1e, 0x8f, + 0x19, 0xa3, 0x47, 0xf2, 0xbc, 0x9a, 0xc7, 0xf7, 0x14, 0xeb, 0x83, 0x20, 0xf7, 0x8d, 0x6d, 0xd3, + 0xa0, 0x3f, 0xa1, 0xc9, 0xa3, 0xa8, 0x18, 0xdb, 0xa9, 0x74, 0xca, 0xf9, 0x4e, 0xe5, 0x26, 0xa4, + 0x5c, 0x50, 0xba, 0x42, 0xe2, 0x47, 0x5d, 0x21, 0xb3, 0x0e, 0x01, 0x02, 0x82, 0x36, 0x00, 0xdc, + 0x35, 0x48, 0xb7, 0xca, 0x12, 0xe3, 0x67, 0xcc, 0x5d, 0xcd, 0xde, 0xc1, 0x78, 0x08, 0xa0, 0x6f, + 0x80, 0xf9, 0x8e, 0x6e, 0xa8, 0x16, 0x6e, 0xef, 0xa8, 0x9c, 0x73, 0x84, 0x6e, 0xe2, 0xe8, 0xb3, + 0x39, 0xd7, 0xd1, 0x8d, 0x3a, 0x6e, 0xef, 0x94, 0x1c, 0x2a, 0xe8, 0xdd, 0x70, 0xca, 0x1d, 0xbd, + 0x69, 0xa8, 0x7b, 0x66, 0xbb, 0xa5, 0xf6, 0xf0, 0x8e, 0xda, 0xa4, 0xef, 0xfc, 0x25, 0x29, 0xcf, + 0x4e, 0x38, 0x20, 0x35, 0x63, 0xcd, 0x6c, 0xb7, 0x14, 0xbc, 0x53, 0x24, 0xd5, 0xe8, 0x5e, 0x70, + 0x87, 0xae, 0xea, 0x2d, 0x2b, 0x33, 0xbb, 0x14, 0x3c, 0x13, 0x52, 0x92, 0x4e, 0x61, 0xa5, 0x65, + 0xad, 0xc6, 0x3e, 0xf8, 0x89, 0xc5, 0x99, 0x37, 0x3f, 0xb1, 0x38, 0x93, 0xbb, 0x42, 0xdf, 0x94, + 0xe2, 0xeb, 0x08, 0x5b, 0xe8, 0x22, 0xc4, 0x35, 0xf1, 0xc1, 0x6e, 0x8c, 0x1d, 0xb2, 0x0e, 0x5d, + 0xd0, 0xdc, 0x4f, 0x4a, 0x10, 0x29, 0x5d, 0xdf, 0xd4, 0xf4, 0x1e, 0x2a, 0xc3, 0x9c, 0x2b, 0x98, + 0xd3, 0x2e, 0x69, 0x57, 0x96, 0xc5, 0x9a, 0xae, 0x8e, 0x3b, 0xaa, 0x16, 0x2f, 0xdc, 0xf3, 0xdb, + 0x9f, 0x7d, 0xe4, 0x6e, 0x4e, 0xe6, 0xfa, 0xc0, 0xa9, 0x35, 0x41, 0x6f, 0xf0, 0x34, 0x9b, 0x67, + 0xcc, 0xd7, 0x20, 0xca, 0xba, 0x6a, 0xa1, 0xa7, 0x21, 0xdc, 0x25, 0x7f, 0xf0, 0x0c, 0xfc, 0xe9, + 0xb1, 0x02, 0x4e, 0xe1, 0xbd, 0xe2, 0xc0, 0xf0, 0x72, 0x1f, 0x0a, 0x00, 0x94, 0xae, 0x5f, 0x6f, + 0xf4, 0xf4, 0x6e, 0x1b, 0xdb, 0x6f, 0xd7, 0xd8, 0xb7, 0xe0, 0x98, 0xe7, 0x2e, 0x74, 0xaf, 0x79, + 0xf4, 0xf1, 0xcf, 0xbb, 0xd7, 0xa2, 0x7b, 0xcd, 0x91, 0x64, 0x5b, 0x96, 0xed, 0x90, 0x0d, 0x1e, + 0x9d, 0x6c, 0xc9, 0xb2, 0x87, 0x39, 0xfb, 0x3c, 0x24, 0x5c, 0x66, 0x58, 0xa8, 0x02, 0x31, 0x9b, + 0xff, 0xcd, 0x19, 0x9c, 0x1b, 0xcf, 0x60, 0x81, 0xe6, 0x65, 0xb2, 0x83, 0x9e, 0xfb, 0x2b, 0x09, + 0xc0, 0xb3, 0x46, 0xde, 0x99, 0x32, 0x46, 0xc2, 0x75, 0xae, 0x89, 0x83, 0x77, 0xfc, 0x1a, 0x27, + 0x23, 0xe0, 0x61, 0xea, 0x87, 0x03, 0x30, 0xbf, 0x25, 0x56, 0xef, 0x3b, 0x9f, 0x07, 0x5b, 0x10, + 0xc5, 0x86, 0xdd, 0xd3, 0x9d, 0x3d, 0xa4, 0x47, 0xc7, 0xcd, 0xf9, 0x88, 0x41, 0x95, 0x0d, 0xbb, + 0x77, 0xe0, 0x95, 0x00, 0x41, 0xcb, 0xc3, 0x8f, 0x8f, 0x06, 0x21, 0x33, 0x0e, 0x15, 0x3d, 0x00, + 0xe9, 0x66, 0x0f, 0xd3, 0x02, 0xff, 0x15, 0xd1, 0x94, 0x28, 0xe6, 0x36, 0x46, 0x01, 0xe2, 0x95, + 0x11, 0xe1, 0x22, 0xa0, 0x77, 0xe6, 0x86, 0xa5, 0x5c, 0x0a, 0xd4, 0xca, 0x34, 0x20, 0x2d, 0xee, + 0x9c, 0x6c, 0x6b, 0x6d, 0xcd, 0x68, 0x0a, 0x77, 0xf5, 0x48, 0x26, 0x41, 0xdc, 0x5b, 0x29, 0x30, + 0x12, 0xa8, 0x0c, 0x51, 0x41, 0x2d, 0x74, 0x74, 0x6a, 0x02, 0x17, 0xdd, 0x03, 0x49, 0xaf, 0x61, + 0xa0, 0xae, 0x47, 0x48, 0x49, 0x78, 0xec, 0xc2, 0x24, 0xcb, 0x13, 0x39, 0xd4, 0xf2, 0x70, 0xef, + 0xee, 0x87, 0xe9, 0xd1, 0xf0, 0xd6, 0xdf, 0xfc, 0x69, 0xd9, 0x04, 0x60, 0x4b, 0x95, 0x68, 0x52, + 0x3e, 0x33, 0x77, 0xb0, 0xde, 0xe3, 0x8c, 0x48, 0xc9, 0xb2, 0xff, 0xba, 0x66, 0xe8, 0x77, 0x03, + 0x90, 0xf4, 0xce, 0xd0, 0xdf, 0x4a, 0xa3, 0x85, 0xaa, 0xae, 0x9a, 0x62, 0xd7, 0x67, 0x1e, 0x1c, + 0xa7, 0xa6, 0x86, 0xa4, 0x79, 0x82, 0x7e, 0xfa, 0x58, 0x10, 0x22, 0xfc, 0x7c, 0x5b, 0x6d, 0xc8, + 0x91, 0x95, 0x26, 0x3d, 0x00, 0x30, 0x2b, 0x1e, 0x00, 0x18, 0xe9, 0xc7, 0xde, 0x07, 0x29, 0x12, + 0x10, 0xfb, 0x0e, 0xcd, 0x49, 0x67, 0x66, 0x69, 0x5c, 0xeb, 0x1e, 0x11, 0x47, 0x8b, 0x90, 0x20, + 0x60, 0xae, 0x1e, 0x26, 0x30, 0xd0, 0xd1, 0xf6, 0xcb, 0xac, 0x04, 0x3d, 0x02, 0x68, 0xcf, 0x49, + 0x50, 0xa8, 0x2e, 0x23, 0x08, 0xdc, 0x9c, 0x5b, 0x23, 0xc0, 0xef, 0x06, 0x20, 0xbd, 0x50, 0xd9, + 0x03, 0xd4, 0xfc, 0x79, 0x6f, 0x52, 0x52, 0xa2, 0x8f, 0x50, 0x7f, 0x40, 0x62, 0xfe, 0xf0, 0x40, + 0xd8, 0xcc, 0xc3, 0x91, 0xc6, 0x14, 0x8b, 0xe2, 0xcf, 0x5f, 0x5f, 0xcc, 0x1e, 0x68, 0x9d, 0xf6, + 0x6a, 0x6e, 0x04, 0x9d, 0xdc, 0xa8, 0x48, 0x9e, 0x38, 0xce, 0xfe, 0xb0, 0x7b, 0xf5, 0x5d, 0x44, + 0xbc, 0x5f, 0x7d, 0xe3, 0x67, 0xcf, 0x9e, 0xf2, 0xbc, 0xf9, 0xbc, 0xef, 0xa4, 0xaf, 0xd8, 0x9c, + 0x10, 0x4f, 0x15, 0xb9, 0x56, 0xc3, 0x39, 0x19, 0xbf, 0x01, 0xe0, 0xf1, 0xe4, 0xa5, 0xc3, 0x23, + 0x04, 0x17, 0xdf, 0x17, 0x21, 0x78, 0xd6, 0xd4, 0x7b, 0x5c, 0xa5, 0x2d, 0xde, 0x7c, 0x18, 0xf1, + 0x22, 0xf9, 0x72, 0xd1, 0xd4, 0x7d, 0x24, 0x04, 0x12, 0x5d, 0xaa, 0x33, 0xb9, 0x7f, 0x25, 0xc1, + 0xc9, 0x21, 0xf1, 0x73, 0xba, 0xdc, 0x04, 0xd4, 0xf3, 0x54, 0xd2, 0x69, 0x14, 0x5b, 0xb1, 0x77, + 0x26, 0xcd, 0x73, 0xbd, 0x21, 0xcd, 0xfd, 0xf6, 0x58, 0x1f, 0xae, 0x7a, 0x7e, 0x43, 0x82, 0x05, + 0x6f, 0x07, 0x9c, 0xa1, 0xd4, 0x21, 0xe9, 0x6d, 0x9a, 0x0f, 0xe2, 0x5d, 0xd3, 0x0c, 0xc2, 0xdb, + 0x7f, 0x1f, 0x11, 0x74, 0xdd, 0x5d, 0xe2, 0x2c, 0x6f, 0x76, 0x7e, 0x6a, 0xa6, 0x88, 0x8e, 0x8d, + 0x5c, 0xea, 0x6c, 0x6e, 0xfe, 0x48, 0x82, 0xd0, 0xa6, 0x69, 0xb6, 0xd1, 0xfb, 0x60, 0xce, 0x30, + 0x6d, 0x95, 0x2c, 0x07, 0xdc, 0x52, 0x79, 0x60, 0xcf, 0xd4, 0x67, 0xf9, 0x50, 0x5e, 0x7d, 0xe9, + 0xf5, 0xc5, 0x61, 0xcc, 0x51, 0x6f, 0xc2, 0xa7, 0x0d, 0xd3, 0x2e, 0x50, 0xa0, 0x06, 0x8b, 0xfd, + 0x77, 0x60, 0xd6, 0xdf, 0x1c, 0x53, 0xb1, 0xf9, 0x49, 0xcd, 0xcd, 0x4e, 0x6c, 0x2a, 0xb9, 0xed, + 0x69, 0x87, 0x3d, 0xa3, 0xfc, 0xa7, 0x64, 0xe6, 0x6e, 0x80, 0x7c, 0x7d, 0xf0, 0x88, 0x4f, 0x19, + 0xa2, 0xe2, 0x48, 0x8f, 0x34, 0xe5, 0x69, 0x21, 0x2f, 0x3b, 0x39, 0xee, 0xd9, 0x9f, 0x97, 0x00, + 0xdc, 0x24, 0x09, 0x7a, 0x18, 0x4e, 0x14, 0x6a, 0xd5, 0x92, 0x5a, 0x6f, 0xe4, 0x1b, 0x5b, 0x75, + 0xff, 0x6f, 0xad, 0x88, 0xf7, 0x87, 0xac, 0x2e, 0x6e, 0xea, 0x3b, 0x3a, 0x6e, 0xa1, 0xfb, 0x61, + 0xc1, 0x0f, 0x4d, 0xbe, 0xca, 0x25, 0x59, 0xca, 0x26, 0x5f, 0xbd, 0xbd, 0x14, 0x63, 0x7e, 0x22, + 0x6e, 0xa1, 0x33, 0x70, 0x6c, 0x18, 0xae, 0x52, 0xbd, 0x2a, 0x07, 0xb2, 0xb3, 0xaf, 0xde, 0x5e, + 0x8a, 0x3b, 0x0e, 0x25, 0xca, 0x01, 0xf2, 0x42, 0x72, 0x7a, 0xc1, 0x2c, 0xbc, 0x7a, 0x7b, 0x29, + 0xc2, 0x66, 0x21, 0x1b, 0xfa, 0xe0, 0x8f, 0x9e, 0x9e, 0x39, 0xfb, 0x4d, 0x00, 0x15, 0x63, 0xa7, + 0xa7, 0x35, 0xa9, 0xb4, 0x65, 0xe1, 0x78, 0xa5, 0x7a, 0x45, 0xc9, 0x17, 0x1b, 0x95, 0x5a, 0x75, + 0xe0, 0x27, 0x62, 0xfc, 0x75, 0xa5, 0xda, 0x56, 0x61, 0xbd, 0xac, 0xd6, 0x2b, 0x57, 0xab, 0x6c, + 0xb3, 0xd5, 0x57, 0xf7, 0x5c, 0xb5, 0x51, 0xd9, 0x28, 0xcb, 0x81, 0xc2, 0x95, 0xb1, 0xc9, 0xfc, + 0x87, 0x0f, 0x7d, 0xe5, 0xde, 0xd5, 0x78, 0xbe, 0x8c, 0xfe, 0xff, 0x0c, 0x00, 0x00, 0xff, 0xff, + 0x29, 0x2b, 0x22, 0x54, 0x7c, 0xb2, 0x00, 0x00, } r := bytes.NewReader(gzipped) gzipr, err := compress_gzip.NewReader(r) diff --git a/x/tx/go.mod b/x/tx/go.mod index c104c4fcd02e..8e31e857446f 100644 --- a/x/tx/go.mod +++ b/x/tx/go.mod @@ -28,12 +28,14 @@ require ( golang.org/x/net v0.35.0 // indirect golang.org/x/sys v0.30.0 // indirect golang.org/x/text v0.22.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b // indirect google.golang.org/grpc v1.70.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) +replace cosmossdk.io/api => ../../api + // NOTE: we do not want to replace to the development version of cosmossdk.io/api yet // Until https://github.com/cosmos/cosmos-sdk/issues/19228 is resolved // We are tagging x/tx v0.14+ from main and v0.13 from release/v0.50.x and must keep using released versions of x/tx dependencies diff --git a/x/tx/go.sum b/x/tx/go.sum index 75d3419bb4ba..698e0a09bcd4 100644 --- a/x/tx/go.sum +++ b/x/tx/go.sum @@ -1,5 +1,3 @@ -cosmossdk.io/api v0.7.4 h1:sPo8wKwCty1lht8kgL3J7YL1voJywP3YWuA5JKkBz30= -cosmossdk.io/api v0.7.4/go.mod h1:IcxpYS5fMemZGqyYtErK7OqvdM0C8kdW3dq8Q/XIG38= cosmossdk.io/core v0.11.0 h1:vtIafqUi+1ZNAE/oxLOQQ7Oek2n4S48SWLG8h/+wdbo= cosmossdk.io/core v0.11.0/go.mod h1:LaTtayWBSoacF5xNzoF8tmLhehqlA9z1SWiPuNC6X1w= cosmossdk.io/errors v1.0.1 h1:bzu+Kcr0kS/1DuPBtUFdWjzLqyUuCiyHjyJB6srBV/0= @@ -73,10 +71,10 @@ golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a h1:OAiGFfOiA0v9MRYsSidp3ubZaBnteRUyn3xB2ZQ5G/E= -google.golang.org/genproto/googleapis/api v0.0.0-20241202173237-19429a94021a/go.mod h1:jehYqy3+AhJU9ve55aNOaSml7wUXjF9x6z2LcCfpAhY= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a h1:hgh8P4EuoxpsuKMXX/To36nOFD7vixReXgn8lPGnt+o= -google.golang.org/genproto/googleapis/rpc v0.0.0-20241202173237-19429a94021a/go.mod h1:5uTbfoYQed2U9p3KIj2/Zzm02PYhndfdmML0qC3q3FU= +google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b h1:i+d0RZa8Hs2L/MuaOQYI+krthcxdEbEM2N+Tf3kJ4zk= +google.golang.org/genproto/googleapis/api v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:iYONQfRdizDB8JJBybql13nArx91jcUk7zCXEsOofM4= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b h1:FQtJ1MxbXoIIrZHZ33M+w5+dAP9o86rgpjoKr/ZmT7k= +google.golang.org/genproto/googleapis/rpc v0.0.0-20250212204824-5a70512c5d8b/go.mod h1:8BS3B93F/U1juMFq9+EDk+qOT5CO1R9IzXxG3PTqiRk= google.golang.org/grpc v1.70.0 h1:pWFv03aZoHzlRKHWicjsZytKAiYCtNS0dHbXnIdq7jQ= google.golang.org/grpc v1.70.0/go.mod h1:ofIJqVKDXx/JiXrwr2IG4/zwdH9txy3IlF40RmcJSQw= google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= diff --git a/x/tx/signing/textual/any_test.go b/x/tx/signing/textual/any_test.go index da64acf0df79..0bcce5988151 100644 --- a/x/tx/signing/textual/any_test.go +++ b/x/tx/signing/textual/any_test.go @@ -88,7 +88,6 @@ func TestDynamicpb(t *testing.T) { } for _, tc := range testcases { - tc := tc t.Run(tc.name, func(t *testing.T) { any, err := anyutil.New(tc.msg) require.NoError(t, err) diff --git a/x/tx/signing/textual/dec_test.go b/x/tx/signing/textual/dec_test.go index f8c7b3ebe2f4..152e2b71619e 100644 --- a/x/tx/signing/textual/dec_test.go +++ b/x/tx/signing/textual/dec_test.go @@ -27,7 +27,6 @@ func TestDecJSONTestcases(t *testing.T) { require.NoError(t, err) for _, tc := range testcases { - tc := tc t.Run(tc[0], func(t *testing.T) { r, err := textual.GetFieldValueRenderer(fieldDescriptorFromName("SDKDEC")) require.NoError(t, err) diff --git a/x/tx/signing/textual/handler_test.go b/x/tx/signing/textual/handler_test.go index 70c2ea124a9f..13e15b981845 100644 --- a/x/tx/signing/textual/handler_test.go +++ b/x/tx/signing/textual/handler_test.go @@ -32,7 +32,6 @@ func TestDispatcher(t *testing.T) { } for _, tc := range testcases { - tc := tc t.Run(tc.name, func(t *testing.T) { textual, err := textual.NewSignModeHandler(textual.SignModeOptions{CoinMetadataQuerier: EmptyCoinMetadataQuerier}) require.NoError(t, err) diff --git a/x/tx/signing/textual/internal/testdata/tx.json b/x/tx/signing/textual/internal/testdata/tx.json index bbafe3b14120..98bb9db58f32 100644 --- a/x/tx/signing/textual/internal/testdata/tx.json +++ b/x/tx/signing/textual/internal/testdata/tx.json @@ -232,6 +232,8 @@ ], "memo": "> ⚛️\\u269B⚛️ ", "timeout_height": 20, + "unordered": true, + "timeout_timestamp": "2042-01-01T00:00:20Z", "extension_options": [ { "@type": "/cosmos.base.v1beta1.Coin", @@ -385,7 +387,9 @@ { "title": "Non critical extension options (1/1)", "content": "/cosmos.auth.v1beta1.Params", "indent": 1, "expert": true }, { "title": "Max memo characters", "content": "10", "indent": 2, "expert": true }, { "content": "End of Non critical extension options", "expert": true }, - { "title": "Hash of raw bytes", "content": "e7be7808de4985bd609811d2a32805cb233c168c7d247d61d37f4a6dd4cf3a2a", "expert": true } + { "title": "Hash of raw bytes", "content": "9c8e99e281e501bb8778b0361dd574c764e54d96ba354a8abc9ccd2ea18e3e06", "expert": true }, + { "title": "Unordered", "content": "True", "expert": true }, + {"title": "Timeout timestamp", "content": "2042-01-01T00:00:20Z", "expert": true} ] } ] diff --git a/x/tx/signing/textual/internal/textualpb/buf.lock b/x/tx/signing/textual/internal/textualpb/buf.lock index 259bd9ce82b1..ca09fbb4fad6 100644 --- a/x/tx/signing/textual/internal/textualpb/buf.lock +++ b/x/tx/signing/textual/internal/textualpb/buf.lock @@ -4,8 +4,30 @@ deps: - remote: buf.build owner: cosmos repository: cosmos-proto - commit: 1935555c206d4afb9e94615dfd0fad31 + commit: 04467658e59e44bbb22fe568206e1f70 + digest: shake256:73a640bd60e0c523b0f8237ff34eab67c45a38b64bbbde1d80224819d272dbf316ac183526bd245f994af6608b025f5130483d0133c5edd385531326b5990466 + - remote: buf.build + owner: cosmos + repository: cosmos-sdk + commit: 05419252bcc241ea8023acf1ed4cadc5 + digest: shake256:1e54a48c19a8b59d35e0a7efa76402939f515f2d8005df099856f24c37c20a52800308f025abb8cffcd014d437b49707388aaca4865d9d063d8f25d5d4eb77d5 - remote: buf.build owner: cosmos repository: gogo-proto - commit: 6652e3443c3b4504bb3bf82e73a7e409 + commit: 88ef6483f90f478fb938c37dde52ece3 + digest: shake256:89c45df2aa11e0cff97b0d695436713db3d993d76792e9f8dc1ae90e6ab9a9bec55503d48ceedd6b86069ab07d3041b32001b2bfe0227fa725dd515ff381e5ba + - remote: buf.build + owner: googleapis + repository: googleapis + commit: 7e6f6e774e29406da95bd61cdcdbc8bc + digest: shake256:fe43dd2265ea0c07d76bd925eeba612667cf4c948d2ce53d6e367e1b4b3cb5fa69a51e6acb1a6a50d32f894f054a35e6c0406f6808a483f2752e10c866ffbf73 + - remote: buf.build + owner: protocolbuffers + repository: wellknowntypes + commit: 657250e6a39648cbb169d079a60bd9ba + digest: shake256:00de25001b8dd2e29d85fc4bcc3ede7aed886d76d67f5e0f7a9b320b90f871d3eb73507d50818d823a0512f3f8db77a11c043685528403e31ff3fef18323a9fb + - remote: buf.build + owner: tendermint + repository: tendermint + commit: 33ed361a90514289beabf3189e1d7665 + digest: shake256:038267e06294714fd883610626554b04a127b576b4e253befb4206cb72d5d3c1eeccacd4b9ec8e3fb891f7c14e1cb0f770c077d2989638995b0a61c85afedb1d diff --git a/x/tx/signing/textual/internal/textualpb/buf.yaml b/x/tx/signing/textual/internal/textualpb/buf.yaml index 5aee45ac2b4f..9e1bb8366908 100644 --- a/x/tx/signing/textual/internal/textualpb/buf.yaml +++ b/x/tx/signing/textual/internal/textualpb/buf.yaml @@ -1,7 +1,9 @@ version: v1 deps: + - buf.build/cosmos/cosmos-sdk - buf.build/cosmos/cosmos-proto - buf.build/cosmos/gogo-proto + - buf.build/protocolbuffers/wellknowntypes:v23.4 lint: use: - DEFAULT diff --git a/x/tx/signing/textual/internal/textualpb/textual.proto b/x/tx/signing/textual/internal/textualpb/textual.proto index cddfc99d6e6b..0f9273472932 100644 --- a/x/tx/signing/textual/internal/textualpb/textual.proto +++ b/x/tx/signing/textual/internal/textualpb/textual.proto @@ -4,6 +4,7 @@ import "cosmos/base/v1beta1/coin.proto"; import "cosmos/tx/v1beta1/tx.proto"; import "cosmos_proto/cosmos.proto"; import "google/protobuf/any.proto"; +import "google/protobuf/timestamp.proto"; // TextualData represents all the information needed to generate // the textual SignDoc (which is []Screen encoded to CBOR). It is meant to be @@ -83,4 +84,6 @@ message Envelope { repeated google.protobuf.Any extension_options = 16; repeated google.protobuf.Any non_critical_extension_options = 17; string hash_of_raw_bytes = 18; + bool unordered = 19; + google.protobuf.Timestamp timeout_timestamp = 20; } diff --git a/x/tx/signing/textual/internal/textualpb/textual.pulsar.go b/x/tx/signing/textual/internal/textualpb/textual.pulsar.go index 14b94260756f..050fd821a6cd 100644 --- a/x/tx/signing/textual/internal/textualpb/textual.pulsar.go +++ b/x/tx/signing/textual/internal/textualpb/textual.pulsar.go @@ -11,6 +11,7 @@ import ( protoiface "google.golang.org/protobuf/runtime/protoiface" protoimpl "google.golang.org/protobuf/runtime/protoimpl" anypb "google.golang.org/protobuf/types/known/anypb" + timestamppb "google.golang.org/protobuf/types/known/timestamppb" io "io" reflect "reflect" sync "sync" @@ -1344,57 +1345,6 @@ func (x *_Envelope_8_list) IsValid() bool { return x.list != nil } -var _ protoreflect.List = (*_Envelope_11_list)(nil) - -type _Envelope_11_list struct { - list *[]*v1beta1.Coin -} - -func (x *_Envelope_11_list) Len() int { - if x.list == nil { - return 0 - } - return len(*x.list) -} - -func (x *_Envelope_11_list) Get(i int) protoreflect.Value { - return protoreflect.ValueOfMessage((*x.list)[i].ProtoReflect()) -} - -func (x *_Envelope_11_list) Set(i int, value protoreflect.Value) { - valueUnwrapped := value.Message() - concreteValue := valueUnwrapped.Interface().(*v1beta1.Coin) - (*x.list)[i] = concreteValue -} - -func (x *_Envelope_11_list) Append(value protoreflect.Value) { - valueUnwrapped := value.Message() - concreteValue := valueUnwrapped.Interface().(*v1beta1.Coin) - *x.list = append(*x.list, concreteValue) -} - -func (x *_Envelope_11_list) AppendMutable() protoreflect.Value { - v := new(v1beta1.Coin) - *x.list = append(*x.list, v) - return protoreflect.ValueOfMessage(v.ProtoReflect()) -} - -func (x *_Envelope_11_list) Truncate(n int) { - for i := n; i < len(*x.list); i++ { - (*x.list)[i] = nil - } - *x.list = (*x.list)[:n] -} - -func (x *_Envelope_11_list) NewElement() protoreflect.Value { - v := new(v1beta1.Coin) - return protoreflect.ValueOfMessage(v.ProtoReflect()) -} - -func (x *_Envelope_11_list) IsValid() bool { - return x.list != nil -} - var _ protoreflect.List = (*_Envelope_15_list)(nil) type _Envelope_15_list struct { @@ -1560,14 +1510,14 @@ var ( fd_Envelope_fees protoreflect.FieldDescriptor fd_Envelope_fee_payer protoreflect.FieldDescriptor fd_Envelope_fee_granter protoreflect.FieldDescriptor - fd_Envelope_tip protoreflect.FieldDescriptor - fd_Envelope_tipper protoreflect.FieldDescriptor fd_Envelope_gas_limit protoreflect.FieldDescriptor fd_Envelope_timeout_height protoreflect.FieldDescriptor fd_Envelope_other_signer protoreflect.FieldDescriptor fd_Envelope_extension_options protoreflect.FieldDescriptor fd_Envelope_non_critical_extension_options protoreflect.FieldDescriptor fd_Envelope_hash_of_raw_bytes protoreflect.FieldDescriptor + fd_Envelope_unordered protoreflect.FieldDescriptor + fd_Envelope_timeout_timestamp protoreflect.FieldDescriptor ) func init() { @@ -1583,14 +1533,14 @@ func init() { fd_Envelope_fees = md_Envelope.Fields().ByName("fees") fd_Envelope_fee_payer = md_Envelope.Fields().ByName("fee_payer") fd_Envelope_fee_granter = md_Envelope.Fields().ByName("fee_granter") - fd_Envelope_tip = md_Envelope.Fields().ByName("tip") - fd_Envelope_tipper = md_Envelope.Fields().ByName("tipper") fd_Envelope_gas_limit = md_Envelope.Fields().ByName("gas_limit") fd_Envelope_timeout_height = md_Envelope.Fields().ByName("timeout_height") fd_Envelope_other_signer = md_Envelope.Fields().ByName("other_signer") fd_Envelope_extension_options = md_Envelope.Fields().ByName("extension_options") fd_Envelope_non_critical_extension_options = md_Envelope.Fields().ByName("non_critical_extension_options") fd_Envelope_hash_of_raw_bytes = md_Envelope.Fields().ByName("hash_of_raw_bytes") + fd_Envelope_unordered = md_Envelope.Fields().ByName("unordered") + fd_Envelope_timeout_timestamp = md_Envelope.Fields().ByName("timeout_timestamp") } var _ protoreflect.Message = (*fastReflection_Envelope)(nil) @@ -1718,18 +1668,6 @@ func (x *fastReflection_Envelope) Range(f func(protoreflect.FieldDescriptor, pro return } } - if len(x.Tip) != 0 { - value := protoreflect.ValueOfList(&_Envelope_11_list{list: &x.Tip}) - if !f(fd_Envelope_tip, value) { - return - } - } - if x.Tipper != "" { - value := protoreflect.ValueOfString(x.Tipper) - if !f(fd_Envelope_tipper, value) { - return - } - } if x.GasLimit != uint64(0) { value := protoreflect.ValueOfUint64(x.GasLimit) if !f(fd_Envelope_gas_limit, value) { @@ -1766,6 +1704,18 @@ func (x *fastReflection_Envelope) Range(f func(protoreflect.FieldDescriptor, pro return } } + if x.Unordered != false { + value := protoreflect.ValueOfBool(x.Unordered) + if !f(fd_Envelope_unordered, value) { + return + } + } + if x.TimeoutTimestamp != nil { + value := protoreflect.ValueOfMessage(x.TimeoutTimestamp.ProtoReflect()) + if !f(fd_Envelope_timeout_timestamp, value) { + return + } + } } // Has reports whether a field is populated. @@ -1801,10 +1751,6 @@ func (x *fastReflection_Envelope) Has(fd protoreflect.FieldDescriptor) bool { return x.FeePayer != "" case "Envelope.fee_granter": return x.FeeGranter != "" - case "Envelope.tip": - return len(x.Tip) != 0 - case "Envelope.tipper": - return x.Tipper != "" case "Envelope.gas_limit": return x.GasLimit != uint64(0) case "Envelope.timeout_height": @@ -1817,6 +1763,10 @@ func (x *fastReflection_Envelope) Has(fd protoreflect.FieldDescriptor) bool { return len(x.NonCriticalExtensionOptions) != 0 case "Envelope.hash_of_raw_bytes": return x.HashOfRawBytes != "" + case "Envelope.unordered": + return x.Unordered != false + case "Envelope.timeout_timestamp": + return x.TimeoutTimestamp != nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: Envelope")) @@ -1853,10 +1803,6 @@ func (x *fastReflection_Envelope) Clear(fd protoreflect.FieldDescriptor) { x.FeePayer = "" case "Envelope.fee_granter": x.FeeGranter = "" - case "Envelope.tip": - x.Tip = nil - case "Envelope.tipper": - x.Tipper = "" case "Envelope.gas_limit": x.GasLimit = uint64(0) case "Envelope.timeout_height": @@ -1869,6 +1815,10 @@ func (x *fastReflection_Envelope) Clear(fd protoreflect.FieldDescriptor) { x.NonCriticalExtensionOptions = nil case "Envelope.hash_of_raw_bytes": x.HashOfRawBytes = "" + case "Envelope.unordered": + x.Unordered = false + case "Envelope.timeout_timestamp": + x.TimeoutTimestamp = nil default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: Envelope")) @@ -1921,15 +1871,6 @@ func (x *fastReflection_Envelope) Get(descriptor protoreflect.FieldDescriptor) p case "Envelope.fee_granter": value := x.FeeGranter return protoreflect.ValueOfString(value) - case "Envelope.tip": - if len(x.Tip) == 0 { - return protoreflect.ValueOfList(&_Envelope_11_list{}) - } - listValue := &_Envelope_11_list{list: &x.Tip} - return protoreflect.ValueOfList(listValue) - case "Envelope.tipper": - value := x.Tipper - return protoreflect.ValueOfString(value) case "Envelope.gas_limit": value := x.GasLimit return protoreflect.ValueOfUint64(value) @@ -1957,6 +1898,12 @@ func (x *fastReflection_Envelope) Get(descriptor protoreflect.FieldDescriptor) p case "Envelope.hash_of_raw_bytes": value := x.HashOfRawBytes return protoreflect.ValueOfString(value) + case "Envelope.unordered": + value := x.Unordered + return protoreflect.ValueOfBool(value) + case "Envelope.timeout_timestamp": + value := x.TimeoutTimestamp + return protoreflect.ValueOfMessage(value.ProtoReflect()) default: if descriptor.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: Envelope")) @@ -2001,12 +1948,6 @@ func (x *fastReflection_Envelope) Set(fd protoreflect.FieldDescriptor, value pro x.FeePayer = value.Interface().(string) case "Envelope.fee_granter": x.FeeGranter = value.Interface().(string) - case "Envelope.tip": - lv := value.List() - clv := lv.(*_Envelope_11_list) - x.Tip = *clv.list - case "Envelope.tipper": - x.Tipper = value.Interface().(string) case "Envelope.gas_limit": x.GasLimit = value.Uint() case "Envelope.timeout_height": @@ -2025,6 +1966,10 @@ func (x *fastReflection_Envelope) Set(fd protoreflect.FieldDescriptor, value pro x.NonCriticalExtensionOptions = *clv.list case "Envelope.hash_of_raw_bytes": x.HashOfRawBytes = value.Interface().(string) + case "Envelope.unordered": + x.Unordered = value.Bool() + case "Envelope.timeout_timestamp": + x.TimeoutTimestamp = value.Message().Interface().(*timestamppb.Timestamp) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: Envelope")) @@ -2062,12 +2007,6 @@ func (x *fastReflection_Envelope) Mutable(fd protoreflect.FieldDescriptor) proto } value := &_Envelope_8_list{list: &x.Fees} return protoreflect.ValueOfList(value) - case "Envelope.tip": - if x.Tip == nil { - x.Tip = []*v1beta1.Coin{} - } - value := &_Envelope_11_list{list: &x.Tip} - return protoreflect.ValueOfList(value) case "Envelope.other_signer": if x.OtherSigner == nil { x.OtherSigner = []*v1beta11.SignerInfo{} @@ -2086,6 +2025,11 @@ func (x *fastReflection_Envelope) Mutable(fd protoreflect.FieldDescriptor) proto } value := &_Envelope_17_list{list: &x.NonCriticalExtensionOptions} return protoreflect.ValueOfList(value) + case "Envelope.timeout_timestamp": + if x.TimeoutTimestamp == nil { + x.TimeoutTimestamp = new(timestamppb.Timestamp) + } + return protoreflect.ValueOfMessage(x.TimeoutTimestamp.ProtoReflect()) case "Envelope.chain_id": panic(fmt.Errorf("field chain_id of message Envelope is not mutable")) case "Envelope.account_number": @@ -2100,14 +2044,14 @@ func (x *fastReflection_Envelope) Mutable(fd protoreflect.FieldDescriptor) proto panic(fmt.Errorf("field fee_payer of message Envelope is not mutable")) case "Envelope.fee_granter": panic(fmt.Errorf("field fee_granter of message Envelope is not mutable")) - case "Envelope.tipper": - panic(fmt.Errorf("field tipper of message Envelope is not mutable")) case "Envelope.gas_limit": panic(fmt.Errorf("field gas_limit of message Envelope is not mutable")) case "Envelope.timeout_height": panic(fmt.Errorf("field timeout_height of message Envelope is not mutable")) case "Envelope.hash_of_raw_bytes": panic(fmt.Errorf("field hash_of_raw_bytes of message Envelope is not mutable")) + case "Envelope.unordered": + panic(fmt.Errorf("field unordered of message Envelope is not mutable")) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: Envelope")) @@ -2144,11 +2088,6 @@ func (x *fastReflection_Envelope) NewField(fd protoreflect.FieldDescriptor) prot return protoreflect.ValueOfString("") case "Envelope.fee_granter": return protoreflect.ValueOfString("") - case "Envelope.tip": - list := []*v1beta1.Coin{} - return protoreflect.ValueOfList(&_Envelope_11_list{list: &list}) - case "Envelope.tipper": - return protoreflect.ValueOfString("") case "Envelope.gas_limit": return protoreflect.ValueOfUint64(uint64(0)) case "Envelope.timeout_height": @@ -2164,6 +2103,11 @@ func (x *fastReflection_Envelope) NewField(fd protoreflect.FieldDescriptor) prot return protoreflect.ValueOfList(&_Envelope_17_list{list: &list}) case "Envelope.hash_of_raw_bytes": return protoreflect.ValueOfString("") + case "Envelope.unordered": + return protoreflect.ValueOfBool(false) + case "Envelope.timeout_timestamp": + m := new(timestamppb.Timestamp) + return protoreflect.ValueOfMessage(m.ProtoReflect()) default: if fd.IsExtension() { panic(fmt.Errorf("proto3 declared messages do not support extensions: Envelope")) @@ -2275,16 +2219,6 @@ func (x *fastReflection_Envelope) ProtoMethods() *protoiface.Methods { if l > 0 { n += 1 + l + runtime.Sov(uint64(l)) } - if len(x.Tip) > 0 { - for _, e := range x.Tip { - l = options.Size(e) - n += 1 + l + runtime.Sov(uint64(l)) - } - } - l = len(x.Tipper) - if l > 0 { - n += 1 + l + runtime.Sov(uint64(l)) - } if x.GasLimit != 0 { n += 1 + runtime.Sov(uint64(x.GasLimit)) } @@ -2313,6 +2247,13 @@ func (x *fastReflection_Envelope) ProtoMethods() *protoiface.Methods { if l > 0 { n += 2 + l + runtime.Sov(uint64(l)) } + if x.Unordered { + n += 3 + } + if x.TimeoutTimestamp != nil { + l = options.Size(x.TimeoutTimestamp) + n += 2 + l + runtime.Sov(uint64(l)) + } if x.unknownFields != nil { n += len(x.unknownFields) } @@ -2342,6 +2283,34 @@ func (x *fastReflection_Envelope) ProtoMethods() *protoiface.Methods { i -= len(x.unknownFields) copy(dAtA[i:], x.unknownFields) } + if x.TimeoutTimestamp != nil { + encoded, err := options.Marshal(x.TimeoutTimestamp) + if err != nil { + return protoiface.MarshalOutput{ + NoUnkeyedLiterals: input.NoUnkeyedLiterals, + Buf: input.Buf, + }, err + } + i -= len(encoded) + copy(dAtA[i:], encoded) + i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0xa2 + } + if x.Unordered { + i-- + if x.Unordered { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x1 + i-- + dAtA[i] = 0x98 + } if len(x.HashOfRawBytes) > 0 { i -= len(x.HashOfRawBytes) copy(dAtA[i:], x.HashOfRawBytes) @@ -2413,29 +2382,6 @@ func (x *fastReflection_Envelope) ProtoMethods() *protoiface.Methods { i-- dAtA[i] = 0x68 } - if len(x.Tipper) > 0 { - i -= len(x.Tipper) - copy(dAtA[i:], x.Tipper) - i = runtime.EncodeVarint(dAtA, i, uint64(len(x.Tipper))) - i-- - dAtA[i] = 0x62 - } - if len(x.Tip) > 0 { - for iNdEx := len(x.Tip) - 1; iNdEx >= 0; iNdEx-- { - encoded, err := options.Marshal(x.Tip[iNdEx]) - if err != nil { - return protoiface.MarshalOutput{ - NoUnkeyedLiterals: input.NoUnkeyedLiterals, - Buf: input.Buf, - }, err - } - i -= len(encoded) - copy(dAtA[i:], encoded) - i = runtime.EncodeVarint(dAtA, i, uint64(len(encoded))) - i-- - dAtA[i] = 0x5a - } - } if len(x.FeeGranter) > 0 { i -= len(x.FeeGranter) copy(dAtA[i:], x.FeeGranter) @@ -2878,72 +2824,6 @@ func (x *fastReflection_Envelope) ProtoMethods() *protoiface.Methods { } x.FeeGranter = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex - case 11: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Tip", wireType) - } - var msglen int - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - msglen |= int(b&0x7F) << shift - if b < 0x80 { - break - } - } - if msglen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + msglen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Tip = append(x.Tip, &v1beta1.Coin{}) - if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.Tip[len(x.Tip)-1]); err != nil { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err - } - iNdEx = postIndex - case 12: - if wireType != 2 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Tipper", wireType) - } - var stringLen uint64 - for shift := uint(0); ; shift += 7 { - if shift >= 64 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow - } - if iNdEx >= l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - b := dAtA[iNdEx] - iNdEx++ - stringLen |= uint64(b&0x7F) << shift - if b < 0x80 { - break - } - } - intStringLen := int(stringLen) - if intStringLen < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - postIndex := iNdEx + intStringLen - if postIndex < 0 { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength - } - if postIndex > l { - return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF - } - x.Tipper = string(dAtA[iNdEx:postIndex]) - iNdEx = postIndex case 13: if wireType != 0 { return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field GasLimit", wireType) @@ -3116,6 +2996,62 @@ func (x *fastReflection_Envelope) ProtoMethods() *protoiface.Methods { } x.HashOfRawBytes = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 19: + if wireType != 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field Unordered", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + x.Unordered = bool(v != 0) + case 20: + if wireType != 2 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, fmt.Errorf("proto: wrong wireType = %d for field TimeoutTimestamp", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrIntOverflow + } + if iNdEx >= l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, runtime.ErrInvalidLength + } + if postIndex > l { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, io.ErrUnexpectedEOF + } + if x.TimeoutTimestamp == nil { + x.TimeoutTimestamp = ×tamppb.Timestamp{} + } + if err := options.Unmarshal(dAtA[iNdEx:postIndex], x.TimeoutTimestamp); err != nil { + return protoiface.UnmarshalOutput{NoUnkeyedLiterals: input.NoUnkeyedLiterals, Flags: input.Flags}, err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := runtime.Skip(dAtA[iNdEx:]) @@ -3165,7 +3101,7 @@ const ( ) // TextualData represents all the information needed to generate -// the textual SignDoc (which is []Screen encoded to XBOR). It is meant to be +// the textual SignDoc (which is []Screen encoded to CBOR). It is meant to be // used as an internal type in Textual's implementations. type TextualData struct { state protoimpl.MessageState @@ -3228,7 +3164,8 @@ func (x *TextualData) GetSignerData() *SignerData { // isn't included in the transaction body itself. // // It is the same struct as signing.SignerData, but only used internally -// in Textual because we need it as a proto.Message. +// in Textual because we need it as a proto.Message. If that struct is updated, +// then this proto SignerData also needs to be modified. type SignerData struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -3337,14 +3274,14 @@ type Envelope struct { Fees []*v1beta1.Coin `protobuf:"bytes,8,rep,name=fees,proto3" json:"fees,omitempty"` FeePayer string `protobuf:"bytes,9,opt,name=fee_payer,json=feePayer,proto3" json:"fee_payer,omitempty"` FeeGranter string `protobuf:"bytes,10,opt,name=fee_granter,json=feeGranter,proto3" json:"fee_granter,omitempty"` - Tip []*v1beta1.Coin `protobuf:"bytes,11,rep,name=tip,proto3" json:"tip,omitempty"` - Tipper string `protobuf:"bytes,12,opt,name=tipper,proto3" json:"tipper,omitempty"` GasLimit uint64 `protobuf:"varint,13,opt,name=gas_limit,json=gasLimit,proto3" json:"gas_limit,omitempty"` TimeoutHeight uint64 `protobuf:"varint,14,opt,name=timeout_height,json=timeoutHeight,proto3" json:"timeout_height,omitempty"` OtherSigner []*v1beta11.SignerInfo `protobuf:"bytes,15,rep,name=other_signer,json=otherSigner,proto3" json:"other_signer,omitempty"` ExtensionOptions []*anypb.Any `protobuf:"bytes,16,rep,name=extension_options,json=extensionOptions,proto3" json:"extension_options,omitempty"` NonCriticalExtensionOptions []*anypb.Any `protobuf:"bytes,17,rep,name=non_critical_extension_options,json=nonCriticalExtensionOptions,proto3" json:"non_critical_extension_options,omitempty"` HashOfRawBytes string `protobuf:"bytes,18,opt,name=hash_of_raw_bytes,json=hashOfRawBytes,proto3" json:"hash_of_raw_bytes,omitempty"` + Unordered bool `protobuf:"varint,19,opt,name=unordered,proto3" json:"unordered,omitempty"` + TimeoutTimestamp *timestamppb.Timestamp `protobuf:"bytes,20,opt,name=timeout_timestamp,json=timeoutTimestamp,proto3" json:"timeout_timestamp,omitempty"` } func (x *Envelope) Reset() { @@ -3437,20 +3374,6 @@ func (x *Envelope) GetFeeGranter() string { return "" } -func (x *Envelope) GetTip() []*v1beta1.Coin { - if x != nil { - return x.Tip - } - return nil -} - -func (x *Envelope) GetTipper() string { - if x != nil { - return x.Tipper - } - return "" -} - func (x *Envelope) GetGasLimit() uint64 { if x != nil { return x.GasLimit @@ -3493,6 +3416,20 @@ func (x *Envelope) GetHashOfRawBytes() string { return "" } +func (x *Envelope) GetUnordered() bool { + if x != nil { + return x.Unordered + } + return false +} + +func (x *Envelope) GetTimeoutTimestamp() *timestamppb.Timestamp { + if x != nil { + return x.TimeoutTimestamp + } + return nil +} + var File_textual_proto protoreflect.FileDescriptor var file_textual_proto_rawDesc = []byte{ @@ -3504,80 +3441,84 @@ var file_textual_proto_rawDesc = []byte{ 0x6d, 0x6f, 0x73, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x19, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x61, 0x6e, 0x79, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x22, 0x82, 0x01, 0x0a, 0x0b, 0x54, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x61, 0x74, - 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, 0x73, - 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62, 0x79, - 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, 0x49, - 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x0b, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, 0x2e, - 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x73, 0x69, 0x67, 0x6e, - 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc6, 0x01, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, 0x65, - 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0xd2, 0xb4, 0x2d, 0x0d, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, - 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75, - 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, - 0x12, 0x2d, 0x0a, 0x07, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, 0x22, - 0xfc, 0x05, 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, - 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, - 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, 0x6b, - 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x09, - 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x65, 0x73, - 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, - 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, 0x6d, - 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x12, 0x2d, 0x0a, - 0x04, 0x66, 0x65, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, - 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, - 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x04, 0x66, 0x65, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, - 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x66, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x65, 0x65, - 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, - 0x66, 0x65, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x2b, 0x0a, 0x03, 0x74, 0x69, - 0x70, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, - 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x43, 0x6f, - 0x69, 0x6e, 0x52, 0x03, 0x74, 0x69, 0x70, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x69, 0x70, 0x70, 0x65, - 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x74, 0x69, 0x70, 0x70, 0x65, 0x72, 0x12, - 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x25, 0x0a, 0x0e, - 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0e, - 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x48, 0x65, 0x69, - 0x67, 0x68, 0x74, 0x12, 0x40, 0x0a, 0x0c, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, - 0x6e, 0x65, 0x72, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, - 0x6f, 0x73, 0x2e, 0x74, 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, - 0x67, 0x6e, 0x65, 0x72, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, - 0x69, 0x67, 0x6e, 0x65, 0x72, 0x12, 0x41, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, - 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x59, 0x0a, 0x1e, 0x6e, 0x6f, 0x6e, 0x5f, - 0x63, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, - 0x6f, 0x6e, 0x5f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x1b, 0x6e, 0x6f, 0x6e, 0x43, 0x72, 0x69, 0x74, 0x69, - 0x63, 0x61, 0x6c, 0x45, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, - 0x6f, 0x6e, 0x73, 0x12, 0x29, 0x0a, 0x11, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6f, 0x66, 0x5f, 0x72, - 0x61, 0x77, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, - 0x68, 0x61, 0x73, 0x68, 0x4f, 0x66, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x42, 0x3c, - 0x42, 0x0c, 0x54, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, - 0x5a, 0x2a, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, 0x6f, 0x2f, 0x74, - 0x78, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, - 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x6f, 0x1a, 0x1f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x22, 0x82, 0x01, 0x0a, 0x0b, 0x54, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6f, 0x64, 0x79, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6f, 0x64, 0x79, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x26, 0x0a, 0x0f, 0x61, 0x75, 0x74, 0x68, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x61, 0x75, 0x74, 0x68, + 0x49, 0x6e, 0x66, 0x6f, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x0b, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0b, + 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x52, 0x0a, 0x73, 0x69, 0x67, + 0x6e, 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x22, 0xc6, 0x01, 0x0a, 0x0a, 0x53, 0x69, 0x67, 0x6e, + 0x65, 0x72, 0x44, 0x61, 0x74, 0x61, 0x12, 0x2b, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x11, 0xd2, 0xb4, 0x2d, 0x0d, 0x41, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, + 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, + 0x65, 0x12, 0x2d, 0x0a, 0x07, 0x70, 0x75, 0x62, 0x5f, 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, 0x06, 0x70, 0x75, 0x62, 0x4b, 0x65, 0x79, + 0x22, 0x9e, 0x06, 0x0a, 0x08, 0x45, 0x6e, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x12, 0x19, 0x0a, + 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x12, 0x25, 0x0a, 0x0e, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0d, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, + 0x1a, 0x0a, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x08, 0x73, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x61, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x33, 0x0a, 0x0a, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x5f, + 0x6b, 0x65, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, 0x79, 0x52, + 0x09, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x4b, 0x65, 0x79, 0x12, 0x2e, 0x0a, 0x07, 0x6d, 0x65, + 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, 0x6e, + 0x79, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x65, + 0x6d, 0x6f, 0x18, 0x07, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6d, 0x65, 0x6d, 0x6f, 0x12, 0x2d, + 0x0a, 0x04, 0x66, 0x65, 0x65, 0x73, 0x18, 0x08, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x63, + 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x62, 0x61, 0x73, 0x65, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, + 0x61, 0x31, 0x2e, 0x43, 0x6f, 0x69, 0x6e, 0x52, 0x04, 0x66, 0x65, 0x65, 0x73, 0x12, 0x1b, 0x0a, + 0x09, 0x66, 0x65, 0x65, 0x5f, 0x70, 0x61, 0x79, 0x65, 0x72, 0x18, 0x09, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x08, 0x66, 0x65, 0x65, 0x50, 0x61, 0x79, 0x65, 0x72, 0x12, 0x1f, 0x0a, 0x0b, 0x66, 0x65, + 0x65, 0x5f, 0x67, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x0a, 0x66, 0x65, 0x65, 0x47, 0x72, 0x61, 0x6e, 0x74, 0x65, 0x72, 0x12, 0x1b, 0x0a, 0x09, 0x67, + 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, + 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x25, 0x0a, 0x0e, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x5f, 0x68, 0x65, 0x69, 0x67, 0x68, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0d, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x48, 0x65, 0x69, 0x67, 0x68, 0x74, 0x12, + 0x40, 0x0a, 0x0c, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x5f, 0x73, 0x69, 0x67, 0x6e, 0x65, 0x72, 0x18, + 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x2e, 0x74, + 0x78, 0x2e, 0x76, 0x31, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x69, 0x67, 0x6e, 0x65, 0x72, + 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x0b, 0x6f, 0x74, 0x68, 0x65, 0x72, 0x53, 0x69, 0x67, 0x6e, 0x65, + 0x72, 0x12, 0x41, 0x0a, 0x11, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x10, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, + 0x6e, 0x79, 0x52, 0x10, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, + 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x59, 0x0a, 0x1e, 0x6e, 0x6f, 0x6e, 0x5f, 0x63, 0x72, 0x69, 0x74, + 0x69, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x5f, 0x6f, + 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x11, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x41, + 0x6e, 0x79, 0x52, 0x1b, 0x6e, 0x6f, 0x6e, 0x43, 0x72, 0x69, 0x74, 0x69, 0x63, 0x61, 0x6c, 0x45, + 0x78, 0x74, 0x65, 0x6e, 0x73, 0x69, 0x6f, 0x6e, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, + 0x29, 0x0a, 0x11, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6f, 0x66, 0x5f, 0x72, 0x61, 0x77, 0x5f, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x68, 0x61, 0x73, 0x68, + 0x4f, 0x66, 0x52, 0x61, 0x77, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x0a, 0x09, 0x75, 0x6e, + 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x08, 0x52, 0x09, 0x75, + 0x6e, 0x6f, 0x72, 0x64, 0x65, 0x72, 0x65, 0x64, 0x12, 0x47, 0x0a, 0x11, 0x74, 0x69, 0x6d, 0x65, + 0x6f, 0x75, 0x74, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x14, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x52, + 0x10, 0x74, 0x69, 0x6d, 0x65, 0x6f, 0x75, 0x74, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x42, 0x3e, 0x42, 0x0c, 0x54, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x50, 0x72, 0x6f, 0x74, + 0x6f, 0x50, 0x01, 0x5a, 0x2c, 0x63, 0x6f, 0x73, 0x6d, 0x6f, 0x73, 0x73, 0x64, 0x6b, 0x2e, 0x69, + 0x6f, 0x2f, 0x78, 0x2f, 0x74, 0x78, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x2f, 0x69, + 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x78, 0x74, 0x75, 0x61, 0x6c, 0x70, + 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -3594,12 +3535,13 @@ func file_textual_proto_rawDescGZIP() []byte { var file_textual_proto_msgTypes = make([]protoimpl.MessageInfo, 3) var file_textual_proto_goTypes = []interface{}{ - (*TextualData)(nil), // 0: TextualData - (*SignerData)(nil), // 1: SignerData - (*Envelope)(nil), // 2: Envelope - (*anypb.Any)(nil), // 3: google.protobuf.Any - (*v1beta1.Coin)(nil), // 4: cosmos.base.v1beta1.Coin - (*v1beta11.SignerInfo)(nil), // 5: cosmos.tx.v1beta1.SignerInfo + (*TextualData)(nil), // 0: TextualData + (*SignerData)(nil), // 1: SignerData + (*Envelope)(nil), // 2: Envelope + (*anypb.Any)(nil), // 3: google.protobuf.Any + (*v1beta1.Coin)(nil), // 4: cosmos.base.v1beta1.Coin + (*v1beta11.SignerInfo)(nil), // 5: cosmos.tx.v1beta1.SignerInfo + (*timestamppb.Timestamp)(nil), // 6: google.protobuf.Timestamp } var file_textual_proto_depIdxs = []int32{ 1, // 0: TextualData.signer_data:type_name -> SignerData @@ -3607,10 +3549,10 @@ var file_textual_proto_depIdxs = []int32{ 3, // 2: Envelope.public_key:type_name -> google.protobuf.Any 3, // 3: Envelope.message:type_name -> google.protobuf.Any 4, // 4: Envelope.fees:type_name -> cosmos.base.v1beta1.Coin - 4, // 5: Envelope.tip:type_name -> cosmos.base.v1beta1.Coin - 5, // 6: Envelope.other_signer:type_name -> cosmos.tx.v1beta1.SignerInfo - 3, // 7: Envelope.extension_options:type_name -> google.protobuf.Any - 3, // 8: Envelope.non_critical_extension_options:type_name -> google.protobuf.Any + 5, // 5: Envelope.other_signer:type_name -> cosmos.tx.v1beta1.SignerInfo + 3, // 6: Envelope.extension_options:type_name -> google.protobuf.Any + 3, // 7: Envelope.non_critical_extension_options:type_name -> google.protobuf.Any + 6, // 8: Envelope.timeout_timestamp:type_name -> google.protobuf.Timestamp 9, // [9:9] is the sub-list for method output_type 9, // [9:9] is the sub-list for method input_type 9, // [9:9] is the sub-list for extension type_name diff --git a/x/tx/signing/textual/tx.go b/x/tx/signing/textual/tx.go index 501189e3e5d6..f49012870df3 100644 --- a/x/tx/signing/textual/tx.go +++ b/x/tx/signing/textual/tx.go @@ -79,6 +79,8 @@ func (vr txValueRenderer) Format(ctx context.Context, v protoreflect.Value) ([]S FeeGranter: txAuthInfo.Fee.Granter, GasLimit: txAuthInfo.Fee.GasLimit, TimeoutHeight: txBody.TimeoutHeight, + TimeoutTimestamp: txBody.TimeoutTimestamp, + Unordered: txBody.Unordered, ExtensionOptions: txBody.ExtensionOptions, NonCriticalExtensionOptions: txBody.NonCriticalExtensionOptions, HashOfRawBytes: getHash(textualData.BodyBytes, textualData.AuthInfoBytes), @@ -125,6 +127,8 @@ func (vr txValueRenderer) Format(ctx context.Context, v protoreflect.Value) ([]S "Fee granter": {}, "Gas limit": {}, "Timeout height": {}, + "Timeout timestamp": {}, + "Unordered": {}, "Other signer": {}, "Extension options": {}, "Non critical extension options": {}, @@ -229,6 +233,8 @@ func (vr txValueRenderer) Parse(ctx context.Context, screens []Screen) (protoref Messages: envelope.Message, Memo: envelope.Memo, TimeoutHeight: envelope.TimeoutHeight, + TimeoutTimestamp: envelope.TimeoutTimestamp, + Unordered: envelope.Unordered, ExtensionOptions: envelope.ExtensionOptions, NonCriticalExtensionOptions: envelope.NonCriticalExtensionOptions, }