Commit 9868e5ed authored by harrylee's avatar harrylee Committed by vipwzw

fix a bug for precision

parent faf9a573
...@@ -463,14 +463,19 @@ func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error ...@@ -463,14 +463,19 @@ func signTx(tx *types.Transaction, hexPrivKey string) (*types.Transaction, error
} }
func TestTruncate(t *testing.T) { func TestTruncate(t *testing.T) {
a := float32(1.00000212000000000001) a := float64(1.00000212000000000001)
b := float32(0.34567) b := float64(0.34567)
c := float32(1234) c := float64(1234567)
t.Log(Truncate(a)) t.Log(Truncate(a))
t.Log(Truncate(b)) t.Log(Truncate(b))
t.Log(Truncate(c)) t.Log(Truncate(c))
t.Log(float64(1.00000212000000000001))
t.Logf("%f", Truncate(float64(1e8)))
t.Log(Truncate(float64(1e-8)))
} }
func TestCheckPrice(t *testing.T) { func TestCheckPrice(t *testing.T) {
t.Log(CheckPrice(0.25)) t.Log(CheckPrice(Truncate(float64(1e8))))
t.Log(CheckPrice(Truncate(float64(1e-8))))
t.Log(CheckPrice(Truncate(float64(1e-9))))
} }
...@@ -60,16 +60,16 @@ func (a *Action) OpSwap(op int32) int32 { ...@@ -60,16 +60,16 @@ func (a *Action) OpSwap(op int32) int32 {
} }
//计算实际花费 //计算实际花费
func (a *Action) calcActualCost(op int32, amount int64, price float32) int64 { func (a *Action) calcActualCost(op int32, amount int64, price float64) int64 {
if op == et.OpBuy { if op == et.OpBuy {
return int64(float32(amount) * Truncate(price)) return int64(float64(amount) * Truncate(price))
} }
return amount return amount
} }
//price 精度允许范围小数点后面7位数,0<price<1e8 //price 精度允许范围小数点后面8位数,0<price<1e8
func CheckPrice(price float32) bool { func CheckPrice(price float64) bool {
if (Truncate(price) >= 1e8) || (Truncate(price)*float32(1e8) <= 0) { if (Truncate(price) >= 1e8) || (Truncate(price)*float64(1e8) < 1) {
return false return false
} }
return true return true
...@@ -138,7 +138,7 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) { ...@@ -138,7 +138,7 @@ func (a *Action) LimitOrder(payload *et.LimitOrder) (*types.Receipt, error) {
} }
//先检查账户余额 //先检查账户余额
if payload.GetOp() == et.OpBuy { if payload.GetOp() == et.OpBuy {
amount := int64(float32(payload.GetAmount()) * Truncate(payload.GetPrice())) amount := int64(float64(payload.GetAmount()) * Truncate(payload.GetPrice()))
rightAccount := rightAssetDB.LoadExecAccount(a.fromaddr, a.execaddr) rightAccount := rightAssetDB.LoadExecAccount(a.fromaddr, a.execaddr)
if rightAccount.Balance < amount { if rightAccount.Balance < amount {
elog.Error("LimitOrder.BalanceCheck", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", amount, "err", et.ErrAssetBalance.Error()) elog.Error("LimitOrder.BalanceCheck", "addr", a.fromaddr, "execaddr", a.execaddr, "amount", amount, "err", et.ErrAssetBalance.Error())
...@@ -445,7 +445,7 @@ func findOrderByOrderID(statedb dbm.KV, orderID string) (*et.Order, error) { ...@@ -445,7 +445,7 @@ func findOrderByOrderID(statedb dbm.KV, orderID string) (*et.Order, error) {
return &order, nil return &order, nil
} }
func findOrderIDListByPrice(localdb dbm.Lister, left, right *et.Asset, price float32, op, direction int32, index int64) ([]*et.OrderID, error) { func findOrderIDListByPrice(localdb dbm.Lister, left, right *et.Asset, price float64, op, direction int32, index int64) ([]*et.OrderID, error) {
prefix := calcMarketDepthOrderPrefix(left, right, op, price) prefix := calcMarketDepthOrderPrefix(left, right, op, price)
key := calcMarketDepthOrderKey(left, right, op, price, index) key := calcMarketDepthOrderKey(left, right, op, price, index)
var values [][]byte var values [][]byte
...@@ -490,7 +490,7 @@ func Direction(op int32) int32 { ...@@ -490,7 +490,7 @@ func Direction(op int32) int32 {
} }
//这里price当作索引来用,首次查询不需要填值 //这里price当作索引来用,首次查询不需要填值
func QueryMarketDepth(localdb dbm.Lister, left, right *et.Asset, op int32, price float32, count int32) (types.Message, error) { func QueryMarketDepth(localdb dbm.Lister, left, right *et.Asset, op int32, price float64, count int32) (types.Message, error) {
prefix := calcMarketDepthPrefix(left, right, op) prefix := calcMarketDepthPrefix(left, right, op)
key := calcMarketDepthKey(left, right, op, price) key := calcMarketDepthKey(left, right, op, price)
var values [][]byte var values [][]byte
...@@ -592,6 +592,6 @@ func QueryOrderList(localdb dbm.Lister, statedb dbm.KV, addr string, status, cou ...@@ -592,6 +592,6 @@ func QueryOrderList(localdb dbm.Lister, statedb dbm.KV, addr string, status, cou
} }
//截取小数点后7位 //截取小数点后7位
func Truncate(price float32) float32 { func Truncate(price float64) float64 {
return float32(math.Trunc(float64(1e8)*float64(price)) / float64(1e8)) return math.Trunc(float64(1e8)*float64(price)) / float64(1e8)
} }
...@@ -30,22 +30,22 @@ func calcMarketDepthPrefix(left, right *types.Asset, op int32) []byte { ...@@ -30,22 +30,22 @@ func calcMarketDepthPrefix(left, right *types.Asset, op int32) []byte {
} }
//市场深度 //市场深度
func calcMarketDepthKey(left, right *types.Asset, op int32, price float32) []byte { func calcMarketDepthKey(left, right *types.Asset, op int32, price float64) []byte {
// 设置精度为1e8 // 设置精度为1e8
key := fmt.Sprintf("%s"+"depth-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8))) key := fmt.Sprintf("%s"+"depth-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float64(1e8)))
return []byte(key) return []byte(key)
} }
func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float32) []byte { func calcMarketDepthOrderPrefix(left, right *types.Asset, op int32, price float64) []byte {
// 设置精度为1e8 // 设置精度为1e8
key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8))) key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float64(1e8)))
return []byte(key) return []byte(key)
} }
// localdb中存储市场挂单ID // localdb中存储市场挂单ID
func calcMarketDepthOrderKey(left, right *types.Asset, op int32, price float32, index int64) []byte { func calcMarketDepthOrderKey(left, right *types.Asset, op int32, price float64, index int64) []byte {
// 设置精度为1e8 // 设置精度为1e8
key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d:%022d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float32(1e8)), index) key := fmt.Sprintf("%s"+"order-%s-%s-%d:%016d:%022d", KeyPrefixLocalDB, left.GetSymbol(), right.GetSymbol(), op, int64(Truncate(price)*float64(1e8)), index)
return []byte(key) return []byte(key)
} }
......
...@@ -19,7 +19,7 @@ message LimitOrder { ...@@ -19,7 +19,7 @@ message LimitOrder {
//交易对 //交易对
asset rightAsset = 2; asset rightAsset = 2;
//价格 //价格
float price = 3; double price = 3;
//总量 //总量
int64 amount = 4; int64 amount = 4;
//操作, 1为买,2为卖 //操作, 1为买,2为卖
...@@ -74,7 +74,7 @@ message Order { ...@@ -74,7 +74,7 @@ message Order {
//挂单价 //挂单价
message OrderPrice { message OrderPrice {
float price = 1; double price = 1;
int64 index = 2; int64 index = 2;
} }
//单号 //单号
...@@ -91,7 +91,7 @@ message QueryMarketDepth { ...@@ -91,7 +91,7 @@ message QueryMarketDepth {
//操作, 1为买,2为卖 //操作, 1为买,2为卖
int32 op = 3; int32 op = 3;
// 这里用价格作为索引值 // 这里用价格作为索引值
float price = 4; double price = 4;
//单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 //单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
int32 count = 5; int32 count = 5;
} }
...@@ -102,7 +102,7 @@ message MarketDepth { ...@@ -102,7 +102,7 @@ message MarketDepth {
//资产2 //资产2
asset rightAsset = 2; asset rightAsset = 2;
//价格 //价格
float price = 3; double price = 3;
//总量 //总量
int64 amount = 4; int64 amount = 4;
//操作, 1为买,2为卖 //操作, 1为买,2为卖
......
...@@ -28,15 +28,12 @@ It has these top-level messages: ...@@ -28,15 +28,12 @@ It has these top-level messages:
*/ */
package types package types
import ( import proto "github.com/golang/protobuf/proto"
fmt "fmt" import fmt "fmt"
import math "math"
proto "github.com/golang/protobuf/proto"
math "math"
import (
context "golang.org/x/net/context" context "golang.org/x/net/context"
grpc "google.golang.org/grpc" grpc "google.golang.org/grpc"
) )
...@@ -226,7 +223,7 @@ type LimitOrder struct { ...@@ -226,7 +223,7 @@ type LimitOrder struct {
// 交易对 // 交易对
RightAsset *Asset `protobuf:"bytes,2,opt,name=rightAsset" json:"rightAsset,omitempty"` RightAsset *Asset `protobuf:"bytes,2,opt,name=rightAsset" json:"rightAsset,omitempty"`
// 价格 // 价格
Price float32 `protobuf:"fixed32,3,opt,name=price" json:"price,omitempty"` Price float64 `protobuf:"fixed64,3,opt,name=price" json:"price,omitempty"`
// 总量 // 总量
Amount int64 `protobuf:"varint,4,opt,name=amount" json:"amount,omitempty"` Amount int64 `protobuf:"varint,4,opt,name=amount" json:"amount,omitempty"`
// 操作, 1为买,2为卖 // 操作, 1为买,2为卖
...@@ -252,7 +249,7 @@ func (m *LimitOrder) GetRightAsset() *Asset { ...@@ -252,7 +249,7 @@ func (m *LimitOrder) GetRightAsset() *Asset {
return nil return nil
} }
func (m *LimitOrder) GetPrice() float32 { func (m *LimitOrder) GetPrice() float64 {
if m != nil { if m != nil {
return m.Price return m.Price
} }
...@@ -556,7 +553,7 @@ func _Order_OneofSizer(msg proto.Message) (n int) { ...@@ -556,7 +553,7 @@ func _Order_OneofSizer(msg proto.Message) (n int) {
// 挂单价 // 挂单价
type OrderPrice struct { type OrderPrice struct {
Price float32 `protobuf:"fixed32,1,opt,name=price" json:"price,omitempty"` Price float64 `protobuf:"fixed64,1,opt,name=price" json:"price,omitempty"`
Index int64 `protobuf:"varint,2,opt,name=index" json:"index,omitempty"` Index int64 `protobuf:"varint,2,opt,name=index" json:"index,omitempty"`
} }
...@@ -565,7 +562,7 @@ func (m *OrderPrice) String() string { return proto.CompactTextString ...@@ -565,7 +562,7 @@ func (m *OrderPrice) String() string { return proto.CompactTextString
func (*OrderPrice) ProtoMessage() {} func (*OrderPrice) ProtoMessage() {}
func (*OrderPrice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} } func (*OrderPrice) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{7} }
func (m *OrderPrice) GetPrice() float32 { func (m *OrderPrice) GetPrice() float64 {
if m != nil { if m != nil {
return m.Price return m.Price
} }
...@@ -613,7 +610,7 @@ type QueryMarketDepth struct { ...@@ -613,7 +610,7 @@ type QueryMarketDepth struct {
// 操作, 1为买,2为卖 // 操作, 1为买,2为卖
Op int32 `protobuf:"varint,3,opt,name=op" json:"op,omitempty"` Op int32 `protobuf:"varint,3,opt,name=op" json:"op,omitempty"`
// 这里用价格作为索引值 // 这里用价格作为索引值
Price float32 `protobuf:"fixed32,4,opt,name=price" json:"price,omitempty"` Price float64 `protobuf:"fixed64,4,opt,name=price" json:"price,omitempty"`
// 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条 // 单页返回多少条记录,默认返回10条,为了系统安全最多单次只能返回20条
Count int32 `protobuf:"varint,5,opt,name=count" json:"count,omitempty"` Count int32 `protobuf:"varint,5,opt,name=count" json:"count,omitempty"`
} }
...@@ -644,7 +641,7 @@ func (m *QueryMarketDepth) GetOp() int32 { ...@@ -644,7 +641,7 @@ func (m *QueryMarketDepth) GetOp() int32 {
return 0 return 0
} }
func (m *QueryMarketDepth) GetPrice() float32 { func (m *QueryMarketDepth) GetPrice() float64 {
if m != nil { if m != nil {
return m.Price return m.Price
} }
...@@ -665,7 +662,7 @@ type MarketDepth struct { ...@@ -665,7 +662,7 @@ type MarketDepth struct {
// 资产2 // 资产2
RightAsset *Asset `protobuf:"bytes,2,opt,name=rightAsset" json:"rightAsset,omitempty"` RightAsset *Asset `protobuf:"bytes,2,opt,name=rightAsset" json:"rightAsset,omitempty"`
// 价格 // 价格
Price float32 `protobuf:"fixed32,3,opt,name=price" json:"price,omitempty"` Price float64 `protobuf:"fixed64,3,opt,name=price" json:"price,omitempty"`
// 总量 // 总量
Amount int64 `protobuf:"varint,4,opt,name=amount" json:"amount,omitempty"` Amount int64 `protobuf:"varint,4,opt,name=amount" json:"amount,omitempty"`
// 操作, 1为买,2为卖 // 操作, 1为买,2为卖
...@@ -691,7 +688,7 @@ func (m *MarketDepth) GetRightAsset() *Asset { ...@@ -691,7 +688,7 @@ func (m *MarketDepth) GetRightAsset() *Asset {
return nil return nil
} }
func (m *MarketDepth) GetPrice() float32 { func (m *MarketDepth) GetPrice() float64 {
if m != nil { if m != nil {
return m.Price return m.Price
} }
...@@ -967,45 +964,45 @@ func init() { proto.RegisterFile("exchange.proto", fileDescriptor0) } ...@@ -967,45 +964,45 @@ func init() { proto.RegisterFile("exchange.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{ var fileDescriptor0 = []byte{
// 659 bytes of a gzipped FileDescriptorProto // 659 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xed, 0x6a, 0xd4, 0x4c, 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xed, 0x6a, 0xd4, 0x4c,
0x14, 0x6e, 0xbe, 0xba, 0xcd, 0xd9, 0x97, 0xed, 0xeb, 0x20, 0x1a, 0x44, 0x64, 0xc9, 0x8f, 0x5a, 0x14, 0xee, 0xe4, 0xa3, 0xdb, 0x9c, 0x7d, 0xd9, 0xbe, 0x0e, 0xa2, 0x41, 0x44, 0x96, 0xfc, 0xa8,
0x44, 0x57, 0x68, 0xc1, 0x8f, 0x9f, 0xd5, 0x0a, 0x2d, 0x54, 0xaa, 0x83, 0x37, 0x90, 0x26, 0xc7, 0x45, 0x74, 0x85, 0x16, 0xfc, 0xf8, 0x59, 0xad, 0xd0, 0x42, 0xa5, 0x3a, 0x78, 0x03, 0x69, 0x72,
0x6e, 0x68, 0x76, 0x13, 0x92, 0xd9, 0xd2, 0xc5, 0x5b, 0x10, 0xbc, 0x09, 0x05, 0x6f, 0x42, 0xbc, 0xec, 0x86, 0x66, 0x37, 0x21, 0x99, 0x2d, 0x5d, 0xbc, 0x05, 0xc1, 0x9b, 0x50, 0xf0, 0x26, 0xc4,
0x03, 0xaf, 0x49, 0xe6, 0xcc, 0x24, 0x33, 0xdb, 0xae, 0x54, 0xd4, 0xfd, 0x97, 0x67, 0xce, 0x47, 0x3b, 0xf0, 0x9a, 0x64, 0x4e, 0x26, 0x99, 0xd9, 0x76, 0xa5, 0xa2, 0xee, 0xbf, 0x3c, 0x73, 0x3e,
0x9e, 0x73, 0xce, 0x73, 0x66, 0x60, 0x80, 0x17, 0xe9, 0x38, 0x99, 0x9e, 0xe2, 0xa8, 0xaa, 0x4b, 0xf2, 0x9c, 0x73, 0x9e, 0x33, 0x03, 0x03, 0xbc, 0x48, 0xc6, 0xf1, 0xf4, 0x14, 0x47, 0x65, 0x55,
0x51, 0xb2, 0x40, 0xcc, 0x2b, 0x6c, 0x62, 0x80, 0x8d, 0x57, 0xda, 0x10, 0xff, 0x70, 0x60, 0xd0, 0xc8, 0x82, 0xfb, 0x72, 0x5e, 0x62, 0x1d, 0x01, 0x6c, 0xbc, 0xd2, 0x86, 0xe8, 0x07, 0x83, 0x41,
0x82, 0xbd, 0x54, 0xe4, 0xe5, 0x94, 0xed, 0x02, 0x14, 0xf9, 0x24, 0x17, 0xc7, 0x75, 0x86, 0x75, 0x0b, 0xf6, 0x12, 0x99, 0x15, 0x53, 0xbe, 0x0b, 0x90, 0x67, 0x93, 0x4c, 0x1e, 0x57, 0x29, 0x56,
0xe4, 0x0c, 0x9d, 0xed, 0xfe, 0xce, 0x8d, 0x11, 0x85, 0x8e, 0x8e, 0x3a, 0xc3, 0xc1, 0x1a, 0xb7, 0x21, 0x1b, 0xb2, 0xed, 0xfe, 0xce, 0x8d, 0x11, 0x85, 0x8e, 0x8e, 0x3a, 0xc3, 0xc1, 0x9a, 0xb0,
0xdc, 0xd8, 0x13, 0xe8, 0x4f, 0x92, 0xfa, 0x0c, 0x75, 0x94, 0x4b, 0x51, 0x4c, 0x47, 0xbd, 0x36, 0xdc, 0xf8, 0x13, 0xe8, 0x4f, 0xe2, 0xea, 0x0c, 0x75, 0x94, 0x43, 0x51, 0x5c, 0x47, 0xbd, 0x36,
0x96, 0x83, 0x35, 0x6e, 0x3b, 0xca, 0xb8, 0x1a, 0xcf, 0xcb, 0x33, 0x54, 0x71, 0xde, 0x42, 0x1c, 0x96, 0x83, 0x35, 0x61, 0x3b, 0xaa, 0xb8, 0x0a, 0xcf, 0x8b, 0x33, 0x6c, 0xe2, 0xdc, 0x85, 0x38,
0x37, 0x16, 0x19, 0x67, 0x39, 0xb2, 0x01, 0xb8, 0x62, 0x1e, 0xad, 0x0f, 0x9d, 0xed, 0x80, 0xbb, 0x61, 0x2c, 0x2a, 0xce, 0x72, 0xe4, 0x03, 0x70, 0xe4, 0x3c, 0x5c, 0x1f, 0xb2, 0x6d, 0x5f, 0x38,
0x62, 0xfe, 0xa2, 0x07, 0xc1, 0x79, 0x52, 0xcc, 0x30, 0xfe, 0xec, 0x00, 0x18, 0x96, 0xec, 0x01, 0x72, 0xfe, 0xa2, 0x07, 0xfe, 0x79, 0x9c, 0xcf, 0x30, 0xfa, 0xcc, 0x00, 0x0c, 0x4b, 0xfe, 0x00,
0x84, 0x05, 0xbe, 0x17, 0x7b, 0x4d, 0x83, 0x42, 0xd7, 0xf2, 0x9f, 0xce, 0x9e, 0xc8, 0x33, 0x6e, 0x82, 0x1c, 0xdf, 0xcb, 0xbd, 0xba, 0x46, 0xa9, 0x6b, 0xf9, 0x4f, 0x67, 0x8f, 0xd5, 0x99, 0x30,
0xcc, 0xec, 0x21, 0x40, 0x9d, 0x9f, 0x8e, 0xb5, 0xb3, 0xbb, 0xc4, 0xd9, 0xb2, 0xb3, 0x9b, 0x10, 0x66, 0xfe, 0x10, 0xa0, 0xca, 0x4e, 0xc7, 0xda, 0xd9, 0x59, 0xe2, 0x6c, 0xd9, 0xf9, 0x4d, 0xf0,
0x54, 0x75, 0x9e, 0x22, 0x71, 0x76, 0xb9, 0x02, 0xec, 0x16, 0xac, 0x27, 0x93, 0x72, 0x36, 0x15, 0xcb, 0x2a, 0x4b, 0x90, 0x38, 0x33, 0xd1, 0x00, 0x7e, 0x0b, 0xd6, 0xe3, 0x49, 0x31, 0x9b, 0xca,
0x91, 0x3f, 0x74, 0xb6, 0x3d, 0xae, 0x91, 0xe4, 0x5b, 0x56, 0x51, 0xa0, 0xf8, 0x96, 0x55, 0xfc, 0xd0, 0x1b, 0xb2, 0x6d, 0x57, 0x68, 0xa4, 0xf8, 0x16, 0x65, 0xe8, 0x37, 0x7c, 0x8b, 0x32, 0xfa,
0xc9, 0x81, 0xbe, 0xd5, 0x96, 0x15, 0xf2, 0x34, 0x8c, 0xbc, 0x25, 0x8c, 0xfc, 0x8e, 0xd1, 0x7d, 0xc4, 0xa0, 0x6f, 0xb5, 0x65, 0x85, 0x3c, 0x0d, 0x23, 0x77, 0x09, 0x23, 0xaf, 0x63, 0x74, 0x1f,
0xe8, 0x5b, 0xfd, 0x66, 0x11, 0xf4, 0x4a, 0xf9, 0x71, 0xb8, 0x4f, 0x74, 0x42, 0xde, 0xc2, 0xf8, 0xfa, 0x56, 0xbf, 0x79, 0x08, 0xbd, 0x42, 0x7d, 0x1c, 0xee, 0x13, 0x9d, 0x40, 0xb4, 0x30, 0x7a,
0x29, 0x04, 0x49, 0x9b, 0x19, 0x2f, 0x30, 0xd5, 0x22, 0x09, 0xb9, 0x46, 0xf2, 0xbc, 0x99, 0x4f, 0x0a, 0x7e, 0xdc, 0x66, 0xc6, 0x0b, 0x4c, 0xb4, 0x48, 0x02, 0xa1, 0x91, 0x3a, 0xaf, 0xe7, 0x93,
0x4e, 0xca, 0x82, 0xb8, 0x85, 0x5c, 0xa3, 0xf8, 0xbb, 0x0b, 0xc1, 0x35, 0xc9, 0x2f, 0x89, 0xcf, 0x93, 0x22, 0x27, 0x6e, 0x81, 0xd0, 0x28, 0xfa, 0xee, 0x80, 0x7f, 0x4d, 0xf2, 0x4b, 0xe2, 0x73,
0xfd, 0x23, 0xf1, 0x79, 0xbf, 0x2b, 0x3e, 0x25, 0x22, 0xbf, 0x15, 0x11, 0xbb, 0x03, 0x1b, 0xb2, 0xfe, 0x48, 0x7c, 0xee, 0xef, 0x8a, 0xaf, 0x11, 0x91, 0xd7, 0x8a, 0x88, 0xdf, 0x81, 0x0d, 0x55,
0x84, 0x99, 0xc0, 0x8c, 0x46, 0xe5, 0xf1, 0x0e, 0x4b, 0xca, 0x27, 0x49, 0x91, 0x4c, 0x53, 0x24, 0xc2, 0x4c, 0x62, 0x4a, 0xa3, 0x72, 0x45, 0x87, 0x15, 0xe5, 0x93, 0x38, 0x8f, 0xa7, 0x09, 0x92,
0xd5, 0x79, 0xbc, 0x85, 0x54, 0xae, 0x48, 0xc4, 0xac, 0x89, 0x7a, 0x94, 0x49, 0x23, 0xc6, 0xc0, 0xea, 0x5c, 0xd1, 0x42, 0x2a, 0x57, 0xc6, 0x72, 0x56, 0x87, 0x3d, 0xca, 0xa4, 0x11, 0xe7, 0xe0,
0x4f, 0xb2, 0xac, 0x8e, 0x36, 0xa8, 0x42, 0xfa, 0x66, 0xf7, 0x00, 0x66, 0x55, 0x96, 0x08, 0x7c, 0xc5, 0x69, 0x5a, 0x85, 0x1b, 0x54, 0x21, 0x7d, 0xf3, 0x7b, 0x00, 0xb3, 0x32, 0x8d, 0x25, 0xbe,
0x97, 0x4f, 0x30, 0x0a, 0x29, 0x91, 0x75, 0x22, 0x45, 0x95, 0x4f, 0x33, 0xbc, 0x88, 0x80, 0x4c, 0xcb, 0x26, 0x18, 0x06, 0x94, 0xc8, 0x3a, 0x51, 0xa2, 0xca, 0xa6, 0x29, 0x5e, 0x84, 0x40, 0xa6,
0x0a, 0x18, 0x71, 0x3f, 0x03, 0x20, 0xe6, 0x6f, 0x48, 0x6b, 0x9d, 0x02, 0x1d, 0x5b, 0x81, 0x5d, 0x06, 0x18, 0x71, 0x3f, 0x03, 0x20, 0xe6, 0x6f, 0x48, 0x6b, 0x9d, 0x02, 0x99, 0xad, 0xc0, 0x2e,
0x0a, 0xd7, 0x4a, 0x11, 0x3f, 0x86, 0xde, 0xb1, 0x6e, 0xf1, 0x00, 0xdc, 0xae, 0xef, 0xee, 0xe1, 0x85, 0x63, 0xa5, 0x88, 0x1e, 0x43, 0xef, 0x58, 0xb7, 0x78, 0x00, 0x4e, 0xd7, 0x77, 0xe7, 0x70,
0xfe, 0x2f, 0x02, 0xbe, 0x3a, 0xf0, 0xff, 0xdb, 0x19, 0xd6, 0x73, 0xd5, 0xbf, 0x7d, 0xac, 0xc4, 0xff, 0x17, 0x01, 0x5f, 0x19, 0xfc, 0xff, 0x76, 0x86, 0xd5, 0xbc, 0xe9, 0xdf, 0x3e, 0x96, 0x72,
0x78, 0x85, 0x2a, 0x55, 0x6a, 0xf4, 0x5a, 0x35, 0x9a, 0xda, 0xfc, 0x4b, 0xb5, 0xa5, 0x24, 0x65, 0xbc, 0x42, 0x95, 0x36, 0x6a, 0x74, 0x5b, 0x35, 0x9a, 0xda, 0xbc, 0x4b, 0xb5, 0x25, 0x24, 0xe5,
0xb5, 0x48, 0x0a, 0xc4, 0x5f, 0xba, 0x5d, 0x5a, 0x35, 0xcb, 0xbf, 0xdb, 0xf9, 0xe7, 0xb0, 0x69, 0x66, 0x91, 0x1a, 0x10, 0x7d, 0xe9, 0x76, 0x69, 0xd5, 0x2c, 0xff, 0x6e, 0xe7, 0x9f, 0xc3, 0xa6,
0xd1, 0x3c, 0xca, 0x1b, 0xc1, 0xb6, 0xc0, 0x2f, 0xf2, 0x46, 0xb2, 0xf4, 0xae, 0x48, 0x96, 0xbc, 0x45, 0xf3, 0x28, 0xab, 0x25, 0xdf, 0x02, 0x2f, 0xcf, 0x6a, 0xc5, 0xd2, 0xbd, 0x22, 0x59, 0xf2,
0x38, 0xd9, 0xe3, 0x6f, 0x0e, 0xdc, 0xa6, 0x69, 0xbc, 0x2c, 0x27, 0x55, 0x81, 0x02, 0x33, 0x9a, 0x12, 0x64, 0x8f, 0xbe, 0x31, 0xb8, 0x4d, 0xd3, 0x78, 0x59, 0x4c, 0xca, 0x1c, 0x25, 0xa6, 0x34,
0x26, 0xe5, 0x58, 0x69, 0xb9, 0x4a, 0x19, 0x9e, 0xa5, 0x0c, 0x33, 0x04, 0xdf, 0x1a, 0x02, 0xbb, 0x4d, 0xca, 0xb1, 0xd2, 0x72, 0x1b, 0x65, 0xb8, 0x96, 0x32, 0xcc, 0x10, 0x3c, 0x6b, 0x08, 0xfc,
0x0b, 0x61, 0x96, 0xd7, 0x48, 0x4f, 0x88, 0xae, 0xd9, 0x1c, 0xc4, 0x5b, 0x00, 0x44, 0xff, 0xba, 0x2e, 0x04, 0x69, 0x56, 0x21, 0x3d, 0x21, 0xba, 0x66, 0x73, 0x10, 0x6d, 0x01, 0x10, 0xfd, 0xeb,
0xbb, 0xe5, 0xa3, 0x03, 0x03, 0xe3, 0x48, 0xe5, 0x99, 0xf5, 0x72, 0x16, 0xd6, 0x2b, 0x82, 0x9e, 0xee, 0x96, 0x8f, 0x0c, 0x06, 0xc6, 0x91, 0xca, 0x33, 0xeb, 0xc5, 0x16, 0xd6, 0x2b, 0x84, 0x9e,
0x5c, 0x29, 0x6c, 0x1a, 0x7d, 0xcd, 0xb4, 0xf0, 0x1f, 0xd2, 0x7e, 0x04, 0xa1, 0x21, 0x32, 0x5c, 0x5a, 0x29, 0xac, 0x6b, 0x7d, 0xcd, 0xb4, 0xf0, 0x1f, 0xd2, 0x7e, 0x04, 0x81, 0x21, 0x32, 0x5c,
0x98, 0x55, 0xdb, 0x35, 0xb2, 0xeb, 0x29, 0x7d, 0x80, 0x4d, 0x8e, 0x29, 0xe6, 0x95, 0x68, 0x9f, 0x98, 0x55, 0xdb, 0x35, 0xb2, 0xeb, 0x29, 0x7d, 0x80, 0x4d, 0x81, 0x09, 0x66, 0xa5, 0x6c, 0x9f,
0x54, 0x16, 0x43, 0x50, 0x5a, 0xef, 0xe8, 0x62, 0x94, 0x32, 0xb1, 0x91, 0xbc, 0xbe, 0x44, 0x3a, 0x54, 0x1e, 0x81, 0x5f, 0x58, 0xef, 0xe8, 0x62, 0x54, 0x63, 0xe2, 0x23, 0x75, 0x7d, 0xc9, 0x64,
0xa6, 0x43, 0x59, 0xcd, 0xd5, 0xfc, 0xb6, 0xc3, 0xf2, 0xfa, 0x76, 0x40, 0x5e, 0x5e, 0xea, 0xaf, 0x4c, 0x87, 0xaa, 0x9a, 0xab, 0xf9, 0x6d, 0x87, 0xe5, 0xf5, 0xed, 0x80, 0xba, 0xbc, 0x9a, 0xbf,
0x27, 0xeb, 0xf4, 0xde, 0xef, 0xfe, 0x0c, 0x00, 0x00, 0xff, 0xff, 0x08, 0x34, 0x16, 0x15, 0x01, 0x9e, 0xac, 0xd3, 0x7b, 0xbf, 0xfb, 0x33, 0x00, 0x00, 0xff, 0xff, 0xd8, 0xc6, 0x87, 0x60, 0x01,
0x08, 0x00, 0x00, 0x08, 0x00, 0x00,
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment