From f45245e8fc351ed0e77bbbf9ac83c03de9daef5f Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 6 Oct 2020 11:42:00 -0700 Subject: [PATCH 1/6] order+rpc: introduce MinUnitsMatch field --- auctioneer/client.go | 1 + order/interface.go | 18 +- order/rpc_parse.go | 14 ++ poolrpc/auctioneer.pb.go | 466 ++++++++++++++++++------------------ poolrpc/auctioneer.proto | 5 +- poolrpc/trader.pb.go | 385 ++++++++++++++--------------- poolrpc/trader.proto | 3 + poolrpc/trader.swagger.json | 5 + rpcserver.go | 1 + 9 files changed, 478 insertions(+), 420 deletions(-) diff --git a/auctioneer/client.go b/auctioneer/client.go index 5f6ed22..92915fd 100644 --- a/auctioneer/client.go +++ b/auctioneer/client.go @@ -352,6 +352,7 @@ func (c *Client) SubmitOrder(ctx context.Context, o order.Order, TraderKey: o.Details().AcctKey[:], RateFixed: o.Details().FixedRate, Amt: uint64(o.Details().Amt), + MinChanAmt: uint64(o.Details().MinUnitsMatch.ToSatoshis()), OrderNonce: nonce[:], OrderSig: serverParams.RawSig, MultiSigKey: serverParams.MultiSigKey[:], diff --git a/order/interface.go b/order/interface.go index bcaba98..abe43d5 100644 --- a/order/interface.go +++ b/order/interface.go @@ -279,6 +279,10 @@ type Kit struct { // LeaseDuration identifies how long this order wishes to acquire or // lease out capital in the Lightning Network for. LeaseDuration uint32 + + // MinUnitsMatch signals the minimum number of units that must be + // matched against an order. + MinUnitsMatch SupplyUnit } // Nonce is the unique identifier of each order and MUST be created by hashing a @@ -344,7 +348,7 @@ func (a *Ask) Digest() ([sha256.Size]byte, error) { result [sha256.Size]byte ) switch a.Kit.Version { - case VersionDefault, VersionNodeTierMinMatch: + case VersionDefault: err := lnwire.WriteElements( &msg, a.nonce[:], uint32(a.Version), a.FixedRate, a.Amt, a.LeaseDuration, uint64(a.MaxBatchFeeRate), @@ -353,6 +357,16 @@ func (a *Ask) Digest() ([sha256.Size]byte, error) { return result, err } + case VersionNodeTierMinMatch: + err := lnwire.WriteElements( + &msg, a.nonce[:], uint32(a.Version), a.FixedRate, + a.Amt, a.LeaseDuration, uint64(a.MaxBatchFeeRate), + uint32(a.MinUnitsMatch), + ) + if err != nil { + return result, err + } + default: return result, fmt.Errorf("unknown version %d", a.Kit.Version) } @@ -506,7 +520,7 @@ func (b *Bid) Digest() ([sha256.Size]byte, error) { err := lnwire.WriteElements( &msg, b.nonce[:], uint32(b.Version), b.FixedRate, b.Amt, b.LeaseDuration, uint64(b.MaxBatchFeeRate), - uint32(b.MinNodeTier), + uint32(b.MinNodeTier), uint32(b.MinUnitsMatch), ) if err != nil { return result, err diff --git a/order/rpc_parse.go b/order/rpc_parse.go index 46de5cd..e3a5b34 100644 --- a/order/rpc_parse.go +++ b/order/rpc_parse.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto/rand" "encoding/hex" + "errors" "fmt" "net" @@ -47,6 +48,19 @@ func ParseRPCOrder(version, leaseDuration uint32, kit.Units = NewSupplyFromSats(kit.Amt) kit.UnitsUnfulfilled = kit.Units kit.LeaseDuration = leaseDuration + + switch { + // If a min units match constraint was not provided, return an error. + case details.MinUnitsMatch == 0: + return nil, errors.New("min units match must be greater than 0") + + // The min units match must not exceed the total order units. + case details.MinUnitsMatch > uint32(kit.Units): + return nil, errors.New("min units match must not exceed " + + "total order units") + } + kit.MinUnitsMatch = SupplyUnit(details.MinUnitsMatch) + return kit, nil } diff --git a/poolrpc/auctioneer.pb.go b/poolrpc/auctioneer.pb.go index 2f92f5c..f167179 100644 --- a/poolrpc/auctioneer.pb.go +++ b/poolrpc/auctioneer.pb.go @@ -2364,7 +2364,8 @@ type ServerOrder struct { RateFixed uint32 `protobuf:"varint,2,opt,name=rate_fixed,json=rateFixed,proto3" json:"rate_fixed,omitempty"` // //Order amount in satoshis. - Amt uint64 `protobuf:"varint,3,opt,name=amt,proto3" json:"amt,omitempty"` + Amt uint64 `protobuf:"varint,3,opt,name=amt,proto3" json:"amt,omitempty"` + MinChanAmt uint64 `protobuf:"varint,4,opt,name=min_chan_amt,json=minChanAmt,proto3" json:"min_chan_amt,omitempty"` // //Order nonce of 32 byte length, acts as unique order identifier. OrderNonce []byte `protobuf:"bytes,6,opt,name=order_nonce,json=orderNonce,proto3" json:"order_nonce,omitempty"` @@ -2442,6 +2443,13 @@ func (m *ServerOrder) GetAmt() uint64 { return 0 } +func (m *ServerOrder) GetMinChanAmt() uint64 { + if m != nil { + return m.MinChanAmt + } + return 0 +} + func (m *ServerOrder) GetOrderNonce() []byte { if m != nil { return m.OrderNonce @@ -4029,234 +4037,234 @@ func init() { func init() { proto.RegisterFile("auctioneer.proto", fileDescriptor_f3883418d94ca37f) } var fileDescriptor_f3883418d94ca37f = []byte{ - // 3620 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3a, 0xcb, 0x72, 0xdb, 0x58, - 0x76, 0xe2, 0x43, 0x22, 0x79, 0xf8, 0x10, 0x74, 0x25, 0xd9, 0x14, 0x6d, 0xb9, 0x6d, 0xf4, 0x23, - 0x6e, 0x75, 0x5b, 0x6e, 0xcb, 0xdd, 0x4e, 0x3f, 0x9c, 0x4e, 0x81, 0x24, 0xd4, 0xa4, 0x4d, 0x91, - 0x6c, 0x80, 0xb4, 0xdb, 0x5d, 0x95, 0x42, 0x81, 0xe4, 0x15, 0x85, 0x88, 0x04, 0x18, 0x00, 0xb4, - 0xa5, 0x2c, 0x7a, 0x91, 0x5d, 0x3e, 0x20, 0x95, 0x45, 0xaa, 0x17, 0xa9, 0xca, 0x3e, 0xa9, 0x64, - 0x93, 0x65, 0x2a, 0x8b, 0x59, 0xce, 0x27, 0xcc, 0xa3, 0x6a, 0x7e, 0x62, 0xaa, 0x66, 0x31, 0x75, - 0x1f, 0x00, 0x01, 0x10, 0x94, 0x3c, 0x3d, 0x33, 0x55, 0xb3, 0x91, 0x80, 0x73, 0xcf, 0xb9, 0xf7, - 0x9c, 0x73, 0xcf, 0x1b, 0x04, 0x41, 0x9f, 0x0f, 0x5d, 0xc3, 0x32, 0x31, 0xb6, 0x0f, 0x67, 0xb6, - 0xe5, 0x5a, 0x28, 0x33, 0xb3, 0xac, 0x89, 0x3d, 0x1b, 0x8a, 0xff, 0x94, 0x80, 0x5d, 0x05, 0x3b, - 0xd8, 0x7e, 0x8d, 0xa5, 0xe1, 0xd0, 0x9a, 0x9b, 0xae, 0x82, 0xff, 0x61, 0x8e, 0x1d, 0x17, 0xbd, - 0x0b, 0x45, 0x9d, 0x41, 0xb4, 0xd7, 0xfa, 0x64, 0x8e, 0xcb, 0x89, 0xbb, 0x89, 0xfb, 0x69, 0xa5, - 0xc0, 0x81, 0x2f, 0x08, 0x0c, 0xbd, 0x0f, 0x25, 0x0f, 0x09, 0x5f, 0xcc, 0x0c, 0xfb, 0xb2, 0x9c, - 0xbc, 0x9b, 0xb8, 0x5f, 0x54, 0x3c, 0x52, 0x99, 0x02, 0xd1, 0x3e, 0x80, 0x6b, 0xeb, 0x23, 0x6c, - 0x6b, 0xe7, 0xf8, 0xb2, 0x9c, 0xba, 0x9b, 0xb8, 0x5f, 0x50, 0x72, 0x0c, 0xf2, 0x1c, 0x5f, 0x8a, - 0xe7, 0x70, 0x23, 0xca, 0x83, 0x33, 0xb3, 0x4c, 0x87, 0xed, 0xef, 0xf3, 0x4e, 0x89, 0x13, 0x94, - 0xb8, 0xb8, 0x80, 0x3e, 0xc7, 0x97, 0xe8, 0x00, 0xb6, 0x0c, 0xd3, 0x70, 0x0d, 0x7d, 0xa2, 0x0d, - 0x74, 0x77, 0x78, 0x46, 0x31, 0x93, 0x14, 0x73, 0x93, 0x2f, 0x54, 0x09, 0x9c, 0x1c, 0xf6, 0x9b, - 0x04, 0x94, 0x55, 0x72, 0x96, 0xdd, 0x34, 0x0d, 0x37, 0x22, 0xf4, 0x93, 0x85, 0xd0, 0x33, 0xcb, - 0x30, 0x5d, 0x7a, 0x5c, 0xfe, 0x68, 0xeb, 0x90, 0xeb, 0xeb, 0xb0, 0x33, 0x77, 0xbb, 0x64, 0xc1, - 0xd7, 0x03, 0x7d, 0x0b, 0xea, 0xc1, 0x19, 0xda, 0xc6, 0xcc, 0xe5, 0xa7, 0x7b, 0xbb, 0xa9, 0x14, - 0xb8, 0xac, 0xd3, 0xd4, 0x5b, 0xe9, 0x34, 0x7d, 0xbd, 0x4e, 0xd7, 0xa3, 0x3a, 0xbd, 0x05, 0x7b, - 0x31, 0x52, 0x32, 0xb5, 0x8a, 0x73, 0x4f, 0x05, 0xea, 0x7c, 0x30, 0x35, 0xdc, 0x8e, 0x3d, 0xc2, - 0xb6, 0xa7, 0x82, 0x0f, 0x20, 0xa5, 0x3b, 0xe7, 0x5c, 0x70, 0xe4, 0x0b, 0xce, 0xf0, 0x25, 0xe7, - 0xbc, 0xb1, 0xa6, 0x10, 0x04, 0x82, 0x37, 0x30, 0x46, 0x54, 0xce, 0x65, 0xbc, 0xaa, 0x31, 0x22, - 0x78, 0x03, 0x63, 0x54, 0xcd, 0x41, 0x66, 0x84, 0x5d, 0xdd, 0x98, 0x38, 0xc4, 0xd8, 0xf6, 0x62, - 0xce, 0xe5, 0x77, 0xfd, 0x14, 0x8a, 0x86, 0xf9, 0x5a, 0x9f, 0x18, 0x23, 0xcd, 0x22, 0x0b, 0x9c, - 0x85, 0x5d, 0x7f, 0xeb, 0x26, 0x5b, 0xa5, 0x54, 0x8d, 0x35, 0xa5, 0x60, 0x04, 0xde, 0xd1, 0x6d, - 0xc8, 0xea, 0xc3, 0x21, 0x9e, 0xb9, 0x98, 0xf1, 0x94, 0x6d, 0xac, 0x29, 0x3e, 0x24, 0xc8, 0xc4, - 0x57, 0x9e, 0xec, 0x35, 0xdd, 0x1c, 0xe2, 0x49, 0x48, 0xf6, 0x77, 0x20, 0x4f, 0x8f, 0xd6, 0x4c, - 0xcb, 0x1c, 0x62, 0x6e, 0x6b, 0x40, 0x41, 0x6d, 0x02, 0x59, 0x68, 0x35, 0x44, 0xcc, 0xb5, 0xfa, - 0xab, 0x24, 0xec, 0xd4, 0x26, 0x06, 0x36, 0x5d, 0x89, 0x59, 0xe7, 0x09, 0x76, 0x1c, 0x7d, 0x8c, - 0xd1, 0xa7, 0xb0, 0x31, 0xb4, 0xa6, 0x53, 0xc3, 0x33, 0xa7, 0x8a, 0x2f, 0x12, 0xbf, 0x98, 0x1a, - 0x5d, 0x9d, 0x62, 0xd3, 0x6d, 0xac, 0x29, 0x1c, 0x17, 0x3d, 0x85, 0x9c, 0x33, 0x1f, 0x10, 0x73, - 0x1a, 0x60, 0xae, 0xe6, 0xdb, 0x51, 0x42, 0x95, 0x21, 0xcc, 0xc8, 0x69, 0x8d, 0x35, 0x65, 0x41, - 0x80, 0x1e, 0xc3, 0x06, 0x93, 0x9e, 0xda, 0x58, 0xfe, 0x68, 0x6f, 0x61, 0xc2, 0x84, 0xe9, 0x13, - 0xe2, 0x0e, 0x12, 0x45, 0x20, 0x47, 0x32, 0x54, 0x42, 0x64, 0xe3, 0xbf, 0xc7, 0x43, 0x97, 0x9a, - 0x5c, 0x3c, 0x91, 0x42, 0x11, 0x08, 0x11, 0x43, 0x45, 0x0f, 0x20, 0xed, 0x18, 0x63, 0x93, 0x9a, - 0x60, 0xfe, 0xe8, 0x66, 0x0c, 0x89, 0x6a, 0x8c, 0x09, 0x77, 0x14, 0x0d, 0x7d, 0x0a, 0x19, 0x1b, - 0x0f, 0xad, 0xd7, 0xd8, 0x2e, 0x6f, 0x50, 0x8a, 0x72, 0x54, 0x28, 0x85, 0x2d, 0x5f, 0x36, 0xd6, - 0x14, 0x0f, 0xb5, 0xba, 0x0e, 0xa9, 0xa9, 0x33, 0x16, 0x5f, 0xc1, 0xd6, 0x92, 0xca, 0xc8, 0xad, - 0x31, 0x95, 0x69, 0x67, 0xba, 0x73, 0xe6, 0xdd, 0x1a, 0x03, 0x35, 0x74, 0xe7, 0x8c, 0xb8, 0x1d, - 0x0b, 0x0b, 0xaf, 0xb1, 0xed, 0x18, 0x96, 0xc9, 0x83, 0x54, 0x81, 0x02, 0x5f, 0x30, 0x98, 0x68, - 0xc3, 0x76, 0x8c, 0x52, 0x23, 0x6e, 0x96, 0x88, 0xb8, 0x19, 0xba, 0x07, 0x05, 0x7e, 0x36, 0x33, - 0x19, 0xe6, 0xf6, 0x9c, 0x1f, 0x6a, 0x33, 0x68, 0x0f, 0xb2, 0xfa, 0xdc, 0x3d, 0xd3, 0x1c, 0x63, - 0xcc, 0x43, 0x5f, 0x86, 0xbc, 0xab, 0xc6, 0x58, 0x7c, 0x00, 0x42, 0xf4, 0x36, 0x08, 0x3a, 0x63, - 0xd6, 0x18, 0xf1, 0xe3, 0x32, 0xf4, 0xbd, 0x39, 0x12, 0xff, 0x23, 0x15, 0xc4, 0x67, 0x17, 0x71, - 0x05, 0x3e, 0xba, 0x41, 0xae, 0x53, 0x77, 0xb8, 0xc0, 0x39, 0x85, 0xbf, 0xa1, 0x6f, 0x20, 0xcf, - 0x9e, 0xb4, 0xa1, 0x35, 0x62, 0x41, 0xa8, 0x74, 0xf4, 0xc1, 0xca, 0xbb, 0x3e, 0x64, 0xff, 0x14, - 0x4a, 0xa2, 0x00, 0x23, 0xad, 0x59, 0x23, 0x8c, 0x5e, 0xc0, 0x26, 0x33, 0x02, 0xcc, 0x7d, 0xd6, - 0x29, 0xa7, 0xef, 0xa6, 0xee, 0xe7, 0x8f, 0x1e, 0x5c, 0xb7, 0x19, 0x66, 0x6e, 0xeb, 0xc8, 0xa6, - 0x6b, 0x5f, 0x2a, 0x25, 0x3b, 0x04, 0xac, 0xbc, 0x84, 0xed, 0x18, 0x34, 0x24, 0x40, 0xca, 0xbb, - 0x84, 0x9c, 0x42, 0x1e, 0xd1, 0x01, 0xac, 0xb3, 0x40, 0xca, 0xfc, 0x63, 0x27, 0x7c, 0x2c, 0xe7, - 0x9b, 0xa1, 0x7c, 0x99, 0xfc, 0x3c, 0x21, 0x0e, 0xa1, 0x10, 0x14, 0x06, 0xe5, 0x21, 0xd3, 0x6f, - 0x3f, 0x6f, 0x77, 0x5e, 0xb6, 0x85, 0x35, 0x74, 0x03, 0x90, 0x2a, 0x2b, 0x2f, 0x64, 0x45, 0x3b, - 0x69, 0xaa, 0x55, 0xb9, 0x21, 0xbd, 0x68, 0x76, 0x14, 0x21, 0x81, 0x2a, 0x70, 0xa3, 0x2a, 0xf5, - 0x6a, 0x0d, 0xed, 0x85, 0xac, 0xa8, 0xcd, 0x4e, 0x9b, 0x2c, 0x9f, 0x10, 0x80, 0x90, 0x44, 0x08, - 0x4a, 0x5d, 0x49, 0xe9, 0x35, 0xa5, 0x96, 0xa6, 0xc8, 0xcf, 0xe4, 0x5a, 0x4f, 0x48, 0x89, 0xff, - 0x93, 0x80, 0x7c, 0xe0, 0xfc, 0xc0, 0x35, 0x24, 0xae, 0xba, 0x86, 0x64, 0xdc, 0x35, 0x70, 0xa5, - 0x05, 0xc5, 0x59, 0xba, 0x06, 0xb1, 0x06, 0x5b, 0x4b, 0x08, 0x84, 0xb3, 0x7a, 0xbf, 0xdb, 0x6a, - 0xd6, 0xa4, 0x9e, 0xac, 0x75, 0x65, 0x59, 0x11, 0xd6, 0x88, 0x24, 0xb5, 0x86, 0xd4, 0x6e, 0xcb, - 0x2d, 0xed, 0xb8, 0xdf, 0xae, 0x37, 0xdb, 0xdf, 0x68, 0xc7, 0x52, 0xb3, 0x25, 0xd7, 0x85, 0x84, - 0xf8, 0xdb, 0x04, 0xe4, 0x6b, 0x67, 0xba, 0x69, 0xe2, 0x49, 0xd3, 0x3c, 0xb5, 0xd0, 0x7d, 0x48, - 0xbb, 0x97, 0x33, 0x16, 0x04, 0x4b, 0x01, 0xcd, 0x72, 0x9c, 0xde, 0xe5, 0x0c, 0x2b, 0x14, 0x03, - 0xbd, 0x07, 0xa5, 0x89, 0x35, 0xd4, 0x27, 0x9a, 0x69, 0x8d, 0x70, 0x20, 0xf5, 0x16, 0x28, 0xb4, - 0x6d, 0x8d, 0x30, 0xf1, 0x94, 0x0f, 0x88, 0xad, 0x4c, 0x2d, 0x17, 0x2f, 0xd0, 0x98, 0x37, 0x14, - 0x19, 0xd8, 0xc3, 0xfb, 0x6b, 0x28, 0xb3, 0xdd, 0x66, 0xfa, 0x25, 0x71, 0x6f, 0x6d, 0xa0, 0x3b, - 0x98, 0x67, 0xe3, 0x34, 0x25, 0xd8, 0xa5, 0xeb, 0x5d, 0xb6, 0x5c, 0xd5, 0x1d, 0xcc, 0x72, 0xf0, - 0x17, 0xb0, 0xc7, 0x0f, 0x88, 0xa1, 0x64, 0xf9, 0xf1, 0x06, 0x43, 0x88, 0x92, 0x8a, 0xbf, 0x4c, - 0x42, 0x29, 0x1c, 0xae, 0xae, 0x72, 0xab, 0xe7, 0x50, 0xf0, 0x93, 0xbd, 0x31, 0x76, 0xca, 0x49, - 0x6a, 0xf2, 0xf7, 0x57, 0x04, 0x3e, 0x3f, 0x54, 0x1b, 0x63, 0x6e, 0xed, 0x79, 0x7d, 0x01, 0x41, - 0x6d, 0x28, 0x0e, 0x99, 0x46, 0x35, 0xc3, 0x3c, 0xb5, 0x9c, 0x72, 0x8a, 0xee, 0xf6, 0xe1, 0xaa, - 0xdd, 0x02, 0x57, 0xc4, 0xb7, 0x2b, 0x0c, 0x03, 0xa0, 0xca, 0xd7, 0x20, 0x44, 0x0f, 0x8c, 0xf1, - 0x9b, 0x9d, 0xa0, 0xdf, 0x14, 0x02, 0x1e, 0x52, 0xe9, 0xc3, 0xd6, 0xd2, 0x11, 0x7f, 0x88, 0xe3, - 0x05, 0x88, 0x83, 0x8e, 0xf7, 0x09, 0x6c, 0x46, 0xa2, 0xfb, 0x35, 0x91, 0x55, 0xfc, 0xb7, 0x14, - 0xec, 0xf0, 0xa2, 0x23, 0x9c, 0x4d, 0x3f, 0x87, 0xdc, 0xf0, 0x4c, 0x9f, 0x4c, 0xb0, 0x39, 0xc6, - 0x3c, 0xa1, 0x96, 0x23, 0xe5, 0x47, 0xcd, 0x5b, 0x27, 0x39, 0xd1, 0x47, 0x46, 0x9f, 0x41, 0xc6, - 0x99, 0x0f, 0x87, 0xd8, 0x71, 0x38, 0xdb, 0x8b, 0xfc, 0xa6, 0x7a, 0x89, 0x53, 0x65, 0x08, 0x24, - 0xf7, 0x70, 0x5c, 0xf4, 0x10, 0xd6, 0xb1, 0x6d, 0x5b, 0x36, 0xcf, 0xa4, 0x37, 0x97, 0x89, 0x64, - 0xb2, 0xdc, 0x58, 0x53, 0x18, 0x1e, 0x7a, 0x02, 0x99, 0x99, 0x8d, 0x67, 0xba, 0x8d, 0x79, 0x1e, - 0xad, 0xc4, 0xdc, 0x66, 0x97, 0x61, 0x90, 0x83, 0x38, 0x32, 0x3a, 0x0a, 0x65, 0xd2, 0xdb, 0x2b, - 0x4c, 0xa0, 0x8a, 0xc7, 0xc6, 0x22, 0x9d, 0x7e, 0x01, 0xd9, 0x53, 0xc3, 0xd4, 0x27, 0xc6, 0x3f, - 0x62, 0x9e, 0x4f, 0x6f, 0xc5, 0xd0, 0x1d, 0x73, 0x14, 0x52, 0x14, 0x79, 0xe8, 0xe8, 0x31, 0x64, - 0xb8, 0x25, 0x96, 0x33, 0x11, 0xc9, 0xb8, 0xca, 0xf9, 0x95, 0x11, 0x1e, 0x39, 0xa6, 0x97, 0x88, - 0xbb, 0xb0, 0x19, 0x51, 0x35, 0xba, 0x1d, 0xbd, 0x97, 0x42, 0x50, 0xf7, 0x91, 0x24, 0x9d, 0x8c, - 0x26, 0x69, 0xf1, 0x11, 0x08, 0xd1, 0x4b, 0xb8, 0xce, 0x44, 0xfe, 0x2b, 0xcd, 0x03, 0x5f, 0x50, - 0xa1, 0xa8, 0x07, 0xa5, 0x29, 0x79, 0x5f, 0xe4, 0xa4, 0xc4, 0xca, 0x9c, 0xc4, 0x69, 0x0e, 0x4f, - 0x18, 0x41, 0x30, 0x27, 0x15, 0xa7, 0x41, 0x18, 0x3a, 0x84, 0xed, 0xe1, 0x04, 0xeb, 0xb6, 0x61, - 0x8e, 0xb5, 0x99, 0x6d, 0x0c, 0xb1, 0x66, 0xeb, 0x2e, 0xe6, 0x95, 0xc4, 0x96, 0xb7, 0xd4, 0x25, - 0x2b, 0x8a, 0xee, 0x62, 0xf4, 0xb7, 0x20, 0x0c, 0xcf, 0x74, 0x7b, 0x8c, 0x47, 0x1a, 0x57, 0x9d, - 0xe7, 0xda, 0x3b, 0xd1, 0x7a, 0xa7, 0x6e, 0x9c, 0x9e, 0x2a, 0x9b, 0x1c, 0x9b, 0xc3, 0x1c, 0xf4, - 0x25, 0x14, 0xf1, 0x05, 0x1e, 0xce, 0xc9, 0x3d, 0x68, 0xa7, 0xd8, 0x33, 0xa5, 0x45, 0x39, 0x2c, - 0x7b, 0xab, 0xc7, 0x18, 0x2b, 0x05, 0x1c, 0x78, 0x43, 0x1f, 0xc1, 0x16, 0x0b, 0x5e, 0xae, 0xad, - 0x9b, 0x8e, 0x4e, 0xef, 0x92, 0x87, 0x40, 0x81, 0x2e, 0xf4, 0x16, 0x70, 0xf4, 0x31, 0x6c, 0x9f, - 0x62, 0x26, 0x8e, 0xe6, 0xe8, 0xae, 0x36, 0x23, 0xea, 0x7e, 0x43, 0x8d, 0x29, 0xad, 0x6c, 0x9e, - 0x62, 0x2a, 0x8f, 0xaa, 0xbb, 0x5d, 0x6c, 0x3f, 0x7f, 0x43, 0x82, 0x3d, 0xc5, 0xc6, 0x03, 0x8e, - 0x4f, 0x6d, 0x27, 0xad, 0x14, 0x08, 0x22, 0x05, 0xaa, 0x7a, 0xb8, 0x28, 0xc9, 0x86, 0xa3, 0xe7, - 0x52, 0x31, 0x96, 0x5b, 0x2e, 0xc6, 0x2a, 0x2f, 0x01, 0x2d, 0x5f, 0x49, 0x4c, 0x18, 0xfa, 0x28, - 0x1c, 0x86, 0x16, 0xca, 0x09, 0x52, 0x87, 0xe3, 0xd0, 0x76, 0x8c, 0x37, 0x5d, 0x55, 0x74, 0x59, - 0x80, 0x96, 0xfd, 0xe8, 0xaa, 0xf4, 0xb0, 0x0f, 0xc0, 0x95, 0x7f, 0xc1, 0xfb, 0xa3, 0x82, 0x92, - 0x63, 0x5a, 0xbf, 0x30, 0x46, 0xc4, 0x11, 0xce, 0xb0, 0x31, 0x3e, 0x73, 0xb5, 0x33, 0x92, 0x98, - 0x52, 0x54, 0x7a, 0x60, 0xa0, 0x06, 0x49, 0x46, 0xff, 0x9b, 0x84, 0x52, 0x38, 0xb2, 0x90, 0x70, - 0xcd, 0x22, 0x10, 0x13, 0x9d, 0x87, 0x99, 0xa7, 0x00, 0xf4, 0x21, 0x58, 0x3e, 0xec, 0xaf, 0x08, - 0x4e, 0x87, 0xf4, 0xaf, 0x92, 0xa3, 0x04, 0xb4, 0x76, 0xbb, 0xba, 0x27, 0x47, 0x0d, 0xd8, 0xf6, - 0x92, 0x9c, 0x4d, 0x7b, 0x73, 0x9d, 0x1a, 0x51, 0xfa, 0xca, 0x40, 0xa1, 0x20, 0xdd, 0xef, 0x34, - 0x3d, 0x12, 0xd1, 0x80, 0x75, 0x26, 0x45, 0xa8, 0xd8, 0xda, 0x86, 0x4d, 0x5e, 0x6c, 0xa9, 0x8d, - 0x7e, 0xaf, 0x4e, 0x80, 0xb4, 0xd2, 0x92, 0x6a, 0xb5, 0x4e, 0xbf, 0xdd, 0xd3, 0xea, 0x1d, 0x59, - 0xd5, 0xda, 0x9d, 0x9e, 0x26, 0x7f, 0xd7, 0x54, 0x7b, 0x42, 0x12, 0x89, 0x70, 0xa7, 0xd9, 0xae, - 0x75, 0x4e, 0xba, 0x2d, 0xb9, 0x27, 0x6b, 0x1e, 0x9a, 0x22, 0x93, 0x5d, 0xa4, 0x5e, 0xb3, 0xd3, - 0x16, 0x52, 0xe2, 0xff, 0x27, 0xa1, 0x14, 0xe6, 0x68, 0x91, 0xe9, 0xd8, 0xf8, 0x82, 0xbd, 0x90, - 0x92, 0x2c, 0x34, 0xaf, 0xe0, 0x6f, 0xd7, 0x29, 0x65, 0x79, 0x1c, 0x91, 0x8e, 0x1b, 0x47, 0xdc, - 0x82, 0xdc, 0x62, 0x0c, 0xc1, 0xdc, 0x8e, 0x59, 0x0b, 0x59, 0x3c, 0x82, 0x75, 0xc7, 0x25, 0xa1, - 0x63, 0x83, 0x5e, 0xd8, 0xed, 0x15, 0xaa, 0x54, 0x09, 0x8e, 0xc2, 0x50, 0xa3, 0x36, 0x93, 0x89, - 0xda, 0x0c, 0x7a, 0x00, 0x59, 0x6b, 0xee, 0xb2, 0x52, 0x27, 0xbb, 0x6a, 0x64, 0xe1, 0xa3, 0x10, - 0x06, 0x27, 0xba, 0x8b, 0x1d, 0x57, 0x73, 0x2f, 0xa8, 0xff, 0x15, 0x94, 0x2c, 0x03, 0xf4, 0x2e, - 0xc4, 0x1f, 0xa0, 0x10, 0xf4, 0x1e, 0xf4, 0x04, 0x0a, 0x5e, 0x3c, 0x1d, 0x18, 0x23, 0x2f, 0x9a, - 0x6e, 0x47, 0x5d, 0xad, 0x6a, 0x8c, 0x94, 0xfc, 0xd4, 0x7f, 0x76, 0x82, 0x74, 0xba, 0x73, 0xee, - 0x95, 0x49, 0x4b, 0x74, 0x92, 0x73, 0xee, 0xd3, 0x49, 0xce, 0xb9, 0x23, 0xf6, 0x01, 0x16, 0x4b, - 0xe8, 0xbd, 0x6b, 0xc6, 0x11, 0x6c, 0x18, 0x71, 0x0f, 0x0a, 0x73, 0xd3, 0x70, 0x1d, 0xed, 0xd4, - 0x98, 0x4c, 0xf8, 0x04, 0xa0, 0xa8, 0xe4, 0x29, 0xec, 0x98, 0x82, 0x02, 0xdb, 0x56, 0x8d, 0x11, - 0xd9, 0x76, 0xc0, 0x5d, 0x37, 0x76, 0x7a, 0x41, 0x67, 0x17, 0x6f, 0xb3, 0xed, 0xff, 0x25, 0x21, - 0x1f, 0x88, 0xe3, 0xc4, 0x44, 0xb0, 0x39, 0x22, 0x59, 0x62, 0xa0, 0x4f, 0x74, 0x6f, 0x8a, 0x90, - 0x56, 0x8a, 0x0c, 0x5a, 0x65, 0x40, 0x54, 0x87, 0x02, 0x47, 0x63, 0xc6, 0xc0, 0xbc, 0xf7, 0x5e, - 0x5c, 0x6a, 0x38, 0x0c, 0x59, 0x44, 0x9e, 0x91, 0xd1, 0x17, 0x72, 0x98, 0x77, 0xa7, 0x9a, 0x61, - 0x8e, 0xf0, 0x05, 0x35, 0xd9, 0x75, 0xa5, 0xe8, 0x41, 0x9b, 0x04, 0x18, 0xb1, 0xea, 0x74, 0x34, - 0x8d, 0xfe, 0x00, 0x85, 0xe0, 0x11, 0x68, 0x07, 0x84, 0x4e, 0xbf, 0xd7, 0xed, 0x13, 0xef, 0xaa, - 0x29, 0xb2, 0xd4, 0x93, 0xeb, 0xc2, 0x1a, 0xba, 0x07, 0xfb, 0x1c, 0x5a, 0xef, 0xab, 0xc4, 0x2d, - 0x7b, 0x72, 0xbb, 0x2e, 0xd7, 0xb5, 0xce, 0xf1, 0x71, 0xad, 0x21, 0x35, 0x89, 0xfb, 0xee, 0xc3, - 0x5e, 0x10, 0x45, 0xaa, 0x93, 0xf5, 0x5e, 0x47, 0x3b, 0x96, 0x65, 0x55, 0x48, 0x92, 0xfe, 0x8a, - 0x2f, 0x1f, 0xf7, 0x5b, 0xad, 0x57, 0x9a, 0xda, 0x95, 0xdb, 0xa4, 0x5f, 0xfa, 0x5d, 0x12, 0xf2, - 0x4c, 0xf1, 0xcc, 0xe0, 0xae, 0x69, 0xb9, 0xf7, 0x01, 0x68, 0xae, 0x3a, 0x35, 0x2e, 0xfc, 0x2b, - 0xc9, 0x11, 0xc8, 0x31, 0x01, 0x90, 0x24, 0xa1, 0x4f, 0x5d, 0x3e, 0x59, 0x23, 0x8f, 0xd1, 0xa9, - 0xce, 0x46, 0x74, 0xaa, 0x43, 0xdc, 0x81, 0x21, 0x90, 0x16, 0x3d, 0xc3, 0xdc, 0x81, 0x02, 0x54, - 0x63, 0x8c, 0x44, 0x28, 0x4e, 0xe7, 0x13, 0xd7, 0x20, 0x8b, 0x94, 0x21, 0x96, 0xcf, 0xf2, 0x14, - 0xa8, 0x1a, 0x63, 0xc2, 0xd2, 0x1e, 0x64, 0x69, 0x53, 0x33, 0x9b, 0x0f, 0xb8, 0x3b, 0x65, 0xc8, - 0x7b, 0x77, 0x3e, 0x40, 0x8f, 0x20, 0x47, 0x97, 0xf4, 0xd1, 0xc8, 0x2e, 0x43, 0xa4, 0x00, 0x20, - 0x3d, 0x8f, 0x34, 0x1a, 0xd9, 0xd8, 0x71, 0x14, 0xba, 0x03, 0x79, 0x21, 0xec, 0x90, 0x92, 0x5e, - 0xa3, 0xed, 0x57, 0x81, 0xca, 0x97, 0x25, 0x00, 0xd2, 0x72, 0xa1, 0xaf, 0x61, 0x7f, 0xaa, 0x5f, - 0xf0, 0x31, 0x67, 0x5c, 0xde, 0x2e, 0x52, 0xc1, 0x6f, 0x4e, 0xf5, 0x0b, 0x3a, 0xf2, 0x3c, 0x0e, - 0xe7, 0xef, 0x67, 0xe9, 0x6c, 0x5a, 0x58, 0x7f, 0x96, 0xce, 0xae, 0x0b, 0x1b, 0xcf, 0xd2, 0xd9, - 0xbc, 0x50, 0x10, 0x7f, 0x96, 0x80, 0x9c, 0x6f, 0xf7, 0xe8, 0xd0, 0x9f, 0x94, 0x71, 0xe7, 0xd8, - 0x89, 0x38, 0x07, 0x4b, 0xa9, 0x1e, 0x12, 0x3a, 0x82, 0xdd, 0x09, 0x26, 0x7d, 0xd6, 0x68, 0x6e, - 0xd3, 0x78, 0xaf, 0x0d, 0x26, 0xd6, 0xf0, 0xdc, 0xe1, 0x17, 0xb3, 0x4d, 0x17, 0xeb, 0x7c, 0xad, - 0x4a, 0x97, 0x50, 0x19, 0x32, 0x5e, 0xf2, 0x67, 0xa3, 0x4d, 0xef, 0x15, 0x7d, 0x06, 0xc5, 0xa9, - 0x61, 0xb2, 0x0e, 0xd1, 0x35, 0xb0, 0x4d, 0xa3, 0x67, 0x29, 0x10, 0xcc, 0x88, 0xc6, 0x7a, 0x06, - 0xb6, 0x95, 0xfc, 0xd4, 0x30, 0xbd, 0x97, 0x67, 0xe9, 0x6c, 0x4a, 0x48, 0x8b, 0xff, 0xec, 0x0b, - 0x42, 0x02, 0xc7, 0x9f, 0x4c, 0x90, 0xf4, 0x5b, 0x09, 0xb2, 0x1e, 0x12, 0x44, 0x3c, 0x84, 0x7c, - 0x60, 0x44, 0x78, 0xfd, 0x60, 0xf1, 0xbf, 0x13, 0x50, 0x08, 0xce, 0x37, 0xaf, 0xa5, 0x40, 0x12, - 0xe4, 0x4f, 0x75, 0x63, 0xa2, 0x05, 0x26, 0x3c, 0xa5, 0xa3, 0xbb, 0xb1, 0xc3, 0xd2, 0xc3, 0x63, - 0xdd, 0x98, 0x78, 0x73, 0x83, 0x53, 0xff, 0x99, 0x9c, 0x41, 0xb7, 0x70, 0x5c, 0x52, 0xbb, 0x52, - 0x97, 0xc9, 0x31, 0x04, 0x95, 0x42, 0xc4, 0x7d, 0x80, 0x05, 0x29, 0xda, 0x84, 0x7c, 0xb3, 0xfd, - 0x42, 0x6a, 0x35, 0xeb, 0x9a, 0x74, 0xd2, 0x13, 0xd6, 0xc4, 0xa7, 0x9e, 0xdf, 0x36, 0xcd, 0xd9, - 0x3c, 0x9c, 0x84, 0x12, 0xd7, 0x26, 0x21, 0xf1, 0x29, 0x14, 0xf8, 0x45, 0xcc, 0x5d, 0x42, 0xbe, - 0x32, 0x53, 0x87, 0x26, 0xea, 0xfc, 0x4d, 0xfc, 0xcf, 0x24, 0x54, 0x18, 0xf9, 0x89, 0x35, 0x32, - 0x4e, 0x2f, 0x23, 0x83, 0xfc, 0x6b, 0x62, 0xc8, 0x63, 0x00, 0x13, 0xbf, 0xd1, 0x0c, 0xc2, 0xb7, - 0x97, 0x99, 0xa2, 0xf6, 0x41, 0x85, 0x52, 0x72, 0x26, 0x7e, 0x43, 0x9f, 0x48, 0x42, 0xcb, 0x13, - 0x22, 0x8b, 0xb2, 0xeb, 0x55, 0xf3, 0xbb, 0x51, 0xab, 0xa2, 0xab, 0x0a, 0xd9, 0x9e, 0x3d, 0x3a, - 0xe8, 0x25, 0x3b, 0x6c, 0xa6, 0xdb, 0xfa, 0xd4, 0xe1, 0x15, 0xd4, 0xe7, 0x11, 0xb2, 0x38, 0x21, - 0x0e, 0xdb, 0xf8, 0x0d, 0x87, 0x74, 0x09, 0x2d, 0x76, 0xb1, 0xed, 0x50, 0x86, 0xe8, 0xab, 0x53, - 0xf9, 0x18, 0x76, 0xe2, 0x50, 0xe2, 0x35, 0x29, 0x7e, 0x0d, 0xb7, 0x62, 0xcf, 0xe2, 0xe3, 0xf7, - 0x77, 0x20, 0x1f, 0x98, 0x6a, 0x78, 0x06, 0xb7, 0x18, 0x55, 0x88, 0x5f, 0xc2, 0xcd, 0x80, 0xe3, - 0xb0, 0x6c, 0xf4, 0xb6, 0x73, 0x73, 0xdb, 0x1b, 0xba, 0x07, 0x69, 0xf9, 0xc1, 0x1f, 0x7a, 0x05, - 0x11, 0x9b, 0x34, 0x6d, 0x87, 0xdb, 0xb4, 0x50, 0x1d, 0xf4, 0x11, 0x6c, 0xb1, 0x7c, 0x3c, 0x37, - 0x4f, 0xe7, 0x93, 0x50, 0x52, 0x16, 0xe8, 0x42, 0x7f, 0x01, 0x17, 0x4b, 0x50, 0xe8, 0x61, 0x7b, - 0xea, 0x70, 0x26, 0xc5, 0x9f, 0x27, 0xa1, 0xc8, 0x01, 0xfc, 0xe4, 0x03, 0xd8, 0x22, 0xb1, 0x34, - 0xee, 0x33, 0xd7, 0xe6, 0x54, 0xbf, 0x90, 0x82, 0x5f, 0x65, 0xfe, 0x06, 0xf6, 0x08, 0x2e, 0x13, - 0x33, 0x36, 0xd6, 0x55, 0x93, 0xe5, 0x84, 0x72, 0x63, 0xaa, 0x5f, 0x50, 0xbe, 0x23, 0x91, 0x62, - 0xa9, 0x9b, 0x4b, 0xbd, 0x7d, 0x37, 0xa7, 0xc2, 0x66, 0x38, 0x32, 0x79, 0x53, 0xd6, 0x03, 0x9f, - 0x3a, 0x24, 0xd7, 0x61, 0x2b, 0x18, 0xaa, 0xbc, 0x11, 0x6b, 0x28, 0x7e, 0x39, 0x15, 0x09, 0xb6, - 0x63, 0xd0, 0x82, 0x2d, 0x56, 0x31, 0x66, 0x54, 0x94, 0x0d, 0xf6, 0x52, 0x55, 0xd8, 0x51, 0xf0, - 0x04, 0xbf, 0xd6, 0x4d, 0xb7, 0xca, 0x06, 0xbc, 0xcc, 0x1a, 0x4a, 0x90, 0xf4, 0xbb, 0xa2, 0xa4, - 0x31, 0x42, 0x15, 0xfa, 0x69, 0x86, 0xb5, 0xc0, 0xc4, 0xd5, 0x0a, 0x8a, 0xff, 0x2e, 0xfe, 0x3a, - 0x05, 0xc5, 0xd0, 0x26, 0xc1, 0x98, 0x9a, 0x08, 0x27, 0x07, 0xb6, 0x6f, 0xd2, 0xdf, 0xf7, 0x8f, - 0x6e, 0xb1, 0xbb, 0x4b, 0x93, 0x82, 0x74, 0x64, 0xf8, 0x16, 0x62, 0xed, 0xa7, 0x4f, 0x09, 0xd6, - 0x57, 0x4d, 0x09, 0x96, 0xcc, 0x62, 0xe3, 0xed, 0xcd, 0xe2, 0x2e, 0xe4, 0x83, 0xed, 0x3d, 0xab, - 0x5b, 0x82, 0xa0, 0x55, 0x9d, 0x7d, 0x36, 0xb6, 0xb3, 0xff, 0xf3, 0xf5, 0xdc, 0x75, 0x28, 0x04, - 0xc5, 0x60, 0xbd, 0xb3, 0x83, 0xa9, 0xbc, 0xcc, 0xdb, 0x32, 0xe4, 0x9d, 0x2f, 0x79, 0x1c, 0xd3, - 0xed, 0xd3, 0x4a, 0x86, 0xb3, 0x29, 0x7e, 0x05, 0xf9, 0x40, 0xb9, 0x44, 0xcc, 0xc4, 0xc4, 0xee, - 0x1b, 0xcb, 0x3e, 0xe7, 0xbc, 0x79, 0xaf, 0x08, 0x41, 0x9a, 0x16, 0x5b, 0xec, 0x9b, 0x07, 0x7d, - 0x16, 0x25, 0xc8, 0x7a, 0x19, 0x88, 0xac, 0xd3, 0xce, 0x9c, 0x19, 0x28, 0x7d, 0x26, 0x85, 0x3e, - 0x0b, 0xeb, 0xbc, 0x8c, 0xe6, 0x85, 0x3e, 0x83, 0xd1, 0x22, 0x5a, 0xfc, 0xd7, 0x04, 0xe4, 0x25, - 0xe7, 0x5c, 0x35, 0xf5, 0x99, 0x73, 0x66, 0xb9, 0x57, 0xd8, 0xe9, 0x4f, 0x29, 0x89, 0xc2, 0x45, - 0x6d, 0x2a, 0x5a, 0xd4, 0x86, 0x4a, 0xc2, 0x74, 0xb8, 0x24, 0xa4, 0x9c, 0x55, 0x8d, 0xd1, 0x5f, - 0x20, 0x67, 0xbf, 0x48, 0xc0, 0x4e, 0xd0, 0x2a, 0x7c, 0x16, 0x43, 0x1f, 0x99, 0x03, 0xde, 0xba, - 0xd0, 0x6f, 0xcc, 0x47, 0xe6, 0x05, 0x5e, 0x40, 0x5a, 0xd6, 0xa8, 0xbd, 0x0b, 0xcc, 0x11, 0x89, - 0xdf, 0x51, 0xe3, 0x61, 0x7c, 0x16, 0x3c, 0x20, 0x75, 0xb6, 0x8f, 0x01, 0xb9, 0x96, 0xab, 0x4f, - 0x88, 0x2f, 0x38, 0x1a, 0x75, 0x46, 0x3c, 0xa2, 0x3c, 0xa7, 0x15, 0x81, 0xae, 0xa8, 0xba, 0xeb, - 0xd4, 0x18, 0x9c, 0x6c, 0xc9, 0x72, 0x0d, 0xf7, 0x70, 0xee, 0xc4, 0xac, 0x21, 0xe4, 0x42, 0x89, - 0x8f, 0x60, 0x87, 0x86, 0x06, 0x9f, 0x1b, 0x1e, 0x02, 0xaf, 0x98, 0x27, 0xfd, 0x7b, 0x12, 0x76, - 0x23, 0x34, 0x3c, 0x1d, 0xad, 0xbe, 0xb7, 0xe0, 0x76, 0xc9, 0xf0, 0xb4, 0x49, 0x84, 0xe2, 0xcc, - 0xc6, 0xaf, 0x35, 0x7f, 0x9d, 0x0d, 0x2d, 0xf2, 0x04, 0x58, 0xe5, 0x38, 0x2b, 0xa2, 0x52, 0x7a, - 0x55, 0x54, 0xaa, 0x2f, 0xc5, 0xc5, 0x75, 0x1a, 0x17, 0xf7, 0x63, 0x5d, 0xdd, 0x97, 0x23, 0x12, - 0x0b, 0xef, 0x40, 0xde, 0x9b, 0x83, 0x11, 0xbe, 0x32, 0xd4, 0x1d, 0xbd, 0x41, 0x58, 0x73, 0xb4, - 0x10, 0xca, 0xbd, 0xe0, 0x3d, 0x59, 0x86, 0x2f, 0x8a, 0x4f, 0xbd, 0x52, 0x83, 0x78, 0xbc, 0xa2, - 0xbb, 0xe4, 0x06, 0xb9, 0x66, 0xef, 0x41, 0xc1, 0x6b, 0xb5, 0xce, 0xf1, 0x25, 0x9b, 0x46, 0x14, - 0x94, 0x3c, 0x6f, 0xb7, 0x08, 0x48, 0xfc, 0x3b, 0x80, 0x05, 0x1d, 0xa9, 0x4d, 0x02, 0x04, 0x5e, - 0x6d, 0xb2, 0xc0, 0x47, 0x87, 0xbc, 0x43, 0xa3, 0xfd, 0x46, 0x72, 0x55, 0xbf, 0x41, 0xdb, 0x33, - 0xf2, 0x24, 0x2a, 0x5e, 0x2d, 0x13, 0x64, 0x8e, 0x5f, 0xe1, 0x13, 0xce, 0x9d, 0x4d, 0xc1, 0xcb, - 0xb3, 0x92, 0x00, 0x09, 0xe5, 0x8a, 0x3d, 0x3b, 0x07, 0x1f, 0xfa, 0xdf, 0xde, 0x68, 0x93, 0x57, - 0x84, 0x5c, 0xef, 0xa5, 0x2c, 0x3d, 0x6f, 0xc9, 0xaa, 0x2a, 0xac, 0xa1, 0x3c, 0x64, 0xa4, 0x76, - 0xad, 0xd1, 0x51, 0x54, 0x21, 0x71, 0xf0, 0x2f, 0x09, 0xd8, 0x8e, 0x19, 0x15, 0xd1, 0xaf, 0x97, - 0x3d, 0xf6, 0xad, 0x8f, 0x7d, 0xd9, 0xeb, 0x74, 0xe5, 0xb6, 0xb0, 0x86, 0x4a, 0x00, 0x0c, 0x4e, - 0xdf, 0x13, 0x68, 0x0b, 0x8a, 0xec, 0x5d, 0xfe, 0xae, 0xdb, 0x54, 0xe4, 0xba, 0x90, 0x44, 0x65, - 0xd8, 0x09, 0x93, 0xf6, 0xbb, 0x75, 0xa9, 0x27, 0x0b, 0x29, 0x24, 0x40, 0x81, 0xad, 0xd4, 0x5a, - 0x1d, 0x55, 0xae, 0x0b, 0x69, 0x74, 0x13, 0xb6, 0xc3, 0xb8, 0xf4, 0xd3, 0xa8, 0xb0, 0x7e, 0xf0, - 0x29, 0x64, 0x3d, 0x65, 0x11, 0xb2, 0x5e, 0x53, 0x56, 0xb4, 0xba, 0x7c, 0x2c, 0xf5, 0x5b, 0x3d, - 0x61, 0x0d, 0x01, 0x6c, 0x50, 0xc8, 0x27, 0x42, 0xc2, 0x7f, 0x7e, 0x24, 0x24, 0x0f, 0x7e, 0x4c, - 0x00, 0x2c, 0xea, 0x3c, 0xb4, 0x0d, 0x9b, 0x1d, 0xa5, 0x2e, 0x2b, 0x9a, 0xda, 0xaf, 0x9e, 0x34, - 0x7b, 0x6c, 0xf2, 0xb0, 0x05, 0x45, 0x06, 0xac, 0xb5, 0x64, 0x89, 0x70, 0x4c, 0x07, 0x85, 0x0c, - 0xc4, 0x3f, 0xbe, 0xb6, 0x5e, 0x69, 0xc7, 0xcd, 0x56, 0x8b, 0x4a, 0x83, 0xa0, 0xc4, 0xd6, 0xe4, - 0xef, 0xe4, 0x5a, 0x9f, 0x6c, 0x91, 0x5a, 0xc0, 0x6a, 0x52, 0xbb, 0x26, 0xb7, 0xa8, 0x24, 0xfe, - 0xb6, 0x9e, 0x22, 0xd6, 0x09, 0xdf, 0x0c, 0xc4, 0xbf, 0x8a, 0x6e, 0x1c, 0xfd, 0x98, 0xf1, 0xbf, - 0x87, 0x49, 0xfe, 0x8c, 0x0f, 0x7d, 0x0b, 0xa5, 0xf0, 0x0f, 0x96, 0xd0, 0x9d, 0x40, 0xc9, 0x10, - 0xf3, 0x6b, 0xaa, 0xca, 0x3b, 0x2b, 0xd7, 0xb9, 0xe5, 0xf4, 0x20, 0x1f, 0xf8, 0xa5, 0x0e, 0xba, - 0xb7, 0xd4, 0x8c, 0x44, 0x7f, 0xab, 0x54, 0x11, 0xaf, 0x42, 0xe1, 0xbb, 0x7e, 0x0f, 0xc5, 0x50, - 0xb5, 0x8f, 0xde, 0x7d, 0x8b, 0xbe, 0xa3, 0xf2, 0xde, 0xd5, 0x48, 0x0b, 0x8e, 0x03, 0x3f, 0xe3, - 0x59, 0xe2, 0x78, 0xf9, 0xa7, 0x45, 0x4b, 0x1c, 0xc7, 0xfd, 0x0a, 0xa8, 0x17, 0x6e, 0x9c, 0xa3, - 0xbb, 0x2e, 0xff, 0x68, 0x67, 0x69, 0xd7, 0x98, 0x9f, 0xe6, 0xa0, 0x6f, 0x43, 0x56, 0x76, 0x37, - 0x6e, 0x12, 0x10, 0x6c, 0x68, 0x2a, 0xf7, 0xae, 0xc0, 0xe0, 0x5b, 0xbe, 0x82, 0x5d, 0x7f, 0xc4, - 0x4e, 0x03, 0x2d, 0xb7, 0x0f, 0xb4, 0x88, 0x92, 0x71, 0x3f, 0x06, 0xaa, 0xec, 0x47, 0x67, 0x98, - 0xa1, 0xe5, 0xfb, 0x89, 0x4f, 0x12, 0xe8, 0x09, 0xac, 0xd3, 0x82, 0x1e, 0xed, 0x46, 0x0b, 0x7c, - 0xc6, 0xdd, 0x8d, 0xf8, 0xba, 0x1f, 0xb5, 0x61, 0x37, 0x54, 0xb0, 0xfa, 0xe9, 0x76, 0x3f, 0xbe, - 0xa0, 0x5d, 0xde, 0x2f, 0x5c, 0x8a, 0xb7, 0xa1, 0xb8, 0x6a, 0x9f, 0xb8, 0xac, 0x57, 0xb9, 0xb3, - 0x6a, 0x79, 0x71, 0x0b, 0x81, 0xc0, 0x1c, 0xbd, 0x85, 0xa5, 0x58, 0xbf, 0x74, 0x0b, 0xcb, 0x01, - 0xb7, 0xfa, 0x57, 0xdf, 0xbf, 0x3f, 0x36, 0xdc, 0xb3, 0xf9, 0xe0, 0x70, 0x68, 0x4d, 0x1f, 0x4e, - 0x8c, 0xf1, 0x99, 0x6b, 0x1a, 0xe6, 0x78, 0xa2, 0x0f, 0x9c, 0x87, 0x84, 0xf8, 0x21, 0xdf, 0x61, - 0xb0, 0x41, 0x7f, 0xf8, 0xf8, 0xf8, 0xf7, 0x01, 0x00, 0x00, 0xff, 0xff, 0x1b, 0x22, 0xc2, 0x07, - 0x0c, 0x29, 0x00, 0x00, + // 3630 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x3a, 0x4d, 0x6f, 0xdb, 0xd8, + 0x76, 0xd6, 0x87, 0x2d, 0xe9, 0x88, 0x92, 0xe9, 0x6b, 0x3b, 0x91, 0x95, 0x38, 0xe3, 0x70, 0x3e, + 0x9a, 0xf1, 0x4c, 0x9c, 0x89, 0x33, 0x93, 0xce, 0x47, 0x3a, 0x05, 0x25, 0xd1, 0x23, 0x25, 0xb2, + 0xa4, 0xa1, 0xa4, 0x64, 0x32, 0x40, 0x41, 0x50, 0xd2, 0xb5, 0xcc, 0x5a, 0x22, 0x55, 0x92, 0x4a, + 0xec, 0x2e, 0x66, 0xd1, 0x5d, 0x7f, 0x40, 0xd1, 0x02, 0xc5, 0x2c, 0x0a, 0x74, 0xdf, 0xa2, 0xdd, + 0x74, 0x59, 0x74, 0xd1, 0x65, 0x7f, 0x42, 0x3f, 0x80, 0xfe, 0x89, 0xb7, 0x7b, 0xb8, 0x1f, 0xa4, + 0x48, 0x8a, 0xb2, 0xf3, 0xe6, 0xbd, 0x07, 0xbc, 0x8d, 0x4d, 0x9e, 0x7b, 0xce, 0xbd, 0xe7, 0x9c, + 0x7b, 0xbe, 0x29, 0x10, 0xf5, 0xf9, 0xd0, 0x35, 0x2c, 0x13, 0x63, 0xfb, 0x68, 0x66, 0x5b, 0xae, + 0x85, 0x32, 0x33, 0xcb, 0x9a, 0xd8, 0xb3, 0xa1, 0xf4, 0x57, 0x09, 0xd8, 0x55, 0xb1, 0x83, 0xed, + 0x37, 0x58, 0x1e, 0x0e, 0xad, 0xb9, 0xe9, 0xaa, 0xf8, 0x2f, 0xe6, 0xd8, 0x71, 0xd1, 0xfb, 0x50, + 0xd0, 0x19, 0x44, 0x7b, 0xa3, 0x4f, 0xe6, 0xb8, 0x94, 0x38, 0x48, 0x3c, 0x48, 0xab, 0x02, 0x07, + 0xbe, 0x24, 0x30, 0xf4, 0x21, 0x14, 0x3d, 0x24, 0x7c, 0x39, 0x33, 0xec, 0xab, 0x52, 0xf2, 0x20, + 0xf1, 0xa0, 0xa0, 0x7a, 0xa4, 0x0a, 0x05, 0xa2, 0x7d, 0x00, 0xd7, 0xd6, 0x47, 0xd8, 0xd6, 0x2e, + 0xf0, 0x55, 0x29, 0x75, 0x90, 0x78, 0x20, 0xa8, 0x39, 0x06, 0x79, 0x81, 0xaf, 0xa4, 0x0b, 0xb8, + 0x15, 0xe5, 0xc1, 0x99, 0x59, 0xa6, 0xc3, 0xf6, 0xf7, 0x79, 0xa7, 0xc4, 0x09, 0x4a, 0x5c, 0x58, + 0x40, 0x5f, 0xe0, 0x2b, 0x74, 0x08, 0x5b, 0x86, 0x69, 0xb8, 0x86, 0x3e, 0xd1, 0x06, 0xba, 0x3b, + 0x3c, 0xa7, 0x98, 0x49, 0x8a, 0xb9, 0xc9, 0x17, 0x2a, 0x04, 0x4e, 0x0e, 0xfb, 0xff, 0x04, 0x94, + 0xba, 0xe4, 0x2c, 0xbb, 0x61, 0x1a, 0x6e, 0x44, 0xe8, 0xa7, 0x0b, 0xa1, 0x67, 0x96, 0x61, 0xba, + 0xf4, 0xb8, 0xfc, 0xf1, 0xd6, 0x11, 0xd7, 0xd7, 0x51, 0x7b, 0xee, 0x76, 0xc8, 0x82, 0xaf, 0x07, + 0xfa, 0x16, 0xd4, 0x83, 0x33, 0xb4, 0x8d, 0x99, 0xcb, 0x4f, 0xf7, 0x76, 0xeb, 0x52, 0xe0, 0xb2, + 0x4e, 0x53, 0xef, 0xa4, 0xd3, 0xf4, 0xcd, 0x3a, 0x5d, 0x8f, 0xea, 0xf4, 0x0e, 0xec, 0xc5, 0x48, + 0xc9, 0xd4, 0x2a, 0xcd, 0x3d, 0x15, 0x74, 0xe7, 0x83, 0xa9, 0xe1, 0xb6, 0xed, 0x11, 0xb6, 0x3d, + 0x15, 0x7c, 0x04, 0x29, 0xdd, 0xb9, 0xe0, 0x82, 0x23, 0x5f, 0x70, 0x86, 0x2f, 0x3b, 0x17, 0xf5, + 0x35, 0x95, 0x20, 0x10, 0xbc, 0x81, 0x31, 0xa2, 0x72, 0x2e, 0xe3, 0x55, 0x8c, 0x11, 0xc1, 0x1b, + 0x18, 0xa3, 0x4a, 0x0e, 0x32, 0x23, 0xec, 0xea, 0xc6, 0xc4, 0x21, 0xc6, 0xb6, 0x17, 0x73, 0x2e, + 0xbf, 0xeb, 0x67, 0x50, 0x30, 0xcc, 0x37, 0xfa, 0xc4, 0x18, 0x69, 0x16, 0x59, 0xe0, 0x2c, 0xec, + 0xfa, 0x5b, 0x37, 0xd8, 0x2a, 0xa5, 0xaa, 0xaf, 0xa9, 0x82, 0x11, 0x78, 0x47, 0x77, 0x21, 0xab, + 0x0f, 0x87, 0x78, 0xe6, 0x62, 0xc6, 0x53, 0xb6, 0xbe, 0xa6, 0xfa, 0x90, 0x20, 0x13, 0xdf, 0x78, + 0xb2, 0x57, 0x75, 0x73, 0x88, 0x27, 0x21, 0xd9, 0xdf, 0x83, 0x3c, 0x3d, 0x5a, 0x33, 0x2d, 0x73, + 0x88, 0xb9, 0xad, 0x01, 0x05, 0xb5, 0x08, 0x64, 0xa1, 0xd5, 0x10, 0x31, 0xd7, 0xea, 0xff, 0x26, + 0x61, 0xa7, 0x3a, 0x31, 0xb0, 0xe9, 0xca, 0xcc, 0x3a, 0x4f, 0xb1, 0xe3, 0xe8, 0x63, 0x8c, 0x3e, + 0x87, 0x8d, 0xa1, 0x35, 0x9d, 0x1a, 0x9e, 0x39, 0x95, 0x7d, 0x91, 0xf8, 0xc5, 0x54, 0xe9, 0xea, + 0x14, 0x9b, 0x6e, 0x7d, 0x4d, 0xe5, 0xb8, 0xe8, 0x19, 0xe4, 0x9c, 0xf9, 0x80, 0x98, 0xd3, 0x00, + 0x73, 0x35, 0xdf, 0x8d, 0x12, 0x76, 0x19, 0xc2, 0x8c, 0x9c, 0x56, 0x5f, 0x53, 0x17, 0x04, 0xe8, + 0x09, 0x6c, 0x30, 0xe9, 0xa9, 0x8d, 0xe5, 0x8f, 0xf7, 0x16, 0x26, 0x4c, 0x98, 0x3e, 0x25, 0xee, + 0x20, 0x53, 0x04, 0x72, 0x24, 0x43, 0x25, 0x44, 0x36, 0xfe, 0x73, 0x3c, 0x74, 0xa9, 0xc9, 0xc5, + 0x13, 0xa9, 0x14, 0x81, 0x10, 0x31, 0x54, 0xf4, 0x10, 0xd2, 0x8e, 0x31, 0x36, 0xa9, 0x09, 0xe6, + 0x8f, 0x6f, 0xc7, 0x90, 0x74, 0x8d, 0x31, 0xe1, 0x8e, 0xa2, 0xa1, 0xcf, 0x21, 0x63, 0xe3, 0xa1, + 0xf5, 0x06, 0xdb, 0xa5, 0x0d, 0x4a, 0x51, 0x8a, 0x0a, 0xa5, 0xb2, 0xe5, 0xab, 0xfa, 0x9a, 0xea, + 0xa1, 0x56, 0xd6, 0x21, 0x35, 0x75, 0xc6, 0xd2, 0x6b, 0xd8, 0x5a, 0x52, 0x19, 0xb9, 0x35, 0xa6, + 0x32, 0xed, 0x5c, 0x77, 0xce, 0xbd, 0x5b, 0x63, 0xa0, 0xba, 0xee, 0x9c, 0x13, 0xb7, 0x63, 0x61, + 0xe1, 0x0d, 0xb6, 0x1d, 0xc3, 0x32, 0x79, 0x90, 0x12, 0x28, 0xf0, 0x25, 0x83, 0x49, 0x36, 0x6c, + 0xc7, 0x28, 0x35, 0xe2, 0x66, 0x89, 0x88, 0x9b, 0xa1, 0xfb, 0x20, 0xf0, 0xb3, 0x99, 0xc9, 0x30, + 0xb7, 0xe7, 0xfc, 0x50, 0x9b, 0x41, 0x7b, 0x90, 0xd5, 0xe7, 0xee, 0xb9, 0xe6, 0x18, 0x63, 0x1e, + 0xfa, 0x32, 0xe4, 0xbd, 0x6b, 0x8c, 0xa5, 0x87, 0x20, 0x46, 0x6f, 0x83, 0xa0, 0x33, 0x66, 0x8d, + 0x11, 0x3f, 0x2e, 0x43, 0xdf, 0x1b, 0x23, 0xe9, 0x1f, 0x53, 0x41, 0x7c, 0x76, 0x11, 0xd7, 0xe0, + 0xa3, 0x5b, 0xe4, 0x3a, 0x75, 0x87, 0x0b, 0x9c, 0x53, 0xf9, 0x1b, 0xfa, 0x0e, 0xf2, 0xec, 0x49, + 0x1b, 0x5a, 0x23, 0x16, 0x84, 0x8a, 0xc7, 0x1f, 0xad, 0xbc, 0xeb, 0x23, 0xf6, 0x4f, 0xa5, 0x24, + 0x2a, 0x30, 0xd2, 0xaa, 0x35, 0xc2, 0xe8, 0x25, 0x6c, 0x32, 0x23, 0xc0, 0xdc, 0x67, 0x9d, 0x52, + 0xfa, 0x20, 0xf5, 0x20, 0x7f, 0xfc, 0xf0, 0xa6, 0xcd, 0x30, 0x73, 0x5b, 0x47, 0x31, 0x5d, 0xfb, + 0x4a, 0x2d, 0xda, 0x21, 0x60, 0xf9, 0x15, 0x6c, 0xc7, 0xa0, 0x21, 0x11, 0x52, 0xde, 0x25, 0xe4, + 0x54, 0xf2, 0x88, 0x0e, 0x61, 0x9d, 0x05, 0x52, 0xe6, 0x1f, 0x3b, 0xe1, 0x63, 0x39, 0xdf, 0x0c, + 0xe5, 0xeb, 0xe4, 0x97, 0x09, 0x69, 0x08, 0x42, 0x50, 0x18, 0x94, 0x87, 0x4c, 0xbf, 0xf5, 0xa2, + 0xd5, 0x7e, 0xd5, 0x12, 0xd7, 0xd0, 0x2d, 0x40, 0x5d, 0x45, 0x7d, 0xa9, 0xa8, 0xda, 0x69, 0xa3, + 0x5b, 0x51, 0xea, 0xf2, 0xcb, 0x46, 0x5b, 0x15, 0x13, 0xa8, 0x0c, 0xb7, 0x2a, 0x72, 0xaf, 0x5a, + 0xd7, 0x5e, 0x2a, 0x6a, 0xb7, 0xd1, 0x6e, 0x91, 0xe5, 0x53, 0x02, 0x10, 0x93, 0x08, 0x41, 0xb1, + 0x23, 0xab, 0xbd, 0x86, 0xdc, 0xd4, 0x54, 0xe5, 0xb9, 0x52, 0xed, 0x89, 0x29, 0xe9, 0x5f, 0x13, + 0x90, 0x0f, 0x9c, 0x1f, 0xb8, 0x86, 0xc4, 0x75, 0xd7, 0x90, 0x8c, 0xbb, 0x06, 0xae, 0xb4, 0xa0, + 0x38, 0x4b, 0xd7, 0x20, 0x55, 0x61, 0x6b, 0x09, 0x81, 0x70, 0x56, 0xeb, 0x77, 0x9a, 0x8d, 0xaa, + 0xdc, 0x53, 0xb4, 0x8e, 0xa2, 0xa8, 0xe2, 0x1a, 0x91, 0xa4, 0x5a, 0x97, 0x5b, 0x2d, 0xa5, 0xa9, + 0x9d, 0xf4, 0x5b, 0xb5, 0x46, 0xeb, 0x3b, 0xed, 0x44, 0x6e, 0x34, 0x95, 0x9a, 0x98, 0x90, 0x7e, + 0x95, 0x80, 0x7c, 0xf5, 0x5c, 0x37, 0x4d, 0x3c, 0x69, 0x98, 0x67, 0x16, 0x7a, 0x00, 0x69, 0xf7, + 0x6a, 0xc6, 0x82, 0x60, 0x31, 0xa0, 0x59, 0x8e, 0xd3, 0xbb, 0x9a, 0x61, 0x95, 0x62, 0xa0, 0x0f, + 0xa0, 0x38, 0xb1, 0x86, 0xfa, 0x44, 0x33, 0xad, 0x11, 0x0e, 0xa4, 0x5e, 0x81, 0x42, 0x5b, 0xd6, + 0x08, 0x13, 0x4f, 0xf9, 0x88, 0xd8, 0xca, 0xd4, 0x72, 0xf1, 0x02, 0x8d, 0x79, 0x43, 0x81, 0x81, + 0x3d, 0xbc, 0x3f, 0x86, 0x12, 0xdb, 0x6d, 0xa6, 0x5f, 0x11, 0xf7, 0xd6, 0x06, 0xba, 0x83, 0x79, + 0x36, 0x4e, 0x53, 0x82, 0x5d, 0xba, 0xde, 0x61, 0xcb, 0x15, 0xdd, 0xc1, 0x2c, 0x07, 0x7f, 0x05, + 0x7b, 0xfc, 0x80, 0x18, 0x4a, 0x96, 0x1f, 0x6f, 0x31, 0x84, 0x28, 0xa9, 0xf4, 0x3f, 0x49, 0x28, + 0x86, 0xc3, 0xd5, 0x75, 0x6e, 0xf5, 0x02, 0x04, 0x3f, 0xd9, 0x1b, 0x63, 0xa7, 0x94, 0xa4, 0x26, + 0xff, 0x60, 0x45, 0xe0, 0xf3, 0x43, 0xb5, 0x31, 0xe6, 0xd6, 0x9e, 0xd7, 0x17, 0x10, 0xd4, 0x82, + 0xc2, 0x90, 0x69, 0x54, 0x33, 0xcc, 0x33, 0xcb, 0x29, 0xa5, 0xe8, 0x6e, 0x1f, 0xaf, 0xda, 0x2d, + 0x70, 0x45, 0x7c, 0x3b, 0x61, 0x18, 0x00, 0x95, 0xbf, 0x05, 0x31, 0x7a, 0x60, 0x8c, 0xdf, 0xec, + 0x04, 0xfd, 0x46, 0x08, 0x78, 0x48, 0xb9, 0x0f, 0x5b, 0x4b, 0x47, 0xfc, 0x26, 0x8e, 0x17, 0x20, + 0x0e, 0x3a, 0xde, 0x67, 0xb0, 0x19, 0x89, 0xee, 0x37, 0x44, 0x56, 0xe9, 0xef, 0x53, 0xb0, 0xc3, + 0x8b, 0x8e, 0x70, 0x36, 0xfd, 0x12, 0x72, 0xc3, 0x73, 0x7d, 0x32, 0xc1, 0xe6, 0x18, 0xf3, 0x84, + 0x5a, 0x8a, 0x94, 0x1f, 0x55, 0x6f, 0x9d, 0xe4, 0x44, 0x1f, 0x19, 0x7d, 0x01, 0x19, 0x67, 0x3e, + 0x1c, 0x62, 0xc7, 0xe1, 0x6c, 0x2f, 0xf2, 0x5b, 0xd7, 0x4b, 0x9c, 0x5d, 0x86, 0x40, 0x72, 0x0f, + 0xc7, 0x45, 0x8f, 0x60, 0x1d, 0xdb, 0xb6, 0x65, 0xf3, 0x4c, 0x7a, 0x7b, 0x99, 0x48, 0x21, 0xcb, + 0xf5, 0x35, 0x95, 0xe1, 0xa1, 0xa7, 0x90, 0x99, 0xd9, 0x78, 0xa6, 0xdb, 0x98, 0xe7, 0xd1, 0x72, + 0xcc, 0x6d, 0x76, 0x18, 0x06, 0x39, 0x88, 0x23, 0xa3, 0xe3, 0x50, 0x26, 0xbd, 0xbb, 0xc2, 0x04, + 0x2a, 0x78, 0x6c, 0x2c, 0xd2, 0xe9, 0x57, 0x90, 0x3d, 0x33, 0x4c, 0x7d, 0x62, 0xfc, 0x25, 0xe6, + 0xf9, 0xf4, 0x4e, 0x0c, 0xdd, 0x09, 0x47, 0x21, 0x45, 0x91, 0x87, 0x8e, 0x9e, 0x40, 0x86, 0x5b, + 0x62, 0x29, 0x13, 0x91, 0x8c, 0xab, 0x9c, 0x5f, 0x19, 0xe1, 0x91, 0x63, 0x7a, 0x89, 0xb8, 0x03, + 0x9b, 0x11, 0x55, 0xa3, 0xbb, 0xd1, 0x7b, 0x11, 0x82, 0xba, 0x8f, 0x24, 0xe9, 0x64, 0x34, 0x49, + 0x4b, 0x8f, 0x41, 0x8c, 0x5e, 0xc2, 0x4d, 0x26, 0xf2, 0xcf, 0x69, 0x1e, 0xf8, 0x82, 0x0a, 0x45, + 0x3d, 0x28, 0x4e, 0xc9, 0xfb, 0x22, 0x27, 0x25, 0x56, 0xe6, 0x24, 0x4e, 0x73, 0x74, 0xca, 0x08, + 0x82, 0x39, 0xa9, 0x30, 0x0d, 0xc2, 0xd0, 0x11, 0x6c, 0x0f, 0x27, 0x58, 0xb7, 0x0d, 0x73, 0xac, + 0xcd, 0x6c, 0x63, 0x88, 0x35, 0x5b, 0x77, 0x31, 0xaf, 0x24, 0xb6, 0xbc, 0xa5, 0x0e, 0x59, 0x51, + 0x75, 0x17, 0xa3, 0x3f, 0x05, 0x71, 0x78, 0xae, 0xdb, 0x63, 0x3c, 0xd2, 0xb8, 0xea, 0x3c, 0xd7, + 0xde, 0x89, 0xd6, 0x3b, 0x35, 0xe3, 0xec, 0x4c, 0xdd, 0xe4, 0xd8, 0x1c, 0xe6, 0xa0, 0xaf, 0xa1, + 0x80, 0x2f, 0xf1, 0x70, 0x4e, 0xee, 0x41, 0x3b, 0xc3, 0x9e, 0x29, 0x2d, 0xca, 0x61, 0xc5, 0x5b, + 0x3d, 0xc1, 0x58, 0x15, 0x70, 0xe0, 0x0d, 0x7d, 0x02, 0x5b, 0x2c, 0x78, 0xb9, 0xb6, 0x6e, 0x3a, + 0x3a, 0xbd, 0x4b, 0x1e, 0x02, 0x45, 0xba, 0xd0, 0x5b, 0xc0, 0xd1, 0xa7, 0xb0, 0x7d, 0x86, 0x99, + 0x38, 0x9a, 0xa3, 0xbb, 0xda, 0x8c, 0xa8, 0xfb, 0x2d, 0x35, 0xa6, 0xb4, 0xba, 0x79, 0x86, 0xa9, + 0x3c, 0x5d, 0xdd, 0xed, 0x60, 0xfb, 0xc5, 0x5b, 0x12, 0xec, 0x29, 0x36, 0x1e, 0x70, 0x7c, 0x6a, + 0x3b, 0x69, 0x55, 0x20, 0x88, 0x14, 0xd8, 0xd5, 0xc3, 0x45, 0x49, 0x36, 0x1c, 0x3d, 0x97, 0x8a, + 0xb1, 0xdc, 0x72, 0x31, 0x56, 0x7e, 0x05, 0x68, 0xf9, 0x4a, 0x62, 0xc2, 0xd0, 0x27, 0xe1, 0x30, + 0xb4, 0x50, 0x4e, 0x90, 0x3a, 0x1c, 0x87, 0xb6, 0x63, 0xbc, 0xe9, 0xba, 0xa2, 0xcb, 0x02, 0xb4, + 0xec, 0x47, 0xd7, 0xa5, 0x87, 0x7d, 0x00, 0xae, 0xfc, 0x4b, 0xde, 0x1f, 0x09, 0x6a, 0x8e, 0x69, + 0xfd, 0xd2, 0x18, 0x11, 0x47, 0x38, 0xc7, 0xc6, 0xf8, 0xdc, 0xd5, 0xce, 0x49, 0x62, 0x4a, 0x51, + 0xe9, 0x81, 0x81, 0xea, 0x24, 0x19, 0xfd, 0x5b, 0x12, 0x8a, 0xe1, 0xc8, 0x42, 0xc2, 0x35, 0x8b, + 0x40, 0x4c, 0x74, 0x1e, 0x66, 0x9e, 0x01, 0xd0, 0x87, 0x60, 0xf9, 0xb0, 0xbf, 0x22, 0x38, 0x1d, + 0xd1, 0xbf, 0x6a, 0x8e, 0x12, 0xd0, 0xda, 0xed, 0xfa, 0x9e, 0x1c, 0xd5, 0x61, 0xdb, 0x4b, 0x72, + 0x36, 0xed, 0xcd, 0x75, 0x6a, 0x44, 0xe9, 0x6b, 0x03, 0x85, 0x8a, 0x74, 0xbf, 0xd3, 0xf4, 0x48, + 0x24, 0x03, 0xd6, 0x99, 0x14, 0xa1, 0x62, 0x6b, 0x1b, 0x36, 0x79, 0xb1, 0xd5, 0xad, 0xf7, 0x7b, + 0x35, 0x02, 0xa4, 0x95, 0x96, 0x5c, 0xad, 0xb6, 0xfb, 0xad, 0x9e, 0x56, 0x6b, 0x2b, 0x5d, 0xad, + 0xd5, 0xee, 0x69, 0xca, 0x0f, 0x8d, 0x6e, 0x4f, 0x4c, 0x22, 0x09, 0xee, 0x35, 0x5a, 0xd5, 0xf6, + 0x69, 0xa7, 0xa9, 0xf4, 0x14, 0xcd, 0x43, 0x53, 0x15, 0xb2, 0x8b, 0xdc, 0x6b, 0xb4, 0x5b, 0x62, + 0x4a, 0xfa, 0x8f, 0x24, 0x14, 0xc3, 0x1c, 0x2d, 0x32, 0x1d, 0x1b, 0x5f, 0xb0, 0x17, 0x52, 0x92, + 0x85, 0xe6, 0x15, 0xfc, 0xed, 0x26, 0xa5, 0x2c, 0x8f, 0x23, 0xd2, 0x71, 0xe3, 0x88, 0x3b, 0x90, + 0x5b, 0x8c, 0x21, 0x98, 0xdb, 0x31, 0x6b, 0x21, 0x8b, 0xc7, 0xb0, 0xee, 0xb8, 0x24, 0x74, 0x6c, + 0xd0, 0x0b, 0xbb, 0xbb, 0x42, 0x95, 0x5d, 0x82, 0xa3, 0x32, 0xd4, 0xa8, 0xcd, 0x64, 0xa2, 0x36, + 0x83, 0x1e, 0x42, 0xd6, 0x9a, 0xbb, 0xac, 0xd4, 0xc9, 0xae, 0x1a, 0x59, 0xf8, 0x28, 0x84, 0xc1, + 0x89, 0xee, 0x62, 0xc7, 0xd5, 0xdc, 0x4b, 0xea, 0x7f, 0x82, 0x9a, 0x65, 0x80, 0xde, 0xa5, 0xf4, + 0x13, 0x08, 0x41, 0xef, 0x41, 0x4f, 0x41, 0xf0, 0xe2, 0xe9, 0xc0, 0x18, 0x79, 0xd1, 0x74, 0x3b, + 0xea, 0x6a, 0x15, 0x63, 0xa4, 0xe6, 0xa7, 0xfe, 0xb3, 0x13, 0xa4, 0xd3, 0x9d, 0x0b, 0xaf, 0x4c, + 0x5a, 0xa2, 0x93, 0x9d, 0x0b, 0x9f, 0x4e, 0x76, 0x2e, 0x1c, 0xa9, 0x0f, 0xb0, 0x58, 0x42, 0x1f, + 0xdc, 0x30, 0x8e, 0x60, 0xc3, 0x88, 0xfb, 0x20, 0xcc, 0x4d, 0xc3, 0x75, 0xb4, 0x33, 0x63, 0x32, + 0xe1, 0x13, 0x80, 0x82, 0x9a, 0xa7, 0xb0, 0x13, 0x0a, 0x0a, 0x6c, 0x5b, 0x31, 0x46, 0x64, 0xdb, + 0x01, 0x77, 0xdd, 0xd8, 0xe9, 0x05, 0x9d, 0x5d, 0xbc, 0xcb, 0xb6, 0xff, 0x9e, 0x84, 0x7c, 0x20, + 0x8e, 0x13, 0x13, 0xc1, 0xe6, 0x88, 0x64, 0x89, 0x81, 0x3e, 0xd1, 0xbd, 0x29, 0x42, 0x5a, 0x2d, + 0x30, 0x68, 0x85, 0x01, 0x51, 0x0d, 0x04, 0x8e, 0xc6, 0x8c, 0x81, 0x79, 0xef, 0xfd, 0xb8, 0xd4, + 0x70, 0x14, 0xb2, 0x88, 0x3c, 0x23, 0xa3, 0x2f, 0xe4, 0x30, 0xef, 0x4e, 0x35, 0xc3, 0x1c, 0xe1, + 0x4b, 0x6a, 0xb2, 0xeb, 0x6a, 0xc1, 0x83, 0x36, 0x08, 0x30, 0x62, 0xd5, 0xe9, 0x68, 0x1a, 0xfd, + 0x09, 0x84, 0xe0, 0x11, 0x68, 0x07, 0xc4, 0x76, 0xbf, 0xd7, 0xe9, 0x13, 0xef, 0xaa, 0xaa, 0x8a, + 0xdc, 0x53, 0x6a, 0xe2, 0x1a, 0xba, 0x0f, 0xfb, 0x1c, 0x5a, 0xeb, 0x77, 0x89, 0x5b, 0xf6, 0x94, + 0x56, 0x4d, 0xa9, 0x69, 0xed, 0x93, 0x93, 0x6a, 0x5d, 0x6e, 0x10, 0xf7, 0xdd, 0x87, 0xbd, 0x20, + 0x8a, 0x5c, 0x23, 0xeb, 0xbd, 0xb6, 0x76, 0xa2, 0x28, 0x5d, 0x31, 0x49, 0xfa, 0x2b, 0xbe, 0x7c, + 0xd2, 0x6f, 0x36, 0x5f, 0x6b, 0xdd, 0x8e, 0xd2, 0x22, 0xfd, 0xd2, 0xdf, 0xa5, 0x20, 0xcf, 0x14, + 0xcf, 0x0c, 0xee, 0x86, 0x96, 0x7b, 0x1f, 0x80, 0xe6, 0xaa, 0x33, 0xe3, 0xd2, 0xbf, 0x92, 0x1c, + 0x81, 0x9c, 0x10, 0x00, 0x49, 0x12, 0xfa, 0xd4, 0xe5, 0x93, 0x35, 0xf2, 0x88, 0x0e, 0x40, 0x98, + 0x1a, 0xa6, 0x46, 0xca, 0x64, 0x8d, 0x2c, 0xa5, 0xe9, 0x12, 0x4c, 0x0d, 0x93, 0x14, 0xab, 0xf2, + 0x74, 0x69, 0xee, 0xb3, 0x11, 0x9d, 0xfb, 0x10, 0x87, 0x61, 0x08, 0xa4, 0x89, 0xcf, 0x30, 0x87, + 0xa1, 0x80, 0xae, 0x31, 0x46, 0x12, 0x14, 0xa6, 0xf3, 0x89, 0x6b, 0x90, 0x45, 0xca, 0x32, 0xcb, + 0x78, 0x79, 0x0a, 0xec, 0x1a, 0x63, 0xc2, 0xf4, 0x1e, 0x64, 0x69, 0xdb, 0x33, 0x9b, 0x0f, 0xb8, + 0xc3, 0x65, 0xc8, 0x7b, 0x67, 0x3e, 0x40, 0x8f, 0x21, 0x47, 0x97, 0xf4, 0xd1, 0xc8, 0x2e, 0x41, + 0xa4, 0x44, 0x20, 0x5d, 0x91, 0x3c, 0x1a, 0xd9, 0xd8, 0x71, 0x54, 0xba, 0x03, 0x79, 0x21, 0xec, + 0x50, 0x69, 0x68, 0x83, 0x26, 0x50, 0x0d, 0x64, 0x09, 0x80, 0x34, 0x65, 0xe8, 0x5b, 0xd8, 0x9f, + 0xea, 0x97, 0x7c, 0x10, 0x1a, 0x97, 0xd9, 0x0b, 0x54, 0xfe, 0xdb, 0x53, 0xfd, 0x92, 0x0e, 0x45, + 0x4f, 0xc2, 0x19, 0xfe, 0x79, 0x3a, 0xbb, 0x2e, 0x6e, 0x3c, 0x4f, 0x67, 0xf3, 0xa2, 0x20, 0xfd, + 0x67, 0x02, 0x72, 0xbe, 0x4f, 0xa0, 0x23, 0x7f, 0x8a, 0xc6, 0x1d, 0x67, 0x27, 0xe2, 0x38, 0x2c, + 0xdd, 0x7a, 0x48, 0xe8, 0x18, 0x76, 0x27, 0x98, 0xf4, 0x60, 0xa3, 0xb9, 0x4d, 0x73, 0x81, 0x36, + 0x98, 0x58, 0xc3, 0x0b, 0x87, 0x5f, 0xda, 0x36, 0x5d, 0xac, 0xf1, 0xb5, 0x0a, 0x5d, 0x42, 0x25, + 0xc8, 0x78, 0x85, 0x01, 0x1b, 0x7b, 0x7a, 0xaf, 0xe8, 0x0b, 0x28, 0x90, 0x6b, 0xa4, 0xba, 0x72, + 0x0d, 0x6c, 0xd3, 0xc8, 0x5a, 0x0c, 0x04, 0x3a, 0xa2, 0xab, 0x9e, 0x81, 0x6d, 0x35, 0x3f, 0x35, + 0x4c, 0xef, 0xe5, 0x79, 0x3a, 0x9b, 0x12, 0xd3, 0xd2, 0x5f, 0xfb, 0x82, 0x90, 0xa0, 0xf2, 0x3b, + 0x13, 0x24, 0xfd, 0x4e, 0x82, 0xac, 0x87, 0x04, 0x91, 0x8e, 0x20, 0x1f, 0x18, 0x1f, 0xde, 0x3c, + 0x74, 0xfc, 0x97, 0x04, 0x08, 0xc1, 0xd9, 0xe7, 0x8d, 0x14, 0x48, 0x86, 0xfc, 0x99, 0x6e, 0x4c, + 0xb4, 0xc0, 0xf4, 0xa7, 0x78, 0x7c, 0x10, 0x3b, 0x48, 0x3d, 0x3a, 0xd1, 0x8d, 0x89, 0x37, 0x53, + 0x38, 0xf3, 0x9f, 0xc9, 0x19, 0x74, 0x0b, 0xc7, 0x25, 0x75, 0x2d, 0x75, 0xa7, 0x1c, 0x43, 0xe8, + 0x52, 0x88, 0xb4, 0x0f, 0xb0, 0x20, 0x45, 0x9b, 0x90, 0x6f, 0xb4, 0x5e, 0xca, 0xcd, 0x46, 0x4d, + 0x93, 0x4f, 0x7b, 0xe2, 0x9a, 0xf4, 0xcc, 0xf3, 0xe9, 0x86, 0x39, 0x9b, 0x87, 0x13, 0x54, 0xe2, + 0xc6, 0x04, 0x25, 0x3d, 0x03, 0x81, 0x5f, 0xc4, 0xdc, 0x25, 0xe4, 0x2b, 0xb3, 0x78, 0x68, 0xda, + 0xce, 0xdf, 0xa4, 0x7f, 0x4a, 0x42, 0x99, 0x91, 0x9f, 0x5a, 0x23, 0xe3, 0xec, 0x2a, 0x32, 0xe4, + 0xbf, 0x21, 0xbe, 0x3c, 0x01, 0x30, 0xf1, 0x5b, 0xcd, 0x20, 0x7c, 0x7b, 0x59, 0x2b, 0x6a, 0x1f, + 0x54, 0x28, 0x35, 0x67, 0xe2, 0xb7, 0xf4, 0x89, 0x24, 0xbb, 0x3c, 0x21, 0xb2, 0x28, 0xbb, 0x5e, + 0xa5, 0xbf, 0x1b, 0xb5, 0x2a, 0xba, 0xaa, 0x92, 0xed, 0xd9, 0xa3, 0x83, 0x5e, 0xb1, 0xc3, 0x66, + 0xba, 0xad, 0x4f, 0x1d, 0x5e, 0x5d, 0x7d, 0x19, 0x21, 0x8b, 0x13, 0xe2, 0xa8, 0x85, 0xdf, 0x72, + 0x48, 0x87, 0xd0, 0x62, 0x17, 0xdb, 0x0e, 0x65, 0x88, 0xbe, 0x3a, 0xe5, 0x4f, 0x61, 0x27, 0x0e, + 0x25, 0x5e, 0x93, 0xd2, 0xb7, 0x70, 0x27, 0xf6, 0x2c, 0x3e, 0x9a, 0x7f, 0x0f, 0xf2, 0x81, 0x89, + 0x87, 0x67, 0x70, 0x8b, 0x31, 0x86, 0xf4, 0x35, 0xdc, 0x0e, 0x38, 0x0e, 0xcb, 0x54, 0xef, 0x3a, + 0x53, 0xb7, 0xbd, 0x81, 0x7c, 0x90, 0x96, 0x1f, 0xfc, 0xb1, 0x57, 0x2c, 0xb1, 0x29, 0xd4, 0x76, + 0xb8, 0x85, 0x0b, 0xd5, 0x48, 0x9f, 0xc0, 0x16, 0xcb, 0xd5, 0x73, 0xf3, 0x6c, 0x3e, 0x09, 0x25, + 0x6c, 0x91, 0x2e, 0xf4, 0x17, 0x70, 0xa9, 0x08, 0x42, 0x0f, 0xdb, 0x53, 0x87, 0x33, 0x29, 0xfd, + 0x57, 0x12, 0x0a, 0x1c, 0xc0, 0x4f, 0x3e, 0x84, 0x2d, 0x12, 0x45, 0xe3, 0x3e, 0x81, 0x6d, 0x4e, + 0xf5, 0x4b, 0x39, 0xf8, 0xc5, 0xe6, 0x4f, 0x60, 0x8f, 0xe0, 0x32, 0x31, 0x63, 0x63, 0x5d, 0x25, + 0x59, 0x4a, 0xa8, 0xb7, 0xa6, 0xfa, 0x25, 0xe5, 0x3b, 0x12, 0x29, 0x96, 0x3a, 0xbd, 0xd4, 0xbb, + 0x77, 0x7a, 0x5d, 0xd8, 0x0c, 0x47, 0x26, 0x6f, 0x02, 0x7b, 0xe8, 0x53, 0x87, 0xe4, 0x3a, 0x6a, + 0x06, 0x43, 0x95, 0x37, 0x7e, 0x0d, 0xc5, 0x2f, 0xa7, 0x2c, 0xc3, 0x76, 0x0c, 0x5a, 0xb0, 0xfd, + 0x2a, 0xc4, 0x8c, 0x91, 0xb2, 0xc1, 0x3e, 0xab, 0x02, 0x3b, 0x2a, 0x9e, 0xe0, 0x37, 0xba, 0xe9, + 0x56, 0xd8, 0xf0, 0x97, 0x59, 0x43, 0x11, 0x92, 0x7e, 0xc7, 0x94, 0x34, 0x46, 0xa8, 0x4c, 0x3f, + 0xdb, 0xb0, 0xf6, 0x98, 0xb8, 0x9a, 0xa0, 0xfa, 0xef, 0xd2, 0xff, 0xa5, 0xa0, 0x10, 0xda, 0x24, + 0x18, 0x53, 0x13, 0xe1, 0xe4, 0xc0, 0xf6, 0x4d, 0xfa, 0xfb, 0xfe, 0xd6, 0xed, 0x77, 0x67, 0x69, + 0x8a, 0x90, 0x8e, 0x0c, 0xe6, 0x42, 0xac, 0xfd, 0xf2, 0x09, 0xc2, 0xfa, 0xaa, 0x09, 0xc2, 0x92, + 0x59, 0x6c, 0xbc, 0xbb, 0x59, 0x1c, 0x40, 0x3e, 0xd8, 0xfa, 0xb3, 0x8a, 0x25, 0x08, 0x5a, 0xd5, + 0xf5, 0x67, 0x63, 0xbb, 0xfe, 0xdf, 0x5f, 0x3f, 0x5e, 0x03, 0x21, 0x28, 0x06, 0xeb, 0xab, 0x1d, + 0x4c, 0xe5, 0x65, 0xde, 0x96, 0x21, 0xef, 0x7c, 0xc9, 0xe3, 0x98, 0x6e, 0x9f, 0x56, 0x33, 0x9c, + 0x4d, 0xe9, 0x1b, 0xc8, 0x07, 0x0a, 0x25, 0x62, 0x26, 0x26, 0x76, 0xdf, 0x5a, 0xf6, 0x05, 0xe7, + 0xcd, 0x7b, 0x45, 0x08, 0xd2, 0xb4, 0xcc, 0x62, 0xdf, 0x43, 0xe8, 0xb3, 0x24, 0x43, 0xd6, 0xcb, + 0x40, 0x64, 0x9d, 0x76, 0xed, 0xcc, 0x40, 0xe9, 0x33, 0x69, 0x02, 0x58, 0x58, 0xe7, 0x25, 0x36, + 0x6f, 0x02, 0x18, 0x8c, 0x16, 0xd8, 0xd2, 0xdf, 0x26, 0x20, 0x2f, 0x3b, 0x17, 0x5d, 0x53, 0x9f, + 0x39, 0xe7, 0x96, 0x7b, 0x8d, 0x9d, 0xfe, 0x92, 0x92, 0x28, 0x5c, 0xf0, 0xa6, 0xa2, 0x05, 0x6f, + 0xa8, 0x18, 0x4c, 0x87, 0x8b, 0x41, 0xca, 0x59, 0xc5, 0x18, 0xfd, 0x01, 0x72, 0xf6, 0xdf, 0x09, + 0xd8, 0x09, 0x5a, 0x85, 0xcf, 0x62, 0xe8, 0x03, 0x74, 0xc0, 0x5b, 0x17, 0xfa, 0x8d, 0xf9, 0x00, + 0xbd, 0xc0, 0x0b, 0x48, 0xcb, 0x9a, 0xb8, 0xf7, 0x81, 0x39, 0x22, 0xf1, 0x3b, 0x6a, 0x3c, 0x8c, + 0x4f, 0xc1, 0x03, 0x52, 0x67, 0xfb, 0x14, 0x90, 0x6b, 0xb9, 0xfa, 0x84, 0xf8, 0x82, 0xa3, 0x51, + 0x67, 0xc4, 0x23, 0xde, 0x29, 0x88, 0x74, 0xa5, 0xab, 0xbb, 0x4e, 0x95, 0xc1, 0xc9, 0x96, 0x2c, + 0xd7, 0x70, 0x0f, 0xe7, 0x4e, 0xcc, 0x9a, 0x45, 0x2e, 0x94, 0xf4, 0x18, 0x76, 0x68, 0x68, 0xf0, + 0xb9, 0xe1, 0x21, 0xf0, 0x9a, 0x59, 0xd3, 0x3f, 0x24, 0x61, 0x37, 0x42, 0xc3, 0xd3, 0xd1, 0xea, + 0x7b, 0x0b, 0x6e, 0x97, 0x0c, 0x4f, 0xa2, 0x24, 0x28, 0xcc, 0x6c, 0xfc, 0x46, 0xf3, 0xd7, 0xd9, + 0x40, 0x23, 0x4f, 0x80, 0x15, 0x8e, 0xb3, 0x22, 0x2a, 0xa5, 0x57, 0x45, 0xa5, 0xda, 0x52, 0x5c, + 0x5c, 0xa7, 0x71, 0x71, 0x3f, 0xd6, 0xd5, 0x7d, 0x39, 0x22, 0xb1, 0xf0, 0x1e, 0xe4, 0xbd, 0x19, + 0x19, 0xe1, 0x2b, 0x43, 0xdd, 0xd1, 0x1b, 0x92, 0x35, 0x46, 0x0b, 0xa1, 0xdc, 0x4b, 0xde, 0x8d, + 0x65, 0xf8, 0xa2, 0xf4, 0xcc, 0x2b, 0x35, 0x88, 0xc7, 0xab, 0xba, 0x4b, 0x6e, 0x90, 0x6b, 0xf6, + 0x3e, 0x08, 0x5e, 0x93, 0x75, 0x81, 0xaf, 0xd8, 0xa4, 0x42, 0x50, 0xf3, 0xbc, 0xd1, 0x22, 0x20, + 0xe9, 0xcf, 0x00, 0x16, 0x74, 0xa4, 0x36, 0x09, 0x10, 0x78, 0xb5, 0xc9, 0x02, 0x1f, 0x1d, 0xf1, + 0xde, 0x8c, 0xf6, 0x1b, 0xc9, 0x55, 0xfd, 0x06, 0x6d, 0xcc, 0xc8, 0x93, 0xa4, 0x7a, 0xb5, 0x4c, + 0x90, 0x39, 0x7e, 0x85, 0x4f, 0x39, 0x77, 0x36, 0x05, 0x2f, 0xcf, 0x51, 0x02, 0x24, 0x94, 0x2b, + 0xf6, 0xec, 0x1c, 0x7e, 0xec, 0x7f, 0x97, 0xa3, 0xed, 0x5d, 0x01, 0x72, 0xbd, 0x57, 0x8a, 0xfc, + 0xa2, 0xa9, 0x74, 0xbb, 0xe2, 0x1a, 0xca, 0x43, 0x46, 0x6e, 0x55, 0xeb, 0x6d, 0xb5, 0x2b, 0x26, + 0x0e, 0xff, 0x26, 0x01, 0xdb, 0x31, 0x63, 0x24, 0xfa, 0x65, 0xb3, 0xc7, 0xbe, 0x03, 0xb2, 0xaf, + 0x7e, 0xed, 0x8e, 0xd2, 0x12, 0xd7, 0x50, 0x11, 0x80, 0xc1, 0xe9, 0x7b, 0x02, 0x6d, 0x41, 0x81, + 0xbd, 0x2b, 0x3f, 0x74, 0x1a, 0xaa, 0x52, 0x13, 0x93, 0xa8, 0x04, 0x3b, 0x61, 0xd2, 0x7e, 0xa7, + 0x26, 0xf7, 0x14, 0x31, 0x85, 0x44, 0x10, 0xd8, 0x4a, 0xb5, 0xd9, 0xee, 0x2a, 0x35, 0x31, 0x8d, + 0x6e, 0xc3, 0x76, 0x18, 0x97, 0x7e, 0x36, 0x15, 0xd7, 0x0f, 0x3f, 0x87, 0xac, 0xa7, 0x2c, 0x42, + 0xd6, 0x6b, 0x28, 0xaa, 0x56, 0x53, 0x4e, 0xe4, 0x7e, 0xb3, 0x27, 0xae, 0x21, 0x80, 0x0d, 0x0a, + 0xf9, 0x4c, 0x4c, 0xf8, 0xcf, 0x8f, 0xc5, 0xe4, 0xe1, 0xcf, 0x09, 0x80, 0x45, 0x9d, 0x87, 0xb6, + 0x61, 0xb3, 0xad, 0xd6, 0x14, 0x55, 0xeb, 0xf6, 0x2b, 0xa7, 0x8d, 0x1e, 0x9b, 0x4a, 0x6c, 0x41, + 0x81, 0x01, 0xab, 0x4d, 0x45, 0x26, 0x1c, 0xd3, 0x21, 0x22, 0x03, 0xf1, 0x0f, 0xb3, 0xcd, 0xd7, + 0xda, 0x49, 0xa3, 0xd9, 0xa4, 0xd2, 0x20, 0x28, 0xb2, 0x35, 0xe5, 0x07, 0xa5, 0xda, 0x27, 0x5b, + 0xa4, 0x16, 0xb0, 0xaa, 0xdc, 0xaa, 0x2a, 0x4d, 0x2a, 0x89, 0xbf, 0xad, 0xa7, 0x88, 0x75, 0xc2, + 0x37, 0x03, 0xf1, 0x2f, 0xa6, 0x1b, 0xc7, 0x3f, 0x67, 0xfc, 0x6f, 0x65, 0xb2, 0x3f, 0xff, 0x43, + 0xdf, 0x43, 0x31, 0xfc, 0x63, 0x26, 0x74, 0x2f, 0x50, 0x32, 0xc4, 0xfc, 0xd2, 0xaa, 0xfc, 0xde, + 0xca, 0x75, 0x6e, 0x39, 0x3d, 0xc8, 0x07, 0x7e, 0xc5, 0x83, 0xee, 0x2f, 0x35, 0x23, 0xd1, 0xdf, + 0x31, 0x95, 0xa5, 0xeb, 0x50, 0xf8, 0xae, 0x3f, 0x42, 0x21, 0x54, 0xed, 0xa3, 0xf7, 0xdf, 0xa1, + 0xef, 0x28, 0x7f, 0x70, 0x3d, 0xd2, 0x82, 0xe3, 0xc0, 0x4f, 0x7c, 0x96, 0x38, 0x5e, 0xfe, 0xd9, + 0xd1, 0x12, 0xc7, 0x71, 0xbf, 0x10, 0xea, 0x85, 0x1b, 0xe7, 0xe8, 0xae, 0xcb, 0x3f, 0xe8, 0x59, + 0xda, 0x35, 0xe6, 0x67, 0x3b, 0xe8, 0xfb, 0x90, 0x95, 0x1d, 0xc4, 0x4d, 0x02, 0x82, 0x0d, 0x4d, + 0xf9, 0xfe, 0x35, 0x18, 0x7c, 0xcb, 0xd7, 0xb0, 0xeb, 0x8f, 0xdf, 0x69, 0xa0, 0xe5, 0xf6, 0x81, + 0x16, 0x51, 0x32, 0xee, 0x87, 0x42, 0xe5, 0xfd, 0xe8, 0x7c, 0x33, 0xb4, 0xfc, 0x20, 0xf1, 0x59, + 0x02, 0x3d, 0x85, 0x75, 0x5a, 0xd0, 0xa3, 0xdd, 0x68, 0x81, 0xcf, 0xb8, 0xbb, 0x15, 0x5f, 0xf7, + 0xa3, 0x16, 0xec, 0x86, 0x0a, 0x56, 0x3f, 0xdd, 0xee, 0xc7, 0x17, 0xb4, 0xcb, 0xfb, 0x85, 0x4b, + 0xf1, 0x16, 0x14, 0x56, 0xed, 0x13, 0x97, 0xf5, 0xca, 0xf7, 0x56, 0x2d, 0x2f, 0x6e, 0x21, 0x10, + 0x98, 0xa3, 0xb7, 0xb0, 0x14, 0xeb, 0x97, 0x6e, 0x61, 0x39, 0xe0, 0x56, 0xfe, 0xe8, 0xc7, 0x0f, + 0xc7, 0x86, 0x7b, 0x3e, 0x1f, 0x1c, 0x0d, 0xad, 0xe9, 0xa3, 0x89, 0x31, 0x3e, 0x77, 0x4d, 0xc3, + 0x1c, 0x4f, 0xf4, 0x81, 0xf3, 0x88, 0x10, 0x3f, 0xe2, 0x3b, 0x0c, 0x36, 0xe8, 0x8f, 0x22, 0x9f, + 0xfc, 0x3a, 0x00, 0x00, 0xff, 0xff, 0xe8, 0x22, 0xfb, 0x0f, 0x28, 0x29, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/poolrpc/auctioneer.proto b/poolrpc/auctioneer.proto index 689efcf..5b3a67d 100644 --- a/poolrpc/auctioneer.proto +++ b/poolrpc/auctioneer.proto @@ -737,10 +737,11 @@ message ServerOrder { */ uint64 amt = 3; + uint64 min_chan_amt = 4; + // TODO(guggero): implement - // bool kill_or_fill = 4; // repeated bytes must_fill_pub = 5; - reserved 4, 5; + reserved 5; /* Order nonce of 32 byte length, acts as unique order identifier. diff --git a/poolrpc/trader.pb.go b/poolrpc/trader.pb.go index 7acf1d7..5bb8508 100644 --- a/poolrpc/trader.pb.go +++ b/poolrpc/trader.pb.go @@ -1576,10 +1576,12 @@ type Order struct { // //A list of events that were emitted for this order. This field is only set //when the verbose flag is set to true in the request. - Events []*OrderEvent `protobuf:"bytes,11,rep,name=events,proto3" json:"events,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + Events []*OrderEvent `protobuf:"bytes,11,rep,name=events,proto3" json:"events,omitempty"` + // The minimum number of order units that must be matched per order pair. + MinUnitsMatch uint32 `protobuf:"varint,12,opt,name=min_units_match,json=minUnitsMatch,proto3" json:"min_units_match,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *Order) Reset() { *m = Order{} } @@ -1684,6 +1686,13 @@ func (m *Order) GetEvents() []*OrderEvent { return nil } +func (m *Order) GetMinUnitsMatch() uint32 { + if m != nil { + return m.MinUnitsMatch + } + return 0 +} + type Bid struct { // //The common fields shared between both ask and bid order types. @@ -2852,193 +2861,195 @@ func init() { func init() { proto.RegisterFile("trader.proto", fileDescriptor_b8f61804588c75fe) } var fileDescriptor_b8f61804588c75fe = []byte{ - // 2976 bytes of a gzipped FileDescriptorProto + // 2994 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x59, 0x4b, 0x73, 0x23, 0x49, 0xf1, 0x77, 0xfb, 0xed, 0xd4, 0xc3, 0x72, 0xc9, 0xaf, 0xd1, 0x8c, 0x77, 0x3c, 0xfd, 0xff, 0xef, 0x32, 0xe3, 0x5d, 0xc6, 0xbb, 0xc3, 0xce, 0x40, 0x0c, 0x0b, 0x8b, 0x6c, 0xb7, 0x57, 0x62, 0x3d, 0xb2, 0x28, 0x7b, 0x86, 0x7d, 0x44, 0xd0, 0x51, 0x52, 0x97, 0xed, 0x5e, 0xab, 0xbb, 0xb5, 0xdd, - 0x25, 0x3f, 0xd8, 0xd8, 0x0b, 0xf0, 0x01, 0x08, 0x36, 0xe0, 0xc2, 0x81, 0x2f, 0x01, 0xc1, 0x81, - 0x08, 0x0e, 0x9c, 0x88, 0x80, 0x0b, 0xc1, 0x57, 0xe0, 0x83, 0x10, 0x95, 0x55, 0x25, 0x75, 0x4b, - 0xf2, 0xec, 0xe3, 0xc2, 0x4d, 0x9d, 0x99, 0x55, 0xbf, 0xcc, 0xac, 0xcc, 0xca, 0xac, 0x14, 0xe4, - 0x45, 0xcc, 0x3c, 0x1e, 0x3f, 0xec, 0xc6, 0x91, 0x88, 0xc8, 0x5c, 0x37, 0x8a, 0x3a, 0x71, 0xb7, - 0x5d, 0xb9, 0x73, 0x1a, 0x45, 0xa7, 0x1d, 0xbe, 0xcd, 0xba, 0xfe, 0x36, 0x0b, 0xc3, 0x48, 0x30, - 0xe1, 0x47, 0x61, 0xa2, 0xc4, 0x2a, 0x25, 0xd6, 0x6b, 0xcb, 0x6f, 0x6e, 0x16, 0xda, 0xff, 0xb4, - 0x80, 0xd4, 0x43, 0x5f, 0x54, 0xdb, 0xed, 0xa8, 0x17, 0x0a, 0xca, 0x3f, 0xed, 0xf1, 0x44, 0x90, - 0xff, 0x83, 0x02, 0x53, 0x14, 0xf7, 0x82, 0x75, 0x7a, 0x7c, 0xdd, 0xda, 0xb4, 0xee, 0x4f, 0xd3, - 0xbc, 0x26, 0xbe, 0x90, 0x34, 0xf2, 0x00, 0x16, 0x59, 0x2b, 0x89, 0x3a, 0x3d, 0xc1, 0xdd, 0x33, - 0xee, 0x9f, 0x9e, 0x89, 0xf5, 0xc9, 0x4d, 0xeb, 0x7e, 0xa1, 0x36, 0x41, 0x8b, 0x86, 0x51, 0x43, - 0xba, 0x14, 0x8d, 0x79, 0x87, 0x09, 0xff, 0xa2, 0x2f, 0x3a, 0x65, 0x44, 0x0d, 0x43, 0x8b, 0xde, - 0x83, 0x5c, 0x3b, 0x0a, 0x4f, 0x5c, 0xc1, 0xe2, 0x53, 0x2e, 0xd6, 0xa7, 0x51, 0xcc, 0xa2, 0x20, - 0x89, 0xc7, 0x48, 0xdb, 0x29, 0x41, 0xd1, 0x68, 0xc7, 0xaf, 0xba, 0x7e, 0x7c, 0xbd, 0x33, 0x0b, - 0xd3, 0x27, 0x9c, 0x27, 0x36, 0x87, 0xf2, 0x4f, 0x7a, 0x91, 0xe0, 0xdf, 0xc4, 0x9c, 0x21, 0x60, - 0x63, 0x4a, 0x1a, 0xd8, 0xc0, 0x5c, 0xc2, 0x72, 0x16, 0x26, 0xe9, 0x46, 0x61, 0xc2, 0xc9, 0x77, - 0xe1, 0x56, 0xe0, 0x87, 0x3c, 0x76, 0x4f, 0x38, 0x77, 0x63, 0x26, 0xb8, 0x9b, 0x30, 0xe1, 0x76, - 0x79, 0xec, 0x9e, 0x5f, 0x6a, 0xcc, 0x65, 0x14, 0xd8, 0xe7, 0x9c, 0x32, 0xc1, 0x8f, 0x98, 0x68, - 0xf2, 0xf8, 0xfd, 0x4b, 0xf2, 0x1a, 0x2c, 0x0e, 0x16, 0x8a, 0x48, 0xb0, 0x0e, 0xe2, 0x4f, 0xd3, - 0x82, 0x11, 0x3f, 0x96, 0x44, 0x7b, 0x05, 0xca, 0x07, 0x7e, 0x62, 0x4e, 0x2b, 0xd1, 0xf6, 0xd9, - 0x7b, 0xb0, 0x9c, 0x25, 0x6b, 0x7d, 0xde, 0x80, 0x79, 0x6d, 0x62, 0xb2, 0x6e, 0x6d, 0x4e, 0xdd, - 0xcf, 0x3d, 0x2a, 0x3d, 0xd4, 0x91, 0xf2, 0xd0, 0xe8, 0xde, 0x97, 0xb0, 0xdf, 0x85, 0xd9, 0xc3, - 0x9e, 0xe8, 0xf6, 0x04, 0xb9, 0x0d, 0x0b, 0xe8, 0x27, 0xa9, 0xbe, 0xd6, 0x7b, 0x1e, 0x09, 0x47, - 0x4c, 0x90, 0x75, 0x98, 0x63, 0x9e, 0x17, 0xf3, 0x24, 0x41, 0x1d, 0x17, 0xa8, 0xf9, 0xb4, 0x7f, - 0x65, 0x41, 0x41, 0xed, 0xf0, 0x53, 0x5f, 0x9c, 0xed, 0x73, 0x9e, 0x96, 0xb5, 0x32, 0xb2, 0x5f, - 0xc1, 0xdb, 0xe4, 0x21, 0x94, 0xc7, 0xf9, 0x51, 0x06, 0xce, 0x74, 0x6d, 0x82, 0x2e, 0x9e, 0x64, - 0x9d, 0xd8, 0x3f, 0x9d, 0x5d, 0x58, 0x55, 0x5a, 0x24, 0x52, 0x8d, 0x7a, 0xd0, 0xed, 0xf8, 0x6d, - 0x5f, 0x48, 0x75, 0x1e, 0xc0, 0x5c, 0xa4, 0x38, 0xda, 0x1d, 0x8b, 0x7d, 0x77, 0xa8, 0x15, 0xd4, - 0xf0, 0xed, 0xbf, 0x5b, 0x50, 0xde, 0xed, 0x44, 0xc9, 0x70, 0x28, 0x6d, 0x00, 0xa8, 0xcc, 0x73, - 0xcf, 0xf9, 0x35, 0x1a, 0x95, 0xa7, 0x0b, 0x8a, 0xf2, 0x3e, 0xbf, 0x26, 0x3f, 0x82, 0x45, 0xb5, - 0x83, 0x7b, 0xe9, 0x8b, 0x33, 0x79, 0x9c, 0x68, 0x5a, 0xee, 0xd1, 0xea, 0x10, 0x92, 0xf6, 0x50, - 0x6d, 0x82, 0x16, 0xa2, 0x8c, 0xcb, 0xbe, 0x3f, 0xd0, 0x71, 0x0a, 0x57, 0xde, 0x1d, 0x5a, 0x39, - 0x6c, 0x55, 0x6d, 0xa2, 0xaf, 0xf5, 0x4e, 0x19, 0x96, 0x4e, 0x7a, 0xa1, 0x97, 0xb8, 0x1e, 0x4f, - 0x84, 0x1f, 0x62, 0xf2, 0xdb, 0x8f, 0x61, 0x39, 0x6b, 0x89, 0x8e, 0x8e, 0x0d, 0x80, 0xb6, 0xa4, - 0xbb, 0xe2, 0xca, 0xf7, 0x8c, 0x29, 0x48, 0x39, 0xbe, 0xf2, 0x3d, 0xfb, 0xd7, 0x16, 0xac, 0x4a, - 0x28, 0x2f, 0x66, 0x97, 0x5f, 0xcf, 0x09, 0x29, 0x37, 0x4f, 0xbe, 0xdc, 0xcd, 0xe4, 0x8d, 0x97, - 0x9c, 0xf1, 0xc8, 0x09, 0xdb, 0x9f, 0xc0, 0xda, 0x88, 0x46, 0xda, 0x98, 0x2d, 0x98, 0xd3, 0x81, - 0x8c, 0xfa, 0x8c, 0x8b, 0x74, 0x23, 0x20, 0xaf, 0x83, 0x4b, 0xbd, 0x8d, 0xb2, 0x7d, 0x12, 0x2d, - 0xc8, 0x1b, 0x22, 0x9a, 0xff, 0x4b, 0x0b, 0x56, 0xf6, 0x78, 0x37, 0x4a, 0x46, 0x2e, 0xc7, 0x2f, - 0xb1, 0x7e, 0x03, 0x80, 0x05, 0x78, 0xd7, 0xc8, 0xec, 0x51, 0x69, 0xbc, 0xa0, 0x28, 0x32, 0x7d, - 0xbe, 0x9e, 0xc5, 0xa7, 0xb0, 0x3a, 0xac, 0xc4, 0x37, 0x30, 0xf8, 0x1e, 0xe4, 0x3d, 0xb5, 0x4b, - 0xda, 0xde, 0x9c, 0xa6, 0xa1, 0xb9, 0x1e, 0xac, 0xec, 0xf4, 0x82, 0xae, 0x5e, 0x2a, 0xef, 0xa7, - 0xaf, 0x66, 0xed, 0x0d, 0xe6, 0x4c, 0x8e, 0x37, 0x67, 0x1d, 0x56, 0x87, 0x51, 0x94, 0x39, 0xf6, - 0x6f, 0x27, 0x61, 0x4e, 0x93, 0xbf, 0x0c, 0xf2, 0xdb, 0x30, 0x2f, 0xc3, 0x27, 0xf2, 0x43, 0xa1, - 0x93, 0x6b, 0x29, 0x1d, 0x5f, 0x4d, 0xc9, 0xa0, 0x7d, 0x11, 0xb2, 0x0c, 0x33, 0xea, 0xd2, 0x57, - 0x2e, 0x56, 0x1f, 0xe4, 0x75, 0x58, 0x62, 0x17, 0xcc, 0xef, 0xb0, 0x56, 0x87, 0xbb, 0x2d, 0xd6, - 0x61, 0x61, 0x9b, 0x63, 0xb1, 0x99, 0xa6, 0xa5, 0x3e, 0x63, 0x47, 0xd1, 0xa5, 0x30, 0x16, 0x1a, - 0xcc, 0x27, 0x53, 0xc0, 0x66, 0xe4, 0x95, 0x45, 0x4b, 0x03, 0x86, 0x2e, 0x60, 0xaf, 0xc3, 0x4c, - 0x22, 0x98, 0xe0, 0xeb, 0xb3, 0x9b, 0xd6, 0xfd, 0xe2, 0xa3, 0x95, 0xe1, 0x63, 0x39, 0x92, 0x4c, - 0xaa, 0x64, 0xc8, 0x5d, 0xc8, 0x75, 0x98, 0xe0, 0x89, 0x3e, 0x98, 0x39, 0xb4, 0x15, 0x14, 0x09, - 0xcf, 0xa5, 0x0d, 0xe4, 0xa8, 0xd7, 0x0a, 0x7c, 0x71, 0x18, 0x7b, 0x3c, 0x36, 0x87, 0xb2, 0x09, - 0x53, 0x2c, 0x39, 0xd7, 0x07, 0x9f, 0x1f, 0x20, 0x24, 0xe7, 0xb5, 0x09, 0x2a, 0x59, 0x52, 0xa2, - 0xa5, 0x4f, 0x3a, 0x2d, 0xb1, 0xe3, 0x7b, 0x52, 0xa2, 0xe5, 0x7b, 0x3b, 0x0b, 0x30, 0xe7, 0x71, - 0xc1, 0xfc, 0x4e, 0x62, 0xff, 0xc6, 0x82, 0x72, 0x06, 0x45, 0xc7, 0xd8, 0x3b, 0x50, 0xf0, 0xc3, - 0x0b, 0xd6, 0xf1, 0x3d, 0x37, 0x92, 0x0c, 0x0d, 0x38, 0x30, 0xa9, 0xae, 0xb8, 0xb8, 0xaa, 0x36, - 0x41, 0xf3, 0x7e, 0xea, 0x9b, 0x3c, 0x82, 0x65, 0xd6, 0x6e, 0xf3, 0xae, 0xe0, 0x7a, 0xb9, 0x1b, - 0x46, 0xd2, 0xcb, 0x18, 0x7d, 0xb5, 0x09, 0x4a, 0x0c, 0x17, 0xc5, 0x1b, 0x92, 0x97, 0x56, 0xaa, - 0x01, 0x4b, 0xb2, 0xa8, 0x21, 0xd3, 0x54, 0x3a, 0x59, 0x50, 0x2e, 0x78, 0xdc, 0x8a, 0x12, 0x55, - 0xc3, 0xe7, 0xa9, 0xf9, 0x94, 0x9e, 0x64, 0x6d, 0x6c, 0x30, 0xa2, 0xb0, 0x73, 0x8d, 0x20, 0xf3, - 0x14, 0x14, 0xe9, 0x30, 0xec, 0x5c, 0xdb, 0x1f, 0x00, 0x49, 0xef, 0xa7, 0x4d, 0xdc, 0x84, 0x69, - 0x96, 0x9c, 0x9b, 0x7a, 0x90, 0x71, 0x25, 0x45, 0x8e, 0x94, 0x68, 0xf9, 0x9e, 0xb9, 0xca, 0x32, - 0xae, 0xa4, 0xc8, 0xb1, 0x1f, 0x03, 0xd9, 0x95, 0x71, 0xd2, 0xc9, 0x9c, 0xd1, 0x5d, 0xc8, 0xa5, - 0xad, 0x56, 0x61, 0x0c, 0x51, 0xdf, 0x56, 0x59, 0xcc, 0x33, 0xcb, 0x74, 0x26, 0xfc, 0x69, 0x0a, - 0x66, 0x94, 0x03, 0xbf, 0xfc, 0xa2, 0xc1, 0xb4, 0x3b, 0xf1, 0xaf, 0xb8, 0x3a, 0xe9, 0x02, 0x5d, - 0x90, 0x94, 0x7d, 0x49, 0x20, 0x25, 0x98, 0x62, 0x81, 0xd0, 0x51, 0x2f, 0x7f, 0x92, 0x1f, 0xc2, - 0x46, 0xc0, 0xae, 0xdc, 0x16, 0x13, 0xed, 0xb3, 0xb1, 0x2d, 0x8a, 0x8a, 0xff, 0xb5, 0x80, 0x5d, - 0xed, 0x48, 0x99, 0xe1, 0x2e, 0x65, 0xc8, 0xa2, 0x99, 0x61, 0x8b, 0xc8, 0x83, 0x6c, 0xe8, 0x97, - 0x07, 0x69, 0x29, 0x65, 0x32, 0x81, 0xbf, 0x0c, 0x33, 0xbd, 0xd0, 0x17, 0x09, 0x86, 0x7c, 0x81, - 0xaa, 0x0f, 0x99, 0x68, 0xf8, 0xc3, 0xed, 0x85, 0x27, 0xbd, 0xce, 0x89, 0xdf, 0xe9, 0x70, 0x6f, - 0x7d, 0x5e, 0x25, 0x1a, 0x32, 0x9e, 0x0f, 0xe8, 0xe4, 0x0d, 0x20, 0x31, 0x4f, 0x78, 0x7c, 0xc1, - 0x3d, 0x77, 0xd0, 0xae, 0x2c, 0xa8, 0x1c, 0x36, 0x9c, 0x17, 0xa6, 0x6d, 0x79, 0x04, 0x2b, 0xed, - 0x98, 0xab, 0x0c, 0x16, 0x7e, 0xc0, 0x13, 0xc1, 0x82, 0xae, 0x1b, 0x26, 0xeb, 0x80, 0x0b, 0xca, - 0x86, 0x79, 0x6c, 0x78, 0x0d, 0xa9, 0xce, 0x2c, 0xbf, 0xe0, 0xb2, 0x7b, 0xca, 0xe1, 0xe1, 0x0f, - 0x19, 0xe4, 0x48, 0x1e, 0xd5, 0x22, 0xf6, 0x1f, 0x2d, 0x98, 0xda, 0xf1, 0x3d, 0x72, 0xbf, 0x1f, - 0xc2, 0x3a, 0x5d, 0x8a, 0xd9, 0x55, 0xd4, 0xb0, 0xa5, 0x4a, 0x1d, 0xce, 0x12, 0xee, 0x7a, 0x3d, - 0x7d, 0xb5, 0xb4, 0x3a, 0x51, 0xfb, 0x3c, 0xd1, 0x67, 0x59, 0x46, 0xe6, 0x9e, 0xe6, 0xed, 0x20, - 0x4b, 0x27, 0x40, 0xe2, 0x47, 0xa1, 0xea, 0xa0, 0xa9, 0xf9, 0x24, 0x8f, 0x41, 0x36, 0x8b, 0x6e, - 0x18, 0x79, 0xdc, 0x15, 0x3e, 0x8f, 0xf1, 0x34, 0x8b, 0xa9, 0xbb, 0xb1, 0x11, 0x79, 0xfc, 0xd8, - 0xe7, 0x31, 0xcd, 0x05, 0x7e, 0x68, 0x3e, 0xec, 0xcf, 0x61, 0xaa, 0x9a, 0x9c, 0xff, 0xaf, 0xb4, - 0xb6, 0xff, 0x66, 0x01, 0x0c, 0x9c, 0x29, 0x2b, 0x55, 0xe6, 0x70, 0xa4, 0x2e, 0x53, 0x34, 0x27, - 0x52, 0x87, 0x72, 0x1b, 0x16, 0xd0, 0xe3, 0x6e, 0x22, 0x62, 0xdd, 0x81, 0xce, 0x23, 0xe1, 0x48, - 0xc4, 0xe4, 0x29, 0xe4, 0x31, 0xbe, 0xdc, 0xf6, 0x19, 0x0b, 0x4f, 0xb9, 0x6e, 0xa1, 0x06, 0x17, - 0xd6, 0xf3, 0xae, 0xc7, 0x04, 0xf7, 0x10, 0xac, 0x36, 0x41, 0x73, 0x28, 0xbc, 0x8b, 0xb2, 0x64, - 0x1b, 0xe6, 0x02, 0x19, 0xf6, 0xdc, 0x43, 0xd7, 0xa5, 0x8f, 0xfb, 0x99, 0xa4, 0x9b, 0x45, 0x46, - 0x6a, 0x67, 0x0e, 0x66, 0x10, 0xd8, 0xfe, 0x83, 0x05, 0xf9, 0xf4, 0xce, 0xe4, 0x29, 0x14, 0xbb, - 0x31, 0xbf, 0xf0, 0xa3, 0x5e, 0xe2, 0xaa, 0x8c, 0xb0, 0x6e, 0xce, 0x88, 0x82, 0x11, 0xc5, 0x4f, - 0xf2, 0x26, 0x2c, 0x84, 0xfc, 0x52, 0x2f, 0x9b, 0xbc, 0x79, 0xd9, 0x7c, 0xc8, 0x2f, 0xd5, 0x8a, - 0x7b, 0x90, 0x57, 0x59, 0xa3, 0x13, 0x46, 0xb9, 0x38, 0x87, 0xb4, 0x7d, 0x24, 0xd9, 0xff, 0xb0, - 0x00, 0x06, 0x46, 0x90, 0xb7, 0x21, 0x87, 0x46, 0xdc, 0xa0, 0x1c, 0x4a, 0x2a, 0x14, 0x08, 0xfa, - 0xbf, 0x47, 0x70, 0x26, 0x47, 0x70, 0x64, 0x6b, 0xa5, 0xbd, 0xa3, 0x2b, 0xc6, 0x94, 0x6a, 0xad, - 0x34, 0x51, 0xdd, 0x6b, 0xef, 0x42, 0x21, 0xe6, 0x9f, 0xf0, 0xb6, 0x70, 0x63, 0xce, 0x92, 0x28, - 0xd4, 0x91, 0x5a, 0xc9, 0xe2, 0x53, 0x14, 0xa1, 0x28, 0x41, 0xf3, 0x71, 0xea, 0x4b, 0xb6, 0x11, - 0x94, 0xb7, 0xa3, 0x0b, 0x1e, 0x0f, 0xbf, 0x84, 0x0e, 0x61, 0x6d, 0x84, 0xa3, 0x6f, 0xfa, 0xb7, - 0x61, 0x35, 0xec, 0x05, 0x6e, 0xac, 0xd8, 0xdc, 0x73, 0x53, 0x4f, 0x23, 0x69, 0xc7, 0x72, 0xd8, - 0x0b, 0xa8, 0x61, 0x9a, 0xd5, 0x76, 0x19, 0x96, 0xaa, 0xea, 0xd1, 0x3c, 0xe8, 0x89, 0xec, 0x26, - 0x90, 0x34, 0x51, 0x03, 0x3c, 0x85, 0x02, 0xbf, 0xe2, 0xed, 0x1e, 0xe6, 0x84, 0xec, 0xfc, 0x87, - 0xab, 0xa5, 0x63, 0xb8, 0x72, 0x55, 0x9e, 0xa7, 0xbe, 0xec, 0x7f, 0x4d, 0xc3, 0xcc, 0x81, 0x4c, - 0x1c, 0xf2, 0x04, 0x0a, 0x32, 0x76, 0x43, 0xde, 0x71, 0x55, 0x8b, 0x63, 0xdd, 0xd4, 0xe2, 0xe4, - 0xb5, 0x1c, 0x7e, 0xc9, 0x27, 0xa4, 0x59, 0xc7, 0x82, 0x74, 0xef, 0x69, 0xb6, 0xab, 0x06, 0xd8, - 0x7f, 0x3e, 0x81, 0x35, 0x23, 0x37, 0x9c, 0xc0, 0x2a, 0x6e, 0x56, 0x34, 0x7b, 0x28, 0x85, 0xdf, - 0x84, 0x65, 0xb3, 0x4e, 0xa5, 0xbf, 0x7a, 0x7a, 0xab, 0x07, 0x3a, 0x25, 0x9a, 0x87, 0x36, 0x38, - 0xc8, 0x91, 0xe5, 0xa2, 0x1b, 0xf3, 0xc0, 0xef, 0x05, 0xa8, 0xcd, 0x0c, 0x6a, 0x03, 0x9a, 0x24, - 0x55, 0xd9, 0x92, 0x6d, 0x55, 0xca, 0x61, 0x28, 0x36, 0xab, 0x3a, 0xc7, 0xb4, 0x77, 0xa4, 0xac, - 0x8d, 0x6e, 0xf1, 0x07, 0x72, 0x73, 0x28, 0x97, 0x43, 0xa2, 0x96, 0x79, 0x08, 0xe5, 0x76, 0x87, - 0xb3, 0xd8, 0x0f, 0x4f, 0x55, 0x69, 0xeb, 0xc6, 0x7e, 0x9b, 0x63, 0xfd, 0x98, 0xa6, 0x4b, 0x86, - 0x25, 0x4b, 0x5a, 0x53, 0x32, 0xc8, 0x7d, 0x28, 0xa9, 0x7a, 0x86, 0x15, 0x14, 0x97, 0xe8, 0xf2, - 0x51, 0x44, 0x3a, 0xd6, 0x51, 0xaa, 0xdb, 0xb4, 0x74, 0xe5, 0x83, 0x91, 0xca, 0x77, 0x07, 0x16, - 0xba, 0xbd, 0xb8, 0x7d, 0xc6, 0x12, 0xee, 0xad, 0xe7, 0xb0, 0xf7, 0x18, 0x10, 0xc8, 0xe3, 0x81, - 0xcf, 0x63, 0x1e, 0x44, 0x82, 0xab, 0x5b, 0x5a, 0x56, 0xf5, 0x3c, 0x6e, 0x65, 0x5c, 0x4b, 0x91, - 0x2b, 0xef, 0x66, 0x59, 0xe0, 0x7f, 0x00, 0x4b, 0x66, 0xd9, 0xe0, 0x56, 0x2f, 0xdc, 0x74, 0xab, - 0x9b, 0xe3, 0xef, 0xdf, 0xec, 0x35, 0x28, 0xe0, 0x71, 0xf4, 0x9b, 0xa7, 0xdb, 0xb0, 0xa0, 0x6a, - 0xbf, 0x6c, 0x67, 0x64, 0xc3, 0x93, 0xa7, 0xf3, 0x48, 0xa8, 0x7b, 0x09, 0xa9, 0xa4, 0x66, 0x05, - 0x93, 0x8a, 0xd7, 0x9f, 0x0c, 0xfc, 0xce, 0x82, 0xa2, 0xd9, 0x4a, 0x07, 0xfb, 0x6b, 0x30, 0x8b, - 0x61, 0x60, 0x3a, 0xa7, 0x41, 0xb9, 0x40, 0x41, 0xaa, 0xb9, 0x64, 0x1b, 0x96, 0x71, 0x9e, 0x81, - 0x41, 0xc9, 0x59, 0x1c, 0x72, 0x2f, 0x15, 0x9b, 0x4b, 0xc8, 0xab, 0x06, 0xc2, 0x41, 0x8e, 0x3c, - 0xc4, 0xd7, 0x81, 0x0c, 0x16, 0x74, 0x99, 0xaf, 0xc4, 0xf5, 0xf3, 0xc8, 0x88, 0x37, 0x99, 0x2f, - 0x85, 0xed, 0x45, 0x28, 0x1c, 0x47, 0xe7, 0x3c, 0xec, 0xe7, 0xff, 0x3b, 0x50, 0x34, 0x84, 0xfe, - 0x3b, 0x69, 0x56, 0x20, 0x45, 0x2b, 0x4a, 0x06, 0x8a, 0x26, 0x4c, 0xa0, 0x30, 0xd5, 0x12, 0xf6, - 0x5f, 0x26, 0x61, 0xa1, 0x4f, 0x95, 0x77, 0x59, 0x4b, 0x06, 0x7a, 0xc0, 0xda, 0x2c, 0x8e, 0xa2, - 0x50, 0x77, 0x60, 0x79, 0x49, 0x7c, 0xa6, 0x69, 0xf2, 0x4e, 0xec, 0xb2, 0xeb, 0x40, 0xd6, 0xa3, - 0x33, 0x96, 0x9c, 0x99, 0xa7, 0x95, 0xa6, 0xd5, 0x58, 0x72, 0x46, 0x1e, 0x40, 0xc9, 0x88, 0x74, - 0x63, 0xee, 0x07, 0x4c, 0xd7, 0xa5, 0x3c, 0x5d, 0xd4, 0xf4, 0xa6, 0x26, 0xcb, 0x88, 0xd4, 0x6f, - 0x47, 0xb4, 0x3c, 0x90, 0xa6, 0x4f, 0x63, 0x09, 0x2c, 0x2a, 0xba, 0x34, 0xfc, 0x59, 0xc2, 0x04, - 0x79, 0x0b, 0x56, 0xe2, 0xa8, 0x27, 0x64, 0xa8, 0xcb, 0x8c, 0x18, 0x88, 0xcf, 0xa0, 0x38, 0xd1, - 0xcc, 0x7d, 0xce, 0xfb, 0x4b, 0x74, 0x6d, 0x75, 0xb1, 0xd3, 0xe1, 0x1e, 0x66, 0x9a, 0xae, 0xad, - 0xbb, 0x8a, 0x24, 0xeb, 0x34, 0xa6, 0x35, 0x57, 0x4f, 0x91, 0x79, 0x6a, 0x3e, 0xe5, 0xe2, 0x44, - 0x44, 0x31, 0x3b, 0xe5, 0x6e, 0xc8, 0x02, 0x95, 0x54, 0x0b, 0xb2, 0x7e, 0x22, 0xad, 0xc1, 0x02, - 0x6e, 0xaf, 0xc2, 0xf2, 0x41, 0xba, 0xf6, 0x9b, 0x33, 0xf9, 0xb3, 0x05, 0x2b, 0x43, 0x0c, 0x7d, - 0x36, 0x1f, 0xc3, 0x62, 0xb6, 0x95, 0x30, 0x87, 0xf4, 0x28, 0x1b, 0x4d, 0xc3, 0x0b, 0xb3, 0xd4, - 0xc4, 0x09, 0x45, 0x7c, 0x4d, 0x8b, 0x99, 0xc6, 0x23, 0xa9, 0x54, 0xa1, 0x3c, 0x46, 0x4c, 0xb6, - 0xc5, 0xa6, 0x9b, 0x2e, 0x50, 0xf9, 0x73, 0xf0, 0x40, 0x54, 0x6f, 0x06, 0xf5, 0xf1, 0x74, 0xf2, - 0x7b, 0x96, 0xfd, 0x04, 0x96, 0x64, 0x36, 0x51, 0x26, 0x5d, 0x69, 0xb2, 0xe8, 0x1e, 0xe4, 0x31, - 0x1b, 0xbb, 0xbd, 0xd6, 0x39, 0xbf, 0x36, 0x89, 0x94, 0x93, 0xb4, 0xa6, 0x22, 0xd9, 0x07, 0x40, - 0xd2, 0xeb, 0xb4, 0xb5, 0x4f, 0xf4, 0xc2, 0x18, 0xc9, 0xc6, 0xd4, 0x72, 0x26, 0x93, 0xf5, 0x12, - 0xdc, 0x4d, 0xfd, 0x4e, 0xb6, 0xbe, 0xb0, 0x20, 0x9f, 0x7e, 0x3b, 0x92, 0x12, 0xe4, 0x9b, 0x4e, - 0x63, 0xaf, 0xde, 0x78, 0xcf, 0x3d, 0x6c, 0x3a, 0x8d, 0xd2, 0x04, 0x21, 0x50, 0x34, 0x94, 0xe7, - 0xcd, 0xbd, 0xea, 0xb1, 0x53, 0xb2, 0xc8, 0x3c, 0x4c, 0x23, 0x77, 0x92, 0xe4, 0x60, 0xce, 0xf9, - 0xa0, 0x59, 0xa7, 0xce, 0x5e, 0x69, 0x2a, 0x2d, 0xba, 0x7b, 0x70, 0x78, 0xe4, 0xec, 0x95, 0xa6, - 0x09, 0xc0, 0xac, 0xfe, 0x3d, 0x43, 0xca, 0xb0, 0x48, 0x9d, 0xdd, 0xc3, 0x17, 0x0e, 0xfd, 0xd0, - 0xdd, 0xaf, 0xd6, 0x0f, 0x9c, 0xbd, 0xd2, 0x2c, 0x59, 0x82, 0x82, 0x59, 0xb4, 0x53, 0x3d, 0xde, - 0xad, 0x95, 0xe6, 0xb6, 0x9a, 0xba, 0xa1, 0x50, 0x2a, 0xe5, 0x60, 0xae, 0x49, 0x9d, 0x66, 0x95, - 0x3a, 0xa5, 0x09, 0x92, 0x87, 0xf9, 0xea, 0xee, 0xae, 0xd3, 0x3c, 0x76, 0xf6, 0x4a, 0x96, 0xfc, - 0xa2, 0xce, 0x8f, 0x9d, 0x5d, 0xf9, 0x35, 0x29, 0xa1, 0x8e, 0xea, 0xef, 0x35, 0x50, 0x95, 0x02, - 0x2c, 0xec, 0xd7, 0x1b, 0xd5, 0x83, 0xfa, 0x47, 0x52, 0x8b, 0xad, 0xbf, 0x5a, 0xb0, 0x34, 0x52, - 0xf9, 0xa5, 0x19, 0x8d, 0xc3, 0x86, 0xdc, 0x76, 0x15, 0xc8, 0x91, 0x43, 0x5f, 0x38, 0xd4, 0x7d, - 0x56, 0x3f, 0xda, 0x71, 0x6a, 0xd5, 0x17, 0xf5, 0x43, 0x5a, 0xb2, 0x48, 0x05, 0x56, 0x51, 0x29, - 0xf7, 0x85, 0x43, 0x8f, 0xea, 0x87, 0x0d, 0xc9, 0x7e, 0x86, 0x5a, 0x4e, 0x92, 0x0d, 0xb8, 0xd5, - 0xac, 0xd2, 0xe3, 0x7a, 0xf5, 0xc0, 0x55, 0x4a, 0xb8, 0xbb, 0x87, 0x07, 0x07, 0xd5, 0x63, 0x87, - 0x56, 0x0f, 0x4a, 0x53, 0xe4, 0x1e, 0x6c, 0x0c, 0xb1, 0xf7, 0x9e, 0x37, 0x0f, 0xea, 0xbb, 0xd5, - 0x63, 0xc7, 0x6d, 0x3a, 0x0e, 0x2d, 0x4d, 0x93, 0x07, 0xf0, 0xea, 0xf0, 0x0e, 0xb5, 0x6a, 0xa3, - 0xe1, 0x1c, 0xb8, 0xfb, 0xcf, 0x95, 0x47, 0xb4, 0x97, 0x66, 0x1e, 0xfd, 0xbe, 0x08, 0xb3, 0xc7, - 0xf8, 0x3c, 0x23, 0x11, 0xe4, 0xd3, 0x13, 0x62, 0x72, 0xa7, 0x7f, 0xca, 0x63, 0xe6, 0xd3, 0x95, - 0x8d, 0x1b, 0xb8, 0xfa, 0x45, 0x68, 0xff, 0xe2, 0xdf, 0xff, 0xf9, 0x62, 0xf2, 0x8e, 0xbd, 0xb6, - 0x7d, 0xf1, 0xd6, 0xb6, 0x94, 0xdc, 0x36, 0x37, 0xf3, 0xf6, 0xa7, 0x52, 0xfe, 0xa9, 0xb5, 0x45, - 0x3e, 0x82, 0x5c, 0x6a, 0x8e, 0x4f, 0x6e, 0xa7, 0x9e, 0xe8, 0xc3, 0x03, 0xac, 0xca, 0xc8, 0xa4, - 0xc8, 0xbe, 0x83, 0x08, 0xab, 0xf6, 0xd2, 0x08, 0x82, 0xdc, 0xfb, 0x04, 0xf2, 0xe9, 0xf1, 0x72, - 0xca, 0x98, 0x31, 0xc3, 0xe8, 0x94, 0x31, 0xe3, 0x66, 0xd2, 0xf6, 0x2d, 0x84, 0x2a, 0x93, 0x51, - 0x28, 0x89, 0x93, 0x1e, 0x54, 0xa6, 0x70, 0xc6, 0x4c, 0x62, 0x53, 0x38, 0xe3, 0xa6, 0x9b, 0x06, - 0x67, 0x6b, 0x0c, 0xce, 0x67, 0xb0, 0x38, 0x34, 0x46, 0x24, 0x83, 0x21, 0xeb, 0xf8, 0x91, 0x67, - 0x65, 0xf3, 0x66, 0x01, 0x0d, 0xf8, 0x2a, 0x02, 0xde, 0xb5, 0x2b, 0xa3, 0xa7, 0x64, 0x06, 0x8b, - 0xd2, 0x99, 0x97, 0x50, 0xcc, 0x4e, 0xf4, 0xc8, 0x2b, 0xfd, 0xad, 0xc7, 0xce, 0x1b, 0x2b, 0x77, - 0x6f, 0xe4, 0x6b, 0xe4, 0xff, 0x47, 0xe4, 0x57, 0xec, 0x5b, 0xa3, 0xc8, 0x7a, 0xc4, 0x27, 0x81, - 0x05, 0x14, 0xb3, 0xb3, 0xb7, 0x14, 0xf0, 0xd8, 0xd1, 0x5f, 0x0a, 0xf8, 0x86, 0xa1, 0xdd, 0x3d, - 0x04, 0xbe, 0x6d, 0xaf, 0x8e, 0x02, 0xb7, 0x7a, 0x41, 0x57, 0xa2, 0xfe, 0x1c, 0x16, 0x87, 0x1a, - 0xf2, 0x94, 0xaf, 0xc7, 0x37, 0xf1, 0x29, 0x5f, 0xdf, 0xd0, 0xcb, 0xbf, 0xcc, 0x62, 0xdd, 0xdf, - 0x4b, 0x6c, 0x0f, 0x72, 0xa9, 0xa9, 0x56, 0x2a, 0x27, 0x46, 0x27, 0x6a, 0x95, 0x3b, 0xe3, 0x99, - 0x1a, 0xaf, 0x82, 0x78, 0xcb, 0xf6, 0x62, 0x1f, 0x0f, 0x7b, 0x3f, 0xcc, 0x8e, 0x9f, 0x01, 0x0c, - 0xe6, 0x4a, 0xa4, 0x92, 0x89, 0xfe, 0xcc, 0xf0, 0xaa, 0x72, 0x7b, 0x2c, 0x4f, 0x43, 0xac, 0x21, - 0xc4, 0x12, 0x19, 0x86, 0x20, 0x11, 0xe4, 0x52, 0x63, 0xa2, 0x94, 0x15, 0xa3, 0x33, 0xa7, 0x94, - 0x15, 0xe3, 0x26, 0x4b, 0x3a, 0x42, 0xb7, 0x36, 0x86, 0x20, 0xb6, 0x3f, 0x4b, 0x35, 0xb7, 0x9f, - 0x93, 0x8f, 0x01, 0x06, 0xaf, 0x9b, 0x94, 0x41, 0x23, 0xef, 0xa0, 0x94, 0x41, 0xa3, 0xcf, 0x21, - 0x7b, 0x19, 0xd1, 0x8a, 0x24, 0xdf, 0x47, 0x3b, 0xe1, 0x9c, 0x7c, 0xaa, 0x3b, 0xc9, 0x7e, 0x55, - 0x26, 0x1b, 0x37, 0xd5, 0x7a, 0x85, 0xf1, 0xca, 0xcb, 0x5b, 0x01, 0x7b, 0x13, 0x61, 0x2a, 0x64, - 0xbd, 0x0f, 0x33, 0xd4, 0x52, 0x90, 0x08, 0x0a, 0x38, 0xce, 0x3a, 0x0a, 0x59, 0x37, 0x39, 0x8b, - 0x44, 0x0a, 0x31, 0x43, 0x1f, 0x45, 0x1c, 0x62, 0x6b, 0xc4, 0xbb, 0x88, 0x78, 0x8b, 0x0c, 0xae, - 0x63, 0x6c, 0xa2, 0xb7, 0x13, 0xb3, 0xff, 0x87, 0x50, 0x78, 0x8f, 0x8b, 0x7e, 0x23, 0x99, 0x90, - 0xc1, 0x9f, 0x3f, 0x99, 0x6e, 0xb5, 0xb2, 0x36, 0x42, 0x1f, 0x17, 0x0c, 0x9d, 0x84, 0x89, 0x6d, - 0xd5, 0xa1, 0x12, 0x0a, 0xb3, 0xaa, 0x11, 0x4f, 0xed, 0x99, 0x69, 0xf2, 0x53, 0x7b, 0x66, 0x3b, - 0xf6, 0x31, 0x01, 0xa6, 0x5b, 0x74, 0x0e, 0xb9, 0x41, 0xeb, 0x91, 0x8e, 0xe0, 0x91, 0xde, 0x27, - 0x75, 0xe0, 0xa3, 0xfd, 0x8d, 0xbd, 0x81, 0x00, 0x6b, 0x64, 0xa5, 0x0f, 0x90, 0x6e, 0x77, 0x76, - 0xbe, 0xf5, 0xd1, 0xab, 0xa7, 0xbe, 0x38, 0xeb, 0xb5, 0x1e, 0xb6, 0xa3, 0x60, 0xbb, 0xe3, 0x9f, - 0x9e, 0x89, 0xd0, 0x0f, 0x4f, 0x3b, 0xac, 0x95, 0x28, 0x69, 0xbd, 0x75, 0x6b, 0x16, 0xff, 0x9a, - 0xfe, 0xce, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x9c, 0xd3, 0x1f, 0xcc, 0xe3, 0x1e, 0x00, 0x00, + 0x25, 0x3f, 0xd8, 0xd8, 0x0b, 0xf0, 0x01, 0x08, 0x36, 0xe0, 0xc2, 0x81, 0x2f, 0x41, 0x04, 0x07, + 0x22, 0x38, 0x70, 0x22, 0x02, 0x2e, 0x04, 0x67, 0x6e, 0x7c, 0x10, 0xa2, 0xb2, 0xaa, 0xa4, 0x6e, + 0x49, 0x9e, 0x7d, 0x5c, 0xb8, 0xa9, 0x33, 0xb3, 0xea, 0x97, 0x99, 0x95, 0x59, 0x99, 0x95, 0x82, + 0xbc, 0x88, 0x99, 0xc7, 0xe3, 0x87, 0xdd, 0x38, 0x12, 0x11, 0x99, 0xeb, 0x46, 0x51, 0x27, 0xee, + 0xb6, 0x2b, 0x77, 0x4e, 0xa3, 0xe8, 0xb4, 0xc3, 0xb7, 0x59, 0xd7, 0xdf, 0x66, 0x61, 0x18, 0x09, + 0x26, 0xfc, 0x28, 0x4c, 0x94, 0x58, 0xa5, 0xc4, 0x7a, 0x6d, 0xf9, 0xcd, 0xcd, 0x42, 0xfb, 0x1f, + 0x16, 0x90, 0x7a, 0xe8, 0x8b, 0x6a, 0xbb, 0x1d, 0xf5, 0x42, 0x41, 0xf9, 0xa7, 0x3d, 0x9e, 0x08, + 0xf2, 0x7f, 0x50, 0x60, 0x8a, 0xe2, 0x5e, 0xb0, 0x4e, 0x8f, 0xaf, 0x5b, 0x9b, 0xd6, 0xfd, 0x69, + 0x9a, 0xd7, 0xc4, 0x17, 0x92, 0x46, 0x1e, 0xc0, 0x22, 0x6b, 0x25, 0x51, 0xa7, 0x27, 0xb8, 0x7b, + 0xc6, 0xfd, 0xd3, 0x33, 0xb1, 0x3e, 0xb9, 0x69, 0xdd, 0x2f, 0xd4, 0x26, 0x68, 0xd1, 0x30, 0x6a, + 0x48, 0x97, 0xa2, 0x31, 0xef, 0x30, 0xe1, 0x5f, 0xf4, 0x45, 0xa7, 0x8c, 0xa8, 0x61, 0x68, 0xd1, + 0x7b, 0x90, 0x6b, 0x47, 0xe1, 0x89, 0x2b, 0x58, 0x7c, 0xca, 0xc5, 0xfa, 0x34, 0x8a, 0x59, 0x14, + 0x24, 0xf1, 0x18, 0x69, 0x3b, 0x25, 0x28, 0x1a, 0xed, 0xf8, 0x55, 0xd7, 0x8f, 0xaf, 0x77, 0x66, + 0x61, 0xfa, 0x84, 0xf3, 0xc4, 0xe6, 0x50, 0xfe, 0x49, 0x2f, 0x12, 0xfc, 0x9b, 0x98, 0x33, 0x04, + 0x6c, 0x4c, 0x49, 0x03, 0x1b, 0x98, 0x4b, 0x58, 0xce, 0xc2, 0x24, 0xdd, 0x28, 0x4c, 0x38, 0xf9, + 0x2e, 0xdc, 0x0a, 0xfc, 0x90, 0xc7, 0xee, 0x09, 0xe7, 0x6e, 0xcc, 0x04, 0x77, 0x13, 0x26, 0xdc, + 0x2e, 0x8f, 0xdd, 0xf3, 0x4b, 0x8d, 0xb9, 0x8c, 0x02, 0xfb, 0x9c, 0x53, 0x26, 0xf8, 0x11, 0x13, + 0x4d, 0x1e, 0xbf, 0x7f, 0x49, 0x5e, 0x83, 0xc5, 0xc1, 0x42, 0x11, 0x09, 0xd6, 0x41, 0xfc, 0x69, + 0x5a, 0x30, 0xe2, 0xc7, 0x92, 0x68, 0xaf, 0x40, 0xf9, 0xc0, 0x4f, 0xcc, 0x69, 0x25, 0xda, 0x3e, + 0x7b, 0x0f, 0x96, 0xb3, 0x64, 0xad, 0xcf, 0x1b, 0x30, 0xaf, 0x4d, 0x4c, 0xd6, 0xad, 0xcd, 0xa9, + 0xfb, 0xb9, 0x47, 0xa5, 0x87, 0x3a, 0x52, 0x1e, 0x1a, 0xdd, 0xfb, 0x12, 0xf6, 0xbb, 0x30, 0x7b, + 0xd8, 0x13, 0xdd, 0x9e, 0x20, 0xb7, 0x61, 0x01, 0xfd, 0x24, 0xd5, 0xd7, 0x7a, 0xcf, 0x23, 0xe1, + 0x88, 0x09, 0xb2, 0x0e, 0x73, 0xcc, 0xf3, 0x62, 0x9e, 0x24, 0xa8, 0xe3, 0x02, 0x35, 0x9f, 0xf6, + 0xaf, 0x2c, 0x28, 0xa8, 0x1d, 0x7e, 0xea, 0x8b, 0xb3, 0x7d, 0xce, 0xd3, 0xb2, 0x56, 0x46, 0xf6, + 0x2b, 0x78, 0x9b, 0x3c, 0x84, 0xf2, 0x38, 0x3f, 0xca, 0xc0, 0x99, 0xae, 0x4d, 0xd0, 0xc5, 0x93, + 0xac, 0x13, 0xfb, 0xa7, 0xb3, 0x0b, 0xab, 0x4a, 0x8b, 0x44, 0xaa, 0x51, 0x0f, 0xba, 0x1d, 0xbf, + 0xed, 0x0b, 0xa9, 0xce, 0x03, 0x98, 0x8b, 0x14, 0x47, 0xbb, 0x63, 0xb1, 0xef, 0x0e, 0xb5, 0x82, + 0x1a, 0xbe, 0xfd, 0x37, 0x0b, 0xca, 0xbb, 0x9d, 0x28, 0x19, 0x0e, 0xa5, 0x0d, 0x00, 0x95, 0x79, + 0xee, 0x39, 0xbf, 0x46, 0xa3, 0xf2, 0x74, 0x41, 0x51, 0xde, 0xe7, 0xd7, 0xe4, 0x47, 0xb0, 0xa8, + 0x76, 0x70, 0x2f, 0x7d, 0x71, 0x26, 0x8f, 0x13, 0x4d, 0xcb, 0x3d, 0x5a, 0x1d, 0x42, 0xd2, 0x1e, + 0xaa, 0x4d, 0xd0, 0x42, 0x94, 0x71, 0xd9, 0xf7, 0x07, 0x3a, 0x4e, 0xe1, 0xca, 0xbb, 0x43, 0x2b, + 0x87, 0xad, 0xaa, 0x4d, 0xf4, 0xb5, 0xde, 0x29, 0xc3, 0xd2, 0x49, 0x2f, 0xf4, 0x12, 0xd7, 0xe3, + 0x89, 0xf0, 0x43, 0x4c, 0x7e, 0xfb, 0x31, 0x2c, 0x67, 0x2d, 0xd1, 0xd1, 0xb1, 0x01, 0xd0, 0x96, + 0x74, 0x57, 0x5c, 0xf9, 0x9e, 0x31, 0x05, 0x29, 0xc7, 0x57, 0xbe, 0x67, 0xff, 0xda, 0x82, 0x55, + 0x09, 0xe5, 0xc5, 0xec, 0xf2, 0xeb, 0x39, 0x21, 0xe5, 0xe6, 0xc9, 0x97, 0xbb, 0x99, 0xbc, 0xf1, + 0x92, 0x33, 0x1e, 0x39, 0x61, 0xfb, 0x13, 0x58, 0x1b, 0xd1, 0x48, 0x1b, 0xb3, 0x05, 0x73, 0x3a, + 0x90, 0x51, 0x9f, 0x71, 0x91, 0x6e, 0x04, 0xe4, 0x75, 0x70, 0xa9, 0xb7, 0x51, 0xb6, 0x4f, 0xa2, + 0x05, 0x79, 0x43, 0x44, 0xf3, 0x7f, 0x69, 0xc1, 0xca, 0x1e, 0xef, 0x46, 0xc9, 0xc8, 0xe5, 0xf8, + 0x25, 0xd6, 0x6f, 0x00, 0xb0, 0x00, 0xef, 0x1a, 0x99, 0x3d, 0x2a, 0x8d, 0x17, 0x14, 0x45, 0xa6, + 0xcf, 0xd7, 0xb3, 0xf8, 0x14, 0x56, 0x87, 0x95, 0xf8, 0x06, 0x06, 0xdf, 0x83, 0xbc, 0xa7, 0x76, + 0x49, 0xdb, 0x9b, 0xd3, 0x34, 0x34, 0xd7, 0x83, 0x95, 0x9d, 0x5e, 0xd0, 0xd5, 0x4b, 0xe5, 0xfd, + 0xf4, 0xd5, 0xac, 0xbd, 0xc1, 0x9c, 0xc9, 0xf1, 0xe6, 0xac, 0xc3, 0xea, 0x30, 0x8a, 0x32, 0xc7, + 0xfe, 0xed, 0x24, 0xcc, 0x69, 0xf2, 0x97, 0x41, 0x7e, 0x1b, 0xe6, 0x65, 0xf8, 0x44, 0x7e, 0x28, + 0x74, 0x72, 0x2d, 0xa5, 0xe3, 0xab, 0x29, 0x19, 0xb4, 0x2f, 0x42, 0x96, 0x61, 0x46, 0x5d, 0xfa, + 0xca, 0xc5, 0xea, 0x83, 0xbc, 0x0e, 0x4b, 0xec, 0x82, 0xf9, 0x1d, 0xd6, 0xea, 0x70, 0xb7, 0xc5, + 0x3a, 0x2c, 0x6c, 0x73, 0x2c, 0x36, 0xd3, 0xb4, 0xd4, 0x67, 0xec, 0x28, 0xba, 0x14, 0xc6, 0x42, + 0x83, 0xf9, 0x64, 0x0a, 0xd8, 0x8c, 0xbc, 0xb2, 0x68, 0x69, 0xc0, 0xd0, 0x05, 0xec, 0x75, 0x98, + 0x49, 0x04, 0x13, 0x7c, 0x7d, 0x76, 0xd3, 0xba, 0x5f, 0x7c, 0xb4, 0x32, 0x7c, 0x2c, 0x47, 0x92, + 0x49, 0x95, 0x0c, 0xb9, 0x0b, 0xb9, 0x0e, 0x13, 0x3c, 0xd1, 0x07, 0x33, 0x87, 0xb6, 0x82, 0x22, + 0xe1, 0xb9, 0xb4, 0x81, 0x1c, 0xf5, 0x5a, 0x81, 0x2f, 0x0e, 0x63, 0x8f, 0xc7, 0xe6, 0x50, 0x36, + 0x61, 0x8a, 0x25, 0xe7, 0xfa, 0xe0, 0xf3, 0x03, 0x84, 0xe4, 0xbc, 0x36, 0x41, 0x25, 0x4b, 0x4a, + 0xb4, 0xf4, 0x49, 0xa7, 0x25, 0x76, 0x7c, 0x4f, 0x4a, 0xb4, 0x7c, 0x6f, 0x67, 0x01, 0xe6, 0x3c, + 0x2e, 0x98, 0xdf, 0x49, 0xec, 0xdf, 0x58, 0x50, 0xce, 0xa0, 0xe8, 0x18, 0x7b, 0x07, 0x0a, 0x7e, + 0x78, 0xc1, 0x3a, 0xbe, 0xe7, 0x46, 0x92, 0xa1, 0x01, 0x07, 0x26, 0xd5, 0x15, 0x17, 0x57, 0xd5, + 0x26, 0x68, 0xde, 0x4f, 0x7d, 0x93, 0x47, 0xb0, 0xcc, 0xda, 0x6d, 0xde, 0x15, 0x5c, 0x2f, 0x77, + 0xc3, 0x48, 0x7a, 0x19, 0xa3, 0xaf, 0x36, 0x41, 0x89, 0xe1, 0xa2, 0x78, 0x43, 0xf2, 0xd2, 0x4a, + 0x35, 0x60, 0x49, 0x16, 0x35, 0x64, 0x9a, 0x4a, 0x27, 0x0b, 0xca, 0x05, 0x8f, 0x5b, 0x51, 0xa2, + 0x6a, 0xf8, 0x3c, 0x35, 0x9f, 0xd2, 0x93, 0xac, 0x8d, 0x0d, 0x46, 0x14, 0x76, 0xae, 0x11, 0x64, + 0x9e, 0x82, 0x22, 0x1d, 0x86, 0x9d, 0x6b, 0xfb, 0x03, 0x20, 0xe9, 0xfd, 0xb4, 0x89, 0x9b, 0x30, + 0xcd, 0x92, 0x73, 0x53, 0x0f, 0x32, 0xae, 0xa4, 0xc8, 0x91, 0x12, 0x2d, 0xdf, 0x33, 0x57, 0x59, + 0xc6, 0x95, 0x14, 0x39, 0xf6, 0x63, 0x20, 0xbb, 0x32, 0x4e, 0x3a, 0x99, 0x33, 0xba, 0x0b, 0xb9, + 0xb4, 0xd5, 0x2a, 0x8c, 0x21, 0xea, 0xdb, 0x2a, 0x8b, 0x79, 0x66, 0x99, 0xce, 0x84, 0x7f, 0x4f, + 0xc1, 0x8c, 0x72, 0xe0, 0x97, 0x5f, 0x34, 0x98, 0x76, 0x27, 0xfe, 0x15, 0x57, 0x27, 0x5d, 0xa0, + 0x0b, 0x92, 0xb2, 0x2f, 0x09, 0xa4, 0x04, 0x53, 0x2c, 0x10, 0x3a, 0xea, 0xe5, 0x4f, 0xf2, 0x43, + 0xd8, 0x08, 0xd8, 0x95, 0xdb, 0x62, 0xa2, 0x7d, 0x36, 0xb6, 0x45, 0x51, 0xf1, 0xbf, 0x16, 0xb0, + 0xab, 0x1d, 0x29, 0x33, 0xdc, 0xa5, 0x0c, 0x59, 0x34, 0x33, 0x6c, 0x11, 0x79, 0x90, 0x0d, 0xfd, + 0xf2, 0x20, 0x2d, 0xa5, 0x4c, 0x26, 0xf0, 0x97, 0x61, 0xa6, 0x17, 0xfa, 0x22, 0xc1, 0x90, 0x2f, + 0x50, 0xf5, 0x21, 0x13, 0x0d, 0x7f, 0xb8, 0xbd, 0xf0, 0xa4, 0xd7, 0x39, 0xf1, 0x3b, 0x1d, 0xee, + 0xad, 0xcf, 0xab, 0x44, 0x43, 0xc6, 0xf3, 0x01, 0x9d, 0xbc, 0x01, 0x24, 0xe6, 0x09, 0x8f, 0x2f, + 0xb8, 0xe7, 0x0e, 0xda, 0x95, 0x05, 0x95, 0xc3, 0x86, 0xf3, 0xc2, 0xb4, 0x2d, 0x8f, 0x60, 0xa5, + 0x1d, 0x73, 0x95, 0xc1, 0xc2, 0x0f, 0x78, 0x22, 0x58, 0xd0, 0x75, 0xc3, 0x64, 0x1d, 0x70, 0x41, + 0xd9, 0x30, 0x8f, 0x0d, 0xaf, 0x21, 0xd5, 0x99, 0xe5, 0x17, 0x5c, 0x76, 0x4f, 0x39, 0x3c, 0xfc, + 0x21, 0x83, 0x1c, 0xc9, 0xa3, 0x5a, 0x44, 0xf7, 0x70, 0xae, 0xd2, 0x3f, 0x90, 0xfe, 0x5b, 0xcf, + 0xa3, 0xe6, 0xb2, 0x87, 0x7b, 0x2e, 0xa9, 0xcf, 0x24, 0xd1, 0xfe, 0xa3, 0x05, 0x53, 0x3b, 0xbe, + 0x47, 0xee, 0xf7, 0x43, 0x5d, 0xa7, 0x55, 0x31, 0xbb, 0x3b, 0x35, 0x6c, 0xa9, 0x7a, 0x87, 0xb3, + 0x84, 0xbb, 0x5e, 0x4f, 0x5f, 0x41, 0xad, 0x4e, 0xd4, 0x3e, 0x4f, 0xf4, 0x99, 0x97, 0x91, 0xb9, + 0xa7, 0x79, 0x3b, 0xc8, 0xd2, 0x89, 0x92, 0xf8, 0x51, 0xa8, 0x3a, 0x6d, 0x6a, 0x3e, 0xc9, 0x63, + 0x90, 0x0a, 0xb9, 0x61, 0xe4, 0x71, 0x57, 0xf8, 0x3c, 0xc6, 0x53, 0x2f, 0xa6, 0xee, 0xd0, 0x46, + 0xe4, 0xf1, 0x63, 0x9f, 0xc7, 0x34, 0x17, 0xf8, 0xa1, 0xf9, 0xb0, 0x3f, 0x87, 0xa9, 0x6a, 0x72, + 0xfe, 0xbf, 0xd2, 0xda, 0xfe, 0xab, 0x05, 0x30, 0x70, 0xba, 0xac, 0x68, 0x99, 0x43, 0x94, 0xba, + 0x4c, 0xd1, 0x9c, 0x48, 0x1d, 0xde, 0x6d, 0x58, 0xc0, 0x93, 0x71, 0x13, 0x11, 0xeb, 0x4e, 0x75, + 0x1e, 0x09, 0x47, 0x22, 0x26, 0x4f, 0x21, 0x8f, 0x71, 0xe8, 0xb6, 0xcf, 0x58, 0x78, 0xca, 0x75, + 0xab, 0x35, 0xb8, 0xd8, 0x9e, 0x77, 0x3d, 0x26, 0xb8, 0x87, 0x60, 0xb5, 0x09, 0x9a, 0x43, 0xe1, + 0x5d, 0x94, 0x25, 0xdb, 0x30, 0x87, 0xc7, 0xcb, 0x3d, 0x74, 0x5d, 0x3a, 0x2c, 0xf0, 0x84, 0xcd, + 0x22, 0x23, 0xb5, 0x33, 0x07, 0x33, 0x08, 0x6c, 0xff, 0xc1, 0x82, 0x7c, 0x7a, 0x67, 0xf2, 0x14, + 0x8a, 0xdd, 0x98, 0x5f, 0xf8, 0x51, 0x2f, 0x71, 0x55, 0xe6, 0x58, 0x37, 0x67, 0x4e, 0xc1, 0x88, + 0xe2, 0x27, 0x79, 0x13, 0x16, 0x42, 0x7e, 0xa9, 0x97, 0x4d, 0xde, 0xbc, 0x6c, 0x3e, 0xe4, 0x97, + 0x6a, 0xc5, 0x3d, 0xc8, 0xab, 0xe8, 0xd4, 0x89, 0xa5, 0x5c, 0x9c, 0x43, 0xda, 0x3e, 0x92, 0xec, + 0xbf, 0x5b, 0x00, 0x03, 0x23, 0xc8, 0xdb, 0x90, 0x43, 0x23, 0x6e, 0x50, 0x0e, 0x25, 0x15, 0x0a, + 0x04, 0xfd, 0xdf, 0x23, 0x38, 0x93, 0x23, 0x38, 0xb2, 0x05, 0xd3, 0xde, 0xd1, 0x95, 0x65, 0x4a, + 0xb5, 0x60, 0x9a, 0xa8, 0xee, 0xbf, 0x77, 0xa1, 0x10, 0xf3, 0x4f, 0x78, 0x5b, 0xb8, 0x31, 0x67, + 0x49, 0x14, 0xea, 0x48, 0xad, 0x64, 0xf1, 0x29, 0x8a, 0x50, 0x94, 0xa0, 0xf9, 0x38, 0xf5, 0x25, + 0xdb, 0x0d, 0xca, 0xdb, 0xd1, 0x05, 0x8f, 0x87, 0x5f, 0x4c, 0x87, 0xb0, 0x36, 0xc2, 0xd1, 0x15, + 0xe1, 0x6d, 0x58, 0x0d, 0x7b, 0x81, 0x1b, 0x2b, 0x36, 0xf7, 0xdc, 0xd4, 0x13, 0x4a, 0xda, 0xb1, + 0x1c, 0xf6, 0x02, 0x6a, 0x98, 0x66, 0xb5, 0x5d, 0x86, 0xa5, 0xaa, 0x7a, 0x5c, 0x0f, 0x7a, 0x27, + 0xbb, 0x09, 0x24, 0x4d, 0xd4, 0x00, 0x4f, 0xa1, 0xc0, 0xaf, 0x78, 0xbb, 0x87, 0x39, 0x21, 0x5f, + 0x08, 0xc3, 0x55, 0xd5, 0x31, 0x5c, 0xb9, 0x2a, 0xcf, 0x53, 0x5f, 0xf6, 0x3f, 0xa7, 0x61, 0xe6, + 0x40, 0x26, 0x0e, 0x79, 0x02, 0x05, 0x19, 0xbb, 0x21, 0xef, 0xb8, 0xaa, 0x15, 0xb2, 0x6e, 0x6a, + 0x85, 0xf2, 0x5a, 0x0e, 0xbf, 0xe4, 0x35, 0x65, 0xd6, 0xb1, 0x20, 0xdd, 0xa3, 0x9a, 0xed, 0xaa, + 0x01, 0xf6, 0xa9, 0x4f, 0x60, 0xcd, 0xc8, 0x0d, 0x27, 0xb0, 0x8a, 0x9b, 0x15, 0xcd, 0x1e, 0x4a, + 0xe1, 0x37, 0x61, 0xd9, 0xac, 0x53, 0xe9, 0xaf, 0x9e, 0xe8, 0xea, 0x21, 0x4f, 0x89, 0xe6, 0xa1, + 0x0d, 0x0e, 0x72, 0x64, 0x59, 0xe9, 0xc6, 0x3c, 0xf0, 0x7b, 0x01, 0x6a, 0x33, 0x83, 0xda, 0x80, + 0x26, 0x49, 0x55, 0xb6, 0x64, 0xfb, 0x95, 0x72, 0x18, 0x8a, 0xcd, 0xaa, 0x0e, 0x33, 0xed, 0x1d, + 0x29, 0x6b, 0xa3, 0x5b, 0xfc, 0x81, 0xdc, 0x1c, 0xca, 0xe5, 0x90, 0xa8, 0x65, 0x1e, 0x42, 0xb9, + 0xdd, 0xe1, 0x2c, 0xf6, 0xc3, 0x53, 0x55, 0x02, 0xbb, 0xb1, 0xdf, 0xe6, 0x58, 0x67, 0xa6, 0xe9, + 0x92, 0x61, 0xc9, 0xd2, 0xd7, 0x94, 0x0c, 0x72, 0x1f, 0x4a, 0xaa, 0xee, 0x61, 0xa5, 0xc5, 0x25, + 0xba, 0xcc, 0x14, 0x91, 0x8e, 0xf5, 0x96, 0xea, 0x76, 0x2e, 0x5d, 0x21, 0x61, 0xa4, 0x42, 0xde, + 0x81, 0x85, 0x6e, 0x2f, 0x6e, 0x9f, 0xb1, 0x84, 0x7b, 0xeb, 0x39, 0xec, 0x51, 0x06, 0x04, 0xf2, + 0x78, 0xe0, 0xf3, 0x98, 0x07, 0x91, 0xe0, 0xea, 0x96, 0x96, 0xd5, 0x3f, 0x8f, 0x5b, 0x19, 0xd7, + 0x52, 0xe4, 0xca, 0xbb, 0x59, 0x36, 0x02, 0x3f, 0x80, 0x25, 0xb3, 0x6c, 0x70, 0xab, 0x17, 0x6e, + 0xba, 0xd5, 0xcd, 0xf1, 0xf7, 0x6f, 0xf6, 0x1a, 0x14, 0xf0, 0x38, 0xfa, 0x4d, 0xd6, 0x6d, 0x58, + 0x50, 0x3d, 0x82, 0x6c, 0x7b, 0x64, 0x63, 0x94, 0xa7, 0xf3, 0x48, 0xa8, 0x7b, 0x09, 0xa9, 0xa4, + 0x66, 0x0a, 0x93, 0x8a, 0xd7, 0x9f, 0x20, 0xfc, 0xce, 0x82, 0xa2, 0xd9, 0x4a, 0x07, 0xfb, 0x6b, + 0x30, 0x8b, 0x61, 0x60, 0x3a, 0xac, 0x41, 0xb9, 0x40, 0x41, 0xaa, 0xb9, 0x64, 0x1b, 0x96, 0x71, + 0xee, 0x81, 0x41, 0xc9, 0x59, 0x1c, 0x72, 0x2f, 0x15, 0x9b, 0x4b, 0xc8, 0xab, 0x06, 0xc2, 0x41, + 0x8e, 0x3c, 0xc4, 0xd7, 0x81, 0x0c, 0x16, 0x74, 0x99, 0xaf, 0xc4, 0xf5, 0x33, 0xca, 0x88, 0x37, + 0x99, 0x2f, 0x85, 0xed, 0x45, 0x28, 0x1c, 0x47, 0xe7, 0x3c, 0xec, 0xe7, 0xff, 0x3b, 0x50, 0x34, + 0x84, 0xfe, 0x7b, 0x6a, 0x56, 0x20, 0x45, 0x2b, 0x4a, 0x06, 0x8a, 0x26, 0x4c, 0xa0, 0x30, 0xd5, + 0x12, 0xf6, 0x9f, 0x27, 0x61, 0xa1, 0x4f, 0x95, 0x77, 0x59, 0x4b, 0x06, 0x7a, 0xc0, 0xda, 0x2c, + 0x8e, 0xa2, 0x50, 0x77, 0x6a, 0x79, 0x49, 0x7c, 0xa6, 0x69, 0xf2, 0x4e, 0xec, 0xb2, 0xeb, 0x40, + 0xd6, 0xa3, 0x33, 0x96, 0x9c, 0x99, 0x27, 0x98, 0xa6, 0xd5, 0x58, 0x72, 0x46, 0x1e, 0x40, 0xc9, + 0x88, 0x74, 0x63, 0xee, 0x07, 0x4c, 0xd7, 0xa5, 0x3c, 0x5d, 0xd4, 0xf4, 0xa6, 0x26, 0xcb, 0x88, + 0xd4, 0x6f, 0x4c, 0xb4, 0x3c, 0x90, 0xa6, 0x4f, 0x63, 0x09, 0x2c, 0x2a, 0xba, 0x34, 0xfc, 0x59, + 0xc2, 0x04, 0x79, 0x0b, 0x56, 0xe2, 0xa8, 0x27, 0x64, 0xa8, 0xcb, 0x8c, 0x18, 0x88, 0xcf, 0xa0, + 0x38, 0xd1, 0xcc, 0x7d, 0xce, 0xfb, 0x4b, 0x74, 0x6d, 0x75, 0xb1, 0x23, 0xe2, 0x1e, 0x66, 0x9a, + 0xae, 0xad, 0xbb, 0x8a, 0x24, 0xeb, 0x34, 0xa6, 0x35, 0x57, 0x4f, 0x96, 0x79, 0x6a, 0x3e, 0xe5, + 0xe2, 0x44, 0x44, 0x31, 0x3b, 0xe5, 0x6e, 0xc8, 0x02, 0x95, 0x54, 0x0b, 0xb2, 0x7e, 0x22, 0xad, + 0xc1, 0x02, 0x6e, 0xaf, 0xc2, 0xf2, 0x41, 0xba, 0xf6, 0x9b, 0x33, 0xf9, 0x93, 0x05, 0x2b, 0x43, + 0x0c, 0x7d, 0x36, 0x1f, 0xc3, 0x62, 0xb6, 0x95, 0x30, 0x87, 0xf4, 0x28, 0x1b, 0x4d, 0xc3, 0x0b, + 0xb3, 0xd4, 0xc4, 0x09, 0x45, 0x7c, 0x4d, 0x8b, 0x99, 0xc6, 0x23, 0xa9, 0x54, 0xa1, 0x3c, 0x46, + 0x4c, 0xb6, 0xcf, 0xa6, 0xeb, 0x2e, 0x50, 0xf9, 0x73, 0xf0, 0x90, 0x54, 0x6f, 0x0b, 0xf5, 0xf1, + 0x74, 0xf2, 0x7b, 0x96, 0xfd, 0x04, 0x96, 0x64, 0x36, 0x51, 0x26, 0x5d, 0x69, 0xb2, 0xe8, 0x1e, + 0xe4, 0x31, 0x1b, 0xbb, 0xbd, 0xd6, 0x39, 0xbf, 0x36, 0x89, 0x94, 0x93, 0xb4, 0xa6, 0x22, 0xd9, + 0x07, 0x40, 0xd2, 0xeb, 0xb4, 0xb5, 0x4f, 0xf4, 0xc2, 0x18, 0xc9, 0xc6, 0xd4, 0x72, 0x26, 0x93, + 0xf5, 0x12, 0xdc, 0x4d, 0xfd, 0x4e, 0xb6, 0xbe, 0xb0, 0x20, 0x9f, 0x7e, 0x63, 0x92, 0x12, 0xe4, + 0x9b, 0x4e, 0x63, 0xaf, 0xde, 0x78, 0xcf, 0x3d, 0x6c, 0x3a, 0x8d, 0xd2, 0x04, 0x21, 0x50, 0x34, + 0x94, 0xe7, 0xcd, 0xbd, 0xea, 0xb1, 0x53, 0xb2, 0xc8, 0x3c, 0x4c, 0x23, 0x77, 0x92, 0xe4, 0x60, + 0xce, 0xf9, 0xa0, 0x59, 0xa7, 0xce, 0x5e, 0x69, 0x2a, 0x2d, 0xba, 0x7b, 0x70, 0x78, 0xe4, 0xec, + 0x95, 0xa6, 0x09, 0xc0, 0xac, 0xfe, 0x3d, 0x43, 0xca, 0xb0, 0x48, 0x9d, 0xdd, 0xc3, 0x17, 0x0e, + 0xfd, 0xd0, 0xdd, 0xaf, 0xd6, 0x0f, 0x9c, 0xbd, 0xd2, 0x2c, 0x59, 0x82, 0x82, 0x59, 0xb4, 0x53, + 0x3d, 0xde, 0xad, 0x95, 0xe6, 0xb6, 0x9a, 0xba, 0xa1, 0x50, 0x2a, 0xe5, 0x60, 0xae, 0x49, 0x9d, + 0x66, 0x95, 0x3a, 0xa5, 0x09, 0x92, 0x87, 0xf9, 0xea, 0xee, 0xae, 0xd3, 0x3c, 0x76, 0xf6, 0x4a, + 0x96, 0xfc, 0xa2, 0xce, 0x8f, 0x9d, 0x5d, 0xf9, 0x35, 0x29, 0xa1, 0x8e, 0xea, 0xef, 0x35, 0x50, + 0x95, 0x02, 0x2c, 0xec, 0xd7, 0x1b, 0xd5, 0x83, 0xfa, 0x47, 0x52, 0x8b, 0xad, 0xbf, 0x58, 0xb0, + 0x34, 0x52, 0xf9, 0xa5, 0x19, 0x8d, 0xc3, 0x86, 0xdc, 0x76, 0x15, 0xc8, 0x91, 0x43, 0x5f, 0x38, + 0xd4, 0x7d, 0x56, 0x3f, 0xda, 0x71, 0x6a, 0xd5, 0x17, 0xf5, 0x43, 0x5a, 0xb2, 0x48, 0x05, 0x56, + 0x51, 0x29, 0xf7, 0x85, 0x43, 0x8f, 0xea, 0x87, 0x0d, 0xc9, 0x7e, 0x86, 0x5a, 0x4e, 0x92, 0x0d, + 0xb8, 0xd5, 0xac, 0xd2, 0xe3, 0x7a, 0xf5, 0xc0, 0x55, 0x4a, 0xb8, 0xbb, 0x87, 0x07, 0x07, 0xd5, + 0x63, 0x87, 0x56, 0x0f, 0x4a, 0x53, 0xe4, 0x1e, 0x6c, 0x0c, 0xb1, 0xf7, 0x9e, 0x37, 0x0f, 0xea, + 0xbb, 0xd5, 0x63, 0xc7, 0x6d, 0x3a, 0x0e, 0x2d, 0x4d, 0x93, 0x07, 0xf0, 0xea, 0xf0, 0x0e, 0xb5, + 0x6a, 0xa3, 0xe1, 0x1c, 0xb8, 0xfb, 0xcf, 0x95, 0x47, 0xb4, 0x97, 0x66, 0x1e, 0xfd, 0xbe, 0x08, + 0xb3, 0xc7, 0xf8, 0x8c, 0x23, 0x11, 0xe4, 0xd3, 0x93, 0x64, 0x72, 0xa7, 0x7f, 0xca, 0x63, 0xe6, + 0xd8, 0x95, 0x8d, 0x1b, 0xb8, 0xfa, 0xe5, 0x68, 0xff, 0xe2, 0x5f, 0xff, 0xf9, 0x62, 0xf2, 0x8e, + 0xbd, 0xb6, 0x7d, 0xf1, 0xd6, 0xb6, 0x94, 0xdc, 0x36, 0x37, 0xf3, 0xf6, 0xa7, 0x52, 0xfe, 0xa9, + 0xb5, 0x45, 0x3e, 0x82, 0x5c, 0x6a, 0xde, 0x4f, 0x6e, 0xa7, 0x9e, 0xf2, 0xc3, 0x83, 0xae, 0xca, + 0xc8, 0x44, 0xc9, 0xbe, 0x83, 0x08, 0xab, 0xf6, 0xd2, 0x08, 0x82, 0xdc, 0xfb, 0x04, 0xf2, 0xe9, + 0x31, 0x74, 0xca, 0x98, 0x31, 0x43, 0xeb, 0x94, 0x31, 0xe3, 0x66, 0xd7, 0xf6, 0x2d, 0x84, 0x2a, + 0x93, 0x51, 0x28, 0x89, 0x93, 0x1e, 0x68, 0xa6, 0x70, 0xc6, 0x4c, 0x6c, 0x53, 0x38, 0xe3, 0xa6, + 0xa0, 0x06, 0x67, 0x6b, 0x0c, 0xce, 0x67, 0xb0, 0x38, 0x34, 0x6e, 0x24, 0x83, 0x61, 0xec, 0xf8, + 0xd1, 0x68, 0x65, 0xf3, 0x66, 0x01, 0x0d, 0xf8, 0x2a, 0x02, 0xde, 0xb5, 0x2b, 0xa3, 0xa7, 0x64, + 0x06, 0x90, 0xd2, 0x99, 0x97, 0x50, 0xcc, 0x4e, 0xfe, 0xc8, 0x2b, 0xfd, 0xad, 0xc7, 0xce, 0x25, + 0x2b, 0x77, 0x6f, 0xe4, 0x6b, 0xe4, 0xff, 0x47, 0xe4, 0x57, 0xec, 0x5b, 0xa3, 0xc8, 0x7a, 0x14, + 0x28, 0x81, 0x05, 0x14, 0xb3, 0x33, 0xba, 0x14, 0xf0, 0xd8, 0x11, 0x61, 0x0a, 0xf8, 0x86, 0xe1, + 0xde, 0x3d, 0x04, 0xbe, 0x6d, 0xaf, 0x8e, 0x02, 0xb7, 0x7a, 0x41, 0x57, 0xa2, 0xfe, 0x1c, 0x16, + 0x87, 0x1a, 0xf2, 0x94, 0xaf, 0xc7, 0x37, 0xf1, 0x29, 0x5f, 0xdf, 0xd0, 0xcb, 0xbf, 0xcc, 0x62, + 0xdd, 0xdf, 0x4b, 0x6c, 0x0f, 0x72, 0xa9, 0xe9, 0x57, 0x2a, 0x27, 0x46, 0x27, 0x6f, 0x95, 0x3b, + 0xe3, 0x99, 0x1a, 0xaf, 0x82, 0x78, 0xcb, 0xf6, 0x62, 0x1f, 0x0f, 0x7b, 0x3f, 0xcc, 0x8e, 0x9f, + 0x01, 0x0c, 0xe6, 0x4f, 0xa4, 0x92, 0x89, 0xfe, 0xcc, 0x90, 0xab, 0x72, 0x7b, 0x2c, 0x4f, 0x43, + 0xac, 0x21, 0xc4, 0x12, 0x19, 0x86, 0x20, 0x11, 0xe4, 0x52, 0xe3, 0xa4, 0x94, 0x15, 0xa3, 0xb3, + 0xa9, 0x94, 0x15, 0xe3, 0x26, 0x50, 0x3a, 0x42, 0xb7, 0x36, 0x86, 0x20, 0xb6, 0x3f, 0x4b, 0x35, + 0xb7, 0x9f, 0x93, 0x8f, 0x01, 0x06, 0xaf, 0x9b, 0x94, 0x41, 0x23, 0xef, 0xa0, 0x94, 0x41, 0xa3, + 0xcf, 0x21, 0x7b, 0x19, 0xd1, 0x8a, 0x24, 0xdf, 0x47, 0x3b, 0xe1, 0x9c, 0x7c, 0xaa, 0x3b, 0xc9, + 0x7e, 0x55, 0x26, 0x1b, 0x37, 0xd5, 0x7a, 0x85, 0xf1, 0xca, 0xcb, 0x5b, 0x01, 0x7b, 0x13, 0x61, + 0x2a, 0x64, 0xbd, 0x0f, 0x33, 0xd4, 0x52, 0x90, 0x08, 0x0a, 0x38, 0xf6, 0x3a, 0x0a, 0x59, 0x37, + 0x39, 0x8b, 0x44, 0x0a, 0x31, 0x43, 0x1f, 0x45, 0x1c, 0x62, 0x6b, 0xc4, 0xbb, 0x88, 0x78, 0x8b, + 0x0c, 0xae, 0x63, 0x6c, 0xa2, 0xb7, 0x13, 0xb3, 0xff, 0x87, 0x50, 0x78, 0x8f, 0x8b, 0x7e, 0x23, + 0x99, 0x90, 0xc1, 0x9f, 0x44, 0x99, 0x6e, 0xb5, 0xb2, 0x36, 0x42, 0x1f, 0x17, 0x0c, 0x9d, 0x84, + 0x89, 0x6d, 0xd5, 0xa1, 0x12, 0x0a, 0xb3, 0xaa, 0x11, 0x4f, 0xed, 0x99, 0x69, 0xf2, 0x53, 0x7b, + 0x66, 0x3b, 0xf6, 0x31, 0x01, 0xa6, 0x5b, 0x74, 0x0e, 0xb9, 0x41, 0xeb, 0x91, 0x8e, 0xe0, 0x91, + 0xde, 0x27, 0x75, 0xe0, 0xa3, 0xfd, 0x8d, 0xbd, 0x81, 0x00, 0x6b, 0x64, 0xa5, 0x0f, 0x90, 0x6e, + 0x77, 0x76, 0xbe, 0xf5, 0xd1, 0xab, 0xa7, 0xbe, 0x38, 0xeb, 0xb5, 0x1e, 0xb6, 0xa3, 0x60, 0xbb, + 0xe3, 0x9f, 0x9e, 0x89, 0xd0, 0x0f, 0x4f, 0x3b, 0xac, 0x95, 0x28, 0x69, 0xbd, 0x75, 0x6b, 0x16, + 0xff, 0xc2, 0xfe, 0xce, 0x7f, 0x03, 0x00, 0x00, 0xff, 0xff, 0x8d, 0x49, 0xe5, 0x32, 0x0b, 0x1f, + 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/poolrpc/trader.proto b/poolrpc/trader.proto index bfe81ad..157ffaa 100644 --- a/poolrpc/trader.proto +++ b/poolrpc/trader.proto @@ -526,6 +526,9 @@ message Order { when the verbose flag is set to true in the request. */ repeated OrderEvent events = 11; + + // The minimum number of order units that must be matched per order pair. + uint32 min_units_match = 12; } message Bid { diff --git a/poolrpc/trader.swagger.json b/poolrpc/trader.swagger.json index 2ebb62e..c19c110 100644 --- a/poolrpc/trader.swagger.json +++ b/poolrpc/trader.swagger.json @@ -1262,6 +1262,11 @@ "$ref": "#/definitions/poolrpcOrderEvent" }, "description": "A list of events that were emitted for this order. This field is only set\nwhen the verbose flag is set to true in the request." + }, + "min_units_match": { + "type": "integer", + "format": "int64", + "description": "The minimum number of order units that must be matched per order pair." } } }, diff --git a/rpcserver.go b/rpcserver.go index c366c31..c2de48a 100644 --- a/rpcserver.go +++ b/rpcserver.go @@ -1283,6 +1283,7 @@ func (s *rpcServer) ListOrders(ctx context.Context, ), CreationTimestampNs: uint64(evt.Timestamp().UnixNano()), Events: rpcEvents, + MinUnitsMatch: uint32(dbOrder.Details().MinUnitsMatch), } switch o := dbOrder.(type) { From 664a55ad3b0998152e6967973c0b1b44fcca2284 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 6 Oct 2020 11:42:05 -0700 Subject: [PATCH 2/6] clientdb: store order MinUnitsMatch field --- clientdb/batch_snapshot.go | 35 ++++++++--- clientdb/order.go | 123 +++++++++++++++++++++++++++---------- clientdb/order_test.go | 2 + 3 files changed, 118 insertions(+), 42 deletions(-) diff --git a/clientdb/batch_snapshot.go b/clientdb/batch_snapshot.go index a5a0e7f..e1385c4 100644 --- a/clientdb/batch_snapshot.go +++ b/clientdb/batch_snapshot.go @@ -229,6 +229,7 @@ func fetchLocalBatchSnapshot(seqBucket *bbolt.Bucket, seqNum []byte, return nil, fmt.Errorf("batch not found for snapshot") } + // Deserialize it. batchSnapshot, err := deserializeLocalBatchSnapshot( bytes.NewReader(rawBatch), ) @@ -236,15 +237,9 @@ func fetchLocalBatchSnapshot(seqBucket *bbolt.Bucket, seqNum []byte, return nil, err } - // The snapshot doesn't contain information such as the min node tier, - // so we'll go ahead and retrieve that information now. + // The snapshot doesn't contain all the order information needed, so + // we'll retrieve the missing data. for nonce, o := range batchSnapshot.Orders { - // We'll only need to populate the values below for bid orders. - bidOrder, ok := o.(*order.Bid) - if !ok { - continue - - } orderBucket, err := getNestedBucket( rootOrderBucket, nonce[:], false, ) @@ -252,6 +247,29 @@ func fetchLocalBatchSnapshot(seqBucket *bbolt.Bucket, seqNum []byte, return nil, ErrNoOrder } + minUnitsMatchBytes := orderBucket.Get(orderMinUnitsMatchKey) + if minUnitsMatchBytes == nil { + // Assume a base unit minimum match for older orders + // which were not aware of the field. + o.Details().MinUnitsMatch = 1 + } else { + var minUnitsMatch order.SupplyUnit + err := ReadElement( + bytes.NewReader(minUnitsMatchBytes), + &minUnitsMatch, + ) + if err != nil { + return nil, err + } + o.Details().MinUnitsMatch = minUnitsMatch + } + + // We'll only need to populate the values below for bid orders. + bidOrder, ok := o.(*order.Bid) + if !ok { + continue + } + minNodeTierBytes := orderBucket.Get(orderTierKey) if minNodeTierBytes == nil { // If not found, then assume the current default value. @@ -265,7 +283,6 @@ func fetchLocalBatchSnapshot(seqBucket *bbolt.Bucket, seqNum []byte, if err != nil { return nil, err } - bidOrder.MinNodeTier = minNodeTier } } diff --git a/clientdb/order.go b/clientdb/order.go index a0a54e6..ef90ddd 100644 --- a/clientdb/order.go +++ b/clientdb/order.go @@ -35,14 +35,26 @@ var ( // stores the min node tier for an order. It allows an order to specify // the required minimum node tier for matching and execution. orderTierKey = []byte("order-tier") + + // orderMinUnitsMatchKey is the key that stores the serialized order's + // minimum units match. It is nested within the sub-bucket for each + // active order. + // + // path: ordersBucketKey -> orderBucket[nonce] -> orderMinUnitsMatchKey + orderMinUnitsMatchKey = []byte("order-min-units-match") ) +type extraOrderData struct { + minNodeTier order.NodeTier + minUnitsMatch order.SupplyUnit +} + // orderCallback is a function type that is used to pass as a callback into the // store's fetch functions to deliver the results to the caller. It also // includes any auxiliary order information as additional arguments after the // raw order bytes. type orderCallback func(nonce order.Nonce, rawOrder []byte, - minNodeTier uint32) error + extraData *extraOrderData) error // SubmitOrder stores an order by using the orders's nonce as an identifier. If // an order with the given nonce already exists in the store, ErrOrderExists is @@ -89,13 +101,20 @@ func (db *DB) SubmitOrder(newOrder order.Order) error { if err != nil { return err } + err = storeOrderMinUnitsMatchTX( + rootBucket, newOrder.Nonce(), + newOrder.Details().MinUnitsMatch, + ) + if err != nil { + return err + } // Finally, store the min node tier, but only if this is a Bid // order. if bidOrder, ok := newOrder.(*order.Bid); ok { return storeOrderMinNoderTierTX( rootBucket, newOrder.Nonce(), - uint32(bidOrder.MinNodeTier), + bidOrder.MinNodeTier, ) } @@ -157,7 +176,7 @@ func (db *DB) GetOrder(nonce order.Nonce) (order.Order, error) { o order.Order err error callback = func(nonce order.Nonce, rawOrder []byte, - minNodeTier uint32) error { + extraData *extraOrderData) error { r := bytes.NewReader(rawOrder) o, err = DeserializeOrder(nonce, r) @@ -168,10 +187,9 @@ func (db *DB) GetOrder(nonce order.Nonce) (order.Order, error) { // TODO(roasbeef): factory func to de-dup w/ all other // instances? if bidOrder, ok := o.(*order.Bid); ok { - bidOrder.MinNodeTier = order.NodeTier( - minNodeTier, - ) + bidOrder.MinNodeTier = extraData.minNodeTier } + o.Details().MinUnitsMatch = extraData.minUnitsMatch return nil } @@ -193,7 +211,7 @@ func (db *DB) GetOrders() ([]order.Order, error) { var ( orders []order.Order callback = func(nonce order.Nonce, rawOrder []byte, - minNodeTier uint32) error { + extraData *extraOrderData) error { r := bytes.NewReader(rawOrder) o, err := DeserializeOrder(nonce, r) @@ -202,10 +220,9 @@ func (db *DB) GetOrders() ([]order.Order, error) { } if bidOrder, ok := o.(*order.Bid); ok { - bidOrder.MinNodeTier = order.NodeTier( - minNodeTier, - ) + bidOrder.MinNodeTier = extraData.minNodeTier } + o.Details().MinUnitsMatch = extraData.minUnitsMatch orders = append(orders, o) return nil @@ -287,7 +304,7 @@ func storeOrderTX(rootBucket *bbolt.Bucket, nonce order.Nonce, // storeOrderMinNoderTierTX saves the currnet node tier for a given order to // the proper bucket. func storeOrderMinNoderTierTX(rootBucket *bbolt.Bucket, nonce order.Nonce, - minNodeTier uint32) error { + minNodeTier order.NodeTier) error { orderBucket, err := rootBucket.CreateBucketIfNotExists(nonce[:]) if err != nil { @@ -302,6 +319,27 @@ func storeOrderMinNoderTierTX(rootBucket *bbolt.Bucket, nonce order.Nonce, return orderBucket.Put(orderTierKey, b.Bytes()) } +// storeOrderMinUnitsMatchTX saves the order's minimum units match within the +// order's root bucket. +func storeOrderMinUnitsMatchTX(rootBucket *bbolt.Bucket, nonce order.Nonce, + minUnitsMatch order.SupplyUnit) error { + + // From the root bucket, we'll make a new sub order bucket using + // the order nonce. + orderBucket, err := rootBucket.CreateBucketIfNotExists(nonce[:]) + if err != nil { + return err + } + + // With the order bucket created, we'll store the order's min units + // match. + var buf bytes.Buffer + if err := WriteElement(&buf, minUnitsMatch); err != nil { + return err + } + return orderBucket.Put(orderMinUnitsMatchKey, buf.Bytes()) +} + // fetchOrderTX fetches the binary data of one order specified by its nonce from // the root orders bucket. func fetchOrderTX(rootBucket *bbolt.Bucket, nonce order.Nonce, @@ -334,7 +372,23 @@ func fetchOrderTX(rootBucket *bbolt.Bucket, nonce order.Nonce, } } - return callback(nonce, orderBytes, minNodeTier) + // Use a default of 1 if the field does not exist (possible for older + // orders). + minUnitsMatch := order.SupplyUnit(1) + minUnitsMatchBytes := orderBucket.Get(orderMinUnitsMatchKey) + if minUnitsMatchBytes != nil { + err := ReadElements( + bytes.NewReader(minUnitsMatchBytes), &minUnitsMatch, + ) + if err != nil { + return err + } + } + + return callback(nonce, orderBytes, &extraOrderData{ + minNodeTier: order.NodeTier(minNodeTier), + minUnitsMatch: minUnitsMatch, + }) } // updateOrder fetches the binary data of one order specified by its nonce from @@ -350,7 +404,7 @@ func updateOrder(ordersBucket, dst *bbolt.Bucket, nonce order.Nonce, o order.Order err error callback = func(nonce order.Nonce, rawOrder []byte, - minNodeTier uint32) error { + extraData *extraOrderData) error { r := bytes.NewReader(rawOrder) o, err = DeserializeOrder(nonce, r) @@ -359,10 +413,9 @@ func updateOrder(ordersBucket, dst *bbolt.Bucket, nonce order.Nonce, } if bidOrder, ok := o.(*order.Bid); ok { - bidOrder.MinNodeTier = order.NodeTier( - minNodeTier, - ) + bidOrder.MinNodeTier = extraData.minNodeTier } + o.Details().MinUnitsMatch = extraData.minUnitsMatch return nil } @@ -407,11 +460,13 @@ func updateOrder(ordersBucket, dst *bbolt.Bucket, nonce order.Nonce, if err := storeOrderTX(dst, nonce, w.Bytes(), nil); err != nil { return nil, err } + err = storeOrderMinUnitsMatchTX(dst, nonce, o.Details().MinUnitsMatch) + if err != nil { + return nil, err + } if bidOrder, ok := o.(*order.Bid); ok { - err = storeOrderMinNoderTierTX( - dst, nonce, uint32(bidOrder.MinNodeTier), - ) + err = storeOrderMinNoderTierTX(dst, nonce, bidOrder.MinNodeTier) if err != nil { return nil, err } @@ -424,12 +479,13 @@ func updateOrder(ordersBucket, dst *bbolt.Bucket, nonce order.Nonce, // event references are copied, only the order itself. func copyOrder(src, dst *bbolt.Bucket, nonce order.Nonce) error { var ( - o order.Order - orderBytes []byte - nodeTier uint32 - err error - callback = func(_ order.Nonce, rawOrder []byte, - minNodeTier uint32) error { + o order.Order + orderBytes []byte + nodeTier order.NodeTier + minUnitsMatch order.SupplyUnit + err error + callback = func(_ order.Nonce, rawOrder []byte, + extraData *extraOrderData) error { orderBytes = rawOrder @@ -441,28 +497,29 @@ func copyOrder(src, dst *bbolt.Bucket, nonce order.Nonce) error { if err != nil { return err } - nodeTier = minNodeTier + nodeTier = extraData.minNodeTier + minUnitsMatch = extraData.minUnitsMatch return nil } ) - // Retrieve the order stored in the database. + // Retrieve the order stored in the source bucket. err = fetchOrderTX(src, nonce, callback) if err != nil { return err } + // Store it in the new bucket. if err := storeOrderTX(dst, nonce, orderBytes, nil); err != nil { return err } - if _, ok := o.(*order.Bid); ok { - return storeOrderMinNoderTierTX( - dst, nonce, nodeTier, - ) + err := storeOrderMinNoderTierTX(dst, nonce, nodeTier) + if err != nil { + return err + } } - - return nil + return storeOrderMinUnitsMatchTX(dst, nonce, minUnitsMatch) } // SerializeOrder binary serializes an order to a writer using the common LN diff --git a/clientdb/order_test.go b/clientdb/order_test.go index 862c1ce..e9b7fd6 100644 --- a/clientdb/order_test.go +++ b/clientdb/order_test.go @@ -26,6 +26,7 @@ func TestSubmitOrder(t *testing.T) { Kit: *dummyOrder(500000, 1337), MinNodeTier: 2, } + o.Details().MinUnitsMatch = 10 err := store.SubmitOrder(o) if err != nil { t.Fatalf("unable to store order: %v", err) @@ -97,6 +98,7 @@ func TestUpdateOrders(t *testing.T) { Kit: *dummyOrder(500000, 1337), MinNodeTier: 3, } + o1.Details().MinUnitsMatch = 10 err := store.SubmitOrder(o1) if err != nil { t.Fatalf("unable to store order: %v", err) From e9031a488510fa750ecf773150a38bc2cc121888 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 6 Oct 2020 11:42:10 -0700 Subject: [PATCH 3/6] order: enforce min units match in batch verification --- order/batch_verifier.go | 14 ++++++++++++-- order/batch_verifier_test.go | 14 ++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/order/batch_verifier.go b/order/batch_verifier.go index b6d283f..1aeb30a 100644 --- a/order/batch_verifier.go +++ b/order/batch_verifier.go @@ -172,9 +172,10 @@ func (v *batchVerifier) Verify(batch *Batch) error { } } - // Last check is to make sure our order has not been over + // Last check is to make sure our order has not been over/under // filled somehow. - if unitsFilled > ourOrder.Details().UnitsUnfulfilled { + switch { + case unitsFilled > ourOrder.Details().UnitsUnfulfilled: return &MismatchErr{ msg: fmt.Sprintf("invalid units to be filled "+ "for order %v. currently unfulfilled "+ @@ -184,6 +185,15 @@ func (v *batchVerifier) Verify(batch *Batch) error { unitsFilled, ), } + + case unitsFilled < ourOrder.Details().MinUnitsMatch: + return &MismatchErr{ + msg: fmt.Sprintf("invalid units to be filled "+ + "for order %v. matched %d units, but "+ + "minimum is %d", ourOrder.Nonce(), + unitsFilled, + ourOrder.Details().MinUnitsMatch), + } } } diff --git a/order/batch_verifier_test.go b/order/batch_verifier_test.go index 4c34bb7..7b3d916 100644 --- a/order/batch_verifier_test.go +++ b/order/batch_verifier_test.go @@ -173,6 +173,16 @@ func TestBatchVerifier(t *testing.T) { return v.Verify(b) }, }, + { + name: "invalid min units match", + expectedErr: "units, but minimum is", + doVerify: func(v BatchVerifier, a *Ask, b1, b2 *Bid, + b *Batch) error { + + a.MinUnitsMatch = b1.MinUnitsMatch * 100 + return v.Verify(b) + }, + }, { name: "invalid funding TX fee rate", expectedErr: "server sent unexpected ending balance", @@ -334,6 +344,7 @@ func TestBatchVerifier(t *testing.T) { }, Units: 4, UnitsUnfulfilled: 4, + MinUnitsMatch: 1, AcctKey: acctIDSmall, FixedRate: uint32(clearingPrice) / 2, LeaseDuration: 1000, @@ -346,6 +357,7 @@ func TestBatchVerifier(t *testing.T) { }, Units: 2, UnitsUnfulfilled: 2, + MinUnitsMatch: 1, AcctKey: acctIDBig, FixedRate: uint32(clearingPrice) * 2, // 1000 * (200_000 * 5000 / 1_000_000_000) = 1000 sats premium @@ -359,6 +371,7 @@ func TestBatchVerifier(t *testing.T) { }, Units: 8, UnitsUnfulfilled: 8, + MinUnitsMatch: 1, AcctKey: acctIDBig, FixedRate: uint32(clearingPrice), // 2000 * (200_000 * 5000 / 1_000_000_000) = 1000 sats premium @@ -508,6 +521,7 @@ func newKitFromTemplate(nonce Nonce, tpl *Kit) Kit { kit.Amt = tpl.Amt kit.Units = tpl.Units kit.UnitsUnfulfilled = tpl.UnitsUnfulfilled + kit.MinUnitsMatch = tpl.MinUnitsMatch kit.MultiSigKeyLocator = tpl.MultiSigKeyLocator kit.MaxBatchFeeRate = tpl.MaxBatchFeeRate kit.AcctKey = tpl.AcctKey From fecb1a83989790cbdf7235bb4b9d6fd451b0baea Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Tue, 6 Oct 2020 11:42:15 -0700 Subject: [PATCH 4/6] pool: add min chan amt flag to order submission --- cmd/pool/order.go | 45 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 41 insertions(+), 4 deletions(-) diff --git a/cmd/pool/order.go b/cmd/pool/order.go index 231e5af..ba48390 100644 --- a/cmd/pool/order.go +++ b/cmd/pool/order.go @@ -106,6 +106,30 @@ func parseCommonParams(ctx *cli.Context, blockDuration uint32) (*poolrpc.Order, return nil, fmt.Errorf("unable to decode amount: %v", err) } + // If the minimum channel amount flag wasn't provided, use a default of + // 10%. + minChanAmt := btcutil.Amount(ctx.Uint64("min_chan_amt")) + if minChanAmt == 0 { + minChanAmt = amt / 10 + } + + // Verify the minimum channel amount flag has been properly set. + minOrderChanAmt := btcutil.Amount(order.BaseSupplyUnit) + switch { + case minChanAmt%minOrderChanAmt != 0: + return nil, fmt.Errorf("minimum channel amount %v must be "+ + "a multiple of %v", minChanAmt, minOrderChanAmt) + + case minChanAmt < minOrderChanAmt: + return nil, fmt.Errorf("minimum channel amount %v is below "+ + "required value of %v", minChanAmt, minOrderChanAmt) + + case minChanAmt > btcutil.Amount(params.Amt): + return nil, fmt.Errorf("minimum channel amount %v is above "+ + "order amount %v", minChanAmt, btcutil.Amount(params.Amt)) + } + params.MinUnitsMatch = uint32(minChanAmt / minOrderChanAmt) + params.TraderKey, err = parseAccountKey(ctx, args) if err != nil { return nil, fmt.Errorf("unable to parse acct_key: %v", err) @@ -209,6 +233,11 @@ var ordersSubmitAskCommand = cli.Command{ "liquidity should be offered for", Value: defaultAskMaxDuration, }, + cli.Uint64Flag{ + Name: "min_chan_amt", + Usage: "the minimum amount of satohis that a resulting " + + "channel from this order must have", + }, cli.BoolFlag{ Name: "force", Usage: "skip order placement confirmation", @@ -248,6 +277,7 @@ func ordersSubmitAsk(ctx *cli.Context) error { // nolint: dupl if !ctx.Bool("force") { if err := printOrderDetails( client, btcutil.Amount(ask.Details.Amt), + order.SupplyUnit(ask.Details.MinUnitsMatch).ToSatoshis(), order.FixedRatePremium(ask.Details.RateFixed), ask.LeaseDurationBlocks, chainfee.SatPerKWeight( @@ -278,9 +308,10 @@ func ordersSubmitAsk(ctx *cli.Context) error { // nolint: dupl return nil } -func printOrderDetails(client poolrpc.TraderClient, amt btcutil.Amount, - rate order.FixedRatePremium, leaseDuration uint32, - maxBatchFeeRate chainfee.SatPerKWeight, isAsk bool) error { +func printOrderDetails(client poolrpc.TraderClient, amt, + minChanAmt btcutil.Amount, rate order.FixedRatePremium, + leaseDuration uint32, maxBatchFeeRate chainfee.SatPerKWeight, + isAsk bool) error { auctionFee, err := client.AuctionFee( context.Background(), &poolrpc.AuctionFeeRequest{}, @@ -305,7 +336,7 @@ func printOrderDetails(client poolrpc.TraderClient, amt btcutil.Amount, premium := rate.LumpSumPremium(amt, leaseDuration) - maxNumMatches := amt / btcutil.Amount(order.BaseSupplyUnit) + maxNumMatches := amt / minChanAmt chainFee := maxNumMatches * order.EstimateTraderFee(1, maxBatchFeeRate) fmt.Println("-- Order Details --") @@ -359,6 +390,11 @@ var ordersSubmitBidCommand = cli.Command{ "regardless of 'quality'", Value: uint64(order.NodeTierDefault), }, + cli.Uint64Flag{ + Name: "min_chan_amt", + Usage: "the minimum amount of satohis that a resulting " + + "channel from this order must have", + }, cli.BoolFlag{ Name: "force", Usage: "skip order placement confirmation", @@ -406,6 +442,7 @@ func ordersSubmitBid(ctx *cli.Context) error { // nolint: dupl if !ctx.Bool("force") { if err := printOrderDetails( client, btcutil.Amount(bid.Details.Amt), + order.SupplyUnit(bid.Details.MinUnitsMatch).ToSatoshis(), order.FixedRatePremium(bid.Details.RateFixed), bid.LeaseDurationBlocks, chainfee.SatPerKWeight( From 3c92676aec9da92275379a243883da86bfa57b2b Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Wed, 7 Oct 2020 14:23:29 -0700 Subject: [PATCH 5/6] order: use min units match to compute reserved value --- order/interface.go | 8 +++---- order/interface_test.go | 52 ++++++++++++++++++++++++++++++++++------- order/manager_test.go | 2 ++ 3 files changed, 50 insertions(+), 12 deletions(-) diff --git a/order/interface.go b/order/interface.go index abe43d5..b305354 100644 --- a/order/interface.go +++ b/order/interface.go @@ -390,11 +390,11 @@ func reservedValue(o Order, } // The situation where the trader needs to pay the largest amount of - // fees is when the order gets partially matched by the base supply - // unit per batch. This situation results in the most chain and + // fees is when the order gets partially matched by its minimum possible + // units per batch. This situation results in the most chain and // execution fees possible. - minMatchSize := btcutil.Amount(BaseSupplyUnit) - maxNumMatches := btcutil.Amount(o.Details().UnitsUnfulfilled) + minMatchSize := o.Details().MinUnitsMatch.ToSatoshis() + maxNumMatches := o.Details().UnitsUnfulfilled.ToSatoshis() / minMatchSize // We'll calculate the worst case possible wrt. fees paid by the // account if the order is filled by minimum size matched. diff --git a/order/interface_test.go b/order/interface_test.go index fa085c8..b5c2bca 100644 --- a/order/interface_test.go +++ b/order/interface_test.go @@ -27,6 +27,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -39,6 +40,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -51,6 +53,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -63,6 +66,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -75,6 +79,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -87,6 +92,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -99,6 +105,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -111,6 +118,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -123,6 +131,7 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, }, }, }, @@ -135,6 +144,33 @@ func TestOrderReservedValue(t *testing.T) { FixedRate: 10_000_000, MaxBatchFeeRate: 1000, LeaseDuration: 144, + MinUnitsMatch: 1, + }, + }, + }, + { + name: "ask 10 units 4 min units match", + order: &Ask{ + Kit: Kit{ + State: StateSubmitted, + UnitsUnfulfilled: 10, + FixedRate: 10_000_000, + MaxBatchFeeRate: 1000, + LeaseDuration: 144, + MinUnitsMatch: 4, + }, + }, + }, + { + name: "bid 10 units 4 min units match", + order: &Bid{ + Kit: Kit{ + State: StateSubmitted, + UnitsUnfulfilled: 10, + FixedRate: 10_000_000, + MaxBatchFeeRate: 1000, + LeaseDuration: 144, + MinUnitsMatch: 4, }, }, }, @@ -153,10 +189,10 @@ func TestOrderReservedValue(t *testing.T) { break } - // For bids the taker pays the most fees if only one - // unit can get matched every block. - numBlocks := int(o.UnitsUnfulfilled) - amt := btcutil.Amount(BaseSupplyUnit) + // For bids the taker pays the most fees if the min + // units get matched every block. + numBlocks := int(o.UnitsUnfulfilled / o.MinUnitsMatch) + amt := o.MinUnitsMatch.ToSatoshis() for i := 0; i < numBlocks; i++ { lumpSum := FixedRatePremium(o.FixedRate). LumpSumPremium(amt, o.LeaseDuration) @@ -176,10 +212,10 @@ func TestOrderReservedValue(t *testing.T) { break } - // For asks the maker pays the most fees if only one - // unit can get matched every blocks. - numBlocks := int(o.UnitsUnfulfilled) - amt := btcutil.Amount(BaseSupplyUnit) + // For asks the maker pays the most fees if min units + // get matched every block. + numBlocks := int(o.UnitsUnfulfilled / o.MinUnitsMatch) + amt := o.MinUnitsMatch.ToSatoshis() for i := 0; i < numBlocks; i++ { // In the worst case, the maker will be paid // only one lump sum for a 144 block duration, diff --git a/order/manager_test.go b/order/manager_test.go index 624e334..fe07f25 100644 --- a/order/manager_test.go +++ b/order/manager_test.go @@ -47,6 +47,7 @@ func TestValidateOrderAccountIsolation(t *testing.T) { MaxBatchFeeRate: 1000, AcctKey: acctKeyB, LeaseDuration: 144, + MinUnitsMatch: 100, }), } @@ -81,6 +82,7 @@ func TestValidateOrderAccountIsolation(t *testing.T) { MaxBatchFeeRate: 1000, AcctKey: acctKeyA, LeaseDuration: 144, + MinUnitsMatch: 100, }), } From bd39dfc78f11d75f7159571a02ca33359be895b5 Mon Sep 17 00:00:00 2001 From: Wilmer Paulino Date: Mon, 12 Oct 2020 17:55:11 -0700 Subject: [PATCH 6/6] order: mark order with unfulfilled units below min as executed --- order/batch_storer.go | 9 +++++++++ order/batch_storer_test.go | 31 ++++++++++++++++--------------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/order/batch_storer.go b/order/batch_storer.go index 45a14be..f088360 100644 --- a/order/batch_storer.go +++ b/order/batch_storer.go @@ -57,6 +57,15 @@ func (s *batchStorer) StorePendingBatch(batch *Batch, bestHeight uint32) error { UnitsFulfilledModifier(0), } + // The order has not been fully filled, but it cannot be matched + // again due to its remaining unfulfilled units being below its + // allowed minimum, so we'll archive it. + case unitsUnfulfilled < ourOrder.Details().MinUnitsMatch: + orderModifiers[orderIndex] = []Modifier{ + StateModifier(StateExecuted), + UnitsFulfilledModifier(unitsUnfulfilled), + } + // Some units were not yet filled. default: orderModifiers[orderIndex] = []Modifier{ diff --git a/order/batch_storer_test.go b/order/batch_storer_test.go index e91c6fa..667c3d4 100644 --- a/order/batch_storer_test.go +++ b/order/batch_storer_test.go @@ -49,9 +49,9 @@ func TestBatchStorer(t *testing.T) { State: account.StateOpen, BatchKey: startBatchKey, } - ask := &Ask{Kit: newKit(Nonce{0x01}, 4)} - bid1 := &Bid{Kit: newKit(Nonce{0x02}, 2)} - bid2 := &Bid{Kit: newKit(Nonce{0x03}, 8)} + ask := &Ask{Kit: newKit(Nonce{0x01}, 4, 1)} + bid1 := &Bid{Kit: newKit(Nonce{0x02}, 3, 1)} + bid2 := &Bid{Kit: newKit(Nonce{0x03}, 3, 2)} batchTx := &wire.MsgTx{ Version: 2, TxOut: []*wire.TxOut{{ @@ -129,28 +129,28 @@ func TestBatchStorer(t *testing.T) { // performed on the actual instances, which makes it easy to check. // Check the order states first. if ask.State != StateExecuted { - t.Fatalf("invalid order state, got %d wanted %d", + t.Fatalf("invalid order state, got %v wanted %v", ask.State, StateExecuted) } if ask.UnitsUnfulfilled != 0 { t.Fatalf("invalid units unfulfilled, got %d wanted %d", ask.UnitsUnfulfilled, 0) } - if bid1.State != StateExecuted { - t.Fatalf("invalid order state, got %d wanted %d", - bid1.State, StateExecuted) + if bid1.State != StatePartiallyFilled { + t.Fatalf("invalid order state, got %v wanted %v", + bid1.State, StatePartiallyFilled) } - if bid1.UnitsUnfulfilled != 0 { + if bid1.UnitsUnfulfilled != 1 { t.Fatalf("invalid units unfulfilled, got %d wanted %d", - bid1.UnitsUnfulfilled, 0) + bid1.UnitsUnfulfilled, 1) } - if bid2.State != StatePartiallyFilled { - t.Fatalf("invalid order state, got %d wanted %d", - bid2.State, StatePartiallyFilled) + if bid2.State != StateExecuted { + t.Fatalf("invalid order state, got %v wanted %v", + bid2.State, StateExecuted) } - if bid2.UnitsUnfulfilled != 6 { + if bid2.UnitsUnfulfilled != 1 { t.Fatalf("invalid units unfulfilled, got %d wanted %d", - bid2.UnitsUnfulfilled, 6) + bid2.UnitsUnfulfilled, 1) } // Check the account states next. @@ -190,10 +190,11 @@ func TestBatchStorer(t *testing.T) { } } -func newKit(nonce Nonce, units SupplyUnit) Kit { +func newKit(nonce Nonce, units, minUnitsMatch SupplyUnit) Kit { kit := NewKit(nonce) kit.Units = units kit.UnitsUnfulfilled = units + kit.MinUnitsMatch = minUnitsMatch kit.State = StateSubmitted return *kit }