Commit 2baff87a authored by harrylee's avatar harrylee Committed by vipwzw

ajust code for table

parent 2dfb0996
......@@ -11,7 +11,7 @@
查询方法名称|功能
-----|----
QueryMarketDepth|获取指定交易资产的市场深度
QueryCompletedOrderList|实时获取指定交易对最新的成交信息
QueryHistoryOrderList|实时获取指定交易对已经成交的订单信息
QueryOrder|根据orderID订单号查询具体的订单信息
QueryOrderList|根据用户地址和订单状态(ordered,completed,revoked),实时地获取相应相应的订单详情
......
......@@ -240,8 +240,8 @@ func TestExchange(t *testing.T) {
//市场深度应该改变
assert.Equal(t, 5*types.Coin, reply1.List[0].GetAmount())
//QueryCompletedOrderList
msg, err = exec.Query(et.FuncNameQueryCompletedOrderList, types.Encode(&et.QueryCompletedOrderList{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
//QueryHistoryOrderList
msg, err = exec.Query(et.FuncNameQueryHistoryOrderList, types.Encode(&et.QueryHistoryOrderList{LeftAsset: &et.Asset{Symbol: "bty", Execer: "coins"},
RightAsset: &et.Asset{Execer: "token", Symbol: "CCNY"}}))
if err != nil {
t.Error(err)
......@@ -831,14 +831,12 @@ func TestCheckPrice(t *testing.T) {
}
func TestRawMeta(t *testing.T) {
CompletedOrderRow := NewCompletedOrderRow()
t.Log(CompletedOrderRow.Get("index"))
HistoryOrderRow := NewHistoryOrderRow()
t.Log(HistoryOrderRow.Get("index"))
MarketDepthRow := NewMarketDepthRow()
t.Log(MarketDepthRow.Get("price"))
marketOrderRow := NewOrderRow()
t.Log(marketOrderRow.Get("orderID"))
UserOrderRow := NewUserOrderRow()
t.Log(UserOrderRow.Get("index"))
}
func TestKV(t *testing.T) {
......
......@@ -585,19 +585,20 @@ func QueryMarketDepth(localdb dbm.KV, left, right *et.Asset, op int32, primaryKe
return &list, nil
}
//QueryCompletedOrderList
func QueryCompletedOrderList(localdb dbm.KV, left, right *et.Asset, primaryKey string, count, direction int32) (types.Message, error) {
table := NewCompletedOrderTable(localdb)
//QueryHistoryOrderList
func QueryHistoryOrderList(localdb dbm.KV, left, right *et.Asset, primaryKey string, count, direction int32) (types.Message, error) {
table := NewHistoryOrderTable(localdb)
prefix := []byte(fmt.Sprintf("%s:%s", left.Symbol, right.Symbol))
indexName := "name"
if count == 0 {
count = et.Count
}
var rows []*tab.Row
var err error
if primaryKey == "" { //第一次查询,默认展示最新得成交记录
rows, err = table.ListIndex("index", prefix, nil, count, direction)
rows, err = table.ListIndex(indexName, prefix, nil, count, direction)
} else {
rows, err = table.ListIndex("index", prefix, []byte(primaryKey), count, direction)
rows, err = table.ListIndex(indexName, prefix, []byte(primaryKey), count, direction)
}
if err != nil {
elog.Error("QueryCompletedOrderList.", "left", left, "right", right, "err", err.Error())
......@@ -607,6 +608,10 @@ func QueryCompletedOrderList(localdb dbm.KV, left, right *et.Asset, primaryKey s
var orderList et.OrderList
for _, row := range rows {
order := row.Data.(*et.Order)
//因为这张表里面记录了 completed,revoked 两种状态的订单,所以需要过滤
if order.Status == et.Revoked {
continue
}
//替换已经成交得量
order.Executed = order.GetLimitOrder().Amount - order.Balance
orderList.List = append(orderList.List, order)
......@@ -620,17 +625,23 @@ func QueryCompletedOrderList(localdb dbm.KV, left, right *et.Asset, primaryKey s
//QueryOrderList,默认展示最新的
func QueryOrderList(localdb dbm.KV, statedb dbm.KV, addr string, status, count, direction int32, primaryKey string) (types.Message, error) {
table := NewUserOrderTable(localdb)
var table *tab.Table
if status == et.Completed || status == et.Revoked {
table = NewHistoryOrderTable(localdb)
} else {
table = NewMarketOrderTable(localdb)
}
prefix := []byte(fmt.Sprintf("%s:%d", addr, status))
indexName := "addr_status"
if count == 0 {
count = et.Count
}
var rows []*tab.Row
var err error
if primaryKey == "" { //第一次查询,默认展示最新得成交记录
rows, err = table.ListIndex("index", prefix, nil, count, direction)
rows, err = table.ListIndex(indexName, prefix, nil, count, direction)
} else {
rows, err = table.ListIndex("index", prefix, []byte(primaryKey), count, direction)
rows, err = table.ListIndex(indexName, prefix, []byte(primaryKey), count, direction)
}
if err != nil {
elog.Error("QueryOrderList.", "addr", addr, "err", err.Error())
......
......@@ -66,16 +66,14 @@ func (e *exchange) ExecLocal_RevokeOrder(payload *ety.RevokeOrder, tx *types.Tra
//设置自动回滚
func (e *exchange) addAutoRollBack(tx *types.Transaction, kv []*types.KeyValue) *types.LocalDBSet {
dbSet := &types.LocalDBSet{}
dbSet.KV = e.AddRollbackKV(tx, tx.Execer, kv)
return dbSet
}
func (e *exchange) updateIndex(receipt *ety.ReceiptExchange) (kvs []*types.KeyValue) {
completedTable := NewCompletedOrderTable(e.GetLocalDB())
historyTable := NewHistoryOrderTable(e.GetLocalDB())
marketTable := NewMarketDepthTable(e.GetLocalDB())
userTable := NewUserOrderTable(e.GetLocalDB())
orderTable := NewMarketOrderTable(e.GetLocalDB())
switch receipt.Order.Status {
case ety.Ordered:
......@@ -111,30 +109,26 @@ func (e *exchange) updateIndex(receipt *ety.ReceiptExchange) (kvs []*types.KeyVa
elog.Error("updateIndex", "orderTable.Replace", err.Error())
return nil
}
err = userTable.Replace(order)
if err != nil {
return nil
}
if len(receipt.MatchOrders) > 0 {
//撮合交易更新
cache := make(map[float64]int64)
for i, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == ety.Completed {
// 删除原有状态orderID
matchOrder.Status = ety.Ordered
err = orderTable.DelRow(matchOrder)
if err != nil {
elog.Error("updateIndex", "orderTable.DelRow", err.Error())
return nil
}
//删除原有状态orderID
matchOrder.Status = ety.Ordered
userTable.DelRow(matchOrder)
//更新状态为已完成,索引index,改为当前的index
//索引index,改为当前的index
matchOrder.Status = ety.Completed
matchOrder.Index = index + int64(i+1)
userTable.Replace(matchOrder)
//calcCompletedOrderKey
completedTable.Replace(matchOrder)
err = historyTable.Replace(matchOrder)
if err != nil {
elog.Error("updateIndex", "historyTable.Replace", err.Error())
return nil
}
}
if matchOrder.Status == ety.Ordered {
//更新数据
......@@ -183,14 +177,9 @@ func (e *exchange) updateIndex(receipt *ety.ReceiptExchange) (kvs []*types.KeyVa
right := receipt.GetOrder().GetLimitOrder().GetRightAsset()
op := receipt.GetOrder().GetLimitOrder().GetOp()
index := receipt.GetIndex()
err := userTable.Replace(receipt.GetOrder())
if err != nil {
elog.Error("updateIndex", "userTable.Replace", err.Error())
return nil
}
err = completedTable.Replace(receipt.Order)
err := historyTable.Replace(receipt.GetOrder())
if err != nil {
elog.Error("updateIndex", "completedTable.Replace", err.Error())
elog.Error("updateIndex", "historyTable.Replace", err.Error())
return nil
}
cache := make(map[float64]int64)
......@@ -199,30 +188,18 @@ func (e *exchange) updateIndex(receipt *ety.ReceiptExchange) (kvs []*types.KeyVa
for i, matchOrder := range receipt.MatchOrders {
if matchOrder.Status == ety.Completed {
// 删除原有状态orderID
matchOrder.Status = ety.Ordered
err = orderTable.DelRow(matchOrder)
if err != nil {
elog.Error("updateIndex", "orderTable.DelRow", err.Error())
return nil
}
//删除原有状态orderID
matchOrder.Status = ety.Ordered
err = userTable.DelRow(matchOrder)
if err != nil {
elog.Error("updateIndex", "userTable.DelRow", err.Error())
return nil
}
//更新状态为已完成,更新索引
//索引index,改为当前的index
matchOrder.Status = ety.Completed
matchOrder.Index = index + int64(i+1)
err = userTable.Replace(matchOrder)
if err != nil {
elog.Error("updateIndex", "userTable.Replace", err.Error())
return nil
}
//calcCompletedOrderKey
err = completedTable.Replace(matchOrder)
err = historyTable.Replace(matchOrder)
if err != nil {
elog.Error("updateIndex", "completedTable.Replace", err.Error())
elog.Error("updateIndex", "historyTable.Replace", err.Error())
return nil
}
}
......@@ -299,25 +276,19 @@ func (e *exchange) updateIndex(receipt *ety.ReceiptExchange) (kvs []*types.KeyVa
return nil
}
}
// 删除原有状态orderID
err = orderTable.DelRow(order)
if err != nil {
elog.Error("updateIndex", "orderTable.DelRow", err.Error())
return nil
}
//删除原有状态orderID
order.Status = ety.Ordered
err = userTable.DelRow(order)
err = orderTable.DelRow(order)
if err != nil {
elog.Error("updateIndex", "userTable.DelRow", err.Error())
elog.Error("updateIndex", "orderTable.DelRow", err.Error())
return nil
}
order.Status = ety.Revoked
order.Index = index
//添加撤销的订单
err = userTable.Replace(order)
err = historyTable.Replace(order)
if err != nil {
elog.Error("updateIndex", "userTable.Replace", err.Error())
elog.Error("updateIndex", "historyTable.Replace", err.Error())
return nil
}
}
......@@ -328,21 +299,15 @@ func (e *exchange) updateIndex(receipt *ety.ReceiptExchange) (kvs []*types.KeyVa
return nil
}
kvs = append(kvs, kv...)
kv, err = userTable.Save()
if err != nil {
elog.Error("updateIndex", "userTable.Save", err.Error())
return nil
}
kvs = append(kvs, kv...)
kv, err = orderTable.Save()
if err != nil {
elog.Error("updateIndex", "orderTable.Save", err.Error())
return nil
}
kvs = append(kvs, kv...)
kv, err = completedTable.Save()
kv, err = historyTable.Save()
if err != nil {
elog.Error("updateIndex", "completedTable.Save", err.Error())
elog.Error("updateIndex", "historyTable.Save", err.Error())
return nil
}
kvs = append(kvs, kv...)
......
......@@ -24,7 +24,7 @@ func (s *exchange) Query_QueryMarketDepth(in *et.QueryMarketDepth) (types.Messag
}
//查询已经完成得订单
func (s *exchange) Query_QueryCompletedOrderList(in *et.QueryCompletedOrderList) (types.Message, error) {
func (s *exchange) Query_QueryHistoryOrderList(in *et.QueryHistoryOrderList) (types.Message, error) {
if !CheckExchangeAsset(in.LeftAsset, in.RightAsset) {
return nil, et.ErrAsset
}
......@@ -35,7 +35,7 @@ func (s *exchange) Query_QueryCompletedOrderList(in *et.QueryCompletedOrderList)
if !CheckDirection(in.Direction) {
return nil, et.ErrDirection
}
return QueryCompletedOrderList(s.GetLocalDB(), in.LeftAsset, in.RightAsset, in.PrimaryKey, in.Count, in.Direction)
return QueryHistoryOrderList(s.GetLocalDB(), in.LeftAsset, in.RightAsset, in.PrimaryKey, in.Count, in.Direction)
}
//根据orderID查询订单信息
......
......@@ -40,22 +40,14 @@ var opt_exchange_order = &table.Option{
Prefix: KeyPrefixLocalDB,
Name: "order",
Primary: "orderID",
Index: []string{"market_order"},
Index: []string{"market_order","addr_status"},
}
//根据地址和状态,index是实时在变化,要有先后顺序
var opt_exchange_user_order = &table.Option{
var opt_exchange_history = &table.Option{
Prefix: KeyPrefixLocalDB,
Name: "UserOrder",
Name: "history",
Primary: "index",
Index: nil,
}
var opt_exchange_completed = &table.Option{
Prefix: KeyPrefixLocalDB,
Name: "completed",
Primary: "index",
Index: nil,
Index: []string{"name","addr_status"},
}
//NewTable 新建表
......@@ -77,17 +69,10 @@ func NewMarketOrderTable(kvdb db.KV) *table.Table {
return table
}
func NewUserOrderTable(kvdb db.KV) *table.Table {
rowmeta := NewUserOrderRow()
table, err := table.NewTable(rowmeta, kvdb, opt_exchange_user_order)
if err != nil {
panic(err)
}
return table
}
func NewCompletedOrderTable(kvdb db.KV) *table.Table {
rowmeta := NewCompletedOrderRow()
table, err := table.NewTable(rowmeta, kvdb, opt_exchange_completed)
func NewHistoryOrderTable(kvdb db.KV) *table.Table {
rowmeta := NewHistoryOrderRow()
table, err := table.NewTable(rowmeta, kvdb, opt_exchange_history)
if err != nil {
panic(err)
}
......@@ -124,57 +109,27 @@ func (r *OrderRow) Get(key string) ([]byte, error) {
return []byte(fmt.Sprintf("%022d", r.OrderID)), nil
} else if key == "market_order" {
return []byte(fmt.Sprintf("%s:%s:%d:%016d", r.GetLimitOrder().LeftAsset.GetSymbol(), r.GetLimitOrder().RightAsset.GetSymbol(), r.GetLimitOrder().Op, int64(Truncate(r.GetLimitOrder().Price*float64(1e8))))), nil
} else if key == "addr_status"{
return []byte(fmt.Sprintf("%s:%d", r.Addr, r.Status)), nil
}
return nil, types.ErrNotFound
}
//UserOrderRow table meta 结构
type UserOrderRow struct {
*ety.Order
}
//NewOrderRow 新建一个meta 结构
func NewUserOrderRow() *UserOrderRow {
return &UserOrderRow{Order: &ety.Order{Value: &ety.Order_LimitOrder{LimitOrder: &ety.LimitOrder{}}}}
}
//CreateRow
func (r *UserOrderRow) CreateRow() *table.Row {
return &table.Row{Data: &ety.Order{}}
}
//SetPayload 设置数据
func (r *UserOrderRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*ety.Order); ok {
r.Order = txdata
return nil
}
return types.ErrTypeAsset
}
//Get 按照indexName 查询 indexValue
func (r *UserOrderRow) Get(key string) ([]byte, error) {
if key == "index" {
return []byte(fmt.Sprintf("%s:%d:%022d", r.Addr, r.Status, r.Index)), nil
}
return nil, types.ErrNotFound
}
//CompletedOrderRow table meta 结构
type CompletedOrderRow struct {
//HistoryOrderRow table meta 结构
type HistoryOrderRow struct {
*ety.Order
}
func NewCompletedOrderRow() *CompletedOrderRow {
return &CompletedOrderRow{Order: &ety.Order{Value: &ety.Order_LimitOrder{LimitOrder: &ety.LimitOrder{}}}}
func NewHistoryOrderRow() *HistoryOrderRow {
return &HistoryOrderRow{Order: &ety.Order{Value: &ety.Order_LimitOrder{LimitOrder: &ety.LimitOrder{}}}}
}
func (m *CompletedOrderRow) CreateRow() *table.Row {
func (m *HistoryOrderRow) CreateRow() *table.Row {
return &table.Row{Data: &ety.Order{Value: &ety.Order_LimitOrder{LimitOrder: &ety.LimitOrder{}}}}
}
//SetPayload 设置数据
func (m *CompletedOrderRow) SetPayload(data types.Message) error {
func (m *HistoryOrderRow) SetPayload(data types.Message) error {
if txdata, ok := data.(*ety.Order); ok {
m.Order = txdata
return nil
......@@ -183,9 +138,13 @@ func (m *CompletedOrderRow) SetPayload(data types.Message) error {
}
//Get 按照indexName 查询 indexValue
func (m *CompletedOrderRow) Get(key string) ([]byte, error) {
func (m *HistoryOrderRow) Get(key string) ([]byte, error) {
if key == "index" {
return []byte(fmt.Sprintf("%s:%s:%022d", m.GetLimitOrder().LeftAsset.GetSymbol(), m.GetLimitOrder().RightAsset.GetSymbol(), m.Index)), nil
return []byte(fmt.Sprintf("%022d", m.Index)), nil
}else if key == "name"{
return []byte(fmt.Sprintf("%s:%s", m.GetLimitOrder().LeftAsset.GetSymbol(), m.GetLimitOrder().RightAsset.GetSymbol())), nil
} else if key == "addr_status"{
return []byte(fmt.Sprintf("%s:%d", m.Addr, m.Status)), nil
}
return nil, types.ErrNotFound
}
......
......@@ -105,7 +105,7 @@ message MarketDepthList {
}
//查询最新得成交信息,外部接口
message QueryCompletedOrderList {
message QueryHistoryOrderList {
//资产1
asset leftAsset = 1;
//资产2
......
......@@ -23,10 +23,10 @@ const (
NameMarketOrderAction = "MarketOrder"
NameRevokeOrderAction = "RevokeOrder"
FuncNameQueryMarketDepth = "QueryMarketDepth"
FuncNameQueryCompletedOrderList = "QueryCompletedOrderList"
FuncNameQueryOrder = "QueryOrder"
FuncNameQueryOrderList = "QueryOrderList"
FuncNameQueryMarketDepth = "QueryMarketDepth"
FuncNameQueryHistoryOrderList = "QueryHistoryOrderList"
FuncNameQueryOrder = "QueryOrder"
FuncNameQueryOrderList = "QueryOrderList"
)
// log类型id值
......
......@@ -18,7 +18,7 @@ It has these top-level messages:
QueryMarketDepth
MarketDepth
MarketDepthList
QueryCompletedOrderList
QueryHistoryOrderList
QueryOrder
QueryOrderList
OrderList
......@@ -26,15 +26,12 @@ It has these top-level messages:
*/
package types
import (
fmt "fmt"
proto "github.com/golang/protobuf/proto"
math "math"
import proto "github.com/golang/protobuf/proto"
import fmt "fmt"
import math "math"
import (
context "golang.org/x/net/context"
grpc "google.golang.org/grpc"
)
......@@ -686,7 +683,7 @@ func (m *MarketDepthList) GetPrimaryKey() string {
}
// 查询最新得成交信息,外部接口
type QueryCompletedOrderList struct {
type QueryHistoryOrderList struct {
// 资产1
LeftAsset *Asset `protobuf:"bytes,1,opt,name=leftAsset" json:"leftAsset,omitempty"`
// 资产2
......@@ -699,40 +696,40 @@ type QueryCompletedOrderList struct {
Direction int32 `protobuf:"varint,5,opt,name=direction" json:"direction,omitempty"`
}
func (m *QueryCompletedOrderList) Reset() { *m = QueryCompletedOrderList{} }
func (m *QueryCompletedOrderList) String() string { return proto.CompactTextString(m) }
func (*QueryCompletedOrderList) ProtoMessage() {}
func (*QueryCompletedOrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (m *QueryHistoryOrderList) Reset() { *m = QueryHistoryOrderList{} }
func (m *QueryHistoryOrderList) String() string { return proto.CompactTextString(m) }
func (*QueryHistoryOrderList) ProtoMessage() {}
func (*QueryHistoryOrderList) Descriptor() ([]byte, []int) { return fileDescriptor0, []int{10} }
func (m *QueryCompletedOrderList) GetLeftAsset() *Asset {
func (m *QueryHistoryOrderList) GetLeftAsset() *Asset {
if m != nil {
return m.LeftAsset
}
return nil
}
func (m *QueryCompletedOrderList) GetRightAsset() *Asset {
func (m *QueryHistoryOrderList) GetRightAsset() *Asset {
if m != nil {
return m.RightAsset
}
return nil
}
func (m *QueryCompletedOrderList) GetPrimaryKey() string {
func (m *QueryHistoryOrderList) GetPrimaryKey() string {
if m != nil {
return m.PrimaryKey
}
return ""
}
func (m *QueryCompletedOrderList) GetCount() int32 {
func (m *QueryHistoryOrderList) GetCount() int32 {
if m != nil {
return m.Count
}
return 0
}
func (m *QueryCompletedOrderList) GetDirection() int32 {
func (m *QueryHistoryOrderList) GetDirection() int32 {
if m != nil {
return m.Direction
}
......@@ -879,7 +876,7 @@ func init() {
proto.RegisterType((*QueryMarketDepth)(nil), "types.QueryMarketDepth")
proto.RegisterType((*MarketDepth)(nil), "types.MarketDepth")
proto.RegisterType((*MarketDepthList)(nil), "types.MarketDepthList")
proto.RegisterType((*QueryCompletedOrderList)(nil), "types.QueryCompletedOrderList")
proto.RegisterType((*QueryHistoryOrderList)(nil), "types.QueryHistoryOrderList")
proto.RegisterType((*QueryOrder)(nil), "types.QueryOrder")
proto.RegisterType((*QueryOrderList)(nil), "types.QueryOrderList")
proto.RegisterType((*OrderList)(nil), "types.OrderList")
......@@ -927,46 +924,46 @@ var _Exchange_serviceDesc = grpc.ServiceDesc{
func init() { proto.RegisterFile("exchange.proto", fileDescriptor0) }
var fileDescriptor0 = []byte{
// 647 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcf, 0x6e, 0xd3, 0x4e,
0x10, 0xae, 0xed, 0xb8, 0xa9, 0x27, 0x3f, 0xa5, 0x3f, 0x56, 0x08, 0x2c, 0x84, 0x50, 0xe4, 0x43,
0xa9, 0x10, 0xca, 0xa1, 0x95, 0xe0, 0x5c, 0x28, 0x52, 0x11, 0xad, 0x10, 0x2b, 0x2e, 0x1c, 0x5d,
0x7b, 0x68, 0x56, 0xb5, 0x63, 0x6b, 0xbd, 0xa9, 0x1a, 0xf1, 0x10, 0xdc, 0x78, 0x02, 0x78, 0x01,
0x5e, 0x80, 0x23, 0x37, 0x9e, 0x09, 0xed, 0xec, 0x3a, 0xde, 0xa4, 0x45, 0xad, 0x40, 0xb9, 0xf9,
0x9b, 0x7f, 0xfe, 0x66, 0xe6, 0xdb, 0x5d, 0x18, 0xe2, 0x65, 0x36, 0x49, 0xa7, 0x67, 0x38, 0xae,
0x65, 0xa5, 0x2a, 0x16, 0xaa, 0x79, 0x8d, 0x4d, 0x02, 0xb0, 0xf5, 0xca, 0x3a, 0x92, 0x5f, 0x1e,
0x0c, 0x5b, 0x70, 0x90, 0x29, 0x51, 0x4d, 0xd9, 0x3e, 0x40, 0x21, 0x4a, 0xa1, 0xde, 0xca, 0x1c,
0x65, 0xec, 0x8d, 0xbc, 0xdd, 0xc1, 0xde, 0x9d, 0x31, 0xa5, 0x8e, 0x8f, 0x17, 0x8e, 0xa3, 0x0d,
0xee, 0x84, 0xb1, 0x67, 0x30, 0x28, 0x53, 0x79, 0x8e, 0x36, 0xcb, 0xa7, 0x2c, 0x66, 0xb3, 0x4e,
0x3a, 0xcf, 0xd1, 0x06, 0x77, 0x03, 0x75, 0x9e, 0xc4, 0x8b, 0xea, 0x1c, 0x4d, 0x5e, 0xb0, 0x94,
0xc7, 0x3b, 0x8f, 0xce, 0x73, 0x02, 0xd9, 0x10, 0x7c, 0x35, 0x8f, 0x37, 0x47, 0xde, 0x6e, 0xc8,
0x7d, 0x35, 0x7f, 0xd1, 0x87, 0xf0, 0x22, 0x2d, 0x66, 0x98, 0x7c, 0xf5, 0x00, 0x3a, 0x96, 0xec,
0x09, 0x44, 0x05, 0x7e, 0x54, 0x07, 0x4d, 0x83, 0xca, 0xf6, 0xf2, 0x9f, 0xad, 0x9e, 0x6a, 0x1b,
0xef, 0xdc, 0xec, 0x29, 0x80, 0x14, 0x67, 0x13, 0x1b, 0xec, 0x5f, 0x13, 0xec, 0xf8, 0xd9, 0x5d,
0x08, 0x6b, 0x29, 0x32, 0x24, 0xce, 0x1e, 0x37, 0x80, 0xdd, 0x83, 0xcd, 0xb4, 0xac, 0x66, 0x53,
0x15, 0xf7, 0x46, 0xde, 0x6e, 0xc0, 0x2d, 0xd2, 0x7c, 0xab, 0x3a, 0x0e, 0x0d, 0xdf, 0xaa, 0x4e,
0x3e, 0x7b, 0x30, 0x70, 0xc6, 0xb2, 0x46, 0x9e, 0x1d, 0xa3, 0xe0, 0x1a, 0x46, 0xbd, 0x05, 0xa3,
0xc7, 0x30, 0x70, 0xe6, 0xcd, 0x62, 0xe8, 0x57, 0xfa, 0xe3, 0xf5, 0x21, 0xd1, 0x09, 0x78, 0x0b,
0x93, 0xe7, 0x10, 0xa6, 0x6d, 0x65, 0xbc, 0xc4, 0xcc, 0x8a, 0x24, 0xe2, 0x16, 0x69, 0x7b, 0x33,
0x2f, 0x4f, 0xab, 0x82, 0xb8, 0x45, 0xdc, 0xa2, 0xe4, 0x87, 0x0f, 0xe1, 0x0d, 0xc5, 0x57, 0xc4,
0xe7, 0xff, 0x95, 0xf8, 0x82, 0xdb, 0x8a, 0xcf, 0x88, 0xa8, 0xd7, 0x8a, 0x88, 0x3d, 0x80, 0x2d,
0xdd, 0xc2, 0x4c, 0x61, 0x4e, 0xab, 0x0a, 0xf8, 0x02, 0x6b, 0xca, 0xa7, 0x69, 0x91, 0x4e, 0x33,
0x24, 0xd5, 0x05, 0xbc, 0x85, 0xd4, 0xae, 0x4a, 0xd5, 0xac, 0x89, 0xfb, 0x54, 0xc9, 0x22, 0xc6,
0xa0, 0x97, 0xe6, 0xb9, 0x8c, 0xb7, 0x68, 0x08, 0xf4, 0xcd, 0x1e, 0x01, 0xcc, 0xea, 0x3c, 0x55,
0xf8, 0x5e, 0x94, 0x18, 0x47, 0x54, 0xc8, 0xb1, 0x68, 0x51, 0x89, 0x69, 0x8e, 0x97, 0x31, 0x90,
0xcb, 0x80, 0x4e, 0xdc, 0xdf, 0x3d, 0xf8, 0xff, 0xdd, 0x0c, 0xe5, 0xdc, 0x34, 0x75, 0x88, 0xb5,
0x9a, 0xac, 0x51, 0x3a, 0x46, 0x22, 0x41, 0x2b, 0x11, 0xcd, 0xbe, 0x96, 0xa2, 0x4c, 0xe5, 0xfc,
0x0d, 0x9a, 0xb9, 0x45, 0xdc, 0xb1, 0x68, 0xf6, 0x19, 0x29, 0xcd, 0xe8, 0xdc, 0x80, 0xe4, 0xdb,
0x42, 0xea, 0xeb, 0xe6, 0xfb, 0x6f, 0x47, 0xf2, 0x03, 0x6c, 0x3b, 0x34, 0x8f, 0x45, 0xa3, 0xd8,
0x0e, 0xf4, 0x0a, 0xd1, 0x68, 0x96, 0xc1, 0x15, 0x45, 0x51, 0x14, 0x27, 0xff, 0xca, 0x60, 0xfc,
0xd5, 0xc1, 0x24, 0x3f, 0x3d, 0xb8, 0x4f, 0x7b, 0x7b, 0x59, 0x95, 0x75, 0x81, 0x0a, 0x73, 0x12,
0x20, 0xfd, 0x63, 0x7d, 0xe3, 0x58, 0x66, 0x15, 0xfc, 0x79, 0x5d, 0x3d, 0x67, 0x5d, 0xec, 0x21,
0x44, 0xb9, 0x90, 0x48, 0x6f, 0x81, 0x9d, 0x4e, 0x67, 0x48, 0x76, 0x00, 0xa8, 0x91, 0x9b, 0x2e,
0x89, 0x2f, 0x1e, 0x0c, 0xbb, 0x40, 0x6a, 0xb4, 0x3b, 0x27, 0xde, 0xd2, 0x39, 0x89, 0xa1, 0xaf,
0xcf, 0x06, 0x36, 0x8d, 0x9d, 0x5c, 0x0b, 0xd7, 0xd2, 0xc0, 0x09, 0x44, 0x1d, 0xa5, 0xd1, 0xd2,
0x7e, 0xdb, 0x49, 0x92, 0xff, 0x96, 0x9b, 0xfd, 0x04, 0xdb, 0x1c, 0x33, 0x14, 0xb5, 0x6a, 0x5f,
0x51, 0x96, 0x40, 0x58, 0x39, 0x4f, 0xe7, 0x72, 0x55, 0xe3, 0x62, 0x63, 0x7d, 0x63, 0xa9, 0x6c,
0x42, 0x46, 0xdd, 0xf7, 0xd5, 0xff, 0xbb, 0x01, 0xdd, 0xbd, 0x10, 0x38, 0xf7, 0xc2, 0x1e, 0xe8,
0xfb, 0xca, 0xfc, 0xf5, 0x74, 0x93, 0x9e, 0xf8, 0xfd, 0xdf, 0x01, 0x00, 0x00, 0xff, 0xff, 0xf3,
0x6d, 0x05, 0xfd, 0xf4, 0x07, 0x00, 0x00,
// 644 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xb4, 0x55, 0xcd, 0x6e, 0xd3, 0x40,
0x10, 0xae, 0xed, 0xb8, 0xa9, 0x27, 0x28, 0x85, 0x15, 0x20, 0x0b, 0x21, 0x14, 0xf9, 0x50, 0x2a,
0x84, 0x72, 0x68, 0x25, 0x38, 0x17, 0x15, 0xa9, 0x88, 0x56, 0x88, 0x15, 0x17, 0x8e, 0xae, 0x3d,
0x34, 0xab, 0x26, 0xb1, 0xb5, 0x5e, 0x57, 0xb5, 0x78, 0x08, 0x6e, 0x3c, 0x01, 0xbc, 0x00, 0x2f,
0xc0, 0x89, 0x2b, 0xcf, 0x84, 0x76, 0x76, 0x1d, 0x6f, 0xd2, 0xa2, 0x56, 0xa0, 0xdc, 0xfc, 0xcd,
0x9f, 0xbf, 0x99, 0xf9, 0x76, 0x17, 0x86, 0x78, 0x99, 0x4d, 0xd2, 0xf9, 0x19, 0x8e, 0x4b, 0x59,
0xa8, 0x82, 0x85, 0xaa, 0x29, 0xb1, 0x4a, 0x00, 0xb6, 0x5e, 0x5b, 0x47, 0xf2, 0xdb, 0x83, 0x61,
0x0b, 0x0e, 0x32, 0x25, 0x8a, 0x39, 0xdb, 0x07, 0x98, 0x8a, 0x99, 0x50, 0xef, 0x64, 0x8e, 0x32,
0xf6, 0x46, 0xde, 0xee, 0x60, 0xef, 0xde, 0x98, 0x52, 0xc7, 0xc7, 0x0b, 0xc7, 0xd1, 0x06, 0x77,
0xc2, 0xd8, 0x0b, 0x18, 0xcc, 0x52, 0x79, 0x8e, 0x36, 0xcb, 0xa7, 0x2c, 0x66, 0xb3, 0x4e, 0x3a,
0xcf, 0xd1, 0x06, 0x77, 0x03, 0x75, 0x9e, 0xc4, 0x8b, 0xe2, 0x1c, 0x4d, 0x5e, 0xb0, 0x94, 0xc7,
0x3b, 0x8f, 0xce, 0x73, 0x02, 0xd9, 0x10, 0x7c, 0xd5, 0xc4, 0x9b, 0x23, 0x6f, 0x37, 0xe4, 0xbe,
0x6a, 0x5e, 0xf5, 0x21, 0xbc, 0x48, 0xa7, 0x35, 0x26, 0xdf, 0x3c, 0x80, 0x8e, 0x25, 0x7b, 0x06,
0xd1, 0x14, 0x3f, 0xa9, 0x83, 0xaa, 0x42, 0x65, 0x7b, 0xb9, 0x63, 0xab, 0xa7, 0xda, 0xc6, 0x3b,
0x37, 0x7b, 0x0e, 0x20, 0xc5, 0xd9, 0xc4, 0x06, 0xfb, 0xd7, 0x04, 0x3b, 0x7e, 0x76, 0x1f, 0xc2,
0x52, 0x8a, 0x0c, 0x89, 0xb3, 0xc7, 0x0d, 0x60, 0x0f, 0x61, 0x33, 0x9d, 0x15, 0xf5, 0x5c, 0xc5,
0xbd, 0x91, 0xb7, 0x1b, 0x70, 0x8b, 0x34, 0xdf, 0xa2, 0x8c, 0x43, 0xc3, 0xb7, 0x28, 0x93, 0x2f,
0x1e, 0x0c, 0x9c, 0xb1, 0xac, 0x91, 0x67, 0xc7, 0x28, 0xb8, 0x86, 0x51, 0x6f, 0xc1, 0xe8, 0x29,
0x0c, 0x9c, 0x79, 0xb3, 0x18, 0xfa, 0x85, 0xfe, 0x78, 0x73, 0x48, 0x74, 0x02, 0xde, 0xc2, 0xe4,
0x25, 0x84, 0x69, 0x5b, 0x19, 0x2f, 0x31, 0xb3, 0x22, 0x89, 0xb8, 0x45, 0xda, 0x5e, 0x35, 0xb3,
0xd3, 0x62, 0x4a, 0xdc, 0x22, 0x6e, 0x51, 0xf2, 0xd3, 0x87, 0xf0, 0x86, 0xe2, 0x2b, 0xe2, 0xf3,
0xff, 0x49, 0x7c, 0xc1, 0x6d, 0xc5, 0x67, 0x44, 0xd4, 0x6b, 0x45, 0xc4, 0x1e, 0xc1, 0x96, 0x6e,
0xa1, 0x56, 0x98, 0xd3, 0xaa, 0x02, 0xbe, 0xc0, 0x9a, 0xf2, 0x69, 0x3a, 0x4d, 0xe7, 0x19, 0x92,
0xea, 0x02, 0xde, 0x42, 0x6a, 0x57, 0xa5, 0xaa, 0xae, 0xe2, 0x3e, 0x55, 0xb2, 0x88, 0x31, 0xe8,
0xa5, 0x79, 0x2e, 0xe3, 0x2d, 0x1a, 0x02, 0x7d, 0xb3, 0x27, 0x00, 0x75, 0x99, 0xa7, 0x0a, 0x3f,
0x88, 0x19, 0xc6, 0x11, 0x15, 0x72, 0x2c, 0x5a, 0x54, 0x62, 0x9e, 0xe3, 0x65, 0x0c, 0xe4, 0x32,
0xa0, 0x13, 0xf7, 0x0f, 0x0f, 0xee, 0xbe, 0xaf, 0x51, 0x36, 0xa6, 0xa9, 0x43, 0x2c, 0xd5, 0x64,
0x8d, 0xd2, 0x31, 0x12, 0x09, 0x5a, 0x89, 0x68, 0xf6, 0xa5, 0x14, 0xb3, 0x54, 0x36, 0x6f, 0xd1,
0xcc, 0x2d, 0xe2, 0x8e, 0x45, 0xb3, 0xcf, 0x48, 0x69, 0x46, 0xe7, 0x06, 0x24, 0xdf, 0x17, 0x52,
0x5f, 0x37, 0xdf, 0xff, 0x3b, 0x92, 0x1f, 0x61, 0xdb, 0xa1, 0x79, 0x2c, 0x2a, 0xc5, 0x76, 0xa0,
0x37, 0x15, 0x95, 0x66, 0x19, 0x5c, 0x51, 0x14, 0x45, 0x71, 0xf2, 0xaf, 0x0c, 0xc6, 0x5f, 0x1d,
0x4c, 0xf2, 0xcb, 0x83, 0x07, 0xb4, 0xb7, 0x23, 0x51, 0xa9, 0x42, 0x36, 0x24, 0x3f, 0xfa, 0xc3,
0xfa, 0x86, 0xb1, 0xcc, 0x29, 0xf8, 0xfb, 0xb2, 0x7a, 0xce, 0xb2, 0xd8, 0x63, 0x88, 0x72, 0x21,
0x91, 0x5e, 0x02, 0x3b, 0x9b, 0xce, 0x90, 0xec, 0x00, 0x50, 0x1b, 0x37, 0x5d, 0x11, 0x5f, 0x3d,
0x18, 0x76, 0x81, 0xd4, 0x68, 0x77, 0x4a, 0xbc, 0xa5, 0x53, 0x12, 0x43, 0x5f, 0x9f, 0x0c, 0xac,
0x2a, 0x3b, 0xb7, 0x16, 0xae, 0xa5, 0x81, 0x13, 0x88, 0x3a, 0x4a, 0xa3, 0xa5, 0xed, 0xb6, 0x93,
0x24, 0xff, 0x2d, 0xf7, 0xfa, 0x19, 0xb6, 0x39, 0x66, 0x28, 0x4a, 0xd5, 0xbe, 0xa1, 0x2c, 0x81,
0xb0, 0x70, 0x1e, 0xce, 0xe5, 0xaa, 0xc6, 0xc5, 0xc6, 0xfa, 0xbe, 0x52, 0xd9, 0x84, 0x8c, 0xba,
0xef, 0xab, 0xff, 0x77, 0x03, 0xba, 0x5b, 0x21, 0x70, 0x6e, 0x85, 0x3d, 0xd0, 0xb7, 0x95, 0xf9,
0xeb, 0xe9, 0x26, 0x3d, 0xf0, 0xfb, 0x7f, 0x02, 0x00, 0x00, 0xff, 0xff, 0x99, 0xd7, 0x24, 0x52,
0xf2, 0x07, 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