diff --git a/cmd/gctcli/commands.go b/cmd/gctcli/commands.go index 34f5af6c..277f3821 100644 --- a/cmd/gctcli/commands.go +++ b/cmd/gctcli/commands.go @@ -3964,7 +3964,7 @@ var candleRangeSize, candleGranularity int64 var getHistoricCandlesCommand = cli.Command{ Name: "gethistoriccandles", Usage: "gets historical candles for the specified granularity up to range size time from now.", - ArgsUsage: " ", + ArgsUsage: " ", Action: getHistoricCandles, Flags: []cli.Flag{ cli.StringFlag{ @@ -3975,6 +3975,10 @@ var getHistoricCandlesCommand = cli.Command{ Name: "pair", Usage: "the currency pair to get the candles for", }, + cli.StringFlag{ + Name: "asset", + Usage: "the asset type of the currency pair", + }, cli.Int64Flag{ Name: "rangesize, r", Usage: "the amount of time to go back from now to fetch candles in the given granularity", @@ -3983,7 +3987,7 @@ var getHistoricCandlesCommand = cli.Command{ }, cli.Int64Flag{ Name: "granularity, g", - Usage: "value is in seconds and can be one of the following {60, 300, 900, 3600, 21600, 86400}", + Usage: "example values are in seconds and can be one of the following {60 (1 Minute), 300 (5 Minute), 900 (15 Minute), 3600 (1 Hour), 21600 (6 Hour), 86400 (1 Day)}", Value: 86400, Destination: &candleGranularity, }, @@ -4017,11 +4021,22 @@ func getHistoricCandles(c *cli.Context) error { } p := currency.NewPairDelimiter(currencyPair, pairDelimiter) + var assetType string + if c.IsSet("asset") { + assetType = c.String("asset") + } else { + assetType = c.Args().Get(2) + } + + if !validAsset(assetType) { + return errInvalidAsset + } + if c.IsSet("rangesize") { candleRangeSize = c.Int64("rangesize") - } else if c.Args().Get(2) != "" { + } else if c.Args().Get(3) != "" { var err error - candleRangeSize, err = strconv.ParseInt(c.Args().Get(2), 10, 64) + candleRangeSize, err = strconv.ParseInt(c.Args().Get(3), 10, 64) if err != nil { return err } @@ -4029,9 +4044,9 @@ func getHistoricCandles(c *cli.Context) error { if c.IsSet("granularity") { candleGranularity = c.Int64("granularity") - } else if c.Args().Get(3) != "" { + } else if c.Args().Get(4) != "" { var err error - candleGranularity, err = strconv.ParseInt(c.Args().Get(3), 10, 64) + candleGranularity, err = strconv.ParseInt(c.Args().Get(4), 10, 64) if err != nil { return err } @@ -4043,6 +4058,11 @@ func getHistoricCandles(c *cli.Context) error { } defer conn.Close() + candleInterval := time.Duration(candleGranularity) * time.Second + + end := time.Now().UTC().Truncate(candleInterval) + start := end.Add(-candleInterval * time.Duration(candleRangeSize)) + client := gctrpc.NewGoCryptoTraderClient(conn) result, err := client.GetHistoricCandles(context.Background(), &gctrpc.GetHistoricCandlesRequest{ @@ -4052,10 +4072,11 @@ func getHistoricCandles(c *cli.Context) error { Base: p.Base.String(), Quote: p.Quote.String(), }, - Rangesize: candleRangeSize, - Granularity: candleGranularity, + AssetType: assetType, + Start: start.Unix(), + End: end.Unix(), + TimeInterval: int64(candleInterval), }) - if err != nil { return err } diff --git a/engine/fake_exchange_test.go b/engine/fake_exchange_test.go index 362b3d60..0d0de220 100644 --- a/engine/fake_exchange_test.go +++ b/engine/fake_exchange_test.go @@ -9,6 +9,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" @@ -176,8 +177,8 @@ func (h *FakePassingExchange) GetSubscriptions() ([]wshandler.WebsocketChannelSu func (h *FakePassingExchange) GetDefaultConfig() (*config.ExchangeConfig, error) { return nil, nil } func (h *FakePassingExchange) GetBase() *exchange.Base { return nil } func (h *FakePassingExchange) SupportsAsset(_ asset.Item) bool { return true } -func (h *FakePassingExchange) GetHistoricCandles(_ currency.Pair, _, _ int64) ([]exchange.Candle, error) { - return []exchange.Candle{}, nil +func (h *FakePassingExchange) GetHistoricCandles(_ currency.Pair, _ asset.Item, _, _ time.Time, _ time.Duration) (kline.Item, error) { + return kline.Item{}, nil } func (h *FakePassingExchange) DisableRateLimiter() error { return nil } func (h *FakePassingExchange) EnableRateLimiter() error { return nil } diff --git a/engine/rpcserver.go b/engine/rpcserver.go index 78ea92e6..750d6228 100644 --- a/engine/rpcserver.go +++ b/engine/rpcserver.go @@ -1530,21 +1530,24 @@ func (s *RPCServer) GetHistoricCandles(ctx context.Context, req *gctrpc.GetHisto Delimiter: req.Pair.Delimiter, Base: currency.NewCode(req.Pair.Base), Quote: currency.NewCode(req.Pair.Quote), - }, req.Rangesize, req.Granularity) + }, + asset.Item(req.AssetType), + time.Unix(req.Start, 0), + time.Unix(req.End, 0), + time.Duration(req.TimeInterval)) if err != nil { return nil, err } resp := gctrpc.GetHistoricCandlesResponse{} - for _, candle := range candles { - tempCandle := &gctrpc.Candle{ - Time: candle.Time, - Low: candle.Low, - High: candle.High, - Open: candle.Open, - Close: candle.Close, - Volume: candle.Volume, - } - resp.Candle = append(resp.Candle, tempCandle) + for i := range candles.Candles { + resp.Candle = append(resp.Candle, &gctrpc.Candle{ + Time: candles.Candles[i].Time.Unix(), + Low: candles.Candles[i].Low, + High: candles.Candles[i].High, + Open: candles.Candles[i].Open, + Close: candles.Candles[i].Close, + Volume: candles.Candles[i].Volume, + }) } return &resp, nil } diff --git a/exchanges/binance/binance.go b/exchanges/binance/binance.go index f1817c32..676d1530 100644 --- a/exchanges/binance/binance.go +++ b/exchanges/binance/binance.go @@ -69,11 +69,6 @@ type Binance struct { validIntervals []TimeInterval } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *Binance) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetExchangeInfo returns exchange information. Check binance_types for more // information func (b *Binance) GetExchangeInfo() (ExchangeInfo, error) { diff --git a/exchanges/binance/binance_wrapper.go b/exchanges/binance/binance_wrapper.go index 443fcf7e..4bba2a0a 100644 --- a/exchanges/binance/binance_wrapper.go +++ b/exchanges/binance/binance_wrapper.go @@ -13,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -670,3 +671,8 @@ func (b *Binance) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *Binance) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index 8ddc32dd..621cd191 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -87,11 +87,6 @@ type Bitfinex struct { WebsocketSubdChannels map[int]WebsocketChanInfo } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *Bitfinex) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetPlatformStatus returns the Bifinex platform status func (b *Bitfinex) GetPlatformStatus() (int, error) { var response []int diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index 45f90116..b4427104 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -13,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -771,3 +772,8 @@ func (b *Bitfinex) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *Bitfinex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/bitflyer/bitflyer.go b/exchanges/bitflyer/bitflyer.go index 1c8922f1..824e2f1b 100644 --- a/exchanges/bitflyer/bitflyer.go +++ b/exchanges/bitflyer/bitflyer.go @@ -7,7 +7,6 @@ import ( "net/url" "strconv" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/request" @@ -72,11 +71,6 @@ type Bitflyer struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *Bitflyer) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetLatestBlockCA returns the latest block information from bitflyer chain // analysis system func (b *Bitflyer) GetLatestBlockCA() (ChainAnalysisBlock, error) { diff --git a/exchanges/bitflyer/bitflyer_wrapper.go b/exchanges/bitflyer/bitflyer_wrapper.go index dc2a4b1f..6a910b6d 100644 --- a/exchanges/bitflyer/bitflyer_wrapper.go +++ b/exchanges/bitflyer/bitflyer_wrapper.go @@ -3,6 +3,7 @@ package bitflyer import ( "strings" "sync" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/config" @@ -10,6 +11,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -388,3 +390,8 @@ func (b *Bitflyer) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *Bitflyer) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/bithumb/bithumb.go b/exchanges/bithumb/bithumb.go index 5cdbabca..0c7bcfa6 100644 --- a/exchanges/bithumb/bithumb.go +++ b/exchanges/bithumb/bithumb.go @@ -11,7 +11,6 @@ import ( "strconv" "strings" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -48,11 +47,6 @@ type Bithumb struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *Bithumb) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetTradablePairs returns a list of tradable currencies func (b *Bithumb) GetTradablePairs() ([]string, error) { result, err := b.GetAllTickers() diff --git a/exchanges/bithumb/bithumb_wrapper.go b/exchanges/bithumb/bithumb_wrapper.go index 6fb120bc..3cc2572f 100644 --- a/exchanges/bithumb/bithumb_wrapper.go +++ b/exchanges/bithumb/bithumb_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -592,3 +593,8 @@ func (b *Bithumb) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *Bithumb) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/bitmex/bitmex.go b/exchanges/bitmex/bitmex.go index 77e59e98..ec1e2ea8 100644 --- a/exchanges/bitmex/bitmex.go +++ b/exchanges/bitmex/bitmex.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -903,8 +902,3 @@ func calculateTradingFee(purchasePrice, amount float64, isMaker bool) float64 { return fee * purchasePrice * amount } - -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *Bitmex) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} diff --git a/exchanges/bitmex/bitmex_wrapper.go b/exchanges/bitmex/bitmex_wrapper.go index 96cdc678..3d5560e7 100644 --- a/exchanges/bitmex/bitmex_wrapper.go +++ b/exchanges/bitmex/bitmex_wrapper.go @@ -5,6 +5,7 @@ import ( "math" "strings" "sync" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/config" @@ -12,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -686,3 +688,8 @@ func (b *Bitmex) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *Bitmex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/bitstamp/bitstamp.go b/exchanges/bitstamp/bitstamp.go index 4c31cf4a..5f0847fb 100644 --- a/exchanges/bitstamp/bitstamp.go +++ b/exchanges/bitstamp/bitstamp.go @@ -65,11 +65,6 @@ type Bitstamp struct { WebsocketConn *wshandler.WebsocketConnection } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *Bitstamp) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetFee returns an estimate of fee based on type of transaction func (b *Bitstamp) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) { var fee float64 diff --git a/exchanges/bitstamp/bitstamp_wrapper.go b/exchanges/bitstamp/bitstamp_wrapper.go index 7f899918..cb7db47f 100644 --- a/exchanges/bitstamp/bitstamp_wrapper.go +++ b/exchanges/bitstamp/bitstamp_wrapper.go @@ -13,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -674,3 +675,8 @@ func (b *Bitstamp) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *Bitstamp) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/bittrex/bittrex.go b/exchanges/bittrex/bittrex.go index c6564d5e..7cb846ab 100644 --- a/exchanges/bittrex/bittrex.go +++ b/exchanges/bittrex/bittrex.go @@ -9,7 +9,6 @@ import ( "strings" "time" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -64,11 +63,6 @@ type Bittrex struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *Bittrex) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetMarkets is used to get the open and available trading markets at Bittrex // along with other meta data. func (b *Bittrex) GetMarkets() (Market, error) { diff --git a/exchanges/bittrex/bittrex_wrapper.go b/exchanges/bittrex/bittrex_wrapper.go index 4849091e..4cae725e 100644 --- a/exchanges/bittrex/bittrex_wrapper.go +++ b/exchanges/bittrex/bittrex_wrapper.go @@ -4,6 +4,7 @@ import ( "errors" "strings" "sync" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/config" @@ -11,6 +12,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -587,3 +589,8 @@ func (b *Bittrex) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *Bittrex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/btcmarkets/btcmarkets.go b/exchanges/btcmarkets/btcmarkets.go index 0c867daf..9844a401 100644 --- a/exchanges/btcmarkets/btcmarkets.go +++ b/exchanges/btcmarkets/btcmarkets.go @@ -80,11 +80,6 @@ type BTCMarkets struct { WebsocketConn *wshandler.WebsocketConnection } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *BTCMarkets) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetMarkets returns the BTCMarkets instruments func (b *BTCMarkets) GetMarkets() ([]Market, error) { var resp []Market diff --git a/exchanges/btcmarkets/btcmarkets_wrapper.go b/exchanges/btcmarkets/btcmarkets_wrapper.go index 50188ab3..b85f97f9 100644 --- a/exchanges/btcmarkets/btcmarkets_wrapper.go +++ b/exchanges/btcmarkets/btcmarkets_wrapper.go @@ -13,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -741,3 +742,8 @@ func (b *BTCMarkets) ValidateCredentials() error { return nil } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *BTCMarkets) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/btse/btse.go b/exchanges/btse/btse.go index 19d4f986..ea3677fc 100644 --- a/exchanges/btse/btse.go +++ b/exchanges/btse/btse.go @@ -10,7 +10,6 @@ import ( "strconv" "time" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -326,8 +325,3 @@ func calculateTradingFee(isMaker bool) float64 { func parseOrderTime(timeStr string) (time.Time, error) { return time.Parse(btseTimeLayout, timeStr) } - -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (b *BTSE) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} diff --git a/exchanges/btse/btse_wrapper.go b/exchanges/btse/btse_wrapper.go index 4cfdffc8..085fc81e 100644 --- a/exchanges/btse/btse_wrapper.go +++ b/exchanges/btse/btse_wrapper.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/config" @@ -13,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -650,3 +652,8 @@ func (b *BTSE) ValidateCredentials() error { _, err := b.UpdateAccountInfo() return b.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (b *BTSE) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/coinbasepro/coinbasepro_test.go b/exchanges/coinbasepro/coinbasepro_test.go index 39ffebb1..511609dc 100644 --- a/exchanges/coinbasepro/coinbasepro_test.go +++ b/exchanges/coinbasepro/coinbasepro_test.go @@ -1,7 +1,6 @@ package coinbasepro import ( - "fmt" "log" "net/http" "os" @@ -13,6 +12,7 @@ import ( "github.com/thrasher-corp/gocryptotrader/core" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" + "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues" "github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler" @@ -77,55 +77,14 @@ func TestGetTrades(t *testing.T) { } } -func TestGetHistoricRatesApiCheck(t *testing.T) { - e := expectedCandles(5, 300, 60) - if e != nil { - t.Error(e) - } - e = expectedCandles(2, 600, 300) - if e != nil { - t.Error(e) - } - e = expectedCandles(2, 1800, 900) - if e != nil { - t.Error(e) - } - e = expectedCandles(2, 7200, 3600) - if e != nil { - t.Error(e) - } - e = expectedCandles(2, 43200, 21600) - if e != nil { - t.Error(e) - } - e = expectedCandles(2, 172800, 86400) - if e != nil { - t.Error(e) - } -} - -// expectedCandles uses the previous candle time window because the current one might not be complete and if used the test would become non-deterministic -func expectedCandles(expectedCandles int, timeRange time.Duration, candleGranularity int64) error { - end := time.Now().UTC().Add(-time.Second * timeRange) // the latest candle may not yet be ready, so skipping to the previous one - start := end.Add(-time.Second * timeRange) - resp, err := c.GetHistoricRates(testPair, start.Format(time.RFC3339), end.Format(time.RFC3339), candleGranularity) - if err != nil { - return err - } - if len(resp) != expectedCandles { - err := fmt.Errorf("expected %d candles, returned: %d", expectedCandles, len(resp)) - return err - } - return nil -} - func TestGetHistoricRatesGranularityCheck(t *testing.T) { end := time.Now().UTC() - start := time.Now().UTC().Add(-time.Second * 300) - invalidGranularity := 11 - _, err := c.GetHistoricRates(testPair, start.Format(time.RFC3339), end.Format(time.RFC3339), int64(invalidGranularity)) - if err == nil { - t.Error("granularity validation did not work as expected") + start := end.Add(-time.Second * 300) + p := currency.NewPair(currency.BTC, currency.USD) + + _, err := c.GetHistoricCandles(p, asset.Spot, start, end, time.Minute) + if err != nil { + t.Fatal(err) } } diff --git a/exchanges/coinbasepro/coinbasepro_wrapper.go b/exchanges/coinbasepro/coinbasepro_wrapper.go index 317c32b8..e7422295 100644 --- a/exchanges/coinbasepro/coinbasepro_wrapper.go +++ b/exchanges/coinbasepro/coinbasepro_wrapper.go @@ -13,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -705,19 +706,50 @@ func (c *CoinbasePro) AuthenticateWebsocket() error { return common.ErrFunctionNotSupported } -// GetHistoricCandles Allows to retrieve an amount of candles back in time starting from now up to rangesize * granularity, where granularity is the trade period covered by each candle -func (c *CoinbasePro) GetHistoricCandles(p currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - end := time.Now().UTC() - b := granularity * rangesize - start := time.Now().UTC().Add(-time.Second * time.Duration(b)) - history, err := c.GetHistoricRates(p.String(), start.Format(time.RFC3339), end.Format(time.RFC3339), granularity) - if err != nil { - return nil, err +// checkInterval checks allowable interval +func checkInterval(i time.Duration) (int64, error) { + switch i.Seconds() { + case 60: + return 60, nil + case 300: + return 300, nil + case 900: + return 900, nil + case 3600: + return 3600, nil + case 21600: + return 21600, nil + case 86400: + return 86400, nil } - var candles []exchange.Candle + return 0, fmt.Errorf("interval not allowed %v", i.Seconds()) +} + +// GetHistoricCandles returns a set of candle between two time periods for a +// designated time period +func (c *CoinbasePro) GetHistoricCandles(p currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + i, err := checkInterval(interval) + if err != nil { + return kline.Item{}, err + } + + history, err := c.GetHistoricRates(c.FormatExchangeCurrency(p, a).String(), + start.Format(time.RFC3339), + end.Format(time.RFC3339), + i) + if err != nil { + return kline.Item{}, err + } + + var candles kline.Item + candles.Asset = a + candles.Exchange = c.Name + candles.Interval = interval + candles.Pair = p + for x := range history { - candles = append(candles, exchange.Candle{ - Time: history[x].Time, + candles.Candles = append(candles.Candles, kline.Candle{ + Time: time.Unix(history[x].Time, 0), Low: history[x].Low, High: history[x].High, Open: history[x].Open, diff --git a/exchanges/coinbene/coinbene.go b/exchanges/coinbene/coinbene.go index 7a8faf12..8a6196cb 100644 --- a/exchanges/coinbene/coinbene.go +++ b/exchanges/coinbene/coinbene.go @@ -14,7 +14,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" - "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/request" @@ -1197,8 +1196,3 @@ func (c *Coinbene) SendAuthHTTPRequest(method, path, epPath string, isSwap bool, } return json.Unmarshal(resp, result) } - -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (c *Coinbene) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrFunctionNotSupported -} diff --git a/exchanges/coinbene/coinbene_wrapper.go b/exchanges/coinbene/coinbene_wrapper.go index ca35196e..59bf3859 100644 --- a/exchanges/coinbene/coinbene_wrapper.go +++ b/exchanges/coinbene/coinbene_wrapper.go @@ -12,6 +12,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -725,3 +726,8 @@ func (c *Coinbene) ValidateCredentials() error { _, err := c.UpdateAccountInfo() return c.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (c *Coinbene) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrFunctionNotSupported +} diff --git a/exchanges/coinut/coinut.go b/exchanges/coinut/coinut.go index f8026592..5d85d6c1 100644 --- a/exchanges/coinut/coinut.go +++ b/exchanges/coinut/coinut.go @@ -10,7 +10,6 @@ import ( "strconv" "strings" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -56,11 +55,6 @@ type COINUT struct { instrumentMap instrumentMap } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (c *COINUT) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // SeedInstruments seeds the instrument map func (c *COINUT) SeedInstruments() error { i, err := c.GetInstruments() diff --git a/exchanges/coinut/coinut_wrapper.go b/exchanges/coinut/coinut_wrapper.go index 2fb19ac0..cbae9c8b 100644 --- a/exchanges/coinut/coinut_wrapper.go +++ b/exchanges/coinut/coinut_wrapper.go @@ -15,6 +15,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -901,3 +902,8 @@ func (c *COINUT) ValidateCredentials() error { _, err := c.UpdateAccountInfo() return c.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (c *COINUT) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/exchange_types.go b/exchanges/exchange_types.go index 27f955bf..18d42711 100644 --- a/exchanges/exchange_types.go +++ b/exchanges/exchange_types.go @@ -119,16 +119,6 @@ type TradeHistory struct { Description string } -// Candle holds historic rate information. Modelled after the Coinbase historic rate structure -type Candle struct { - Time int64 - Low float64 - High float64 - Open float64 - Close float64 - Volume float64 -} - // FundHistory holds exchange funding history data type FundHistory struct { ExchangeName string diff --git a/exchanges/exmo/exmo.go b/exchanges/exmo/exmo.go index adebba64..9e3f9eb9 100644 --- a/exchanges/exmo/exmo.go +++ b/exchanges/exmo/exmo.go @@ -51,11 +51,6 @@ type EXMO struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (e *EXMO) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetTrades returns the trades for a symbol or symbols func (e *EXMO) GetTrades(symbol string) (map[string][]Trades, error) { v := url.Values{} diff --git a/exchanges/exmo/exmo_wrapper.go b/exchanges/exmo/exmo_wrapper.go index ed137e7e..97383f56 100644 --- a/exchanges/exmo/exmo_wrapper.go +++ b/exchanges/exmo/exmo_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -566,3 +567,8 @@ func (e *EXMO) ValidateCredentials() error { _, err := e.UpdateAccountInfo() return e.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (e *EXMO) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/gateio/gateio.go b/exchanges/gateio/gateio.go index 809f18ed..9b4e1148 100644 --- a/exchanges/gateio/gateio.go +++ b/exchanges/gateio/gateio.go @@ -8,7 +8,6 @@ import ( "strconv" "strings" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/convert" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" @@ -47,11 +46,6 @@ type Gateio struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (g *Gateio) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetSymbols returns all supported symbols func (g *Gateio) GetSymbols() ([]string, error) { var result []string diff --git a/exchanges/gateio/gateio_wrapper.go b/exchanges/gateio/gateio_wrapper.go index 7a2a3ba8..23c06d43 100644 --- a/exchanges/gateio/gateio_wrapper.go +++ b/exchanges/gateio/gateio_wrapper.go @@ -15,6 +15,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -714,3 +715,8 @@ func (g *Gateio) ValidateCredentials() error { _, err := g.UpdateAccountInfo() return g.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (g *Gateio) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/gemini/gemini.go b/exchanges/gemini/gemini.go index 8a6d7f3b..eb63622b 100644 --- a/exchanges/gemini/gemini.go +++ b/exchanges/gemini/gemini.go @@ -11,7 +11,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" - "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/request" "github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler" @@ -442,8 +441,3 @@ func calculateTradingFee(notionVolume *NotionalVolume, purchasePrice, amount flo return volumeFee * amount * purchasePrice } - -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (g *Gemini) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrFunctionNotSupported -} diff --git a/exchanges/gemini/gemini_wrapper.go b/exchanges/gemini/gemini_wrapper.go index 9138a12d..b2ffc5c9 100644 --- a/exchanges/gemini/gemini_wrapper.go +++ b/exchanges/gemini/gemini_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -572,3 +573,8 @@ func (g *Gemini) ValidateCredentials() error { _, err := g.UpdateAccountInfo() return g.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (g *Gemini) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrFunctionNotSupported +} diff --git a/exchanges/hitbtc/hitbtc.go b/exchanges/hitbtc/hitbtc.go index 1fe86612..29b50ecb 100644 --- a/exchanges/hitbtc/hitbtc.go +++ b/exchanges/hitbtc/hitbtc.go @@ -8,7 +8,6 @@ import ( "net/url" "strconv" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -49,11 +48,6 @@ type HitBTC struct { WebsocketConn *wshandler.WebsocketConnection } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (h *HitBTC) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // Public Market Data // https://api.hitbtc.com/?python#market-data diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index 9b2ee98d..40402e09 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -6,6 +6,7 @@ import ( "strconv" "strings" "sync" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/config" @@ -13,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -625,3 +627,8 @@ func (h *HitBTC) ValidateCredentials() error { _, err := h.UpdateAccountInfo() return h.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (h *HitBTC) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/huobi/huobi.go b/exchanges/huobi/huobi.go index b1e93e9c..7fd2bbb7 100644 --- a/exchanges/huobi/huobi.go +++ b/exchanges/huobi/huobi.go @@ -66,11 +66,6 @@ type HUOBI struct { AuthenticatedWebsocketConn *wshandler.WebsocketConnection } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (h *HUOBI) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetSpotKline returns kline data // KlinesRequestParams contains symbol, period and size func (h *HUOBI) GetSpotKline(arg KlinesRequestParams) ([]KlineItem, error) { diff --git a/exchanges/huobi/huobi_wrapper.go b/exchanges/huobi/huobi_wrapper.go index b6d2985f..096504e8 100644 --- a/exchanges/huobi/huobi_wrapper.go +++ b/exchanges/huobi/huobi_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -921,3 +922,8 @@ func (h *HUOBI) ValidateCredentials() error { _, err := h.UpdateAccountInfo() return h.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (h *HUOBI) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/interfaces.go b/exchanges/interfaces.go index 1474408d..2616c5d9 100644 --- a/exchanges/interfaces.go +++ b/exchanges/interfaces.go @@ -2,11 +2,13 @@ package exchange import ( "sync" + "time" "github.com/thrasher-corp/gocryptotrader/config" "github.com/thrasher-corp/gocryptotrader/currency" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" @@ -24,23 +26,23 @@ type IBotExchange interface { IsEnabled() bool SetEnabled(bool) ValidateCredentials() error - FetchTicker(currency currency.Pair, assetType asset.Item) (*ticker.Price, error) - UpdateTicker(currency currency.Pair, assetType asset.Item) (*ticker.Price, error) - FetchOrderbook(currency currency.Pair, assetType asset.Item) (*orderbook.Base, error) - UpdateOrderbook(currency currency.Pair, assetType asset.Item) (*orderbook.Base, error) - FetchTradablePairs(assetType asset.Item) ([]string, error) + FetchTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) + UpdateTicker(p currency.Pair, a asset.Item) (*ticker.Price, error) + FetchOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) + UpdateOrderbook(p currency.Pair, a asset.Item) (*orderbook.Base, error) + FetchTradablePairs(a asset.Item) ([]string, error) UpdateTradablePairs(forceUpdate bool) error - GetEnabledPairs(assetType asset.Item) currency.Pairs - GetAvailablePairs(assetType asset.Item) currency.Pairs + GetEnabledPairs(a asset.Item) currency.Pairs + GetAvailablePairs(a asset.Item) currency.Pairs FetchAccountInfo() (account.Holdings, error) UpdateAccountInfo() (account.Holdings, error) GetAuthenticatedAPISupport(endpoint uint8) bool - SetPairs(pairs currency.Pairs, assetType asset.Item, enabled bool) error + SetPairs(pairs currency.Pairs, a asset.Item, enabled bool) error GetAssetTypes() asset.Items - GetExchangeHistory(currencyPair currency.Pair, assetType asset.Item) ([]TradeHistory, error) + GetExchangeHistory(p currency.Pair, a asset.Item) ([]TradeHistory, error) SupportsAutoPairUpdates() bool SupportsRESTTickerBatchUpdates() bool - GetFeeByType(feeBuilder *FeeBuilder) (float64, error) + GetFeeByType(f *FeeBuilder) (float64, error) GetLastPairsUpdateTime() int64 GetWithdrawPermissions() uint32 FormatWithdrawPermissions() string @@ -71,7 +73,7 @@ type IBotExchange interface { GetDefaultConfig() (*config.ExchangeConfig, error) GetBase() *Base SupportsAsset(assetType asset.Item) bool - GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]Candle, error) + GetHistoricCandles(p currency.Pair, a asset.Item, timeStart, timeEnd time.Time, interval time.Duration) (kline.Item, error) DisableRateLimiter() error EnableRateLimiter() error } diff --git a/exchanges/itbit/itbit.go b/exchanges/itbit/itbit.go index 1ad6ea50..c9cd5205 100644 --- a/exchanges/itbit/itbit.go +++ b/exchanges/itbit/itbit.go @@ -38,11 +38,6 @@ type ItBit struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (i *ItBit) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetTicker returns ticker info for a specified market. // currencyPair - example "XBTUSD" "XBTSGD" "XBTEUR" func (i *ItBit) GetTicker(currencyPair string) (Ticker, error) { diff --git a/exchanges/itbit/itbit_wrapper.go b/exchanges/itbit/itbit_wrapper.go index 826b7574..2c194cd7 100644 --- a/exchanges/itbit/itbit_wrapper.go +++ b/exchanges/itbit/itbit_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -569,3 +570,8 @@ func (i *ItBit) ValidateCredentials() error { _, err := i.UpdateAccountInfo() return i.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (i *ItBit) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/kline/kline.go b/exchanges/kline/kline.go new file mode 100644 index 00000000..dc5726e7 --- /dev/null +++ b/exchanges/kline/kline.go @@ -0,0 +1,132 @@ +package kline + +import ( + "errors" + "fmt" + "sort" + "time" + + "github.com/thrasher-corp/gocryptotrader/currency" + "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/order" +) + +// CreateKline creates candles out of trade history data for a set time interval +func CreateKline(trades []order.TradeHistory, interval time.Duration, p currency.Pair, a asset.Item, exchange string) (Item, error) { + if interval < time.Minute { + return Item{}, fmt.Errorf("invalid time interval: [%s]", interval) + } + + err := validateData(trades) + if err != nil { + return Item{}, err + } + + timeIntervalStart := trades[0].Timestamp.Truncate(interval) + timeIntervalEnd := trades[len(trades)-1].Timestamp + + // Adds time interval buffer zones + var timeIntervalCache [][]order.TradeHistory + var candleStart []time.Time + + for t := timeIntervalStart; t.Before(timeIntervalEnd); t = t.Add(interval) { + timeBufferEnd := t.Add(interval) + insertionCount := 0 + + var zonedTradeHistory []order.TradeHistory + for i := 0; i < len(trades); i++ { + if (trades[i].Timestamp.After(t) || + trades[i].Timestamp.Equal(t)) && + (trades[i].Timestamp.Before(timeBufferEnd) || + trades[i].Timestamp.Equal(timeBufferEnd)) { + zonedTradeHistory = append(zonedTradeHistory, trades[i]) + insertionCount++ + continue + } + trades = trades[i:] + break + } + + candleStart = append(candleStart, t) + + // Insert dummy in time period when there is no price action + if insertionCount == 0 { + timeIntervalCache = append(timeIntervalCache, []order.TradeHistory{}) + continue + } + timeIntervalCache = append(timeIntervalCache, zonedTradeHistory) + } + + if candleStart == nil { + return Item{}, errors.New("candle start cannot be nil") + } + + var candles = Item{ + Exchange: exchange, + Pair: p, + Asset: a, + Interval: interval, + } + + var closePriceOfLast float64 + for x := range timeIntervalCache { + if len(timeIntervalCache[x]) == 0 { + candles.Candles = append(candles.Candles, Candle{ + Time: candleStart[x], + High: closePriceOfLast, + Low: closePriceOfLast, + Close: closePriceOfLast, + Open: closePriceOfLast}) + continue + } + + var newCandle = Candle{ + Open: timeIntervalCache[x][0].Price, + Time: candleStart[x], + } + + for y := range timeIntervalCache[x] { + if y == len(timeIntervalCache[x])-1 { + newCandle.Close = timeIntervalCache[x][y].Price + closePriceOfLast = timeIntervalCache[x][y].Price + } + if newCandle.High < timeIntervalCache[x][y].Price { + newCandle.High = timeIntervalCache[x][y].Price + } + if newCandle.Low > timeIntervalCache[x][y].Price || newCandle.Low == 0 { + newCandle.Low = timeIntervalCache[x][y].Price + } + newCandle.Volume += timeIntervalCache[x][y].Amount + } + candles.Candles = append(candles.Candles, newCandle) + } + return candles, nil +} + +// validatData checks for zero values on data and sorts before turning +// converting into OHLC +func validateData(trades []order.TradeHistory) error { + if len(trades) < 2 { + return errors.New("insufficient data") + } + + for i := range trades { + if trades[i].Timestamp.IsZero() || + trades[i].Timestamp.Unix() == 0 { + return fmt.Errorf("timestamp not set for element %d", i) + } + + if trades[i].Amount == 0 { + return fmt.Errorf("amount not set for element %d", i) + } + + if trades[i].Price == 0 { + return fmt.Errorf("price not set for element %d", i) + } + } + + sort.Slice(trades, func(i, j int) bool { + return trades[i].Timestamp.Before(trades[j].Timestamp) + }) + return nil +} diff --git a/exchanges/kline/kline_test.go b/exchanges/kline/kline_test.go new file mode 100644 index 00000000..bea87111 --- /dev/null +++ b/exchanges/kline/kline_test.go @@ -0,0 +1,115 @@ +package kline + +import ( + "math/rand" + "testing" + "time" + + "github.com/thrasher-corp/gocryptotrader/common/crypto" + "github.com/thrasher-corp/gocryptotrader/currency" + "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/order" +) + +func TestValidateData(t *testing.T) { + err := validateData(nil) + if err == nil { + t.Error("error cannot be nil") + } + + var empty []order.TradeHistory + err = validateData(empty) + if err == nil { + t.Error("error cannot be nil") + } + + tn := time.Now() + trade1 := []order.TradeHistory{ + {Timestamp: tn.Add(2 * time.Minute), TID: "2"}, + {Timestamp: tn.Add(time.Minute), TID: "1"}, + {Timestamp: tn.Add(3 * time.Minute), TID: "3"}, + } + + err = validateData(trade1) + if err == nil { + t.Error("error cannot be nil") + } + + trade2 := []order.TradeHistory{ + {Timestamp: tn.Add(2 * time.Minute), TID: "2", Amount: 1, Price: 0}, + } + + err = validateData(trade2) + if err == nil { + t.Error("error cannot be nil") + } + + trade3 := []order.TradeHistory{ + {TID: "2", Amount: 1, Price: 0}, + } + + err = validateData(trade3) + if err == nil { + t.Error("error cannot be nil") + } + + trade4 := []order.TradeHistory{ + {Timestamp: tn.Add(2 * time.Minute), TID: "2", Amount: 1, Price: 1000}, + {Timestamp: tn.Add(time.Minute), TID: "1", Amount: 1, Price: 1001}, + {Timestamp: tn.Add(3 * time.Minute), TID: "3", Amount: 1, Price: 1001.5}, + } + + err = validateData(trade4) + if err != nil { + t.Error(err) + } + + if trade4[0].TID != "1" || trade4[1].TID != "2" || trade4[2].TID != "3" { + t.Error("trade history sorted incorrectly") + } +} + +func TestCreateKline(t *testing.T) { + c, err := CreateKline(nil, + time.Minute, + currency.NewPair(currency.BTC, currency.USD), + asset.Spot, + "Binance") + if err == nil { + t.Fatal("error cannot be nil") + } + + var trades []order.TradeHistory + rand.Seed(time.Now().Unix()) + for i := 0; i < 24000; i++ { + trades = append(trades, order.TradeHistory{ + Timestamp: time.Now().Add((time.Duration(rand.Intn(10)) * time.Minute) + + (time.Duration(rand.Intn(10)) * time.Second)), + TID: crypto.HexEncodeToString([]byte(string(i))), + Amount: float64(rand.Intn(20)) + 1, + Price: 1000 + float64(rand.Intn(1000)), + }) + } + + c, err = CreateKline(trades, + 0, + currency.NewPair(currency.BTC, currency.USD), + asset.Spot, + "Binance") + if err == nil { + t.Fatal("error cannot be nil") + } + + c, err = CreateKline(trades, + OneMin, + currency.NewPair(currency.BTC, currency.USD), + asset.Spot, + "Binance") + if err != nil { + t.Fatal(err) + } + + if len(c.Candles) == 0 { + t.Fatal("no data returned, expecting a lot.") + } +} diff --git a/exchanges/kline/types.go b/exchanges/kline/types.go new file mode 100644 index 00000000..4d38477b --- /dev/null +++ b/exchanges/kline/types.go @@ -0,0 +1,44 @@ +package kline + +import ( + "time" + + "github.com/thrasher-corp/gocryptotrader/currency" + "github.com/thrasher-corp/gocryptotrader/exchanges/asset" +) + +// Consts here define basic time intervals +const ( + OneMin = time.Minute + ThreeMin = 3 * time.Minute + FiveMin = 5 * time.Minute + FifteenMin = 15 * time.Minute + ThirtyMin = 30 * time.Minute + OneHour = 1 * time.Hour + TwoHour = 2 * time.Hour + FourHour = 4 * time.Hour + SixHour = 6 * time.Hour + TwelveHour = 12 * time.Hour + OneDay = 24 * time.Hour + ThreeDay = 72 * time.Hour + OneWeek = 168 * time.Hour +) + +// Item holds all the relevant information for internal kline elements +type Item struct { + Exchange string + Pair currency.Pair + Asset asset.Item + Interval time.Duration + Candles []Candle +} + +// Candle holds historic rate information. +type Candle struct { + Time time.Time + Open float64 + High float64 + Low float64 + Close float64 + Volume float64 +} diff --git a/exchanges/kraken/kraken.go b/exchanges/kraken/kraken.go index b2af83b5..c938d429 100644 --- a/exchanges/kraken/kraken.go +++ b/exchanges/kraken/kraken.go @@ -10,7 +10,6 @@ import ( "sync" "time" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -67,11 +66,6 @@ type Kraken struct { wsRequestMtx sync.Mutex } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (k *Kraken) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetServerTime returns current server time func (k *Kraken) GetServerTime() (TimeResponse, error) { path := fmt.Sprintf("%s/%s/public/%s", k.API.Endpoints.URL, krakenAPIVersion, krakenServerTime) diff --git a/exchanges/kraken/kraken_wrapper.go b/exchanges/kraken/kraken_wrapper.go index 43602df7..88909c0d 100644 --- a/exchanges/kraken/kraken_wrapper.go +++ b/exchanges/kraken/kraken_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -747,3 +748,8 @@ func (k *Kraken) ValidateCredentials() error { _, err := k.UpdateAccountInfo() return k.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (k *Kraken) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/lakebtc/lakebtc.go b/exchanges/lakebtc/lakebtc.go index aade3d35..4a188297 100644 --- a/exchanges/lakebtc/lakebtc.go +++ b/exchanges/lakebtc/lakebtc.go @@ -8,7 +8,6 @@ import ( "strconv" "strings" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -39,11 +38,6 @@ type LakeBTC struct { WebsocketConn } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (l *LakeBTC) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetTicker returns the current ticker from lakeBTC func (l *LakeBTC) GetTicker() (map[string]Ticker, error) { response := make(map[string]TickerResponse) diff --git a/exchanges/lakebtc/lakebtc_wrapper.go b/exchanges/lakebtc/lakebtc_wrapper.go index e81aba47..56c0f819 100644 --- a/exchanges/lakebtc/lakebtc_wrapper.go +++ b/exchanges/lakebtc/lakebtc_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -558,3 +559,8 @@ func (l *LakeBTC) ValidateCredentials() error { _, err := l.UpdateAccountInfo() return l.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (l *LakeBTC) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/lbank/lbank.go b/exchanges/lbank/lbank.go index 9cd7dd85..7c0d917c 100644 --- a/exchanges/lbank/lbank.go +++ b/exchanges/lbank/lbank.go @@ -15,9 +15,7 @@ import ( "strconv" "strings" - "github.com/thrasher-corp/gocryptotrader/common" gctcrypto "github.com/thrasher-corp/gocryptotrader/common/crypto" - "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/request" @@ -578,8 +576,3 @@ func (l *Lbank) SendAuthHTTPRequest(method, endpoint string, vals url.Values, re HTTPRecording: l.HTTPRecording, }) } - -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (l *Lbank) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrFunctionNotSupported -} diff --git a/exchanges/lbank/lbank_wrapper.go b/exchanges/lbank/lbank_wrapper.go index 3842ffa8..10326f01 100644 --- a/exchanges/lbank/lbank_wrapper.go +++ b/exchanges/lbank/lbank_wrapper.go @@ -13,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -717,3 +718,8 @@ func (l *Lbank) ValidateCredentials() error { _, err := l.UpdateAccountInfo() return l.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (l *Lbank) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrFunctionNotSupported +} diff --git a/exchanges/localbitcoins/localbitcoins.go b/exchanges/localbitcoins/localbitcoins.go index 3fed7e31..0d59d4cf 100644 --- a/exchanges/localbitcoins/localbitcoins.go +++ b/exchanges/localbitcoins/localbitcoins.go @@ -11,7 +11,6 @@ import ( "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" - "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/request" "github.com/thrasher-corp/gocryptotrader/log" @@ -112,11 +111,6 @@ type LocalBitcoins struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (l *LocalBitcoins) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrFunctionNotSupported -} - // GetAccountInformation lets you retrieve the public user information on a // LocalBitcoins user. The response contains the same information that is found // on an account's public profile page. diff --git a/exchanges/localbitcoins/localbitcoins_wrapper.go b/exchanges/localbitcoins/localbitcoins_wrapper.go index af482698..03262ed3 100644 --- a/exchanges/localbitcoins/localbitcoins_wrapper.go +++ b/exchanges/localbitcoins/localbitcoins_wrapper.go @@ -15,6 +15,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -597,3 +598,8 @@ func (l *LocalBitcoins) ValidateCredentials() error { _, err := l.UpdateAccountInfo() return l.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (l *LocalBitcoins) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrFunctionNotSupported +} diff --git a/exchanges/okcoin/okcoin.go b/exchanges/okcoin/okcoin.go index 4b296407..fb54fd3d 100644 --- a/exchanges/okcoin/okcoin.go +++ b/exchanges/okcoin/okcoin.go @@ -3,9 +3,6 @@ package okcoin import ( "time" - "github.com/thrasher-corp/gocryptotrader/common" - "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/okgroup" ) @@ -23,8 +20,3 @@ const ( type OKCoin struct { okgroup.OKGroup } - -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (o *OKCoin) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrFunctionNotSupported -} diff --git a/exchanges/okcoin/okcoin_wrapper.go b/exchanges/okcoin/okcoin_wrapper.go index 81d2e728..c22e1683 100644 --- a/exchanges/okcoin/okcoin_wrapper.go +++ b/exchanges/okcoin/okcoin_wrapper.go @@ -2,12 +2,14 @@ package okcoin import ( "sync" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/config" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" "github.com/thrasher-corp/gocryptotrader/exchanges/request" "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" @@ -259,3 +261,8 @@ func (o *OKCoin) FetchTicker(p currency.Pair, assetType asset.Item) (tickerData } return } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (o *OKCoin) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrFunctionNotSupported +} diff --git a/exchanges/okex/okex.go b/exchanges/okex/okex.go index 82832f2a..10f5c778 100644 --- a/exchanges/okex/okex.go +++ b/exchanges/okex/okex.go @@ -6,8 +6,6 @@ import ( "time" "github.com/thrasher-corp/gocryptotrader/common" - "github.com/thrasher-corp/gocryptotrader/currency" - exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/okgroup" ) @@ -48,11 +46,6 @@ type OKEX struct { okgroup.OKGroup } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (o *OKEX) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrFunctionNotSupported -} - // GetFuturesPostions Get the information of all holding positions in futures trading. // Due to high energy consumption, you are advised to capture data with the "Futures Account of a Currency" API instead. func (o *OKEX) GetFuturesPostions() (resp okgroup.GetFuturesPositionsResponse, _ error) { diff --git a/exchanges/okex/okex_wrapper.go b/exchanges/okex/okex_wrapper.go index 8368ee1b..ec42fd20 100644 --- a/exchanges/okex/okex_wrapper.go +++ b/exchanges/okex/okex_wrapper.go @@ -5,12 +5,14 @@ import ( "fmt" "strings" "sync" + "time" "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/config" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" "github.com/thrasher-corp/gocryptotrader/exchanges/request" "github.com/thrasher-corp/gocryptotrader/exchanges/ticker" @@ -415,3 +417,8 @@ func (o *OKEX) FetchTicker(p currency.Pair, assetType asset.Item) (tickerData *t } return } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (o *OKEX) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrFunctionNotSupported +} diff --git a/exchanges/poloniex/poloniex.go b/exchanges/poloniex/poloniex.go index 3ebbc493..d8558d98 100644 --- a/exchanges/poloniex/poloniex.go +++ b/exchanges/poloniex/poloniex.go @@ -10,7 +10,6 @@ import ( "strconv" "time" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -56,11 +55,6 @@ type Poloniex struct { WebsocketConn *wshandler.WebsocketConnection } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (p *Poloniex) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetTicker returns current ticker information func (p *Poloniex) GetTicker() (map[string]Ticker, error) { type response struct { diff --git a/exchanges/poloniex/poloniex_wrapper.go b/exchanges/poloniex/poloniex_wrapper.go index b40361a3..c56cc81d 100644 --- a/exchanges/poloniex/poloniex_wrapper.go +++ b/exchanges/poloniex/poloniex_wrapper.go @@ -13,6 +13,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -635,3 +636,8 @@ func (p *Poloniex) ValidateCredentials() error { _, err := p.UpdateAccountInfo() return p.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (p *Poloniex) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/yobit/yobit.go b/exchanges/yobit/yobit.go index 621bd967..968ef2b7 100644 --- a/exchanges/yobit/yobit.go +++ b/exchanges/yobit/yobit.go @@ -8,7 +8,6 @@ import ( "strconv" "strings" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" exchange "github.com/thrasher-corp/gocryptotrader/exchanges" @@ -44,11 +43,6 @@ type Yobit struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (y *Yobit) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // GetInfo returns the Yobit info func (y *Yobit) GetInfo() (Info, error) { resp := Info{} diff --git a/exchanges/yobit/yobit_wrapper.go b/exchanges/yobit/yobit_wrapper.go index 2aa4dc8d..3e0ed527 100644 --- a/exchanges/yobit/yobit_wrapper.go +++ b/exchanges/yobit/yobit_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -563,3 +564,8 @@ func (y *Yobit) ValidateCredentials() error { _, err := y.UpdateAccountInfo() return y.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (y *Yobit) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/exchanges/zb/zb.go b/exchanges/zb/zb.go index a624bd6f..38b1bbae 100644 --- a/exchanges/zb/zb.go +++ b/exchanges/zb/zb.go @@ -10,7 +10,6 @@ import ( "strings" "time" - "github.com/thrasher-corp/gocryptotrader/common" "github.com/thrasher-corp/gocryptotrader/common/convert" "github.com/thrasher-corp/gocryptotrader/common/crypto" "github.com/thrasher-corp/gocryptotrader/currency" @@ -49,11 +48,6 @@ type ZB struct { exchange.Base } -// GetHistoricCandles returns rangesize number of candles for the given granularity and pair starting from the latest available -func (z *ZB) GetHistoricCandles(pair currency.Pair, rangesize, granularity int64) ([]exchange.Candle, error) { - return nil, common.ErrNotYetImplemented -} - // SpotNewOrder submits an order to ZB func (z *ZB) SpotNewOrder(arg SpotNewOrderRequestParams) (int64, error) { var result SpotNewOrderResponse diff --git a/exchanges/zb/zb_wrapper.go b/exchanges/zb/zb_wrapper.go index 80503f6f..e1f90752 100644 --- a/exchanges/zb/zb_wrapper.go +++ b/exchanges/zb/zb_wrapper.go @@ -14,6 +14,7 @@ import ( exchange "github.com/thrasher-corp/gocryptotrader/exchanges" "github.com/thrasher-corp/gocryptotrader/exchanges/account" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" + "github.com/thrasher-corp/gocryptotrader/exchanges/kline" "github.com/thrasher-corp/gocryptotrader/exchanges/order" "github.com/thrasher-corp/gocryptotrader/exchanges/orderbook" "github.com/thrasher-corp/gocryptotrader/exchanges/protocol" @@ -697,3 +698,8 @@ func (z *ZB) ValidateCredentials() error { _, err := z.UpdateAccountInfo() return z.CheckTransientError(err) } + +// GetHistoricCandles returns candles between a time period for a set time interval +func (z *ZB) GetHistoricCandles(pair currency.Pair, a asset.Item, start, end time.Time, interval time.Duration) (kline.Item, error) { + return kline.Item{}, common.ErrNotYetImplemented +} diff --git a/gctrpc/rpc.pb.go b/gctrpc/rpc.pb.go index bde8a0f4..04a01e2a 100644 --- a/gctrpc/rpc.pb.go +++ b/gctrpc/rpc.pb.go @@ -5718,8 +5718,10 @@ func (m *GetAuditEventResponse) GetEvents() []*AuditEvent { type GetHistoricCandlesRequest struct { Exchange string `protobuf:"bytes,1,opt,name=exchange,proto3" json:"exchange,omitempty"` Pair *CurrencyPair `protobuf:"bytes,2,opt,name=pair,proto3" json:"pair,omitempty"` - Rangesize int64 `protobuf:"varint,3,opt,name=rangesize,proto3" json:"rangesize,omitempty"` - Granularity int64 `protobuf:"varint,4,opt,name=granularity,proto3" json:"granularity,omitempty"` + AssetType string `protobuf:"bytes,3,opt,name=asset_type,json=assetType,proto3" json:"asset_type,omitempty"` + Start int64 `protobuf:"varint,4,opt,name=start,proto3" json:"start,omitempty"` + End int64 `protobuf:"varint,5,opt,name=end,proto3" json:"end,omitempty"` + TimeInterval int64 `protobuf:"varint,6,opt,name=time_interval,json=timeInterval,proto3" json:"time_interval,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -5764,16 +5766,30 @@ func (m *GetHistoricCandlesRequest) GetPair() *CurrencyPair { return nil } -func (m *GetHistoricCandlesRequest) GetRangesize() int64 { +func (m *GetHistoricCandlesRequest) GetAssetType() string { if m != nil { - return m.Rangesize + return m.AssetType + } + return "" +} + +func (m *GetHistoricCandlesRequest) GetStart() int64 { + if m != nil { + return m.Start } return 0 } -func (m *GetHistoricCandlesRequest) GetGranularity() int64 { +func (m *GetHistoricCandlesRequest) GetEnd() int64 { if m != nil { - return m.Granularity + return m.End + } + return 0 +} + +func (m *GetHistoricCandlesRequest) GetTimeInterval() int64 { + if m != nil { + return m.TimeInterval } return 0 } @@ -6687,380 +6703,380 @@ func init() { } var fileDescriptor_77a6da22d6a3feb1 = []byte{ - // 5955 bytes of a gzipped FileDescriptorProto + // 5960 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xc4, 0x7c, 0x4d, 0x6c, 0x24, 0xc7, 0x75, 0x30, 0x7a, 0x38, 0xfc, 0x99, 0xc7, 0xdf, 0x2d, 0xfe, 0xcd, 0xce, 0x92, 0xcb, 0x65, 0xc9, 0x5a, 0xed, 0xca, 0x12, 0x29, 0xad, 0xe4, 0xcf, 0xb2, 0xec, 0xcf, 0x0e, 0x97, 0x2b, 0xd1, 0x6b, 0xcb, 0xd2, 0xba, 0x49, 0x49, 0x80, 0x1c, 0x68, 0xd2, 0x33, 0x5d, 0x24, 0x3b, 0xdb, 0xd3, 0x3d, 0xea, 0xee, 0xe1, 0xee, 0xc8, 0x08, 0x62, 0x08, 0x49, 0x10, 0x20, 0x41, 0x82, 0xc0, 0x30, 0x92, - 0x00, 0xb9, 0x24, 0xa7, 0x20, 0x17, 0x03, 0x41, 0x0e, 0x41, 0x0e, 0x46, 0xae, 0x41, 0x90, 0x53, - 0x80, 0xc0, 0x97, 0x9c, 0x12, 0xe4, 0x10, 0x20, 0x39, 0x04, 0xc8, 0x25, 0xa7, 0xa0, 0x5e, 0xfd, - 0x74, 0x55, 0x77, 0xcf, 0x70, 0x68, 0xaf, 0x95, 0xcb, 0xee, 0xf4, 0xab, 0x57, 0xef, 0xbd, 0x7a, - 0xf5, 0xea, 0xd5, 0xab, 0x57, 0xaf, 0x08, 0x8d, 0xa4, 0xdf, 0xdd, 0xeb, 0x27, 0x71, 0x16, 0x93, - 0x99, 0xb3, 0x6e, 0x96, 0xf4, 0xbb, 0xad, 0xad, 0xb3, 0x38, 0x3e, 0x0b, 0xd9, 0xbe, 0xd7, 0x0f, - 0xf6, 0xbd, 0x28, 0x8a, 0x33, 0x2f, 0x0b, 0xe2, 0x28, 0x15, 0x58, 0xad, 0x1d, 0xd9, 0x8a, 0x5f, - 0x9d, 0xc1, 0xe9, 0x7e, 0x16, 0xf4, 0x58, 0x9a, 0x79, 0xbd, 0xbe, 0x40, 0xa0, 0x2b, 0xb0, 0x74, - 0xc4, 0xb2, 0x87, 0xd1, 0x69, 0xec, 0xb2, 0x4f, 0x06, 0x2c, 0xcd, 0xe8, 0x5f, 0xd5, 0x61, 0x59, - 0x83, 0xd2, 0x7e, 0x1c, 0xa5, 0x8c, 0x6c, 0xc0, 0xcc, 0xa0, 0xcf, 0xbb, 0x36, 0x9d, 0x5b, 0xce, - 0x9d, 0x86, 0x2b, 0xbf, 0xc8, 0x3e, 0xac, 0x7a, 0x17, 0x5e, 0x10, 0x7a, 0x9d, 0x90, 0xb5, 0xd9, - 0xd3, 0xee, 0xb9, 0x17, 0x9d, 0xb1, 0xb4, 0x59, 0xbb, 0xe5, 0xdc, 0x99, 0x72, 0x89, 0x6e, 0x7a, - 0x4b, 0xb5, 0x90, 0x2f, 0xc2, 0x35, 0x16, 0x71, 0x90, 0x6f, 0xa0, 0x4f, 0x21, 0xfa, 0x8a, 0x6c, - 0xc8, 0x91, 0x5f, 0x87, 0x0d, 0x9f, 0x9d, 0x7a, 0x83, 0x30, 0x6b, 0x9f, 0xc6, 0x09, 0x7b, 0xda, - 0xee, 0x27, 0xf1, 0x45, 0xe0, 0xb3, 0xa4, 0x59, 0x47, 0x29, 0xd6, 0x64, 0xeb, 0xdb, 0xbc, 0xf1, - 0x91, 0x6c, 0x23, 0xf7, 0x60, 0x5d, 0xf7, 0x0a, 0xbc, 0xac, 0xdd, 0x1d, 0x24, 0x09, 0x8b, 0xba, - 0xc3, 0xe6, 0x34, 0x76, 0x5a, 0x55, 0x9d, 0x02, 0x2f, 0x3b, 0x94, 0x4d, 0xe4, 0x43, 0x58, 0x49, - 0x07, 0x9d, 0x74, 0x98, 0x66, 0xac, 0xd7, 0x4e, 0x33, 0x2f, 0x1b, 0xa4, 0xcd, 0x99, 0x5b, 0x53, - 0x77, 0xe6, 0xef, 0xbd, 0xb4, 0x27, 0xf4, 0xbc, 0x57, 0x50, 0xc9, 0xde, 0xb1, 0xc2, 0x3f, 0x46, - 0xf4, 0xb7, 0xa2, 0x2c, 0x19, 0xba, 0xcb, 0xa9, 0x0d, 0x25, 0xef, 0xc2, 0x62, 0xd2, 0xef, 0xb6, - 0x59, 0xe4, 0xf7, 0xe3, 0x20, 0xca, 0xd2, 0xe6, 0x2c, 0x52, 0xbd, 0x3b, 0x8a, 0xaa, 0xdb, 0xef, - 0xbe, 0xa5, 0x70, 0x05, 0xc9, 0x85, 0xc4, 0x00, 0xb5, 0xee, 0xc3, 0x5a, 0x15, 0x63, 0xb2, 0x02, - 0x53, 0x8f, 0xd9, 0x50, 0xce, 0x0e, 0xff, 0x49, 0xd6, 0x60, 0xfa, 0xc2, 0x0b, 0x07, 0x0c, 0x27, - 0x63, 0xce, 0x15, 0x1f, 0x6f, 0xd6, 0xde, 0x70, 0x5a, 0x27, 0x70, 0xad, 0xc4, 0xa6, 0x82, 0xc0, - 0x5d, 0x93, 0xc0, 0xfc, 0xbd, 0x55, 0x25, 0xb2, 0xfb, 0xe8, 0x50, 0xf5, 0x35, 0xa8, 0xd2, 0x5d, - 0xd8, 0x39, 0x62, 0xd9, 0x61, 0xdc, 0xeb, 0x0d, 0xa2, 0xa0, 0x8b, 0x46, 0xe8, 0xb2, 0xd0, 0x1b, - 0xb2, 0x24, 0x55, 0x96, 0xf5, 0x2e, 0xac, 0x55, 0xb5, 0x93, 0x26, 0xcc, 0xca, 0xb9, 0x47, 0xfe, - 0x73, 0xae, 0xfa, 0x24, 0x5b, 0xd0, 0xe8, 0xc6, 0x51, 0xc4, 0xba, 0x19, 0xf3, 0xe5, 0x40, 0x72, - 0x00, 0xfd, 0xad, 0x1a, 0xdc, 0x1a, 0xcd, 0x53, 0x9a, 0xee, 0xa7, 0xb0, 0xd1, 0x35, 0x11, 0xda, - 0x89, 0xc4, 0x68, 0x3a, 0x38, 0x15, 0x87, 0xc6, 0x54, 0x8c, 0xa5, 0xb4, 0x57, 0xd9, 0x2a, 0x26, - 0x69, 0xbd, 0x5b, 0xd5, 0xd6, 0x3a, 0x85, 0xd6, 0xe8, 0x4e, 0x15, 0x2a, 0xbf, 0x67, 0xab, 0x7c, - 0x4b, 0x89, 0x56, 0x45, 0xc4, 0xd4, 0xfd, 0x97, 0x61, 0xf3, 0x88, 0x45, 0x2c, 0x09, 0xba, 0xda, - 0x38, 0xa4, 0xce, 0xb9, 0x06, 0xb5, 0x4d, 0x4a, 0x56, 0x39, 0x80, 0xb6, 0xa0, 0x59, 0xee, 0x28, - 0x86, 0x4b, 0x37, 0x60, 0xed, 0x88, 0x65, 0x1a, 0xae, 0x67, 0xf1, 0x27, 0x0e, 0xac, 0x63, 0x43, - 0xda, 0x49, 0x87, 0xa2, 0x41, 0xaa, 0xfa, 0x57, 0xe0, 0x9a, 0x26, 0x9d, 0xaa, 0x65, 0x24, 0xb4, - 0xfc, 0x9a, 0xa1, 0xe5, 0x72, 0xcf, 0x7c, 0x31, 0xa5, 0xe6, 0x6a, 0xca, 0xd7, 0xa4, 0x04, 0xb7, - 0x0e, 0x61, 0xbd, 0x12, 0xf5, 0x2a, 0xf6, 0x4f, 0x9b, 0xb0, 0x71, 0xc4, 0x32, 0xc3, 0x8c, 0x0d, - 0x03, 0x9d, 0x37, 0xc0, 0xdc, 0x2e, 0xd3, 0xcc, 0x4b, 0xb2, 0xdc, 0x2e, 0xe5, 0x27, 0x79, 0x1e, - 0x96, 0xc2, 0x20, 0xcd, 0x58, 0xd4, 0xf6, 0x7c, 0x3f, 0x61, 0xa9, 0x70, 0x79, 0x0d, 0x77, 0x51, - 0x40, 0x0f, 0x04, 0x90, 0xfe, 0x8d, 0xc3, 0x27, 0xa6, 0xc0, 0x4a, 0x2a, 0xeb, 0x1d, 0x68, 0xe4, - 0x5e, 0x41, 0x28, 0x69, 0xcf, 0x50, 0x52, 0x55, 0x9f, 0xbd, 0x82, 0x6b, 0xc8, 0x09, 0xb4, 0xbe, - 0x0b, 0x4b, 0xcf, 0x7a, 0x41, 0xbf, 0x01, 0x2d, 0x69, 0x1b, 0xca, 0x23, 0xbf, 0xeb, 0xf5, 0x98, - 0xb2, 0xab, 0x16, 0xcc, 0x29, 0x07, 0x2e, 0x79, 0xe8, 0x6f, 0xba, 0x0d, 0x37, 0x2a, 0x7b, 0x4a, - 0xc3, 0xda, 0x87, 0xd5, 0x23, 0x96, 0x69, 0x37, 0xaf, 0x28, 0x8e, 0xf4, 0x02, 0xf4, 0x75, 0xb4, - 0x44, 0xa3, 0x83, 0x54, 0xe1, 0x16, 0x34, 0xf2, 0x4d, 0x44, 0xda, 0xb6, 0x06, 0xd0, 0x7b, 0x68, - 0xa6, 0xaa, 0xd7, 0x7b, 0x27, 0x8f, 0x5c, 0x26, 0xba, 0x5d, 0x87, 0xb9, 0x38, 0xeb, 0xb7, 0xbb, - 0xb1, 0xaf, 0x44, 0x9f, 0x8d, 0xb3, 0xfe, 0x61, 0xec, 0x33, 0x69, 0x1a, 0x46, 0x1f, 0x6d, 0x1a, - 0x7f, 0x26, 0xa6, 0xd2, 0x6e, 0x92, 0x72, 0x7c, 0x0b, 0x1a, 0x8a, 0xa0, 0x9a, 0xca, 0x97, 0x8d, - 0xa9, 0xac, 0xea, 0xb3, 0xf7, 0x9e, 0xe0, 0x28, 0x67, 0x72, 0x4e, 0x0a, 0x90, 0xb6, 0xbe, 0x0a, - 0x8b, 0x56, 0xd3, 0x65, 0x96, 0xdd, 0x30, 0xa7, 0xec, 0x75, 0xd8, 0x78, 0x10, 0xa4, 0xe6, 0x8e, - 0x3b, 0xc9, 0x74, 0x7d, 0x0c, 0x4b, 0x8f, 0xbc, 0x20, 0x49, 0x8f, 0x07, 0xfd, 0x7e, 0x8c, 0xe6, - 0xfd, 0x02, 0x2c, 0xe7, 0xdb, 0x7a, 0x9f, 0xb7, 0xc9, 0x4e, 0x4b, 0x1a, 0x8c, 0x3d, 0xc8, 0x73, - 0xb0, 0xa8, 0xb6, 0x73, 0x81, 0x26, 0x44, 0x5a, 0x90, 0x40, 0x44, 0xa2, 0x9f, 0xd5, 0x2d, 0xd5, - 0x59, 0x81, 0x05, 0x81, 0x7a, 0xe4, 0xe9, 0xb0, 0x02, 0x7f, 0x9b, 0x86, 0x50, 0xb3, 0xb7, 0x83, - 0x26, 0xcc, 0x5e, 0xb0, 0xa4, 0x13, 0xa7, 0x0c, 0x63, 0x86, 0x39, 0x57, 0x7d, 0x72, 0x41, 0x06, - 0x69, 0x10, 0x9d, 0xb5, 0x53, 0x2f, 0xf2, 0x3b, 0xf1, 0x53, 0x8c, 0x10, 0xe6, 0xdc, 0x05, 0x04, - 0x1e, 0x0b, 0x18, 0xd9, 0x85, 0x85, 0xf3, 0x2c, 0xeb, 0xb7, 0x79, 0xe8, 0x12, 0x0f, 0x32, 0x19, - 0x10, 0xcc, 0x73, 0xd8, 0x89, 0x00, 0xf1, 0x85, 0x8d, 0x28, 0x83, 0x94, 0x25, 0xde, 0x19, 0x8b, - 0xb2, 0xe6, 0x8c, 0x58, 0xd8, 0x1c, 0xfa, 0xbe, 0x02, 0x92, 0x6d, 0x00, 0x44, 0xeb, 0x27, 0xf1, - 0xd3, 0x61, 0x73, 0x56, 0x98, 0x1e, 0x87, 0x3c, 0xe2, 0x00, 0xae, 0xbf, 0x8e, 0x97, 0x32, 0x15, - 0x7a, 0x04, 0x2c, 0x6d, 0xce, 0x09, 0xfd, 0x71, 0xf0, 0xa1, 0x86, 0x92, 0x36, 0x8f, 0x3b, 0xa4, - 0xd6, 0xdb, 0x5e, 0x9a, 0xb2, 0x2c, 0x6d, 0x36, 0xd0, 0x80, 0x5e, 0xaf, 0x30, 0xa0, 0x42, 0xfc, - 0x21, 0xfb, 0x1d, 0x60, 0x37, 0x1d, 0x7f, 0x58, 0x50, 0x1e, 0x6f, 0x79, 0x83, 0xec, 0x9c, 0x45, - 0x19, 0xdf, 0x3d, 0x38, 0x93, 0x7e, 0xd0, 0x04, 0xd4, 0xcd, 0x8a, 0xd5, 0x70, 0xd0, 0x0f, 0x5a, - 0x1f, 0xf1, 0xe0, 0xa2, 0x4c, 0xb5, 0xc2, 0x04, 0x5f, 0xb2, 0x5d, 0xc9, 0x86, 0x12, 0xd6, 0xb6, - 0x23, 0xd3, 0x34, 0x9f, 0xc0, 0xca, 0x11, 0xcb, 0x4e, 0x82, 0xee, 0x63, 0x96, 0x4c, 0x60, 0x94, - 0xe4, 0x0e, 0xd4, 0xb9, 0x45, 0x49, 0x06, 0x6b, 0x7a, 0x27, 0x94, 0x11, 0x1b, 0x67, 0xe4, 0x22, - 0x06, 0x9f, 0x0b, 0xd4, 0x5c, 0x3b, 0x1b, 0xf6, 0x85, 0x5d, 0x34, 0xdc, 0x06, 0x42, 0x4e, 0x86, - 0x7d, 0x46, 0x3f, 0x80, 0x05, 0xb3, 0x13, 0x77, 0x1a, 0x3e, 0x0b, 0x83, 0x5e, 0x90, 0xb1, 0x44, - 0x39, 0x0d, 0x0d, 0xe0, 0xf6, 0xc8, 0xa7, 0x48, 0xda, 0x31, 0xfe, 0xe6, 0xeb, 0xed, 0x93, 0x41, - 0x9c, 0x29, 0xda, 0xe2, 0x83, 0xfe, 0xa8, 0x06, 0x4b, 0x6a, 0x38, 0xd2, 0x98, 0x95, 0xcc, 0xce, - 0xa5, 0x32, 0xef, 0xc2, 0x42, 0xe8, 0xa5, 0x59, 0x7b, 0xd0, 0xf7, 0x3d, 0x15, 0xda, 0x4c, 0xb9, - 0xf3, 0x1c, 0xf6, 0xbe, 0x00, 0x71, 0x8b, 0x56, 0x91, 0x2b, 0xae, 0x2d, 0xc9, 0x7d, 0xa1, 0x6b, - 0x0e, 0x86, 0x40, 0x9d, 0xf7, 0x41, 0x6b, 0x77, 0x5c, 0xfc, 0xcd, 0x61, 0xe7, 0xc1, 0xd9, 0x39, - 0x5a, 0xb7, 0xe3, 0xe2, 0x6f, 0x3e, 0x83, 0x61, 0xfc, 0x04, 0x6d, 0xd9, 0x71, 0xf9, 0x4f, 0x0e, - 0xe9, 0x04, 0x3e, 0x9a, 0xae, 0xe3, 0xf2, 0x9f, 0x1c, 0xe2, 0xa5, 0x8f, 0xd1, 0x50, 0x1d, 0x97, - 0xff, 0xe4, 0x51, 0xff, 0x45, 0x1c, 0x0e, 0x7a, 0xac, 0xd9, 0x40, 0xa0, 0xfc, 0x22, 0x37, 0xa0, - 0xd1, 0x4f, 0x82, 0x2e, 0x6b, 0x7b, 0xd9, 0x39, 0x1a, 0x93, 0xe3, 0xce, 0x21, 0xe0, 0x20, 0x3b, - 0xa7, 0xab, 0x70, 0x4d, 0x4f, 0xb4, 0xf6, 0x9e, 0x1f, 0xc2, 0xac, 0x84, 0x8c, 0x9d, 0xf4, 0x57, - 0x60, 0x36, 0x13, 0x68, 0xcd, 0x1a, 0xae, 0x02, 0x6d, 0x58, 0xb6, 0xa6, 0x5d, 0x85, 0x46, 0xbf, - 0x01, 0xc4, 0xe4, 0x26, 0x27, 0xe2, 0x6e, 0x4e, 0x47, 0xb8, 0xe3, 0x65, 0x9b, 0x4e, 0x9a, 0x13, - 0xf8, 0x14, 0x37, 0xa3, 0xf7, 0x12, 0x9f, 0x3b, 0x92, 0xf8, 0xf1, 0xe7, 0x6a, 0x9a, 0xdf, 0x81, - 0x45, 0xcd, 0xf8, 0x61, 0xc6, 0x7a, 0x5c, 0xe1, 0x5e, 0x2f, 0x1e, 0x44, 0x19, 0xf2, 0x74, 0x5c, - 0xf9, 0xc5, 0x2d, 0x10, 0xf5, 0x8b, 0x2c, 0x1d, 0x57, 0x7c, 0x90, 0x25, 0xa8, 0x05, 0xbe, 0x3c, - 0x3c, 0xd5, 0x02, 0x9f, 0xfe, 0x8f, 0x03, 0xd7, 0x8c, 0x81, 0x5c, 0xd9, 0x28, 0x4b, 0x16, 0x57, - 0xab, 0xb0, 0xb8, 0xbb, 0x50, 0xef, 0x04, 0x3e, 0x3f, 0xb3, 0x71, 0xbd, 0xae, 0x2b, 0x72, 0xd6, - 0x38, 0x5c, 0x44, 0xe1, 0xa8, 0x5e, 0xfa, 0x38, 0x6d, 0xd6, 0xc7, 0xa2, 0x72, 0x94, 0xd2, 0x7a, - 0x98, 0x2e, 0xaf, 0x07, 0x5b, 0x97, 0x33, 0x45, 0x5d, 0x8a, 0x68, 0x55, 0xd3, 0xd6, 0x96, 0xd7, - 0x05, 0xc8, 0x81, 0x63, 0xa7, 0xf5, 0x2b, 0x00, 0xb1, 0xc6, 0x94, 0xf6, 0x77, 0xbd, 0x24, 0xb4, - 0x36, 0x41, 0x03, 0x99, 0x7e, 0x1b, 0x43, 0x0d, 0x93, 0xb9, 0x54, 0xfe, 0x3d, 0x8b, 0xa6, 0xb0, - 0x45, 0x52, 0xa2, 0x99, 0x5a, 0xc4, 0x5e, 0x43, 0x62, 0x07, 0xdd, 0x2e, 0x9f, 0x7a, 0xe3, 0x60, - 0x3e, 0x76, 0x0f, 0xff, 0x00, 0x66, 0x65, 0x0f, 0x69, 0x16, 0x02, 0xa1, 0x16, 0xf8, 0xe4, 0xab, - 0x00, 0xc6, 0x3e, 0x24, 0xc6, 0x75, 0x43, 0xc9, 0x20, 0x3b, 0x29, 0x6b, 0x40, 0x76, 0x06, 0x3a, - 0x3d, 0x85, 0xd5, 0x0a, 0x14, 0x2e, 0x8a, 0x3e, 0x56, 0x4b, 0x51, 0xd4, 0x37, 0xd9, 0x81, 0xf9, - 0x2c, 0xce, 0xbc, 0xb0, 0x9d, 0xef, 0x10, 0x8e, 0x0b, 0x08, 0xfa, 0x80, 0x43, 0xd0, 0x41, 0xc5, - 0xa1, 0xb0, 0x5c, 0xee, 0xa0, 0xe2, 0xd0, 0xa7, 0x1e, 0x06, 0x5e, 0xd6, 0xa0, 0xa5, 0x0a, 0xc7, - 0x4d, 0xd9, 0x17, 0x61, 0xce, 0x13, 0x5d, 0xd4, 0xc0, 0x96, 0x0b, 0x03, 0x73, 0x35, 0x02, 0x25, - 0xb8, 0x03, 0x1d, 0xc6, 0xd1, 0x69, 0x70, 0xa6, 0xac, 0xe3, 0x05, 0x74, 0x56, 0x0a, 0x96, 0xc7, - 0x24, 0xbe, 0x97, 0x79, 0xc8, 0x6d, 0xc1, 0xc5, 0xdf, 0xf4, 0x37, 0x1d, 0x58, 0x79, 0x14, 0x27, - 0xd9, 0x69, 0x1c, 0x06, 0xb1, 0x0c, 0xef, 0x79, 0x38, 0xa2, 0xc2, 0x7f, 0x19, 0x47, 0xca, 0x4f, - 0xee, 0x21, 0xbb, 0x71, 0x10, 0x09, 0x5b, 0xad, 0x49, 0x05, 0xc5, 0x41, 0xc4, 0x4d, 0x95, 0xdc, - 0x82, 0x79, 0x9f, 0xa5, 0xdd, 0x24, 0xe8, 0xf3, 0xe3, 0x9c, 0x74, 0x0b, 0x26, 0x88, 0x13, 0xee, - 0x78, 0xa1, 0x17, 0x75, 0x99, 0xf4, 0xec, 0xea, 0x93, 0xae, 0xa3, 0xbb, 0xd2, 0x92, 0x18, 0x27, - 0x6b, 0x1b, 0x2c, 0x87, 0xf2, 0xff, 0xa0, 0xd1, 0x57, 0x40, 0x69, 0x7e, 0x4d, 0xbd, 0x57, 0x17, - 0x86, 0xe3, 0xe6, 0xa8, 0x74, 0x8b, 0xc7, 0xfe, 0x39, 0xbd, 0xe3, 0x41, 0xaf, 0xe7, 0x25, 0x43, - 0xc5, 0x2d, 0x82, 0xfa, 0x61, 0x1c, 0x44, 0x5c, 0x51, 0x7c, 0x50, 0x2a, 0x78, 0xe3, 0xbf, 0x4d, - 0xd1, 0x6b, 0x96, 0xe8, 0xa6, 0xb6, 0xa6, 0x6c, 0x6d, 0xdd, 0x04, 0xe8, 0xb3, 0xa4, 0xcb, 0xa2, - 0xcc, 0x3b, 0x53, 0x23, 0x36, 0x20, 0xf4, 0x1c, 0xc8, 0x7b, 0xa7, 0xa7, 0x61, 0x10, 0x31, 0xce, - 0x56, 0x0a, 0x33, 0x46, 0xfb, 0xa3, 0x65, 0xb0, 0x39, 0x4d, 0x95, 0x38, 0x7d, 0x07, 0xae, 0xbd, - 0x17, 0x55, 0x30, 0x52, 0xe4, 0x9c, 0x71, 0xe4, 0x6a, 0x25, 0x72, 0xdf, 0x84, 0x05, 0x43, 0xf0, - 0x94, 0xbc, 0x01, 0x0d, 0x29, 0xa3, 0x3e, 0x28, 0xb4, 0xb4, 0x37, 0x28, 0x8d, 0xd0, 0xcd, 0x91, - 0xe9, 0x1f, 0x39, 0x30, 0x9f, 0x4b, 0x96, 0x92, 0xd7, 0x61, 0x9a, 0xab, 0x5b, 0x51, 0xb9, 0xa9, - 0xa9, 0xe4, 0x38, 0x7b, 0xf8, 0xaf, 0x88, 0x0b, 0x05, 0x72, 0xeb, 0x18, 0x20, 0x07, 0x56, 0x84, - 0x75, 0xfb, 0x76, 0x58, 0x77, 0xbd, 0x4c, 0x55, 0x89, 0x66, 0x44, 0x76, 0x7f, 0x5f, 0xe7, 0xc7, - 0xbd, 0x0a, 0x63, 0x91, 0x36, 0xf8, 0x32, 0xcc, 0x8b, 0xb5, 0xc0, 0x3d, 0x80, 0x12, 0x78, 0x21, - 0x4f, 0x6d, 0x04, 0x91, 0x0b, 0xb8, 0x36, 0xb0, 0x9d, 0xbc, 0x0a, 0x8b, 0x28, 0x6c, 0x3b, 0x16, - 0x0a, 0x91, 0x0b, 0xdb, 0xee, 0xb0, 0x80, 0x28, 0x52, 0x65, 0xa4, 0x0f, 0xeb, 0x56, 0x97, 0x76, - 0x2a, 0x44, 0x90, 0x9b, 0xd4, 0xd7, 0x8c, 0x50, 0x7a, 0x94, 0x94, 0x42, 0x59, 0x92, 0xa0, 0x6c, - 0x13, 0xaa, 0x5b, 0xed, 0x96, 0x5b, 0xc8, 0x3e, 0x2c, 0x48, 0x8e, 0xa8, 0x19, 0xb9, 0xc5, 0xd9, - 0x32, 0xce, 0x8b, 0x8e, 0x88, 0x40, 0x7a, 0xb0, 0x66, 0x76, 0xd0, 0x12, 0x4e, 0x63, 0xc7, 0xaf, - 0x4e, 0x2e, 0x61, 0x54, 0x12, 0x90, 0x74, 0x4b, 0x0d, 0xad, 0x5f, 0x86, 0xe6, 0xa8, 0x01, 0x55, - 0x4c, 0xfb, 0x8b, 0xf6, 0xb4, 0xaf, 0x55, 0x98, 0x64, 0x6a, 0x26, 0x10, 0x3f, 0x82, 0xcd, 0x11, - 0xc2, 0x5c, 0x21, 0xeb, 0x60, 0x58, 0xaa, 0x69, 0x4d, 0xff, 0xe2, 0x40, 0xeb, 0xc0, 0xf7, 0x4b, - 0xce, 0x29, 0x4f, 0x12, 0x7c, 0xce, 0x2e, 0x97, 0xec, 0xc3, 0x6a, 0x7e, 0x46, 0xcb, 0xf3, 0x0d, - 0xe2, 0xf0, 0x48, 0x74, 0x53, 0x9e, 0xb6, 0xde, 0xe5, 0xc6, 0x11, 0xfa, 0xed, 0x34, 0x8b, 0xf9, - 0x71, 0x11, 0x63, 0x95, 0x39, 0x6e, 0x0e, 0xa1, 0x7f, 0x2c, 0x40, 0x74, 0x1b, 0x6e, 0x54, 0x0e, - 0x52, 0x66, 0x48, 0x9e, 0xc2, 0xb6, 0xcb, 0x7a, 0xf1, 0x05, 0xfb, 0xbc, 0xd5, 0x40, 0x6f, 0xc1, - 0xcd, 0x51, 0x9c, 0xa5, 0x6c, 0x98, 0x32, 0xb4, 0x53, 0xee, 0x3a, 0xd8, 0xfa, 0x0f, 0x07, 0x16, - 0xed, 0x64, 0xfc, 0xb3, 0x3a, 0xdf, 0xbf, 0x04, 0x24, 0x61, 0x69, 0xd6, 0xee, 0xc7, 0x61, 0xc8, - 0x8f, 0xf9, 0x3e, 0x0b, 0xbd, 0xa1, 0xbc, 0x06, 0x58, 0xe1, 0x2d, 0x8f, 0x44, 0xc3, 0x03, 0x0e, - 0x27, 0x9b, 0x30, 0xeb, 0xf5, 0x83, 0x36, 0xb7, 0x44, 0x31, 0x4d, 0x33, 0x5e, 0x3f, 0xf8, 0x36, - 0x1b, 0x12, 0x0a, 0x8b, 0xb2, 0xa1, 0x1d, 0xb2, 0x0b, 0x16, 0xe2, 0xdc, 0x4c, 0xb9, 0xf3, 0xa2, - 0xf9, 0x1d, 0x0e, 0x22, 0x77, 0x61, 0xa5, 0x9f, 0x04, 0xdc, 0xa4, 0xf3, 0xfb, 0x86, 0x59, 0x94, - 0x66, 0x59, 0xc2, 0xd5, 0xe8, 0xe8, 0xf7, 0xe0, 0x7a, 0x85, 0x2e, 0xa4, 0xdf, 0xfb, 0x3a, 0x2c, - 0xdb, 0xb7, 0x16, 0xca, 0xf7, 0xe9, 0x48, 0xd8, 0xea, 0xe8, 0x2e, 0x9d, 0x5a, 0x74, 0x64, 0x44, - 0x8b, 0x38, 0xae, 0x97, 0xe9, 0x3c, 0x19, 0xfd, 0x04, 0xd6, 0x72, 0xe0, 0x61, 0x1c, 0x5d, 0xb0, - 0x24, 0xe5, 0x16, 0x4c, 0xa0, 0x7e, 0x9a, 0xc4, 0x2a, 0xc9, 0x8b, 0xbf, 0x79, 0x2c, 0x98, 0xc5, - 0xd2, 0x0c, 0x6a, 0x59, 0xcc, 0x71, 0x12, 0x2f, 0x53, 0x3b, 0x1f, 0xfe, 0xe6, 0xe6, 0x1a, 0x20, - 0x11, 0xd6, 0xc6, 0x36, 0x61, 0xfe, 0xf3, 0x12, 0xc6, 0xb9, 0xd0, 0x0f, 0x30, 0x24, 0x35, 0x45, - 0x91, 0x63, 0xfc, 0xff, 0x30, 0x2f, 0xc6, 0xc8, 0x7b, 0xaa, 0xf1, 0x6d, 0x59, 0xe3, 0x2b, 0x88, - 0xe9, 0xc2, 0xa9, 0x86, 0xd2, 0x1f, 0x4f, 0xc1, 0x02, 0x46, 0xc1, 0x0f, 0x58, 0xe6, 0x05, 0xe1, - 0xf8, 0xf8, 0x5c, 0xc4, 0xb5, 0x35, 0x1d, 0xd7, 0x3e, 0x07, 0x8b, 0x66, 0x92, 0x65, 0xa8, 0x0e, - 0xc8, 0x46, 0x8a, 0x65, 0x48, 0x9e, 0x87, 0x25, 0x3c, 0xae, 0xe7, 0x58, 0xc2, 0x66, 0x16, 0x11, - 0xaa, 0xd1, 0xec, 0xc3, 0xc5, 0x74, 0xe1, 0x70, 0xc1, 0x9b, 0x31, 0x40, 0x6f, 0xa7, 0x81, 0xaf, - 0xcf, 0x1e, 0x08, 0x39, 0x0e, 0x7c, 0xa3, 0x19, 0x7b, 0xcf, 0x1a, 0xcd, 0xd8, 0x9b, 0x9f, 0xab, - 0x12, 0x26, 0x2e, 0x1f, 0xf0, 0x0e, 0x6d, 0x0e, 0x8d, 0x6e, 0x41, 0x01, 0x4f, 0x82, 0x1e, 0xde, - 0xb0, 0xc9, 0x84, 0x79, 0x43, 0x58, 0xac, 0xf8, 0xca, 0x8f, 0x7e, 0x60, 0x1e, 0xfd, 0xf2, 0x83, - 0xe2, 0xbc, 0x75, 0x50, 0xdc, 0x81, 0xf9, 0xb8, 0xcf, 0xa2, 0xb6, 0x3c, 0xb6, 0x2f, 0x88, 0x88, - 0x84, 0x83, 0x3e, 0x10, 0x47, 0xf7, 0x15, 0x98, 0x3a, 0x65, 0xac, 0xb9, 0x28, 0x0e, 0xf9, 0xa7, - 0x8c, 0xaf, 0xac, 0x99, 0x2c, 0xf1, 0x7c, 0x96, 0x36, 0x97, 0x70, 0xf6, 0xb4, 0xf7, 0x3f, 0xe1, - 0xd0, 0x6f, 0x06, 0xdc, 0x8b, 0x0d, 0x5d, 0x89, 0x43, 0xff, 0xd9, 0x81, 0x05, 0xb3, 0xa1, 0x3c, - 0x38, 0xa7, 0x62, 0x70, 0xc5, 0xa9, 0xd3, 0x83, 0x9a, 0xaa, 0x1e, 0x54, 0xdd, 0x1a, 0x94, 0x69, - 0x14, 0xd3, 0x05, 0xa3, 0x18, 0x7f, 0x2a, 0x2c, 0x4c, 0xdc, 0x6c, 0x71, 0xe2, 0xa4, 0x36, 0xe6, - 0xb4, 0x36, 0x64, 0x9a, 0x0a, 0x6d, 0x32, 0x9d, 0x24, 0x17, 0x60, 0xf3, 0xaf, 0x15, 0xf9, 0xab, - 0xc3, 0xf7, 0xd4, 0x65, 0x87, 0x6f, 0x7a, 0x80, 0x27, 0x11, 0xc5, 0x58, 0x2e, 0xaf, 0x97, 0x60, - 0x06, 0x85, 0x55, 0x2b, 0x6b, 0xcd, 0x3a, 0x3a, 0xca, 0x45, 0xe3, 0x4a, 0x1c, 0xfa, 0x4d, 0xbc, - 0xb7, 0xc5, 0xa6, 0x49, 0x44, 0xbf, 0x0e, 0x73, 0x42, 0x37, 0x7a, 0x6a, 0x66, 0xf1, 0xfb, 0xa1, - 0x4f, 0x7f, 0xea, 0x00, 0x39, 0x1e, 0x74, 0x7a, 0xc1, 0xe4, 0xd4, 0x26, 0x4f, 0x8a, 0x10, 0xa8, - 0xe3, 0x6c, 0x88, 0xe5, 0x8a, 0xbf, 0x0b, 0x2b, 0xa8, 0x5e, 0x5c, 0x41, 0xb9, 0x65, 0x4c, 0x57, - 0xe7, 0x45, 0x66, 0x4c, 0x3b, 0xe2, 0x5b, 0x60, 0x18, 0xb0, 0x28, 0x6b, 0xcb, 0x04, 0x17, 0xdf, - 0x02, 0x11, 0xf0, 0xd0, 0xa7, 0xc7, 0xb0, 0x6a, 0x8d, 0x4c, 0x6a, 0x7a, 0x17, 0x16, 0x84, 0x00, - 0xfd, 0xd0, 0xeb, 0xea, 0x1b, 0x88, 0x79, 0x84, 0x3d, 0x42, 0xd0, 0x38, 0x7d, 0xfd, 0xb6, 0x03, - 0x6b, 0xc7, 0x41, 0x6f, 0x10, 0x7a, 0x19, 0xfb, 0x05, 0x68, 0x2c, 0x1f, 0xfe, 0x94, 0x35, 0x7c, - 0xa5, 0xc9, 0x7a, 0xae, 0x49, 0xfa, 0x5f, 0x0e, 0xac, 0x17, 0x44, 0xd1, 0x71, 0xb8, 0x6d, 0x4c, - 0x23, 0x12, 0x32, 0x12, 0xc9, 0x60, 0x5a, 0xb3, 0x98, 0x3e, 0x07, 0x8b, 0xbd, 0x20, 0x0a, 0x7a, - 0x83, 0x5e, 0xdb, 0x5c, 0xc3, 0x0b, 0x12, 0xf8, 0x08, 0xa7, 0x80, 0x23, 0x79, 0x4f, 0x0d, 0xa4, - 0xba, 0x44, 0x12, 0x40, 0x81, 0xf4, 0x0a, 0xac, 0xe5, 0x67, 0xa5, 0xf6, 0x99, 0x17, 0x44, 0xed, - 0x30, 0x4e, 0x53, 0x39, 0xc7, 0x24, 0x6f, 0x3b, 0xf2, 0x82, 0xe8, 0x9d, 0x38, 0x4d, 0x0d, 0x27, - 0x39, 0x63, 0x3a, 0x49, 0xfa, 0xfb, 0x0e, 0xac, 0x7c, 0x78, 0xee, 0x85, 0xec, 0x7e, 0xdc, 0xeb, - 0x3c, 0x5b, 0xdd, 0xef, 0xc2, 0x82, 0xc8, 0x75, 0x66, 0x5e, 0x72, 0xc6, 0xd4, 0x0c, 0xcc, 0x23, - 0xec, 0x04, 0x41, 0x95, 0xd3, 0xf0, 0x9f, 0x0e, 0x90, 0x43, 0x1e, 0x3e, 0x86, 0x13, 0xdb, 0x03, - 0x77, 0x25, 0x22, 0x57, 0x91, 0x5b, 0x58, 0x43, 0x42, 0x1e, 0xda, 0xe6, 0x37, 0x65, 0x99, 0x9f, - 0x1e, 0x4d, 0xfd, 0x8a, 0x09, 0xc9, 0xd2, 0x3e, 0xf7, 0x3c, 0x2c, 0x3d, 0xf1, 0xc2, 0x90, 0x65, - 0xfa, 0x5a, 0x53, 0xde, 0x7e, 0x08, 0xa8, 0xca, 0x7b, 0xa8, 0x01, 0xcf, 0x1a, 0x03, 0x5e, 0x87, - 0x55, 0x6b, 0xbc, 0x32, 0x5a, 0x7c, 0x1d, 0x36, 0x04, 0xf8, 0x20, 0x0c, 0x27, 0xf6, 0xaa, 0xf4, - 0x4f, 0x6a, 0xb0, 0x59, 0xea, 0xa6, 0xc3, 0x2a, 0xdb, 0x8c, 0x6f, 0xeb, 0xe1, 0x56, 0x77, 0xd8, - 0x93, 0x9f, 0xb2, 0x57, 0xeb, 0x6f, 0x1d, 0x98, 0x11, 0xa0, 0xb1, 0xb3, 0xf1, 0x91, 0x72, 0x08, - 0xd2, 0xe0, 0xc4, 0x29, 0xf4, 0xcb, 0x93, 0x31, 0x13, 0xff, 0x99, 0x57, 0xd9, 0xc2, 0x93, 0xc8, - 0x5b, 0xec, 0xaf, 0xc3, 0x4a, 0x11, 0xe1, 0x4a, 0xd7, 0x7c, 0x22, 0x93, 0xf5, 0xd6, 0x05, 0x33, - 0xae, 0xae, 0x7f, 0xe2, 0xc0, 0xf2, 0x61, 0x1c, 0xf9, 0x01, 0xdf, 0x74, 0x1f, 0x79, 0x89, 0xd7, - 0x4b, 0x65, 0xf5, 0x84, 0x00, 0xa9, 0xab, 0x0e, 0x0d, 0x18, 0x91, 0x54, 0xde, 0x06, 0xe8, 0x9e, - 0xb3, 0xee, 0xe3, 0xb6, 0xcc, 0xf2, 0x8a, 0x92, 0x0b, 0x0e, 0xb9, 0x1f, 0xf8, 0x29, 0x79, 0x19, - 0x56, 0xf3, 0xe6, 0xb6, 0x17, 0xf9, 0x6d, 0x99, 0xe2, 0xc5, 0x1b, 0x25, 0x8d, 0x77, 0x10, 0xf9, - 0x07, 0xe9, 0xe3, 0x94, 0xc7, 0xd2, 0x3a, 0xb3, 0xd9, 0xb6, 0x5c, 0xf8, 0xb2, 0x86, 0x1f, 0x20, - 0x98, 0xfe, 0xb7, 0x83, 0x3b, 0xa0, 0x1a, 0x95, 0x9c, 0xed, 0x3c, 0x99, 0x89, 0x39, 0x6e, 0x6b, - 0xca, 0x6a, 0x85, 0x29, 0x23, 0x50, 0x0f, 0x32, 0xd6, 0x53, 0x1b, 0x0b, 0xff, 0x4d, 0xee, 0xc3, - 0x8a, 0x1e, 0x71, 0xbb, 0x8f, 0x6a, 0x91, 0xcb, 0x64, 0x33, 0x3f, 0xac, 0x5b, 0x5a, 0x73, 0x97, - 0xbb, 0x05, 0x35, 0xaa, 0xe5, 0x35, 0x3d, 0x91, 0xa3, 0xee, 0xa2, 0xb6, 0xa5, 0x7f, 0x12, 0x5f, - 0x42, 0x6a, 0xd6, 0x1d, 0x64, 0xcc, 0x97, 0x47, 0x09, 0xfd, 0x4d, 0xff, 0xcd, 0x81, 0xe5, 0x03, - 0xdf, 0xc7, 0x71, 0x4f, 0xe2, 0x26, 0xd4, 0x28, 0x6b, 0x97, 0x8c, 0x72, 0xea, 0x67, 0x1c, 0xe5, - 0xcf, 0xed, 0x44, 0x46, 0x28, 0x81, 0x52, 0x58, 0xc9, 0xc7, 0x59, 0x3d, 0xbd, 0xf4, 0x0b, 0x40, - 0xc4, 0xf1, 0xd3, 0x52, 0x47, 0x11, 0x6b, 0x1d, 0x56, 0x2d, 0x2c, 0xe9, 0x6b, 0xde, 0x86, 0x3b, - 0x47, 0x2c, 0x3b, 0x4c, 0x86, 0xfd, 0x2c, 0x56, 0xe1, 0xfe, 0x03, 0xd6, 0x8f, 0xd3, 0x40, 0x79, - 0x2e, 0x36, 0x91, 0xf7, 0xf9, 0x3b, 0x07, 0xee, 0x4e, 0x40, 0x48, 0x0e, 0xe1, 0xe3, 0x72, 0x4e, - 0xef, 0x97, 0xcc, 0x92, 0xa2, 0x89, 0xa8, 0xec, 0x69, 0x88, 0xac, 0xec, 0xd0, 0x24, 0x5b, 0x5f, - 0x83, 0x25, 0xbb, 0xf1, 0x4a, 0xae, 0x22, 0x84, 0xdb, 0x97, 0x08, 0x31, 0x89, 0xcd, 0xdd, 0x86, - 0xa5, 0xae, 0x45, 0x42, 0x32, 0x2a, 0x40, 0xe9, 0x21, 0xbc, 0x70, 0x29, 0x37, 0xa9, 0xb6, 0x91, - 0x19, 0x0c, 0xfa, 0x63, 0x07, 0x56, 0x3f, 0x0c, 0xb2, 0x73, 0x3f, 0xf1, 0x9e, 0xbc, 0x1d, 0x78, - 0x13, 0x2d, 0x0a, 0xf3, 0x3e, 0xa2, 0x56, 0xb8, 0x8f, 0x18, 0x15, 0x3d, 0x15, 0x92, 0x21, 0xf5, - 0x72, 0x4e, 0xe8, 0x36, 0x2c, 0x77, 0xbc, 0xe8, 0x71, 0xdb, 0xd8, 0x96, 0x85, 0xb5, 0x2f, 0x72, - 0xb0, 0xba, 0xac, 0xf0, 0xe9, 0x3f, 0x39, 0xb0, 0xae, 0x24, 0x16, 0x83, 0x9f, 0x44, 0x66, 0x43, - 0x03, 0x35, 0x3b, 0x87, 0xb3, 0x03, 0xf3, 0xf2, 0x67, 0x3b, 0xf3, 0xce, 0xa4, 0x3f, 0x03, 0x09, - 0x3a, 0xf1, 0xce, 0xac, 0xe1, 0xd6, 0x47, 0x0e, 0xd7, 0x8e, 0x95, 0xe5, 0x59, 0x67, 0x26, 0x3f, - 0xf9, 0x15, 0x14, 0x30, 0x5b, 0xce, 0x06, 0xbd, 0x09, 0x2b, 0x6a, 0x5c, 0x15, 0x4b, 0x56, 0x9c, - 0xe5, 0xf2, 0x98, 0xac, 0x66, 0xc5, 0x64, 0x2f, 0x41, 0x4b, 0xf5, 0xf5, 0x42, 0x5c, 0xa8, 0xf7, - 0x87, 0x0f, 0x1f, 0x94, 0x97, 0x34, 0x52, 0xa1, 0x27, 0x70, 0xa3, 0x12, 0x5b, 0x32, 0xfd, 0x12, - 0x4c, 0x33, 0x0e, 0x94, 0x01, 0xdb, 0x8e, 0x5a, 0x60, 0x85, 0x3e, 0xfa, 0x72, 0x4e, 0x60, 0x53, - 0x06, 0xbb, 0x05, 0x8c, 0xf4, 0xfe, 0xf0, 0x0a, 0xa5, 0x31, 0x55, 0x07, 0x57, 0xac, 0x14, 0xc0, - 0x39, 0x99, 0x76, 0xc5, 0x07, 0x1d, 0xc2, 0x76, 0x99, 0xcd, 0x03, 0x2f, 0x9b, 0x88, 0xc5, 0x1a, - 0x4c, 0x63, 0x55, 0x99, 0x5a, 0xbb, 0xf8, 0xc1, 0x67, 0x8b, 0x45, 0x2a, 0xd0, 0xe3, 0x3f, 0x73, - 0xd6, 0x75, 0x93, 0xf5, 0xf7, 0x80, 0x8e, 0x1b, 0x61, 0x59, 0x7d, 0x53, 0x57, 0x50, 0xdf, 0x8f, - 0x6a, 0xb0, 0x39, 0x02, 0xa5, 0xa4, 0x99, 0x37, 0x8d, 0x21, 0x8a, 0xad, 0xe7, 0x66, 0x91, 0x4b, - 0xa8, 0xe4, 0x12, 0x94, 0x72, 0x15, 0xbc, 0x01, 0xb3, 0x89, 0xd0, 0x94, 0xdc, 0x7d, 0x6e, 0x96, - 0x05, 0x94, 0xaa, 0x14, 0x5d, 0x15, 0x3a, 0xf9, 0x0a, 0x00, 0x26, 0x1a, 0x98, 0xdf, 0xf6, 0x32, - 0xb9, 0x41, 0xb7, 0xf6, 0x44, 0xcd, 0xf3, 0x9e, 0xaa, 0x79, 0xde, 0x3b, 0x51, 0x35, 0xcf, 0x6e, - 0x43, 0x62, 0x1f, 0x60, 0x57, 0x79, 0xdb, 0xcc, 0xbb, 0xce, 0x5c, 0xde, 0x55, 0x62, 0x1f, 0x64, - 0xf4, 0x04, 0x36, 0xaa, 0xc7, 0x54, 0x99, 0xee, 0x2c, 0x6a, 0x2a, 0x5f, 0x30, 0x53, 0xd6, 0x82, - 0xf9, 0x77, 0x27, 0x27, 0x6b, 0x8f, 0x77, 0xac, 0x7b, 0xbb, 0x3c, 0xb5, 0x3d, 0x2a, 0xaf, 0x42, - 0xa0, 0xae, 0x77, 0xf0, 0x69, 0x17, 0x7f, 0x93, 0x7d, 0xa8, 0x9f, 0x06, 0x5a, 0x1f, 0xfa, 0x9a, - 0x98, 0xfb, 0xe1, 0xa2, 0x25, 0x20, 0x22, 0xf9, 0x12, 0xcc, 0x88, 0x4d, 0x00, 0xfd, 0xc7, 0xfc, - 0xbd, 0x6d, 0x1d, 0x38, 0x20, 0xb4, 0xd8, 0x49, 0x22, 0xd3, 0xbf, 0x76, 0x60, 0xb5, 0x82, 0x28, - 0x3f, 0xbb, 0xa3, 0xcb, 0x35, 0xb4, 0x38, 0xc7, 0x01, 0xef, 0x72, 0x4d, 0xee, 0xc2, 0x82, 0x72, - 0xc5, 0xd8, 0x2e, 0x54, 0x31, 0x2f, 0x61, 0x88, 0xf2, 0x3c, 0x2c, 0x69, 0x94, 0x41, 0xaf, 0xc3, - 0x54, 0xd9, 0xcc, 0xa2, 0x42, 0x42, 0x20, 0x56, 0xbf, 0xa4, 0x1d, 0xe9, 0x3b, 0xf9, 0x4f, 0x5c, - 0x86, 0x4f, 0x82, 0x53, 0x55, 0x14, 0x26, 0x3e, 0x30, 0xd8, 0xea, 0x78, 0x2a, 0x92, 0xc1, 0xdf, - 0xd4, 0x87, 0xf5, 0xca, 0xb1, 0x8d, 0x49, 0xca, 0x17, 0x1c, 0x7a, 0xad, 0xe4, 0xd0, 0xa5, 0x73, - 0x9e, 0xca, 0x13, 0x51, 0xaf, 0x62, 0xcd, 0xdc, 0x3b, 0xf1, 0xd9, 0x59, 0x9e, 0xe8, 0x91, 0x46, - 0xbf, 0x01, 0x33, 0x21, 0xc2, 0x55, 0x31, 0xbe, 0xf8, 0xa2, 0x11, 0x66, 0xe6, 0x0b, 0x5d, 0xf2, - 0x3b, 0xed, 0x20, 0x3a, 0x8d, 0x65, 0x5e, 0x03, 0x7f, 0xf3, 0x21, 0xfb, 0xac, 0x33, 0x38, 0x53, - 0x15, 0xb2, 0xf8, 0xc1, 0x31, 0x9f, 0x78, 0x49, 0x24, 0x43, 0x7f, 0xfc, 0xcd, 0x31, 0x59, 0x92, - 0xc4, 0x89, 0x8c, 0xf3, 0xc5, 0x07, 0x3d, 0x82, 0xcd, 0xe3, 0xab, 0x89, 0x88, 0x4e, 0x0c, 0xf3, - 0xee, 0xd2, 0xd9, 0xe1, 0x07, 0xfd, 0xb6, 0x55, 0x1f, 0x88, 0x35, 0x64, 0x13, 0x7a, 0x4e, 0x8c, - 0x3a, 0x15, 0x31, 0xfc, 0xa0, 0x3f, 0x75, 0x50, 0x0d, 0x05, 0x6a, 0xba, 0x42, 0xb9, 0x5c, 0x6f, - 0x27, 0x62, 0xb6, 0x2f, 0x55, 0xd4, 0xdb, 0x59, 0x7d, 0x27, 0x2b, 0xb8, 0xfb, 0x85, 0xd6, 0xd0, - 0x7d, 0x0a, 0xab, 0xa6, 0x68, 0x9f, 0x6b, 0x7e, 0xf2, 0x07, 0x0e, 0xde, 0x75, 0xe8, 0x5c, 0xd1, - 0x71, 0x96, 0x30, 0xaf, 0xf7, 0xb9, 0x96, 0x4b, 0x7d, 0x03, 0x76, 0xcd, 0x6a, 0xda, 0x2b, 0x4b, - 0x42, 0x7f, 0x0d, 0x8b, 0x4c, 0x44, 0x09, 0xd8, 0xff, 0x81, 0xfc, 0x5f, 0x83, 0x9b, 0x86, 0xfc, - 0x57, 0x14, 0x83, 0xfe, 0xb1, 0x83, 0xf7, 0x41, 0x07, 0x03, 0x3f, 0xc8, 0xac, 0xd3, 0xd1, 0x36, - 0x00, 0xc6, 0x0c, 0x6d, 0xbe, 0x3d, 0xe9, 0x12, 0x7f, 0x0e, 0xe1, 0x21, 0x08, 0xb9, 0x0e, 0x73, - 0x2c, 0xf2, 0x45, 0xa3, 0x8c, 0x33, 0x59, 0xe4, 0xab, 0x26, 0x91, 0xe3, 0xe8, 0x0c, 0xad, 0x94, - 0xd2, 0xfd, 0x61, 0x75, 0xb4, 0xc1, 0x97, 0x75, 0x7c, 0x7a, 0xca, 0x97, 0x9c, 0xd8, 0x33, 0xe4, - 0x17, 0x3d, 0x14, 0x25, 0x4b, 0x86, 0x68, 0x72, 0xbd, 0xbd, 0x08, 0x33, 0x18, 0x4a, 0x94, 0x6a, - 0x9f, 0x0c, 0x5c, 0x89, 0x41, 0xff, 0x54, 0x58, 0x98, 0xb8, 0x58, 0x08, 0xba, 0x87, 0x5e, 0xe4, - 0x87, 0x13, 0x1d, 0xd8, 0xae, 0x30, 0x43, 0x5b, 0xd0, 0x48, 0xf0, 0x92, 0x36, 0xf8, 0x94, 0xc9, - 0xca, 0xb9, 0x1c, 0xc0, 0xb7, 0xd2, 0xb3, 0xc4, 0x8b, 0x06, 0xa1, 0x97, 0x04, 0x99, 0x88, 0xac, - 0xa7, 0x5c, 0x13, 0x44, 0x1f, 0x60, 0x5d, 0x4c, 0x49, 0x44, 0x39, 0xda, 0xdb, 0x30, 0xd3, 0x45, - 0x90, 0x1c, 0xed, 0x92, 0x91, 0x2d, 0xf2, 0x43, 0xe6, 0xca, 0x56, 0xfa, 0x1b, 0x0e, 0xcc, 0x08, - 0x10, 0xee, 0xc1, 0xf9, 0xad, 0x09, 0xfe, 0x56, 0xc5, 0x9a, 0xb5, 0xbc, 0x58, 0x53, 0x95, 0x74, - 0x4e, 0x19, 0x25, 0x9d, 0x04, 0xea, 0x71, 0x9f, 0x45, 0xaa, 0xf4, 0x93, 0xff, 0xe6, 0xb3, 0xd6, - 0x0d, 0xe3, 0x94, 0xc9, 0xd0, 0x5f, 0x7c, 0x18, 0x65, 0x9c, 0x33, 0x66, 0x19, 0x27, 0x7d, 0x0a, - 0x90, 0x4f, 0x83, 0x8e, 0x06, 0x64, 0xe8, 0x82, 0xd1, 0xc0, 0x4d, 0x80, 0xc0, 0x67, 0x51, 0x16, - 0x9c, 0x06, 0x4c, 0x95, 0x03, 0x1a, 0x10, 0xbe, 0xe3, 0xf5, 0x58, 0x9a, 0xaa, 0x5a, 0x9a, 0x86, - 0xab, 0x3e, 0xb9, 0xa2, 0xf5, 0x4b, 0x33, 0x95, 0xcf, 0xd7, 0x00, 0xda, 0x81, 0xc6, 0xd1, 0xe1, - 0xc9, 0x31, 0x46, 0x28, 0x9c, 0xf1, 0xfb, 0xef, 0x3f, 0x7c, 0xa0, 0x18, 0xf3, 0xdf, 0x3a, 0x8e, - 0xaa, 0x19, 0x71, 0x14, 0xe1, 0xb3, 0x9c, 0x9d, 0xab, 0xf4, 0x0e, 0xff, 0xcd, 0x2d, 0x38, 0x62, - 0x4f, 0xb3, 0x76, 0x32, 0x50, 0x07, 0xb8, 0x59, 0xfe, 0xed, 0x0e, 0x22, 0xfa, 0x00, 0x36, 0x35, - 0x8f, 0xb7, 0x44, 0xb2, 0x45, 0xd9, 0xd2, 0x5d, 0x98, 0x11, 0xd1, 0x91, 0x2c, 0x8a, 0xbc, 0xa6, - 0x7d, 0xbf, 0xea, 0xe0, 0x4a, 0x04, 0x7a, 0x00, 0x6b, 0x1a, 0x78, 0x9c, 0xc5, 0xfd, 0x9f, 0x81, - 0xc4, 0x75, 0x43, 0x10, 0x4e, 0xe2, 0x20, 0x54, 0xc1, 0x1d, 0x3e, 0x37, 0xc8, 0x9b, 0x78, 0x14, - 0xa8, 0x5a, 0xcc, 0x4e, 0xef, 0x04, 0x69, 0x66, 0x74, 0xfa, 0x73, 0xc7, 0xe8, 0xf5, 0x7e, 0x3f, - 0x8c, 0x3d, 0x5f, 0x49, 0xb5, 0x03, 0xf3, 0x82, 0xa9, 0x19, 0x3f, 0x81, 0x00, 0x61, 0x78, 0x94, - 0x23, 0x60, 0x85, 0x5b, 0xcd, 0x44, 0x78, 0xe0, 0x65, 0x9e, 0xae, 0x7d, 0x9b, 0xca, 0x6b, 0xdf, - 0xf8, 0xd2, 0xf3, 0x92, 0xee, 0x79, 0x70, 0xc1, 0x7c, 0x19, 0x00, 0xe8, 0x6f, 0x3e, 0xcf, 0xf1, - 0x05, 0x4b, 0x9e, 0x24, 0x41, 0x26, 0xac, 0x6e, 0xce, 0xcd, 0x01, 0xf4, 0x08, 0x5a, 0xb9, 0x3e, - 0x98, 0xe7, 0xab, 0x5f, 0x57, 0xd6, 0xe1, 0x7d, 0x58, 0xd7, 0xc0, 0xef, 0x0e, 0x98, 0x2e, 0x45, - 0xbb, 0x0a, 0x8d, 0x6f, 0x41, 0x53, 0x03, 0x0f, 0x06, 0x59, 0xfc, 0x8e, 0xa1, 0xb8, 0x0d, 0x8b, - 0x4c, 0x43, 0xf5, 0x29, 0x1c, 0x6e, 0xe7, 0x74, 0xac, 0xfe, 0xb1, 0x35, 0xa7, 0x62, 0xe2, 0xf2, - 0xa7, 0x92, 0xfa, 0xe5, 0x93, 0x79, 0x91, 0xfb, 0x45, 0x98, 0x15, 0x44, 0x55, 0x2e, 0xb9, 0x42, - 0x54, 0x85, 0x41, 0x63, 0x63, 0x8a, 0xe5, 0x78, 0x2f, 0x21, 0x9f, 0x2b, 0xa2, 0x76, 0x89, 0x22, - 0xac, 0x39, 0x6e, 0xc8, 0xfa, 0xc6, 0xb7, 0x0d, 0xe5, 0xc8, 0xb7, 0x3b, 0x97, 0xb2, 0x54, 0x74, - 0x6a, 0x39, 0x9d, 0x7b, 0xff, 0xf0, 0x06, 0x2c, 0x1d, 0xc5, 0x22, 0x3e, 0xc6, 0x7b, 0xe2, 0x84, - 0xbc, 0x07, 0xb3, 0xf2, 0x95, 0x23, 0xd9, 0x28, 0x3d, 0x7b, 0x44, 0xf5, 0xb7, 0x36, 0x47, 0x3c, - 0x87, 0xa4, 0xab, 0x9f, 0xfd, 0xe3, 0xbf, 0xfe, 0xb0, 0xb6, 0x48, 0xe6, 0xf7, 0x2f, 0x5e, 0xdd, - 0x3f, 0x63, 0x19, 0xc6, 0xad, 0x67, 0xb0, 0x68, 0x3d, 0x4c, 0x23, 0x5b, 0xd6, 0xe3, 0xb2, 0xc2, - 0x7b, 0xb5, 0xd6, 0xf6, 0xd8, 0xa7, 0x67, 0xf4, 0x3a, 0xb2, 0x58, 0x25, 0xd7, 0x24, 0x8b, 0xfc, - 0xcd, 0x19, 0xf9, 0x04, 0x96, 0xdf, 0xc2, 0xca, 0x14, 0x4d, 0x94, 0xec, 0xe4, 0xc4, 0x2a, 0xdf, - 0xdb, 0xb5, 0x6e, 0x8d, 0x46, 0x90, 0x0c, 0x6f, 0x20, 0xc3, 0x75, 0xb2, 0xca, 0x19, 0x8a, 0xca, - 0x17, 0xcd, 0x93, 0xa4, 0xb0, 0x22, 0x5f, 0xf0, 0x3c, 0x53, 0x9e, 0x5b, 0xc8, 0x73, 0x83, 0xac, - 0x71, 0x9e, 0xbe, 0x60, 0x90, 0x33, 0x8d, 0xf1, 0xe2, 0xd8, 0x7c, 0x71, 0x46, 0x6e, 0x8e, 0x7c, - 0x8a, 0x26, 0x58, 0xee, 0x5c, 0xf2, 0x54, 0xcd, 0x1e, 0xe5, 0x19, 0xe3, 0xb8, 0xfa, 0xb5, 0x1a, - 0xf9, 0xa1, 0x88, 0xd1, 0x2b, 0xdf, 0x46, 0x92, 0x17, 0x2e, 0x7f, 0x90, 0x29, 0x64, 0xb8, 0x33, - 0xe9, 0xcb, 0x4d, 0xfa, 0x05, 0x14, 0xe6, 0x26, 0xd9, 0x92, 0xc2, 0x58, 0xaf, 0x35, 0xd5, 0x7b, - 0x50, 0xd2, 0x85, 0x05, 0xf3, 0x99, 0x19, 0xb9, 0x51, 0x71, 0x24, 0xd0, 0xcc, 0xb7, 0xaa, 0x1b, - 0x25, 0xc3, 0x26, 0x32, 0x24, 0x64, 0x45, 0x32, 0xd4, 0x65, 0x63, 0xe4, 0x53, 0x58, 0x2e, 0x3c, - 0xd1, 0x22, 0xb4, 0x30, 0x7d, 0x15, 0xcf, 0xed, 0x5a, 0xcf, 0x8d, 0xc5, 0x91, 0x5c, 0x6f, 0x22, - 0xd7, 0x26, 0x5d, 0x35, 0x66, 0x59, 0x71, 0x7e, 0xd3, 0x79, 0x91, 0xa4, 0x38, 0xcf, 0xe6, 0x6b, - 0xa2, 0x89, 0x78, 0xef, 0x5c, 0xf2, 0x14, 0xa9, 0x34, 0xd7, 0x8a, 0x27, 0xae, 0xd6, 0x14, 0x5f, - 0x68, 0x18, 0x6f, 0xe0, 0x0e, 0x63, 0x7f, 0xb2, 0x31, 0x6f, 0x57, 0xbf, 0xa1, 0x93, 0xcf, 0xf8, - 0x68, 0x0b, 0xb9, 0xae, 0x11, 0x52, 0xe0, 0x1a, 0x67, 0x7d, 0x92, 0x5a, 0x4f, 0x0c, 0x25, 0x53, - 0xdb, 0xaa, 0x2b, 0x1e, 0xf9, 0x55, 0x8e, 0xd4, 0x7c, 0xb5, 0x37, 0x72, 0xa4, 0x71, 0xd6, 0x4f, - 0xc9, 0x53, 0x58, 0x12, 0xee, 0xe2, 0xd9, 0xcf, 0xec, 0x36, 0xf2, 0xdd, 0xa4, 0x24, 0xf7, 0x19, - 0xe6, 0xc4, 0x7e, 0x08, 0x0d, 0x7d, 0xb0, 0x21, 0x4d, 0x63, 0x10, 0xd6, 0x7b, 0xab, 0xd6, 0x88, - 0xd7, 0x34, 0xca, 0x5a, 0xe9, 0xa2, 0x1c, 0x95, 0x78, 0x1b, 0xc3, 0x09, 0x7f, 0x0f, 0x20, 0x7f, - 0x5e, 0x43, 0xae, 0x97, 0x28, 0x6b, 0xcd, 0xb5, 0xaa, 0x9a, 0xd4, 0x43, 0x62, 0x24, 0xbf, 0x42, - 0x96, 0x2c, 0xf2, 0x6a, 0xbd, 0xe9, 0x73, 0x9c, 0xb5, 0xde, 0x8a, 0x0f, 0x72, 0x5a, 0xa3, 0x5f, - 0x62, 0xa8, 0x49, 0xa1, 0x6a, 0xb1, 0xe9, 0x9b, 0x45, 0x3e, 0x02, 0xb1, 0x59, 0x18, 0x4f, 0x40, - 0xb6, 0xaa, 0xb8, 0x54, 0x6e, 0x16, 0xe5, 0xf7, 0x1c, 0xa5, 0xcd, 0x22, 0x7f, 0xb6, 0x41, 0x1e, - 0xe3, 0x1f, 0x52, 0x30, 0x5e, 0x30, 0x10, 0x93, 0x56, 0xf9, 0x39, 0x47, 0xeb, 0xe6, 0xa8, 0xe6, - 0xb4, 0xda, 0xbe, 0x65, 0x06, 0x0b, 0x17, 0xd5, 0x50, 0x9c, 0x05, 0xf3, 0x5e, 0xe2, 0x1c, 0xf9, - 0xf3, 0xb2, 0xbc, 0x85, 0x2c, 0x5b, 0xa4, 0x59, 0x66, 0x99, 0x22, 0x83, 0x57, 0x1c, 0x69, 0x6b, - 0xe2, 0xc9, 0x84, 0x65, 0x6b, 0xd6, 0xcb, 0x8a, 0xd6, 0xf5, 0x8a, 0x16, 0xc9, 0x65, 0x1d, 0xb9, - 0x2c, 0x93, 0x45, 0xed, 0x8d, 0x91, 0x96, 0x30, 0x07, 0x5d, 0x77, 0x6a, 0x99, 0x43, 0xf1, 0xc1, - 0x83, 0xe5, 0x7e, 0x4b, 0xcf, 0x1e, 0x4a, 0xee, 0x57, 0x3f, 0x6c, 0x20, 0xbf, 0x6e, 0xbf, 0x9f, - 0x50, 0xf5, 0xdc, 0x74, 0x6c, 0x01, 0x76, 0x69, 0xa1, 0x8e, 0x2c, 0xd2, 0xa6, 0x3b, 0xc8, 0xf9, - 0x3a, 0xd9, 0x2c, 0x72, 0x96, 0x05, 0xdf, 0xe4, 0x33, 0x07, 0x56, 0x2b, 0x4a, 0x7f, 0x73, 0x09, - 0x46, 0x17, 0x3f, 0xe7, 0x12, 0x8c, 0xab, 0x1d, 0xa6, 0x28, 0xc1, 0x16, 0x45, 0x09, 0x3c, 0xdf, - 0xd7, 0x12, 0xc8, 0x74, 0x23, 0x5f, 0x14, 0xbf, 0xe7, 0xc0, 0x46, 0x75, 0x99, 0x2f, 0x79, 0x5e, - 0xbf, 0x0a, 0x1f, 0x57, 0x80, 0xdc, 0xba, 0x7d, 0x19, 0x9a, 0x94, 0xe6, 0x79, 0x94, 0x66, 0x87, - 0xb6, 0xb8, 0x34, 0x09, 0xe2, 0x56, 0x09, 0xf4, 0x04, 0xef, 0xfe, 0xed, 0x42, 0x5a, 0x62, 0x84, - 0x35, 0xd5, 0xf5, 0xc6, 0xad, 0xdd, 0x31, 0x18, 0xb6, 0xe7, 0x24, 0xeb, 0x72, 0x42, 0xb0, 0xfa, - 0x54, 0x57, 0xe4, 0x4a, 0xf7, 0x90, 0x17, 0xaa, 0x5a, 0xee, 0xa1, 0x54, 0x7b, 0x6b, 0xb9, 0x87, - 0x72, 0x39, 0x6c, 0xc9, 0x3d, 0x20, 0x33, 0x2c, 0x8d, 0x25, 0x1f, 0xe1, 0xb2, 0x91, 0x85, 0x27, - 0xcd, 0xa2, 0x97, 0x49, 0xab, 0x96, 0x8d, 0x5d, 0x5a, 0x52, 0xf2, 0xd2, 0xa2, 0x9e, 0x85, 0x6b, - 0xcf, 0x85, 0x39, 0x85, 0x4e, 0x36, 0x8b, 0x04, 0x14, 0xe5, 0xca, 0xda, 0x41, 0xba, 0x89, 0x44, - 0xaf, 0xd1, 0x05, 0x93, 0x28, 0xa7, 0xd9, 0x81, 0x79, 0xa3, 0x4e, 0x8e, 0x68, 0xff, 0x5e, 0x2e, - 0x0b, 0x6c, 0xdd, 0xa8, 0x6c, 0xb3, 0xbd, 0x18, 0x5d, 0xe6, 0x0c, 0x52, 0x44, 0xd0, 0x3c, 0x7e, - 0x15, 0x16, 0xad, 0x52, 0xb5, 0x5c, 0xf9, 0x55, 0xc5, 0x74, 0xb9, 0xf2, 0x2b, 0xeb, 0xdb, 0x54, - 0x8c, 0x4b, 0x51, 0xf9, 0xa9, 0x44, 0xd1, 0xbc, 0x3e, 0x86, 0x86, 0xae, 0x10, 0xcb, 0xf5, 0x5f, - 0x2c, 0x1a, 0xbb, 0x8c, 0x87, 0x35, 0x07, 0x4f, 0x78, 0xe7, 0x4e, 0xdc, 0xeb, 0x48, 0x7d, 0x19, - 0xf5, 0x4f, 0xb9, 0xbe, 0xca, 0x45, 0x60, 0xb9, 0xbe, 0xaa, 0x0a, 0xa6, 0x2c, 0x7d, 0x75, 0x11, - 0x41, 0x8f, 0x21, 0x81, 0xe5, 0x42, 0xdd, 0x51, 0x1e, 0xd1, 0x54, 0x57, 0x59, 0xe5, 0x11, 0xcd, - 0x88, 0x82, 0x25, 0x3b, 0x66, 0x14, 0xfc, 0xbc, 0x30, 0xcc, 0x6d, 0x4b, 0xb8, 0x7b, 0x71, 0xb3, - 0x68, 0xd9, 0xad, 0x55, 0x7e, 0x64, 0xd9, 0xad, 0x5d, 0xc2, 0x53, 0x72, 0xf7, 0x22, 0xdd, 0x47, - 0x3e, 0x80, 0x39, 0x55, 0x0e, 0x92, 0x1b, 0x6d, 0xa1, 0x10, 0xa6, 0xd5, 0x2c, 0x37, 0x48, 0xaa, - 0x96, 0xe1, 0x7a, 0xbe, 0x8f, 0x54, 0xe5, 0x44, 0x18, 0xc5, 0x21, 0xf9, 0x44, 0x94, 0xeb, 0x4a, - 0xf2, 0x89, 0xa8, 0xaa, 0x26, 0xb1, 0x26, 0x42, 0x78, 0x2e, 0xcd, 0xe3, 0x2f, 0x1d, 0x4c, 0x45, - 0x8f, 0xaf, 0xed, 0x20, 0xaf, 0x5c, 0xa1, 0x0c, 0x44, 0x08, 0xf4, 0xea, 0x95, 0x0b, 0x47, 0xe8, - 0x1d, 0x14, 0x93, 0xd2, 0x6d, 0xb5, 0x99, 0x62, 0x37, 0x5f, 0xa0, 0xeb, 0x2a, 0x12, 0x2e, 0xf4, - 0x5f, 0x38, 0xe2, 0x2f, 0xf4, 0x8c, 0xa1, 0x4b, 0xf6, 0x26, 0x14, 0x40, 0x09, 0xbc, 0x3f, 0x31, - 0xbe, 0x14, 0xf7, 0x36, 0x8a, 0x7b, 0x8b, 0xde, 0x18, 0x23, 0x2e, 0x17, 0x36, 0x84, 0x6b, 0x66, - 0x0d, 0xc8, 0xdb, 0x83, 0xc8, 0x37, 0x0e, 0x64, 0x15, 0xe5, 0x21, 0xb9, 0xa9, 0x14, 0x2b, 0x16, - 0x54, 0x54, 0x43, 0x71, 0x0b, 0x78, 0x22, 0x5b, 0x4f, 0x03, 0x2f, 0x3b, 0xe5, 0x54, 0x39, 0xb7, - 0xdf, 0x71, 0xf2, 0xf2, 0x03, 0x7b, 0x18, 0x82, 0xf1, 0x76, 0x91, 0xb6, 0x55, 0xe5, 0x31, 0x86, - 0xf5, 0x6b, 0xc8, 0xfa, 0x65, 0x7a, 0xc7, 0x64, 0x2d, 0xff, 0x13, 0x43, 0x47, 0x19, 0x6c, 0x69, - 0x3e, 0x33, 0x0a, 0x60, 0x8c, 0x62, 0x88, 0x3c, 0x44, 0x18, 0x5d, 0x57, 0x91, 0x87, 0x08, 0x63, - 0xaa, 0x29, 0xec, 0x10, 0xe1, 0x89, 0x46, 0x44, 0xf3, 0xee, 0x0c, 0x03, 0x9f, 0x0b, 0xf1, 0x87, - 0x4e, 0xa9, 0x7e, 0xc3, 0xa8, 0x2c, 0x20, 0x77, 0x47, 0xf0, 0x29, 0xd7, 0x57, 0xb4, 0x5e, 0x9c, - 0x04, 0xf5, 0x0a, 0x92, 0xfd, 0x81, 0x75, 0x4f, 0x6e, 0x96, 0x5b, 0xe4, 0xc1, 0xcb, 0xd8, 0x72, - 0x8c, 0x2b, 0x49, 0x24, 0x53, 0x07, 0xf4, 0x7a, 0xa5, 0x44, 0xbe, 0x97, 0xc9, 0x93, 0xf5, 0x4a, - 0xf1, 0xea, 0xd5, 0x4c, 0xdb, 0x54, 0x5e, 0x92, 0x9a, 0x69, 0x9b, 0xea, 0x5b, 0x5b, 0x3b, 0x6d, - 0x73, 0xc6, 0x32, 0x71, 0x8b, 0xea, 0x4b, 0x06, 0x17, 0xb0, 0x72, 0x3c, 0x92, 0xe9, 0xf1, 0xcf, - 0xcc, 0x54, 0x86, 0xb0, 0x14, 0x99, 0xa6, 0x05, 0xa6, 0x7c, 0xb0, 0x17, 0xa2, 0xfc, 0xd4, 0xbc, - 0x24, 0x25, 0x3b, 0xa3, 0xaf, 0x4f, 0xcb, 0x7c, 0x2b, 0xef, 0x57, 0x6d, 0xbe, 0xc6, 0xd9, 0x1a, - 0xff, 0xb0, 0x0c, 0xe7, 0x3b, 0x04, 0x62, 0x9f, 0xaf, 0xf1, 0x0f, 0x12, 0x68, 0xa7, 0x50, 0x71, - 0x35, 0x3a, 0xd9, 0xe1, 0x7a, 0x17, 0x19, 0xdf, 0xa0, 0x1b, 0xe5, 0xc3, 0x35, 0xe7, 0xcd, 0x59, - 0x7f, 0x1f, 0x56, 0x0b, 0x59, 0x9b, 0x67, 0xc4, 0xdb, 0x32, 0xf8, 0x42, 0xca, 0x46, 0x31, 0xcf, - 0x30, 0x83, 0x52, 0xb8, 0xef, 0x24, 0xbb, 0x55, 0x27, 0x55, 0xeb, 0x3a, 0x71, 0xdc, 0x99, 0x59, - 0x6e, 0xfb, 0x64, 0xa3, 0x74, 0x90, 0x55, 0xe7, 0xbc, 0xdf, 0x75, 0xf0, 0xae, 0x6b, 0xc4, 0x75, - 0x2b, 0xb9, 0x5b, 0x95, 0x2a, 0xb9, 0xb2, 0x18, 0x72, 0x3b, 0x20, 0x37, 0x8b, 0xf9, 0x94, 0x92, - 0x38, 0xe7, 0x98, 0xbb, 0x32, 0x2f, 0x4d, 0xad, 0x6c, 0x4e, 0xc5, 0x6d, 0xea, 0xc8, 0x74, 0x47, - 0x31, 0x89, 0x23, 0xf3, 0x11, 0x8a, 0xd3, 0x0f, 0xec, 0xbf, 0xf4, 0x64, 0xb1, 0xbc, 0x5d, 0x31, - 0xea, 0xab, 0xb0, 0x7e, 0x0e, 0x59, 0x6f, 0x93, 0x1b, 0x85, 0xf1, 0x16, 0x44, 0x10, 0xa7, 0x12, - 0xe3, 0x72, 0xce, 0x3c, 0x95, 0x94, 0x6e, 0x80, 0xad, 0x53, 0x49, 0xf9, 0x12, 0xb6, 0x74, 0x2a, - 0xf1, 0x38, 0x0a, 0x3a, 0x30, 0x92, 0xc1, 0x4a, 0xf1, 0x92, 0xcc, 0x58, 0xca, 0xd5, 0xd7, 0x67, - 0xc6, 0x52, 0x1e, 0x71, 0x63, 0x50, 0x38, 0x74, 0x75, 0x33, 0x71, 0xf1, 0xb0, 0x2f, 0x6b, 0x9e, - 0x49, 0x06, 0xcb, 0x85, 0x0b, 0x2c, 0x63, 0x2e, 0x2b, 0x6f, 0xb6, 0x26, 0xe0, 0x69, 0xbb, 0x0f, - 0xcd, 0x73, 0x80, 0x64, 0xf8, 0x32, 0x7a, 0x0a, 0xab, 0x15, 0x97, 0x51, 0xc6, 0xd1, 0x7f, 0xe4, - 0x4d, 0x55, 0xab, 0x2c, 0x9d, 0x75, 0x29, 0x63, 0xa7, 0xe7, 0x72, 0xde, 0x09, 0x13, 0x9c, 0xfb, - 0xc6, 0x78, 0xe5, 0xdf, 0x85, 0x2c, 0x53, 0xb4, 0xee, 0xff, 0x5a, 0x3b, 0x23, 0xdb, 0x2b, 0xb7, - 0x06, 0xcd, 0x52, 0x5e, 0xcd, 0x84, 0xb0, 0x64, 0x8b, 0x6a, 0x64, 0x86, 0xaa, 0xee, 0xd1, 0x2e, - 0x1d, 0xa1, 0xbd, 0x66, 0x34, 0xbb, 0x4f, 0x90, 0x76, 0x04, 0x8b, 0xd6, 0x0d, 0xa7, 0x61, 0xae, - 0x15, 0x77, 0xa7, 0x93, 0xdb, 0x4f, 0x51, 0x9f, 0x69, 0x16, 0xf7, 0x85, 0x43, 0x5c, 0x29, 0xde, - 0xa8, 0x92, 0x9d, 0x4a, 0x96, 0xf9, 0xb5, 0xe9, 0xcf, 0xcf, 0x35, 0x35, 0xb8, 0xca, 0x2b, 0xd9, - 0x0a, 0xae, 0xf6, 0x65, 0xed, 0xe5, 0xf3, 0x78, 0x09, 0x53, 0x74, 0x46, 0xc5, 0x5b, 0xcb, 0x93, - 0xf8, 0xec, 0x2c, 0x64, 0xa4, 0x3c, 0xa2, 0xc2, 0xb5, 0xe6, 0x04, 0x63, 0xb6, 0xf6, 0xbe, 0x9c, - 0xbd, 0x37, 0xc8, 0x62, 0xb5, 0x6e, 0xbe, 0x8f, 0xdb, 0x4f, 0xa1, 0xe6, 0xc1, 0xda, 0x7e, 0xaa, - 0x4b, 0x36, 0x5a, 0x74, 0x1c, 0xca, 0x88, 0x7d, 0xe8, 0x5c, 0xe2, 0x89, 0x4a, 0x89, 0xb4, 0x33, - 0x83, 0x95, 0x98, 0xaf, 0xfd, 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x9d, 0xf2, 0x7f, 0x34, 0xf9, - 0x56, 0x00, 0x00, + 0x00, 0x39, 0xe5, 0x14, 0xe4, 0x62, 0x20, 0xc8, 0x21, 0xc8, 0xc1, 0xc8, 0x35, 0x08, 0x7c, 0x0a, + 0x10, 0xf8, 0x92, 0x53, 0x82, 0x1c, 0x02, 0x24, 0x87, 0x00, 0xb9, 0xe4, 0x14, 0xd4, 0xab, 0x9f, + 0xae, 0xea, 0xee, 0x19, 0x0e, 0xed, 0xb5, 0x72, 0xd9, 0x9d, 0x7e, 0xf5, 0xea, 0xbd, 0x57, 0xaf, + 0x5e, 0xbd, 0x7a, 0xf5, 0xea, 0x15, 0xa1, 0x91, 0xf4, 0xbb, 0x7b, 0xfd, 0x24, 0xce, 0x62, 0x32, + 0x73, 0xd6, 0xcd, 0x92, 0x7e, 0xb7, 0xb5, 0x75, 0x16, 0xc7, 0x67, 0x21, 0xdb, 0xf7, 0xfa, 0xc1, + 0xbe, 0x17, 0x45, 0x71, 0xe6, 0x65, 0x41, 0x1c, 0xa5, 0x02, 0xab, 0xb5, 0x23, 0x5b, 0xf1, 0xab, + 0x33, 0x38, 0xdd, 0xcf, 0x82, 0x1e, 0x4b, 0x33, 0xaf, 0xd7, 0x17, 0x08, 0x74, 0x05, 0x96, 0x8e, + 0x58, 0xf6, 0x30, 0x3a, 0x8d, 0x5d, 0xf6, 0xc9, 0x80, 0xa5, 0x19, 0xfd, 0xeb, 0x3a, 0x2c, 0x6b, + 0x50, 0xda, 0x8f, 0xa3, 0x94, 0x91, 0x0d, 0x98, 0x19, 0xf4, 0x79, 0xd7, 0xa6, 0x73, 0xcb, 0xb9, + 0xd3, 0x70, 0xe5, 0x17, 0xd9, 0x87, 0x55, 0xef, 0xc2, 0x0b, 0x42, 0xaf, 0x13, 0xb2, 0x36, 0x7b, + 0xda, 0x3d, 0xf7, 0xa2, 0x33, 0x96, 0x36, 0x6b, 0xb7, 0x9c, 0x3b, 0x53, 0x2e, 0xd1, 0x4d, 0x6f, + 0xa9, 0x16, 0xf2, 0x45, 0xb8, 0xc6, 0x22, 0x0e, 0xf2, 0x0d, 0xf4, 0x29, 0x44, 0x5f, 0x91, 0x0d, + 0x39, 0xf2, 0xeb, 0xb0, 0xe1, 0xb3, 0x53, 0x6f, 0x10, 0x66, 0xed, 0xd3, 0x38, 0x61, 0x4f, 0xdb, + 0xfd, 0x24, 0xbe, 0x08, 0x7c, 0x96, 0x34, 0xeb, 0x28, 0xc5, 0x9a, 0x6c, 0x7d, 0x9b, 0x37, 0x3e, + 0x92, 0x6d, 0xe4, 0x1e, 0xac, 0xeb, 0x5e, 0x81, 0x97, 0xb5, 0xbb, 0x83, 0x24, 0x61, 0x51, 0x77, + 0xd8, 0x9c, 0xc6, 0x4e, 0xab, 0xaa, 0x53, 0xe0, 0x65, 0x87, 0xb2, 0x89, 0x7c, 0x08, 0x2b, 0xe9, + 0xa0, 0x93, 0x0e, 0xd3, 0x8c, 0xf5, 0xda, 0x69, 0xe6, 0x65, 0x83, 0xb4, 0x39, 0x73, 0x6b, 0xea, + 0xce, 0xfc, 0xbd, 0x97, 0xf6, 0x84, 0x9e, 0xf7, 0x0a, 0x2a, 0xd9, 0x3b, 0x56, 0xf8, 0xc7, 0x88, + 0xfe, 0x56, 0x94, 0x25, 0x43, 0x77, 0x39, 0xb5, 0xa1, 0xe4, 0x5d, 0x58, 0x4c, 0xfa, 0xdd, 0x36, + 0x8b, 0xfc, 0x7e, 0x1c, 0x44, 0x59, 0xda, 0x9c, 0x45, 0xaa, 0x77, 0x47, 0x51, 0x75, 0xfb, 0xdd, + 0xb7, 0x14, 0xae, 0x20, 0xb9, 0x90, 0x18, 0xa0, 0xd6, 0x7d, 0x58, 0xab, 0x62, 0x4c, 0x56, 0x60, + 0xea, 0x31, 0x1b, 0xca, 0xd9, 0xe1, 0x3f, 0xc9, 0x1a, 0x4c, 0x5f, 0x78, 0xe1, 0x80, 0xe1, 0x64, + 0xcc, 0xb9, 0xe2, 0xe3, 0xcd, 0xda, 0x1b, 0x4e, 0xeb, 0x04, 0xae, 0x95, 0xd8, 0x54, 0x10, 0xb8, + 0x6b, 0x12, 0x98, 0xbf, 0xb7, 0xaa, 0x44, 0x76, 0x1f, 0x1d, 0xaa, 0xbe, 0x06, 0x55, 0xba, 0x0b, + 0x3b, 0x47, 0x2c, 0x3b, 0x8c, 0x7b, 0xbd, 0x41, 0x14, 0x74, 0xd1, 0x08, 0x5d, 0x16, 0x7a, 0x43, + 0x96, 0xa4, 0xca, 0xb2, 0xde, 0x85, 0xb5, 0xaa, 0x76, 0xd2, 0x84, 0x59, 0x39, 0xf7, 0xc8, 0x7f, + 0xce, 0x55, 0x9f, 0x64, 0x0b, 0x1a, 0xdd, 0x38, 0x8a, 0x58, 0x37, 0x63, 0xbe, 0x1c, 0x48, 0x0e, + 0xa0, 0xbf, 0x53, 0x83, 0x5b, 0xa3, 0x79, 0x4a, 0xd3, 0xfd, 0x14, 0x36, 0xba, 0x26, 0x42, 0x3b, + 0x91, 0x18, 0x4d, 0x07, 0xa7, 0xe2, 0xd0, 0x98, 0x8a, 0xb1, 0x94, 0xf6, 0x2a, 0x5b, 0xc5, 0x24, + 0xad, 0x77, 0xab, 0xda, 0x5a, 0xa7, 0xd0, 0x1a, 0xdd, 0xa9, 0x42, 0xe5, 0xf7, 0x6c, 0x95, 0x6f, + 0x29, 0xd1, 0xaa, 0x88, 0x98, 0xba, 0xff, 0x32, 0x6c, 0x1e, 0xb1, 0x88, 0x25, 0x41, 0x57, 0x1b, + 0x87, 0xd4, 0x39, 0xd7, 0xa0, 0xb6, 0x49, 0xc9, 0x2a, 0x07, 0xd0, 0x16, 0x34, 0xcb, 0x1d, 0xc5, + 0x70, 0xe9, 0x06, 0xac, 0x1d, 0xb1, 0x4c, 0xc3, 0xf5, 0x2c, 0xfe, 0xc4, 0x81, 0x75, 0x6c, 0x48, + 0x3b, 0xe9, 0x50, 0x34, 0x48, 0x55, 0xff, 0x1a, 0x5c, 0xd3, 0xa4, 0x53, 0xb5, 0x8c, 0x84, 0x96, + 0x5f, 0x33, 0xb4, 0x5c, 0xee, 0x99, 0x2f, 0xa6, 0xd4, 0x5c, 0x4d, 0xf9, 0x9a, 0x94, 0xe0, 0xd6, + 0x21, 0xac, 0x57, 0xa2, 0x5e, 0xc5, 0xfe, 0x69, 0x13, 0x36, 0x8e, 0x58, 0x66, 0x98, 0xb1, 0x61, + 0xa0, 0xf3, 0x06, 0x98, 0xdb, 0x65, 0x9a, 0x79, 0x49, 0x96, 0xdb, 0xa5, 0xfc, 0x24, 0xcf, 0xc3, + 0x52, 0x18, 0xa4, 0x19, 0x8b, 0xda, 0x9e, 0xef, 0x27, 0x2c, 0x15, 0x2e, 0xaf, 0xe1, 0x2e, 0x0a, + 0xe8, 0x81, 0x00, 0xd2, 0xbf, 0x75, 0xf8, 0xc4, 0x14, 0x58, 0x49, 0x65, 0xbd, 0x03, 0x8d, 0xdc, + 0x2b, 0x08, 0x25, 0xed, 0x19, 0x4a, 0xaa, 0xea, 0xb3, 0x57, 0x70, 0x0d, 0x39, 0x81, 0xd6, 0x77, + 0x61, 0xe9, 0x59, 0x2f, 0xe8, 0x37, 0xa0, 0x25, 0x6d, 0x43, 0x79, 0xe4, 0x77, 0xbd, 0x1e, 0x53, + 0x76, 0xd5, 0x82, 0x39, 0xe5, 0xc0, 0x25, 0x0f, 0xfd, 0x4d, 0xb7, 0xe1, 0x46, 0x65, 0x4f, 0x69, + 0x58, 0xfb, 0xb0, 0x7a, 0xc4, 0x32, 0xed, 0xe6, 0x15, 0xc5, 0x91, 0x5e, 0x80, 0xbe, 0x8e, 0x96, + 0x68, 0x74, 0x90, 0x2a, 0xdc, 0x82, 0x46, 0xbe, 0x89, 0x48, 0xdb, 0xd6, 0x00, 0x7a, 0x0f, 0xcd, + 0x54, 0xf5, 0x7a, 0xef, 0xe4, 0x91, 0xcb, 0x44, 0xb7, 0xeb, 0x30, 0x17, 0x67, 0xfd, 0x76, 0x37, + 0xf6, 0x95, 0xe8, 0xb3, 0x71, 0xd6, 0x3f, 0x8c, 0x7d, 0x26, 0x4d, 0xc3, 0xe8, 0xa3, 0x4d, 0xe3, + 0xcf, 0xc5, 0x54, 0xda, 0x4d, 0x52, 0x8e, 0x6f, 0x41, 0x43, 0x11, 0x54, 0x53, 0xf9, 0xb2, 0x31, + 0x95, 0x55, 0x7d, 0xf6, 0xde, 0x13, 0x1c, 0xe5, 0x4c, 0xce, 0x49, 0x01, 0xd2, 0xd6, 0x57, 0x61, + 0xd1, 0x6a, 0xba, 0xcc, 0xb2, 0x1b, 0xe6, 0x94, 0xbd, 0x0e, 0x1b, 0x0f, 0x82, 0xd4, 0xdc, 0x71, + 0x27, 0x99, 0xae, 0x8f, 0x61, 0xe9, 0x91, 0x17, 0x24, 0xe9, 0xf1, 0xa0, 0xdf, 0x8f, 0xd1, 0xbc, + 0x5f, 0x80, 0xe5, 0x7c, 0x5b, 0xef, 0xf3, 0x36, 0xd9, 0x69, 0x49, 0x83, 0xb1, 0x07, 0x79, 0x0e, + 0x16, 0xd5, 0x76, 0x2e, 0xd0, 0x84, 0x48, 0x0b, 0x12, 0x88, 0x48, 0xf4, 0xb3, 0xba, 0xa5, 0x3a, + 0x2b, 0xb0, 0x20, 0x50, 0x8f, 0x3c, 0x1d, 0x56, 0xe0, 0x6f, 0xd3, 0x10, 0x6a, 0xf6, 0x76, 0xd0, + 0x84, 0xd9, 0x0b, 0x96, 0x74, 0xe2, 0x94, 0x61, 0xcc, 0x30, 0xe7, 0xaa, 0x4f, 0x2e, 0xc8, 0x20, + 0x0d, 0xa2, 0xb3, 0x76, 0xea, 0x45, 0x7e, 0x27, 0x7e, 0x8a, 0x11, 0xc2, 0x9c, 0xbb, 0x80, 0xc0, + 0x63, 0x01, 0x23, 0xbb, 0xb0, 0x70, 0x9e, 0x65, 0xfd, 0x36, 0x0f, 0x5d, 0xe2, 0x41, 0x26, 0x03, + 0x82, 0x79, 0x0e, 0x3b, 0x11, 0x20, 0xbe, 0xb0, 0x11, 0x65, 0x90, 0xb2, 0xc4, 0x3b, 0x63, 0x51, + 0xd6, 0x9c, 0x11, 0x0b, 0x9b, 0x43, 0xdf, 0x57, 0x40, 0xb2, 0x0d, 0x80, 0x68, 0xfd, 0x24, 0x7e, + 0x3a, 0x6c, 0xce, 0x0a, 0xd3, 0xe3, 0x90, 0x47, 0x1c, 0xc0, 0xf5, 0xd7, 0xf1, 0x52, 0xa6, 0x42, + 0x8f, 0x80, 0xa5, 0xcd, 0x39, 0xa1, 0x3f, 0x0e, 0x3e, 0xd4, 0x50, 0xd2, 0xe6, 0x71, 0x87, 0xd4, + 0x7a, 0xdb, 0x4b, 0x53, 0x96, 0xa5, 0xcd, 0x06, 0x1a, 0xd0, 0xeb, 0x15, 0x06, 0x54, 0x88, 0x3f, + 0x64, 0xbf, 0x03, 0xec, 0xa6, 0xe3, 0x0f, 0x0b, 0xca, 0xe3, 0x2d, 0x6f, 0x90, 0x9d, 0xb3, 0x28, + 0xe3, 0xbb, 0x07, 0x67, 0xd2, 0x0f, 0x9a, 0x80, 0xba, 0x59, 0xb1, 0x1a, 0x0e, 0xfa, 0x41, 0xeb, + 0x23, 0x1e, 0x5c, 0x94, 0xa9, 0x56, 0x98, 0xe0, 0x4b, 0xb6, 0x2b, 0xd9, 0x50, 0xc2, 0xda, 0x76, + 0x64, 0x9a, 0xe6, 0x13, 0x58, 0x39, 0x62, 0xd9, 0x49, 0xd0, 0x7d, 0xcc, 0x92, 0x09, 0x8c, 0x92, + 0xdc, 0x81, 0x3a, 0xb7, 0x28, 0xc9, 0x60, 0x4d, 0xef, 0x84, 0x32, 0x62, 0xe3, 0x8c, 0x5c, 0xc4, + 0xe0, 0x73, 0x81, 0x9a, 0x6b, 0x67, 0xc3, 0xbe, 0xb0, 0x8b, 0x86, 0xdb, 0x40, 0xc8, 0xc9, 0xb0, + 0xcf, 0xe8, 0x07, 0xb0, 0x60, 0x76, 0xe2, 0x4e, 0xc3, 0x67, 0x61, 0xd0, 0x0b, 0x32, 0x96, 0x28, + 0xa7, 0xa1, 0x01, 0xdc, 0x1e, 0xf9, 0x14, 0x49, 0x3b, 0xc6, 0xdf, 0x7c, 0xbd, 0x7d, 0x32, 0x88, + 0x33, 0x45, 0x5b, 0x7c, 0xd0, 0x1f, 0xd5, 0x60, 0x49, 0x0d, 0x47, 0x1a, 0xb3, 0x92, 0xd9, 0xb9, + 0x54, 0xe6, 0x5d, 0x58, 0x08, 0xbd, 0x34, 0x6b, 0x0f, 0xfa, 0xbe, 0xa7, 0x42, 0x9b, 0x29, 0x77, + 0x9e, 0xc3, 0xde, 0x17, 0x20, 0x6e, 0xd1, 0x2a, 0x72, 0xc5, 0xb5, 0x25, 0xb9, 0x2f, 0x74, 0xcd, + 0xc1, 0x10, 0xa8, 0xf3, 0x3e, 0x68, 0xed, 0x8e, 0x8b, 0xbf, 0x39, 0xec, 0x3c, 0x38, 0x3b, 0x47, + 0xeb, 0x76, 0x5c, 0xfc, 0xcd, 0x67, 0x30, 0x8c, 0x9f, 0xa0, 0x2d, 0x3b, 0x2e, 0xff, 0xc9, 0x21, + 0x9d, 0xc0, 0x47, 0xd3, 0x75, 0x5c, 0xfe, 0x93, 0x43, 0xbc, 0xf4, 0x31, 0x1a, 0xaa, 0xe3, 0xf2, + 0x9f, 0x3c, 0xea, 0xbf, 0x88, 0xc3, 0x41, 0x8f, 0x35, 0x1b, 0x08, 0x94, 0x5f, 0xe4, 0x06, 0x34, + 0xfa, 0x49, 0xd0, 0x65, 0x6d, 0x2f, 0x3b, 0x47, 0x63, 0x72, 0xdc, 0x39, 0x04, 0x1c, 0x64, 0xe7, + 0x74, 0x15, 0xae, 0xe9, 0x89, 0xd6, 0xde, 0xf3, 0x43, 0x98, 0x95, 0x90, 0xb1, 0x93, 0xfe, 0x0a, + 0xcc, 0x66, 0x02, 0xad, 0x59, 0xc3, 0x55, 0xa0, 0x0d, 0xcb, 0xd6, 0xb4, 0xab, 0xd0, 0xe8, 0x37, + 0x80, 0x98, 0xdc, 0xe4, 0x44, 0xdc, 0xcd, 0xe9, 0x08, 0x77, 0xbc, 0x6c, 0xd3, 0x49, 0x73, 0x02, + 0x9f, 0xe2, 0x66, 0xf4, 0x5e, 0xe2, 0x73, 0x47, 0x12, 0x3f, 0xfe, 0x5c, 0x4d, 0xf3, 0x3b, 0xb0, + 0xa8, 0x19, 0x3f, 0xcc, 0x58, 0x8f, 0x2b, 0xdc, 0xeb, 0xc5, 0x83, 0x28, 0x43, 0x9e, 0x8e, 0x2b, + 0xbf, 0xb8, 0x05, 0xa2, 0x7e, 0x91, 0xa5, 0xe3, 0x8a, 0x0f, 0xb2, 0x04, 0xb5, 0xc0, 0x97, 0x87, + 0xa7, 0x5a, 0xe0, 0xd3, 0xff, 0x71, 0xe0, 0x9a, 0x31, 0x90, 0x2b, 0x1b, 0x65, 0xc9, 0xe2, 0x6a, + 0x15, 0x16, 0x77, 0x17, 0xea, 0x9d, 0xc0, 0xe7, 0x67, 0x36, 0xae, 0xd7, 0x75, 0x45, 0xce, 0x1a, + 0x87, 0x8b, 0x28, 0x1c, 0xd5, 0x4b, 0x1f, 0xa7, 0xcd, 0xfa, 0x58, 0x54, 0x8e, 0x52, 0x5a, 0x0f, + 0xd3, 0xe5, 0xf5, 0x60, 0xeb, 0x72, 0xa6, 0xa8, 0x4b, 0x11, 0xad, 0x6a, 0xda, 0xda, 0xf2, 0xba, + 0x00, 0x39, 0x70, 0xec, 0xb4, 0x7e, 0x05, 0x20, 0xd6, 0x98, 0xd2, 0xfe, 0xae, 0x97, 0x84, 0xd6, + 0x26, 0x68, 0x20, 0xd3, 0x6f, 0x63, 0xa8, 0x61, 0x32, 0x97, 0xca, 0xbf, 0x67, 0xd1, 0x14, 0xb6, + 0x48, 0x4a, 0x34, 0x53, 0x8b, 0xd8, 0x6b, 0x48, 0xec, 0xa0, 0xdb, 0xe5, 0x53, 0x6f, 0x1c, 0xcc, + 0xc7, 0xee, 0xe1, 0x1f, 0xc0, 0xac, 0xec, 0x21, 0xcd, 0x42, 0x20, 0xd4, 0x02, 0x9f, 0x7c, 0x15, + 0xc0, 0xd8, 0x87, 0xc4, 0xb8, 0x6e, 0x28, 0x19, 0x64, 0x27, 0x65, 0x0d, 0xc8, 0xce, 0x40, 0xa7, + 0xa7, 0xb0, 0x5a, 0x81, 0xc2, 0x45, 0xd1, 0xc7, 0x6a, 0x29, 0x8a, 0xfa, 0x26, 0x3b, 0x30, 0x9f, + 0xc5, 0x99, 0x17, 0xb6, 0xf3, 0x1d, 0xc2, 0x71, 0x01, 0x41, 0x1f, 0x70, 0x08, 0x3a, 0xa8, 0x38, + 0x14, 0x96, 0xcb, 0x1d, 0x54, 0x1c, 0xfa, 0xd4, 0xc3, 0xc0, 0xcb, 0x1a, 0xb4, 0x54, 0xe1, 0xb8, + 0x29, 0xfb, 0x22, 0xcc, 0x79, 0xa2, 0x8b, 0x1a, 0xd8, 0x72, 0x61, 0x60, 0xae, 0x46, 0xa0, 0x04, + 0x77, 0xa0, 0xc3, 0x38, 0x3a, 0x0d, 0xce, 0x94, 0x75, 0xbc, 0x80, 0xce, 0x4a, 0xc1, 0xf2, 0x98, + 0xc4, 0xf7, 0x32, 0x0f, 0xb9, 0x2d, 0xb8, 0xf8, 0x9b, 0xfe, 0xb6, 0x03, 0x2b, 0x8f, 0xe2, 0x24, + 0x3b, 0x8d, 0xc3, 0x20, 0x96, 0xe1, 0x3d, 0x0f, 0x47, 0x54, 0xf8, 0x2f, 0xe3, 0x48, 0xf9, 0xc9, + 0x3d, 0x64, 0x37, 0x0e, 0x22, 0x61, 0xab, 0x35, 0xa9, 0xa0, 0x38, 0x88, 0xb8, 0xa9, 0x92, 0x5b, + 0x30, 0xef, 0xb3, 0xb4, 0x9b, 0x04, 0x7d, 0x7e, 0x9c, 0x93, 0x6e, 0xc1, 0x04, 0x71, 0xc2, 0x1d, + 0x2f, 0xf4, 0xa2, 0x2e, 0x93, 0x9e, 0x5d, 0x7d, 0xd2, 0x75, 0x74, 0x57, 0x5a, 0x12, 0xe3, 0x64, + 0x6d, 0x83, 0xe5, 0x50, 0xfe, 0x1f, 0x34, 0xfa, 0x0a, 0x28, 0xcd, 0xaf, 0xa9, 0xf7, 0xea, 0xc2, + 0x70, 0xdc, 0x1c, 0x95, 0x6e, 0xf1, 0xd8, 0x3f, 0xa7, 0x77, 0x3c, 0xe8, 0xf5, 0xbc, 0x64, 0xa8, + 0xb8, 0x45, 0x50, 0x3f, 0x8c, 0x83, 0x88, 0x2b, 0x8a, 0x0f, 0x4a, 0x05, 0x6f, 0xfc, 0xb7, 0x29, + 0x7a, 0xcd, 0x12, 0xdd, 0xd4, 0xd6, 0x94, 0xad, 0xad, 0x9b, 0x00, 0x7d, 0x96, 0x74, 0x59, 0x94, + 0x79, 0x67, 0x6a, 0xc4, 0x06, 0x84, 0x9e, 0x03, 0x79, 0xef, 0xf4, 0x34, 0x0c, 0x22, 0xc6, 0xd9, + 0x4a, 0x61, 0xc6, 0x68, 0x7f, 0xb4, 0x0c, 0x36, 0xa7, 0xa9, 0x12, 0xa7, 0xef, 0xc0, 0xb5, 0xf7, + 0xa2, 0x0a, 0x46, 0x8a, 0x9c, 0x33, 0x8e, 0x5c, 0xad, 0x44, 0xee, 0x9b, 0xb0, 0x60, 0x08, 0x9e, + 0x92, 0x37, 0xa0, 0x21, 0x65, 0xd4, 0x07, 0x85, 0x96, 0xf6, 0x06, 0xa5, 0x11, 0xba, 0x39, 0x32, + 0xfd, 0x13, 0x07, 0xe6, 0x73, 0xc9, 0x52, 0xf2, 0x3a, 0x4c, 0x73, 0x75, 0x2b, 0x2a, 0x37, 0x35, + 0x95, 0x1c, 0x67, 0x0f, 0xff, 0x15, 0x71, 0xa1, 0x40, 0x6e, 0x1d, 0x03, 0xe4, 0xc0, 0x8a, 0xb0, + 0x6e, 0xdf, 0x0e, 0xeb, 0xae, 0x97, 0xa9, 0x2a, 0xd1, 0x8c, 0xc8, 0xee, 0x1f, 0xea, 0xfc, 0xb8, + 0x57, 0x61, 0x2c, 0xd2, 0x06, 0x5f, 0x86, 0x79, 0xb1, 0x16, 0xb8, 0x07, 0x50, 0x02, 0x2f, 0xe4, + 0xa9, 0x8d, 0x20, 0x72, 0x01, 0xd7, 0x06, 0xb6, 0x93, 0x57, 0x61, 0x11, 0x85, 0x6d, 0xc7, 0x42, + 0x21, 0x72, 0x61, 0xdb, 0x1d, 0x16, 0x10, 0x45, 0xaa, 0x8c, 0xf4, 0x61, 0xdd, 0xea, 0xd2, 0x4e, + 0x85, 0x08, 0x72, 0x93, 0xfa, 0x9a, 0x11, 0x4a, 0x8f, 0x92, 0x52, 0x28, 0x4b, 0x12, 0x94, 0x6d, + 0x42, 0x75, 0xab, 0xdd, 0x72, 0x0b, 0xd9, 0x87, 0x05, 0xc9, 0x11, 0x35, 0x23, 0xb7, 0x38, 0x5b, + 0xc6, 0x79, 0xd1, 0x11, 0x11, 0x48, 0x0f, 0xd6, 0xcc, 0x0e, 0x5a, 0xc2, 0x69, 0xec, 0xf8, 0xd5, + 0xc9, 0x25, 0x8c, 0x4a, 0x02, 0x92, 0x6e, 0xa9, 0xa1, 0xf5, 0xab, 0xd0, 0x1c, 0x35, 0xa0, 0x8a, + 0x69, 0x7f, 0xd1, 0x9e, 0xf6, 0xb5, 0x0a, 0x93, 0x4c, 0xcd, 0x04, 0xe2, 0x47, 0xb0, 0x39, 0x42, + 0x98, 0x2b, 0x64, 0x1d, 0x0c, 0x4b, 0x35, 0xad, 0xe9, 0x5f, 0x1c, 0x68, 0x1d, 0xf8, 0x7e, 0xc9, + 0x39, 0xe5, 0x49, 0x82, 0xcf, 0xd9, 0xe5, 0x92, 0x7d, 0x58, 0xcd, 0xcf, 0x68, 0x79, 0xbe, 0x41, + 0x1c, 0x1e, 0x89, 0x6e, 0xca, 0xd3, 0xd6, 0xbb, 0xdc, 0x38, 0x42, 0xbf, 0x9d, 0x66, 0x31, 0x3f, + 0x2e, 0x62, 0xac, 0x32, 0xc7, 0xcd, 0x21, 0xf4, 0x8f, 0x05, 0x88, 0x6e, 0xc3, 0x8d, 0xca, 0x41, + 0xca, 0x0c, 0xc9, 0x53, 0xd8, 0x76, 0x59, 0x2f, 0xbe, 0x60, 0x9f, 0xb7, 0x1a, 0xe8, 0x2d, 0xb8, + 0x39, 0x8a, 0xb3, 0x94, 0x0d, 0x53, 0x86, 0x76, 0xca, 0x5d, 0x07, 0x5b, 0xff, 0xe1, 0xc0, 0xa2, + 0x9d, 0x8c, 0x7f, 0x56, 0xe7, 0xfb, 0x97, 0x80, 0x24, 0x2c, 0xcd, 0xda, 0xfd, 0x38, 0x0c, 0xf9, + 0x31, 0xdf, 0x67, 0xa1, 0x37, 0x94, 0xd7, 0x00, 0x2b, 0xbc, 0xe5, 0x91, 0x68, 0x78, 0xc0, 0xe1, + 0x64, 0x13, 0x66, 0xbd, 0x7e, 0xd0, 0xe6, 0x96, 0x28, 0xa6, 0x69, 0xc6, 0xeb, 0x07, 0xdf, 0x66, + 0x43, 0x42, 0x61, 0x51, 0x36, 0xb4, 0x43, 0x76, 0xc1, 0x42, 0x9c, 0x9b, 0x29, 0x77, 0x5e, 0x34, + 0xbf, 0xc3, 0x41, 0xe4, 0x2e, 0xac, 0xf4, 0x93, 0x80, 0x9b, 0x74, 0x7e, 0xdf, 0x30, 0x8b, 0xd2, + 0x2c, 0x4b, 0xb8, 0x1a, 0x1d, 0xfd, 0x1e, 0x5c, 0xaf, 0xd0, 0x85, 0xf4, 0x7b, 0x5f, 0x87, 0x65, + 0xfb, 0xd6, 0x42, 0xf9, 0x3e, 0x1d, 0x09, 0x5b, 0x1d, 0xdd, 0xa5, 0x53, 0x8b, 0x8e, 0x8c, 0x68, + 0x11, 0xc7, 0xf5, 0x32, 0x9d, 0x27, 0xa3, 0x9f, 0xc0, 0x5a, 0x0e, 0x3c, 0x8c, 0xa3, 0x0b, 0x96, + 0xa4, 0xdc, 0x82, 0x09, 0xd4, 0x4f, 0x93, 0x58, 0x25, 0x79, 0xf1, 0x37, 0x8f, 0x05, 0xb3, 0x58, + 0x9a, 0x41, 0x2d, 0x8b, 0x39, 0x4e, 0xe2, 0x65, 0x6a, 0xe7, 0xc3, 0xdf, 0xdc, 0x5c, 0x03, 0x24, + 0xc2, 0xda, 0xd8, 0x26, 0xcc, 0x7f, 0x5e, 0xc2, 0x38, 0x17, 0xfa, 0x01, 0x86, 0xa4, 0xa6, 0x28, + 0x72, 0x8c, 0xff, 0x1f, 0xe6, 0xc5, 0x18, 0x79, 0x4f, 0x35, 0xbe, 0x2d, 0x6b, 0x7c, 0x05, 0x31, + 0x5d, 0x38, 0xd5, 0x50, 0xfa, 0xe3, 0x29, 0x58, 0xc0, 0x28, 0xf8, 0x01, 0xcb, 0xbc, 0x20, 0x1c, + 0x1f, 0x9f, 0x8b, 0xb8, 0xb6, 0xa6, 0xe3, 0xda, 0xe7, 0x60, 0xd1, 0x4c, 0xb2, 0x0c, 0xd5, 0x01, + 0xd9, 0x48, 0xb1, 0x0c, 0xc9, 0xf3, 0xb0, 0x84, 0xc7, 0xf5, 0x1c, 0x4b, 0xd8, 0xcc, 0x22, 0x42, + 0x35, 0x9a, 0x7d, 0xb8, 0x98, 0x2e, 0x1c, 0x2e, 0x78, 0x33, 0x06, 0xe8, 0xed, 0x34, 0xf0, 0xf5, + 0xd9, 0x03, 0x21, 0xc7, 0x81, 0x6f, 0x34, 0x63, 0xef, 0x59, 0xa3, 0x19, 0x7b, 0xf3, 0x73, 0x55, + 0xc2, 0xc4, 0xe5, 0x03, 0xde, 0xa1, 0xcd, 0xa1, 0xd1, 0x2d, 0x28, 0xe0, 0x49, 0xd0, 0xc3, 0x1b, + 0x36, 0x99, 0x30, 0x6f, 0x08, 0x8b, 0x15, 0x5f, 0xf9, 0xd1, 0x0f, 0xcc, 0xa3, 0x5f, 0x7e, 0x50, + 0x9c, 0xb7, 0x0e, 0x8a, 0x3b, 0x30, 0x1f, 0xf7, 0x59, 0xd4, 0x96, 0xc7, 0xf6, 0x05, 0x11, 0x91, + 0x70, 0xd0, 0x07, 0xe2, 0xe8, 0xbe, 0x02, 0x53, 0xa7, 0x8c, 0x35, 0x17, 0xc5, 0x21, 0xff, 0x94, + 0xf1, 0x95, 0x35, 0x93, 0x25, 0x9e, 0xcf, 0xd2, 0xe6, 0x12, 0xce, 0x9e, 0xf6, 0xfe, 0x27, 0x1c, + 0xfa, 0xcd, 0x80, 0x7b, 0xb1, 0xa1, 0x2b, 0x71, 0xe8, 0x3f, 0x3b, 0xb0, 0x60, 0x36, 0x94, 0x07, + 0xe7, 0x54, 0x0c, 0xae, 0x38, 0x75, 0x7a, 0x50, 0x53, 0xd5, 0x83, 0xaa, 0x5b, 0x83, 0x32, 0x8d, + 0x62, 0xba, 0x60, 0x14, 0xe3, 0x4f, 0x85, 0x85, 0x89, 0x9b, 0x2d, 0x4e, 0x9c, 0xd4, 0xc6, 0x9c, + 0xd6, 0x86, 0x4c, 0x53, 0xa1, 0x4d, 0xa6, 0x93, 0xe4, 0x02, 0x6c, 0xfe, 0xb5, 0x22, 0x7f, 0x75, + 0xf8, 0x9e, 0xba, 0xec, 0xf0, 0x4d, 0x0f, 0xf0, 0x24, 0xa2, 0x18, 0xcb, 0xe5, 0xf5, 0x12, 0xcc, + 0xa0, 0xb0, 0x6a, 0x65, 0xad, 0x59, 0x47, 0x47, 0xb9, 0x68, 0x5c, 0x89, 0x43, 0xbf, 0x89, 0xf7, + 0xb6, 0xd8, 0x34, 0x89, 0xe8, 0xd7, 0x61, 0x4e, 0xe8, 0x46, 0x4f, 0xcd, 0x2c, 0x7e, 0x3f, 0xf4, + 0xe9, 0xcf, 0x1c, 0x20, 0xc7, 0x83, 0x4e, 0x2f, 0x98, 0x9c, 0xda, 0xe4, 0x49, 0x11, 0x02, 0x75, + 0x9c, 0x0d, 0xb1, 0x5c, 0xf1, 0x77, 0x61, 0x05, 0xd5, 0x8b, 0x2b, 0x28, 0xb7, 0x8c, 0xe9, 0xea, + 0xbc, 0xc8, 0x8c, 0x69, 0x47, 0x7c, 0x0b, 0x0c, 0x03, 0x16, 0x65, 0x6d, 0x99, 0xe0, 0xe2, 0x5b, + 0x20, 0x02, 0x1e, 0xfa, 0xf4, 0x18, 0x56, 0xad, 0x91, 0x49, 0x4d, 0xef, 0xc2, 0x82, 0x10, 0xa0, + 0x1f, 0x7a, 0x5d, 0x7d, 0x03, 0x31, 0x8f, 0xb0, 0x47, 0x08, 0x1a, 0xa7, 0xaf, 0xdf, 0x75, 0x60, + 0xed, 0x38, 0xe8, 0x0d, 0x42, 0x2f, 0x63, 0xbf, 0x04, 0x8d, 0xe5, 0xc3, 0x9f, 0xb2, 0x86, 0xaf, + 0x34, 0x59, 0xcf, 0x35, 0x49, 0xff, 0xcb, 0x81, 0xf5, 0x82, 0x28, 0x3a, 0x0e, 0xb7, 0x8d, 0x69, + 0x44, 0x42, 0x46, 0x22, 0x19, 0x4c, 0x6b, 0x16, 0xd3, 0xe7, 0x60, 0xb1, 0x17, 0x44, 0x41, 0x6f, + 0xd0, 0x6b, 0x9b, 0x6b, 0x78, 0x41, 0x02, 0x1f, 0xe1, 0x14, 0x70, 0x24, 0xef, 0xa9, 0x81, 0x54, + 0x97, 0x48, 0x02, 0x28, 0x90, 0x5e, 0x81, 0xb5, 0xfc, 0xac, 0xd4, 0x3e, 0xf3, 0x82, 0xa8, 0x1d, + 0xc6, 0x69, 0x2a, 0xe7, 0x98, 0xe4, 0x6d, 0x47, 0x5e, 0x10, 0xbd, 0x13, 0xa7, 0xa9, 0xe1, 0x24, + 0x67, 0x4c, 0x27, 0x49, 0xff, 0xd0, 0x81, 0x95, 0x0f, 0xcf, 0xbd, 0x90, 0xdd, 0x8f, 0x7b, 0x9d, + 0x67, 0xab, 0xfb, 0x5d, 0x58, 0x10, 0xb9, 0xce, 0xcc, 0x4b, 0xce, 0x98, 0x9a, 0x81, 0x79, 0x84, + 0x9d, 0x20, 0xa8, 0x72, 0x1a, 0xfe, 0xd3, 0x01, 0x72, 0xc8, 0xc3, 0xc7, 0x70, 0x62, 0x7b, 0xe0, + 0xae, 0x44, 0xe4, 0x2a, 0x72, 0x0b, 0x6b, 0x48, 0xc8, 0x43, 0xdb, 0xfc, 0xa6, 0x2c, 0xf3, 0xd3, + 0xa3, 0xa9, 0x5f, 0x31, 0x21, 0x59, 0xda, 0xe7, 0x9e, 0x87, 0xa5, 0x27, 0x5e, 0x18, 0xb2, 0x4c, + 0x5f, 0x6b, 0xca, 0xdb, 0x0f, 0x01, 0x55, 0x79, 0x0f, 0x35, 0xe0, 0x59, 0x63, 0xc0, 0xeb, 0xb0, + 0x6a, 0x8d, 0x57, 0x46, 0x8b, 0xaf, 0xc3, 0x86, 0x00, 0x1f, 0x84, 0xe1, 0xc4, 0x5e, 0x95, 0xfe, + 0x59, 0x0d, 0x36, 0x4b, 0xdd, 0x74, 0x58, 0x65, 0x9b, 0xf1, 0x6d, 0x3d, 0xdc, 0xea, 0x0e, 0x7b, + 0xf2, 0x53, 0xf6, 0x6a, 0xfd, 0x9d, 0x03, 0x33, 0x02, 0x34, 0x76, 0x36, 0x3e, 0x52, 0x0e, 0x41, + 0x1a, 0x9c, 0x38, 0x85, 0x7e, 0x79, 0x32, 0x66, 0xe2, 0x3f, 0xf3, 0x2a, 0x5b, 0x78, 0x12, 0x79, + 0x8b, 0xfd, 0x75, 0x58, 0x29, 0x22, 0x5c, 0xe9, 0x9a, 0x4f, 0x64, 0xb2, 0xde, 0xba, 0x60, 0xc6, + 0xd5, 0xf5, 0x4f, 0x1c, 0x58, 0x3e, 0x8c, 0x23, 0x3f, 0xe0, 0x9b, 0xee, 0x23, 0x2f, 0xf1, 0x7a, + 0xa9, 0xac, 0x9e, 0x10, 0x20, 0x75, 0xd5, 0xa1, 0x01, 0x23, 0x92, 0xca, 0xdb, 0x00, 0xdd, 0x73, + 0xd6, 0x7d, 0xdc, 0x96, 0x59, 0x5e, 0x51, 0x72, 0xc1, 0x21, 0xf7, 0x03, 0x3f, 0x25, 0x2f, 0xc3, + 0x6a, 0xde, 0xdc, 0xf6, 0x22, 0xbf, 0x2d, 0x53, 0xbc, 0x78, 0xa3, 0xa4, 0xf1, 0x0e, 0x22, 0xff, + 0x20, 0x7d, 0x9c, 0xf2, 0x58, 0x5a, 0x67, 0x36, 0xdb, 0x96, 0x0b, 0x5f, 0xd6, 0xf0, 0x03, 0x04, + 0xd3, 0xff, 0x76, 0x70, 0x07, 0x54, 0xa3, 0x92, 0xb3, 0x9d, 0x27, 0x33, 0x31, 0xc7, 0x6d, 0x4d, + 0x59, 0xad, 0x30, 0x65, 0x04, 0xea, 0x41, 0xc6, 0x7a, 0x6a, 0x63, 0xe1, 0xbf, 0xc9, 0x7d, 0x58, + 0xd1, 0x23, 0x6e, 0xf7, 0x51, 0x2d, 0x72, 0x99, 0x6c, 0xe6, 0x87, 0x75, 0x4b, 0x6b, 0xee, 0x72, + 0xb7, 0xa0, 0x46, 0xb5, 0xbc, 0xa6, 0x27, 0x72, 0xd4, 0x5d, 0xd4, 0xb6, 0xf4, 0x4f, 0xe2, 0x4b, + 0x48, 0xcd, 0xba, 0x83, 0x8c, 0xf9, 0xf2, 0x28, 0xa1, 0xbf, 0xe9, 0xbf, 0x39, 0xb0, 0x7c, 0xe0, + 0xfb, 0x38, 0xee, 0x49, 0xdc, 0x84, 0x1a, 0x65, 0xed, 0x92, 0x51, 0x4e, 0xfd, 0x9c, 0xa3, 0xfc, + 0x85, 0x9d, 0xc8, 0x08, 0x25, 0x50, 0x0a, 0x2b, 0xf9, 0x38, 0xab, 0xa7, 0x97, 0x7e, 0x01, 0x88, + 0x38, 0x7e, 0x5a, 0xea, 0x28, 0x62, 0xad, 0xc3, 0xaa, 0x85, 0x25, 0x7d, 0xcd, 0xdb, 0x70, 0xe7, + 0x88, 0x65, 0x87, 0xc9, 0xb0, 0x9f, 0xc5, 0x2a, 0xdc, 0x7f, 0xc0, 0xfa, 0x71, 0x1a, 0x28, 0xcf, + 0xc5, 0x26, 0xf2, 0x3e, 0x7f, 0xef, 0xc0, 0xdd, 0x09, 0x08, 0xc9, 0x21, 0x7c, 0x5c, 0xce, 0xe9, + 0xfd, 0x8a, 0x59, 0x52, 0x34, 0x11, 0x95, 0x3d, 0x0d, 0x91, 0x95, 0x1d, 0x9a, 0x64, 0xeb, 0x6b, + 0xb0, 0x64, 0x37, 0x5e, 0xc9, 0x55, 0x84, 0x70, 0xfb, 0x12, 0x21, 0x26, 0xb1, 0xb9, 0xdb, 0xb0, + 0xd4, 0xb5, 0x48, 0x48, 0x46, 0x05, 0x28, 0x3d, 0x84, 0x17, 0x2e, 0xe5, 0x26, 0xd5, 0x36, 0x32, + 0x83, 0x41, 0x7f, 0xec, 0xc0, 0xea, 0x87, 0x41, 0x76, 0xee, 0x27, 0xde, 0x93, 0xb7, 0x03, 0x6f, + 0xa2, 0x45, 0x61, 0xde, 0x47, 0xd4, 0x0a, 0xf7, 0x11, 0xa3, 0xa2, 0xa7, 0x42, 0x32, 0xa4, 0x5e, + 0xce, 0x09, 0xdd, 0x86, 0xe5, 0x8e, 0x17, 0x3d, 0x6e, 0x1b, 0xdb, 0xb2, 0xb0, 0xf6, 0x45, 0x0e, + 0x56, 0x97, 0x15, 0x3e, 0xfd, 0x27, 0x07, 0xd6, 0x95, 0xc4, 0x62, 0xf0, 0x93, 0xc8, 0x6c, 0x68, + 0xa0, 0x66, 0xe7, 0x70, 0x76, 0x60, 0x5e, 0xfe, 0x6c, 0x67, 0xde, 0x99, 0xf4, 0x67, 0x20, 0x41, + 0x27, 0xde, 0x99, 0x35, 0xdc, 0xfa, 0xc8, 0xe1, 0xda, 0xb1, 0xb2, 0x3c, 0xeb, 0xcc, 0xe4, 0x27, + 0xbf, 0x82, 0x02, 0x66, 0xcb, 0xd9, 0xa0, 0x37, 0x61, 0x45, 0x8d, 0xab, 0x62, 0xc9, 0x8a, 0xb3, + 0x5c, 0x1e, 0x93, 0xd5, 0xac, 0x98, 0xec, 0x25, 0x68, 0xa9, 0xbe, 0x5e, 0x88, 0x0b, 0xf5, 0xfe, + 0xf0, 0xe1, 0x83, 0xf2, 0x92, 0x46, 0x2a, 0xf4, 0x04, 0x6e, 0x54, 0x62, 0x4b, 0xa6, 0x5f, 0x82, + 0x69, 0xc6, 0x81, 0x32, 0x60, 0xdb, 0x51, 0x0b, 0xac, 0xd0, 0x47, 0x5f, 0xce, 0x09, 0x6c, 0xca, + 0x60, 0xb7, 0x80, 0x91, 0xde, 0x1f, 0x5e, 0xa1, 0x34, 0xa6, 0xea, 0xe0, 0x8a, 0x95, 0x02, 0x38, + 0x27, 0xd3, 0xae, 0xf8, 0xa0, 0x43, 0xd8, 0x2e, 0xb3, 0x79, 0xe0, 0x65, 0x13, 0xb1, 0x58, 0x83, + 0x69, 0xac, 0x2a, 0x53, 0x6b, 0x17, 0x3f, 0xf8, 0x6c, 0xb1, 0x48, 0x05, 0x7a, 0xfc, 0x67, 0xce, + 0xba, 0x6e, 0xb2, 0xfe, 0x1e, 0xd0, 0x71, 0x23, 0x2c, 0xab, 0x6f, 0xea, 0x0a, 0xea, 0xfb, 0x51, + 0x0d, 0x36, 0x47, 0xa0, 0x94, 0x34, 0xf3, 0xa6, 0x31, 0x44, 0xb1, 0xf5, 0xdc, 0x2c, 0x72, 0x09, + 0x95, 0x5c, 0x82, 0x52, 0xae, 0x82, 0x37, 0x60, 0x36, 0x11, 0x9a, 0x92, 0xbb, 0xcf, 0xcd, 0xb2, + 0x80, 0x52, 0x95, 0xa2, 0xab, 0x42, 0x27, 0x5f, 0x01, 0xc0, 0x44, 0x03, 0xf3, 0xdb, 0x5e, 0x26, + 0x37, 0xe8, 0xd6, 0x9e, 0xa8, 0x79, 0xde, 0x53, 0x35, 0xcf, 0x7b, 0x27, 0xaa, 0xe6, 0xd9, 0x6d, + 0x48, 0xec, 0x03, 0xec, 0x2a, 0x6f, 0x9b, 0x79, 0xd7, 0x99, 0xcb, 0xbb, 0x4a, 0xec, 0x83, 0x8c, + 0x9e, 0xc0, 0x46, 0xf5, 0x98, 0x2a, 0xd3, 0x9d, 0x45, 0x4d, 0xe5, 0x0b, 0x66, 0xca, 0x5a, 0x30, + 0xff, 0xee, 0xe4, 0x64, 0xed, 0xf1, 0x8e, 0x75, 0x6f, 0x97, 0xa7, 0xb6, 0x47, 0xe5, 0x55, 0x08, + 0xd4, 0xf5, 0x0e, 0x3e, 0xed, 0xe2, 0x6f, 0xb2, 0x0f, 0xf5, 0xd3, 0x40, 0xeb, 0x43, 0x5f, 0x13, + 0x73, 0x3f, 0x5c, 0xb4, 0x04, 0x44, 0x24, 0x5f, 0x82, 0x19, 0xb1, 0x09, 0xa0, 0xff, 0x98, 0xbf, + 0xb7, 0xad, 0x03, 0x07, 0x84, 0x16, 0x3b, 0x49, 0x64, 0xfa, 0x37, 0x0e, 0xac, 0x56, 0x10, 0xe5, + 0x67, 0x77, 0x74, 0xb9, 0x86, 0x16, 0xe7, 0x38, 0xe0, 0x5d, 0xae, 0xc9, 0x5d, 0x58, 0x50, 0xae, + 0x18, 0xdb, 0x85, 0x2a, 0xe6, 0x25, 0x0c, 0x51, 0x9e, 0x87, 0x25, 0x8d, 0x32, 0xe8, 0x75, 0x98, + 0x2a, 0x9b, 0x59, 0x54, 0x48, 0x08, 0xc4, 0xea, 0x97, 0xb4, 0x23, 0x7d, 0x27, 0xff, 0x89, 0xcb, + 0xf0, 0x49, 0x70, 0xaa, 0x8a, 0xc2, 0xc4, 0x07, 0x06, 0x5b, 0x1d, 0x4f, 0x45, 0x32, 0xf8, 0x9b, + 0xfa, 0xb0, 0x5e, 0x39, 0xb6, 0x31, 0x49, 0xf9, 0x82, 0x43, 0xaf, 0x95, 0x1c, 0xba, 0x74, 0xce, + 0x53, 0x79, 0x22, 0xea, 0x55, 0xac, 0x99, 0x7b, 0x27, 0x3e, 0x3b, 0xcb, 0x13, 0x3d, 0xd2, 0xe8, + 0x37, 0x60, 0x26, 0x44, 0xb8, 0x2a, 0xc6, 0x17, 0x5f, 0x34, 0xc2, 0xcc, 0x7c, 0xa1, 0x4b, 0x7e, + 0xa7, 0x1d, 0x44, 0xa7, 0xb1, 0xcc, 0x6b, 0xe0, 0x6f, 0x3e, 0x64, 0x9f, 0x75, 0x06, 0x67, 0xaa, + 0x42, 0x16, 0x3f, 0x38, 0xe6, 0x13, 0x2f, 0x89, 0x64, 0xe8, 0x8f, 0xbf, 0x39, 0x26, 0x4b, 0x92, + 0x38, 0x91, 0x71, 0xbe, 0xf8, 0xa0, 0x47, 0xb0, 0x79, 0x7c, 0x35, 0x11, 0xd1, 0x89, 0x61, 0xde, + 0x5d, 0x3a, 0x3b, 0xfc, 0xa0, 0xdf, 0xb6, 0xea, 0x03, 0xb1, 0x86, 0x6c, 0x42, 0xcf, 0x89, 0x51, + 0xa7, 0x22, 0x86, 0x1f, 0xf4, 0x67, 0x0e, 0xaa, 0xa1, 0x40, 0x4d, 0x57, 0x28, 0x97, 0xeb, 0xed, + 0x44, 0xcc, 0xf6, 0xa5, 0x8a, 0x7a, 0x3b, 0xab, 0xef, 0x64, 0x05, 0x77, 0xbf, 0xd4, 0x1a, 0xba, + 0x4f, 0x61, 0xd5, 0x14, 0xed, 0x73, 0xcd, 0x4f, 0xfe, 0xc0, 0xc1, 0xbb, 0x0e, 0x9d, 0x2b, 0x3a, + 0xce, 0x12, 0xe6, 0xf5, 0x3e, 0xd7, 0x72, 0xa9, 0x6f, 0xc0, 0xae, 0x59, 0x4d, 0x7b, 0x65, 0x49, + 0xe8, 0x6f, 0x60, 0x91, 0x89, 0x28, 0x01, 0xfb, 0x3f, 0x90, 0xff, 0x6b, 0x70, 0xd3, 0x90, 0xff, + 0x8a, 0x62, 0xd0, 0x3f, 0x75, 0xf0, 0x3e, 0xe8, 0x60, 0xe0, 0x07, 0x99, 0x75, 0x3a, 0xda, 0x06, + 0xc0, 0x98, 0xa1, 0xcd, 0xb7, 0x27, 0x5d, 0xe2, 0xcf, 0x21, 0x3c, 0x04, 0x21, 0xd7, 0x61, 0x8e, + 0x45, 0xbe, 0x68, 0x94, 0x71, 0x26, 0x8b, 0x7c, 0xd5, 0x24, 0x72, 0x1c, 0x9d, 0xa1, 0x95, 0x52, + 0xba, 0x3f, 0xac, 0x8e, 0x36, 0xf8, 0xb2, 0x8e, 0x4f, 0x4f, 0xf9, 0x92, 0x13, 0x7b, 0x86, 0xfc, + 0xa2, 0x87, 0xa2, 0x64, 0xc9, 0x10, 0x4d, 0xae, 0xb7, 0x17, 0x61, 0x06, 0x43, 0x89, 0x52, 0xed, + 0x93, 0x81, 0x2b, 0x31, 0xe8, 0x4f, 0x85, 0x85, 0x89, 0x8b, 0x85, 0xa0, 0x7b, 0xe8, 0x45, 0x7e, + 0x38, 0xd1, 0x81, 0xed, 0x99, 0xcd, 0x50, 0x1e, 0x8b, 0xd5, 0xf1, 0xac, 0x69, 0xc7, 0x62, 0xa2, + 0x26, 0x0d, 0x63, 0xb1, 0xe7, 0x60, 0x31, 0x0b, 0x7a, 0xac, 0x1d, 0x44, 0x19, 0x4b, 0x2e, 0x3c, + 0x75, 0x8d, 0xb8, 0xc0, 0x81, 0x0f, 0x25, 0x8c, 0x3e, 0xc0, 0x1a, 0x9a, 0xd2, 0x70, 0xa4, 0x66, + 0x6e, 0xc3, 0x4c, 0x17, 0x41, 0x52, 0x33, 0x4b, 0x46, 0x66, 0xc9, 0x0f, 0x99, 0x2b, 0x5b, 0xe9, + 0x6f, 0x39, 0x30, 0x23, 0x40, 0xb8, 0x5f, 0xe7, 0x37, 0x2c, 0xf8, 0x5b, 0x15, 0x76, 0xd6, 0xf2, + 0xc2, 0x4e, 0x55, 0xfe, 0x39, 0x65, 0x94, 0x7f, 0x12, 0xa8, 0xc7, 0x7d, 0x16, 0xa9, 0x32, 0x51, + 0xfe, 0x9b, 0x8f, 0xb5, 0x1b, 0xc6, 0x29, 0x93, 0xc7, 0x04, 0xf1, 0x61, 0x94, 0x7c, 0xce, 0x98, + 0x25, 0x9f, 0xf4, 0x29, 0x40, 0x3e, 0x65, 0x3a, 0x72, 0x90, 0x61, 0x0e, 0x46, 0x0e, 0x37, 0x01, + 0x02, 0x9f, 0x45, 0x59, 0x70, 0x1a, 0x30, 0x55, 0x3a, 0x68, 0x40, 0xf8, 0xee, 0xd8, 0x63, 0x69, + 0xaa, 0xea, 0x6e, 0x1a, 0xae, 0xfa, 0x24, 0x5b, 0xd0, 0xd0, 0xaf, 0xd2, 0x54, 0xee, 0x5f, 0x03, + 0x68, 0x07, 0x1a, 0x47, 0x87, 0x27, 0xc7, 0x18, 0xcd, 0x70, 0xc6, 0xef, 0xbf, 0xff, 0xf0, 0x81, + 0x62, 0xcc, 0x7f, 0xeb, 0x98, 0xab, 0x66, 0xc4, 0x5c, 0x84, 0x5b, 0x44, 0x76, 0xae, 0x52, 0x41, + 0xfc, 0x37, 0xb7, 0xf6, 0x88, 0x3d, 0xcd, 0xda, 0xc9, 0x40, 0x1d, 0xf6, 0x66, 0xf9, 0xb7, 0x3b, + 0x88, 0xe8, 0x03, 0xd8, 0xd4, 0x3c, 0xde, 0x12, 0x89, 0x19, 0x65, 0x77, 0x77, 0x61, 0x46, 0x44, + 0x52, 0xb2, 0x80, 0xf2, 0x9a, 0xde, 0x27, 0x54, 0x07, 0x57, 0x22, 0xd0, 0x03, 0x58, 0xd3, 0xc0, + 0xe3, 0x2c, 0xee, 0xff, 0x1c, 0x24, 0xae, 0x1b, 0x82, 0x70, 0x12, 0x07, 0xa1, 0x0a, 0x04, 0xf1, + 0x69, 0x42, 0xde, 0xc4, 0x23, 0x46, 0xd5, 0x62, 0x76, 0x7a, 0x27, 0x48, 0x33, 0xa3, 0xd3, 0x5f, + 0x38, 0x46, 0xaf, 0xf7, 0xfb, 0x61, 0xec, 0xf9, 0x4a, 0xaa, 0x1d, 0x98, 0x17, 0x4c, 0xcd, 0x58, + 0x0b, 0x04, 0x08, 0x43, 0xa9, 0x1c, 0x01, 0xab, 0xe1, 0x6a, 0x26, 0xc2, 0x03, 0x2f, 0xf3, 0x74, + 0x9d, 0xdc, 0x54, 0x5e, 0x27, 0xc7, 0x97, 0xa9, 0x97, 0x74, 0xcf, 0x83, 0x0b, 0xe6, 0xcb, 0x60, + 0x41, 0x7f, 0xf3, 0x79, 0x8e, 0x2f, 0x58, 0xf2, 0x24, 0x09, 0x32, 0x61, 0x75, 0x73, 0x6e, 0x0e, + 0xa0, 0x47, 0xd0, 0xca, 0xf5, 0xc1, 0x3c, 0x5f, 0xfd, 0xba, 0xb2, 0x0e, 0xef, 0xc3, 0xba, 0x06, + 0x7e, 0x77, 0xc0, 0x74, 0xd9, 0xda, 0x55, 0x68, 0x7c, 0x0b, 0x9a, 0x1a, 0x78, 0x30, 0xc8, 0xe2, + 0x77, 0x0c, 0xc5, 0x6d, 0x58, 0x64, 0x1a, 0xaa, 0x4f, 0xe1, 0x20, 0x3c, 0xa7, 0xe3, 0xfa, 0x8f, + 0xad, 0x39, 0x15, 0x13, 0x97, 0x3f, 0xab, 0xd4, 0xaf, 0xa4, 0xcc, 0x4b, 0xdf, 0x2f, 0xc2, 0xac, + 0x20, 0xaa, 0xf2, 0xce, 0x15, 0xa2, 0x2a, 0x0c, 0x1a, 0x1b, 0x53, 0x2c, 0xc7, 0x7b, 0x09, 0xf9, + 0x5c, 0x11, 0xb5, 0x4b, 0x14, 0x61, 0xcd, 0x71, 0x43, 0xd6, 0x42, 0xbe, 0x6d, 0x28, 0x47, 0xbe, + 0xf3, 0xb9, 0x94, 0xa5, 0xa2, 0x53, 0xcb, 0xe9, 0xdc, 0xfb, 0xe9, 0x1b, 0xb0, 0x74, 0x14, 0x8b, + 0x58, 0x1a, 0xef, 0x94, 0x13, 0xf2, 0x1e, 0xcc, 0xca, 0x17, 0x91, 0x64, 0xa3, 0xf4, 0x44, 0x12, + 0xd5, 0xdf, 0xda, 0x1c, 0xf1, 0x74, 0x92, 0xae, 0x7e, 0xf6, 0x8f, 0xff, 0xfa, 0xc3, 0xda, 0x22, + 0x99, 0xdf, 0xbf, 0x78, 0x75, 0xff, 0x8c, 0x65, 0x18, 0xe3, 0x9e, 0xc1, 0xa2, 0xf5, 0x88, 0x8d, + 0x6c, 0x59, 0x0f, 0xd1, 0x0a, 0x6f, 0xdb, 0x5a, 0xdb, 0x63, 0x9f, 0xa9, 0xd1, 0xeb, 0xc8, 0x62, + 0x95, 0x5c, 0x93, 0x2c, 0xf2, 0xf7, 0x69, 0xe4, 0x13, 0x58, 0x7e, 0x0b, 0xab, 0x58, 0x34, 0x51, + 0xb2, 0x93, 0x13, 0xab, 0x7c, 0x9b, 0xd7, 0xba, 0x35, 0x1a, 0x41, 0x32, 0xbc, 0x81, 0x0c, 0xd7, + 0xc9, 0x2a, 0x67, 0x28, 0xaa, 0x64, 0x34, 0x4f, 0x92, 0xc2, 0x8a, 0x7c, 0xed, 0xf3, 0x4c, 0x79, + 0x6e, 0x21, 0xcf, 0x0d, 0xb2, 0xc6, 0x79, 0xfa, 0x82, 0x41, 0xce, 0x34, 0xc6, 0x4b, 0x66, 0xf3, + 0x75, 0x1a, 0xb9, 0x39, 0xf2, 0xd9, 0x9a, 0x60, 0xb9, 0x73, 0xc9, 0xb3, 0x36, 0x7b, 0x94, 0x67, + 0x8c, 0xe3, 0xea, 0x97, 0x6d, 0xe4, 0x87, 0x22, 0x9e, 0xaf, 0x7c, 0x47, 0x49, 0x5e, 0xb8, 0xfc, + 0xf1, 0xa6, 0x90, 0xe1, 0xce, 0xa4, 0xaf, 0x3c, 0xe9, 0x17, 0x50, 0x98, 0x9b, 0x64, 0x4b, 0x0a, + 0x63, 0xbd, 0xec, 0x54, 0x6f, 0x47, 0x49, 0x17, 0x16, 0xcc, 0x27, 0x69, 0xe4, 0x46, 0xc5, 0xf1, + 0x41, 0x33, 0xdf, 0xaa, 0x6e, 0x94, 0x0c, 0x9b, 0xc8, 0x90, 0x90, 0x15, 0xc9, 0x50, 0x97, 0x98, + 0x91, 0x4f, 0x61, 0xb9, 0xf0, 0x9c, 0x8b, 0xd0, 0xc2, 0xf4, 0x55, 0x3c, 0xcd, 0x6b, 0x3d, 0x37, + 0x16, 0x47, 0x72, 0xbd, 0x89, 0x5c, 0x9b, 0x74, 0xd5, 0x98, 0x65, 0xc5, 0xf9, 0x4d, 0xe7, 0x45, + 0x92, 0xe2, 0x3c, 0x9b, 0x2f, 0x8f, 0x26, 0xe2, 0xbd, 0x73, 0xc9, 0xb3, 0xa5, 0xd2, 0x5c, 0x2b, + 0x9e, 0xb8, 0x5a, 0x53, 0x7c, 0xcd, 0x61, 0xbc, 0x97, 0x3b, 0x8c, 0xfd, 0xc9, 0xc6, 0xbc, 0x5d, + 0xfd, 0xde, 0x4e, 0x3e, 0xf9, 0xa3, 0x2d, 0xe4, 0xba, 0x46, 0x48, 0x81, 0x6b, 0x9c, 0xf5, 0x49, + 0x6a, 0x3d, 0x47, 0x94, 0x4c, 0x6d, 0xab, 0xae, 0x78, 0x10, 0x58, 0x39, 0x52, 0xf3, 0x85, 0xdf, + 0xc8, 0x91, 0xc6, 0x59, 0x3f, 0x25, 0x4f, 0x61, 0x49, 0xb8, 0x8b, 0x67, 0x3f, 0xb3, 0xdb, 0xc8, + 0x77, 0x93, 0x92, 0xdc, 0x67, 0x98, 0x13, 0xfb, 0x21, 0x34, 0xf4, 0x21, 0x88, 0x34, 0x8d, 0x41, + 0x58, 0x6f, 0xb3, 0x5a, 0x23, 0x5e, 0xde, 0x28, 0x6b, 0xa5, 0x8b, 0x72, 0x54, 0xe2, 0x1d, 0x0d, + 0x27, 0xfc, 0x3d, 0x80, 0xfc, 0x29, 0x0e, 0xb9, 0x5e, 0xa2, 0xac, 0x35, 0xd7, 0xaa, 0x6a, 0x52, + 0x8f, 0x8e, 0x91, 0xfc, 0x0a, 0x59, 0xb2, 0xc8, 0xab, 0xf5, 0xa6, 0xcf, 0x7c, 0xd6, 0x7a, 0x2b, + 0x3e, 0xde, 0x69, 0x8d, 0x7e, 0xb5, 0xa1, 0x26, 0x85, 0xaa, 0xc5, 0xa6, 0x6f, 0x21, 0xf9, 0x08, + 0xc4, 0x66, 0x61, 0x3c, 0x17, 0xd9, 0xaa, 0xe2, 0x52, 0xb9, 0x59, 0x94, 0xdf, 0x7e, 0x94, 0x36, + 0x8b, 0xfc, 0x89, 0x07, 0x79, 0x8c, 0x7f, 0x74, 0xc1, 0x78, 0xed, 0x40, 0x4c, 0x5a, 0xe5, 0xa7, + 0x1f, 0xad, 0x9b, 0xa3, 0x9a, 0xd3, 0x6a, 0xfb, 0x96, 0xd9, 0x2e, 0x5c, 0x54, 0x43, 0x71, 0x6e, + 0xcc, 0x7b, 0x89, 0x33, 0xe7, 0x2f, 0xca, 0xf2, 0x16, 0xb2, 0x6c, 0x91, 0x66, 0x99, 0x65, 0x8a, + 0x0c, 0x5e, 0x71, 0xa4, 0xad, 0x89, 0xe7, 0x15, 0x96, 0xad, 0x59, 0xaf, 0x30, 0x5a, 0xd7, 0x2b, + 0x5a, 0x24, 0x97, 0x75, 0xe4, 0xb2, 0x4c, 0x16, 0xb5, 0x37, 0x46, 0x5a, 0xc2, 0x1c, 0x74, 0x8d, + 0xaa, 0x65, 0x0e, 0xc5, 0xc7, 0x11, 0x96, 0xfb, 0x2d, 0x3d, 0x91, 0x28, 0xb9, 0x5f, 0xfd, 0x08, + 0x82, 0xfc, 0xa6, 0xfd, 0xd6, 0x42, 0xd5, 0x7e, 0xd3, 0xb1, 0xc5, 0xda, 0xa5, 0x85, 0x3a, 0xb2, + 0xa0, 0x9b, 0xee, 0x20, 0xe7, 0xeb, 0x64, 0xb3, 0xc8, 0x59, 0x16, 0x87, 0x93, 0xcf, 0x1c, 0x58, + 0xad, 0x28, 0x13, 0xce, 0x25, 0x18, 0x5d, 0x28, 0x9d, 0x4b, 0x30, 0xae, 0xce, 0x98, 0xa2, 0x04, + 0x5b, 0x14, 0x25, 0xf0, 0x7c, 0x5f, 0x4b, 0x20, 0x53, 0x93, 0x7c, 0x51, 0xfc, 0x81, 0x03, 0x1b, + 0xd5, 0x25, 0xc1, 0xe4, 0x79, 0xfd, 0x82, 0x7c, 0x5c, 0xb1, 0x72, 0xeb, 0xf6, 0x65, 0x68, 0x52, + 0x9a, 0xe7, 0x51, 0x9a, 0x1d, 0xda, 0xe2, 0xd2, 0x24, 0x88, 0x5b, 0x25, 0xd0, 0x13, 0xac, 0x13, + 0xb0, 0x8b, 0x6e, 0x89, 0x11, 0xd6, 0x54, 0xd7, 0x26, 0xb7, 0x76, 0xc7, 0x60, 0xd8, 0x9e, 0x93, + 0xac, 0xcb, 0x09, 0xc1, 0x4a, 0x55, 0x5d, 0xbd, 0x2b, 0xdd, 0x43, 0x5e, 0xd4, 0x6a, 0xb9, 0x87, + 0x52, 0x9d, 0xae, 0xe5, 0x1e, 0xca, 0xa5, 0xb3, 0x25, 0xf7, 0x80, 0xcc, 0xb0, 0x8c, 0x96, 0x7c, + 0x84, 0xcb, 0x46, 0x16, 0xa9, 0x34, 0x8b, 0x5e, 0x26, 0xad, 0x5a, 0x36, 0x76, 0x19, 0x4a, 0xc9, + 0x4b, 0x8b, 0xda, 0x17, 0xae, 0x3d, 0x17, 0xe6, 0x14, 0x3a, 0xd9, 0x2c, 0x12, 0x50, 0x94, 0x2b, + 0xeb, 0x0c, 0xe9, 0x26, 0x12, 0xbd, 0x46, 0x17, 0x4c, 0xa2, 0x9c, 0x66, 0x07, 0xe6, 0x8d, 0x9a, + 0x3a, 0xa2, 0xfd, 0x7b, 0xb9, 0x84, 0xb0, 0x75, 0xa3, 0xb2, 0xcd, 0xf6, 0x62, 0x74, 0x99, 0x33, + 0x48, 0x11, 0x41, 0xf3, 0xf8, 0x75, 0x58, 0xb4, 0xca, 0xda, 0x72, 0xe5, 0x57, 0x15, 0xde, 0xe5, + 0xca, 0xaf, 0xac, 0x85, 0x53, 0x31, 0x2e, 0x45, 0xe5, 0xa7, 0x12, 0x45, 0xf3, 0xfa, 0x18, 0x1a, + 0xba, 0x9a, 0x2c, 0xd7, 0x7f, 0xb1, 0xc0, 0xec, 0x32, 0x1e, 0xd6, 0x1c, 0x3c, 0xe1, 0x9d, 0x3b, + 0x71, 0xaf, 0x23, 0xf5, 0x65, 0xd4, 0x4a, 0xe5, 0xfa, 0x2a, 0x17, 0x8c, 0xe5, 0xfa, 0xaa, 0x2a, + 0xae, 0xb2, 0xf4, 0xd5, 0x45, 0x04, 0x3d, 0x86, 0x04, 0x96, 0x0b, 0x35, 0x4a, 0x79, 0x44, 0x53, + 0x5d, 0x91, 0x95, 0x47, 0x34, 0x23, 0x8a, 0x9b, 0xec, 0x98, 0x51, 0xf0, 0xf3, 0xc2, 0x30, 0xb7, + 0x2d, 0xe1, 0xee, 0xc5, 0x2d, 0xa4, 0x65, 0xb7, 0x56, 0xa9, 0x92, 0x65, 0xb7, 0x76, 0xb9, 0x4f, + 0xc9, 0xdd, 0x8b, 0xd4, 0x20, 0xf9, 0x00, 0xe6, 0x54, 0xe9, 0x48, 0x6e, 0xb4, 0x85, 0xa2, 0x99, + 0x56, 0xb3, 0xdc, 0x20, 0xa9, 0x5a, 0x86, 0xeb, 0xf9, 0x3e, 0x52, 0x95, 0x13, 0x61, 0x14, 0x92, + 0xe4, 0x13, 0x51, 0xae, 0x41, 0xc9, 0x27, 0xa2, 0xaa, 0xf2, 0xc4, 0x9a, 0x08, 0xe1, 0xb9, 0x34, + 0x8f, 0xbf, 0x72, 0x30, 0x6d, 0x3d, 0xbe, 0x0e, 0x84, 0xbc, 0x72, 0x85, 0x92, 0x11, 0x21, 0xd0, + 0xab, 0x57, 0x2e, 0x32, 0xa1, 0x77, 0x50, 0x4c, 0x4a, 0xb7, 0xd5, 0x66, 0x8a, 0xdd, 0x7c, 0x81, + 0xae, 0x2b, 0x4e, 0xb8, 0xd0, 0x7f, 0xe9, 0x88, 0xbf, 0xe6, 0x33, 0x86, 0x2e, 0xd9, 0x9b, 0x50, + 0x00, 0x25, 0xf0, 0xfe, 0xc4, 0xf8, 0x52, 0xdc, 0xdb, 0x28, 0xee, 0x2d, 0x7a, 0x63, 0x8c, 0xb8, + 0x5c, 0xd8, 0x10, 0xae, 0x99, 0xf5, 0x22, 0x6f, 0x0f, 0x22, 0xdf, 0x38, 0x90, 0x55, 0x94, 0x92, + 0xe4, 0xa6, 0x52, 0xac, 0x6e, 0x50, 0x51, 0x0d, 0xc5, 0x2d, 0xe0, 0x89, 0x6c, 0x3d, 0x0d, 0xbc, + 0xec, 0x94, 0x53, 0xe5, 0xdc, 0x7e, 0xcf, 0xc9, 0x4b, 0x15, 0xec, 0x61, 0x08, 0xc6, 0xdb, 0x45, + 0xda, 0x56, 0x45, 0xc8, 0x18, 0xd6, 0xaf, 0x21, 0xeb, 0x97, 0xe9, 0x1d, 0x93, 0xb5, 0xfc, 0x4f, + 0x0c, 0x1d, 0x65, 0xb0, 0xa5, 0xf9, 0xcc, 0x28, 0x96, 0x31, 0x0a, 0x27, 0xf2, 0x10, 0x61, 0x74, + 0x0d, 0x46, 0x1e, 0x22, 0x8c, 0xa9, 0xbc, 0xb0, 0x43, 0x84, 0x27, 0x1a, 0x11, 0xcd, 0xbb, 0x33, + 0x0c, 0x7c, 0x2e, 0xc4, 0x1f, 0x3b, 0xa5, 0x5a, 0x0f, 0xa3, 0x0a, 0x81, 0xdc, 0x1d, 0xc1, 0xa7, + 0x5c, 0x8b, 0xd1, 0x7a, 0x71, 0x12, 0xd4, 0x2b, 0x48, 0xf6, 0x47, 0xd6, 0x9d, 0xba, 0x59, 0x9a, + 0x91, 0x07, 0x2f, 0x63, 0x4b, 0x37, 0xae, 0x24, 0x91, 0x4c, 0x1d, 0xd0, 0xeb, 0x95, 0x12, 0xf9, + 0x5e, 0x26, 0x4f, 0xd6, 0x2b, 0xc5, 0x6b, 0x5a, 0x33, 0x6d, 0x53, 0x79, 0xa1, 0x6a, 0xa6, 0x6d, + 0xaa, 0x6f, 0x78, 0xed, 0xb4, 0xcd, 0x19, 0xcb, 0xc4, 0x8d, 0xab, 0x2f, 0x19, 0x5c, 0xc0, 0xca, + 0xf1, 0x48, 0xa6, 0xc7, 0x3f, 0x37, 0x53, 0x19, 0xc2, 0x52, 0x64, 0x9a, 0x16, 0x98, 0xf2, 0xc1, + 0x5e, 0x88, 0x52, 0x55, 0xf3, 0x42, 0x95, 0xec, 0x8c, 0xbe, 0x6a, 0x2d, 0xf3, 0xad, 0xbc, 0x8b, + 0xb5, 0xf9, 0x1a, 0x67, 0x6b, 0xfc, 0x23, 0x34, 0x9c, 0xef, 0x10, 0x88, 0x7d, 0xbe, 0xc6, 0x3f, + 0x5e, 0xa0, 0x9d, 0x42, 0xc5, 0x35, 0xea, 0x64, 0x87, 0xeb, 0x5d, 0x64, 0x7c, 0x83, 0x6e, 0x94, + 0x0f, 0xd7, 0x9c, 0x37, 0x67, 0xfd, 0x7d, 0x58, 0x2d, 0x64, 0x6d, 0x9e, 0x11, 0x6f, 0xcb, 0xe0, + 0x0b, 0x29, 0x1b, 0xc5, 0x3c, 0xc3, 0x0c, 0x4a, 0xe1, 0x6e, 0x94, 0xec, 0x56, 0x9d, 0x54, 0xad, + 0xab, 0xc7, 0x71, 0x67, 0x66, 0xb9, 0xed, 0x93, 0x8d, 0xd2, 0x41, 0x56, 0x9d, 0xf3, 0x7e, 0xdf, + 0xc1, 0xbb, 0xae, 0x11, 0x57, 0xb3, 0xe4, 0x6e, 0x55, 0xaa, 0xe4, 0xca, 0x62, 0xc8, 0xed, 0x80, + 0xdc, 0x2c, 0xe6, 0x53, 0x4a, 0xe2, 0x9c, 0x63, 0xee, 0xca, 0xbc, 0x60, 0xb5, 0xb2, 0x39, 0x15, + 0x37, 0xaf, 0x23, 0xd3, 0x1d, 0xc5, 0x24, 0x8e, 0xcc, 0x47, 0x28, 0x4e, 0x3f, 0xb0, 0xff, 0x2a, + 0x94, 0xc5, 0xf2, 0x76, 0xc5, 0xa8, 0xaf, 0xc2, 0xfa, 0x39, 0x64, 0xbd, 0x4d, 0x6e, 0x14, 0xc6, + 0x5b, 0x10, 0x41, 0x9c, 0x4a, 0x8c, 0xcb, 0x39, 0xf3, 0x54, 0x52, 0xba, 0x2d, 0xb6, 0x4e, 0x25, + 0xe5, 0x0b, 0xdb, 0xd2, 0xa9, 0xc4, 0xe3, 0x28, 0xe8, 0xc0, 0x48, 0x06, 0x2b, 0xc5, 0x4b, 0x32, + 0x63, 0x29, 0x57, 0x5f, 0x9f, 0x19, 0x4b, 0x79, 0xc4, 0x8d, 0x41, 0xe1, 0xd0, 0xd5, 0xcd, 0xc4, + 0xc5, 0xc3, 0xbe, 0xac, 0x8f, 0x26, 0x19, 0x2c, 0x17, 0x2e, 0xb0, 0x8c, 0xb9, 0xac, 0xbc, 0xd9, + 0x9a, 0x80, 0xa7, 0xed, 0x3e, 0x34, 0xcf, 0x01, 0x92, 0xe1, 0xcb, 0xe8, 0x29, 0xac, 0x56, 0x5c, + 0x46, 0x19, 0x47, 0xff, 0x91, 0x37, 0x55, 0xad, 0xb2, 0x74, 0xd6, 0xa5, 0x8c, 0x9d, 0x9e, 0xcb, + 0x79, 0x27, 0x4c, 0x70, 0xee, 0x1b, 0xe3, 0x95, 0x7f, 0x43, 0xb2, 0x4c, 0xd1, 0xba, 0xff, 0x6b, + 0xed, 0x8c, 0x6c, 0xaf, 0xdc, 0x1a, 0x34, 0x4b, 0x79, 0x35, 0x13, 0xc2, 0x92, 0x2d, 0xaa, 0x91, + 0x19, 0xaa, 0xba, 0x47, 0xbb, 0x74, 0x84, 0xf6, 0x9a, 0xd1, 0xec, 0x3e, 0x41, 0xda, 0x11, 0x2c, + 0x5a, 0x37, 0x9c, 0x86, 0xb9, 0x56, 0xdc, 0x9d, 0x4e, 0x6e, 0x3f, 0x45, 0x7d, 0xa6, 0x59, 0xdc, + 0x17, 0x0e, 0x71, 0xa5, 0x78, 0xa3, 0x4a, 0x76, 0x2a, 0x59, 0xe6, 0xd7, 0xa6, 0xbf, 0x38, 0xd7, + 0xd4, 0xe0, 0x2a, 0xaf, 0x64, 0x2b, 0xb8, 0xda, 0x97, 0xb5, 0x97, 0xcf, 0xe3, 0x25, 0x4c, 0xd1, + 0x19, 0x15, 0x6f, 0x2d, 0x4f, 0xe2, 0xb3, 0xb3, 0x90, 0x91, 0xf2, 0x88, 0x0a, 0xd7, 0x9a, 0x13, + 0x8c, 0xd9, 0xda, 0xfb, 0x72, 0xf6, 0xde, 0x20, 0x8b, 0xd5, 0xba, 0xf9, 0x3e, 0x6e, 0x3f, 0x85, + 0x9a, 0x07, 0x6b, 0xfb, 0xa9, 0x2e, 0xef, 0x68, 0xd1, 0x71, 0x28, 0x23, 0xf6, 0xa1, 0x73, 0x89, + 0x27, 0x2a, 0x25, 0xd2, 0xce, 0x0c, 0x56, 0x6d, 0xbe, 0xf6, 0xbf, 0x01, 0x00, 0x00, 0xff, 0xff, + 0xfd, 0xda, 0xc4, 0x0d, 0x25, 0x57, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/gctrpc/rpc.proto b/gctrpc/rpc.proto index ad09c7ae..43df04b7 100644 --- a/gctrpc/rpc.proto +++ b/gctrpc/rpc.proto @@ -602,8 +602,10 @@ message GetAuditEventResponse { message GetHistoricCandlesRequest { string exchange = 1; CurrencyPair pair = 2; - int64 rangesize = 3; - int64 granularity = 4; + string asset_type = 3; + int64 start = 4; + int64 end = 5; + int64 time_interval = 6; } message GetHistoricCandlesResponse { diff --git a/gctrpc/rpc.swagger.json b/gctrpc/rpc.swagger.json index 38080f4b..46681db7 100644 --- a/gctrpc/rpc.swagger.json +++ b/gctrpc/rpc.swagger.json @@ -1138,14 +1138,27 @@ "type": "string" }, { - "name": "rangesize", + "name": "asset_type", + "in": "query", + "required": false, + "type": "string" + }, + { + "name": "start", "in": "query", "required": false, "type": "string", "format": "int64" }, { - "name": "granularity", + "name": "end", + "in": "query", + "required": false, + "type": "string", + "format": "int64" + }, + { + "name": "time_interval", "in": "query", "required": false, "type": "string", diff --git a/go.mod b/go.mod index 18244031..72b84c38 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.12 require ( github.com/d5/tengo/v2 v2.1.2 github.com/gofrs/uuid v3.2.0+incompatible - github.com/golang/protobuf v1.3.4 + github.com/golang/protobuf v1.3.5 github.com/google/go-querystring v1.0.0 github.com/gorilla/mux v1.7.4 github.com/gorilla/websocket v1.4.1 diff --git a/go.sum b/go.sum index d26b4c4d..d9d2b014 100644 --- a/go.sum +++ b/go.sum @@ -31,14 +31,6 @@ github.com/cpuguy83/go-md2man v1.0.10 h1:BSKMNlYxDvnunlTymqtgONjNnaRV1sTpcovwwjF github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/d5/tengo/v2 v2.0.2 h1:3APkPZPc1FExaJoWrN5YzvDqc6GNkQH6ehmCRDmN83I= -github.com/d5/tengo/v2 v2.0.2/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8= -github.com/d5/tengo/v2 v2.0.4 h1:iGeE4v6uMYOF7BCHT+zctdIXEti3oqqFOYkUwTHEUv4= -github.com/d5/tengo/v2 v2.0.4/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8= -github.com/d5/tengo/v2 v2.0.5 h1:l8MoAjhylCQ9nfqdPdhqA7IsMXZk2CrNI2U613P32aM= -github.com/d5/tengo/v2 v2.0.5/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8= -github.com/d5/tengo/v2 v2.1.1 h1:b6+k/B7xWENBDIx8iTNMXQbbvASjRKr5DtIto5J6gkU= -github.com/d5/tengo/v2 v2.1.1/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8= github.com/d5/tengo/v2 v2.1.2 h1:JR5O6qJW2GW9lpv/MfEqK16a/Wpp2y8I0JZZ5fqNOL0= github.com/d5/tengo/v2 v2.1.2/go.mod h1:XRGjEs5I9jYIKTxly6HCF8oiiilk5E/RYXOZ5b0DZC8= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= @@ -49,7 +41,6 @@ github.com/denisenkom/go-mssqldb v0.0.0-20190924004331-208c0a498538/go.mod h1:xb github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/ericlagergren/decimal v0.0.0-20180907214518-0bb163153a5d/go.mod h1:1yj25TwtUlJ+pfOu9apAVaM1RWfZGg+aFpd4hPQZekQ= @@ -80,8 +71,8 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3 h1:gyjaxf+svBWX08ZjK86iN9geUJF0H6gp2IRKX6Nf6/I= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4 h1:87PNWwrRvUSnqS4dlcBU/ftvOIBep4sYuBLlh6rX2wk= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5 h1:F768QJ1E9tib+q5Sc8MkdJi1RxLTbRcTf8LJV56aRls= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -89,8 +80,6 @@ github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASu github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/mux v1.7.3 h1:gnP5JzjVOuiZD07fKKToCAOjS0yOpj/qPETTXCCS6hw= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.7.4 h1:VuZ8uybHlWmqV03+zRzdwKL4tUnIp1MAQtp1mIFE1bc= github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.0 h1:WDFjx/TMzVgy9VdMMQi2K2Emtwi2QcUQsztZ/zLaH/Q= @@ -103,12 +92,6 @@ github.com/grpc-ecosystem/go-grpc-middleware v1.2.0 h1:0IKlLyQ3Hs9nDaiK5cSHAGmcQ github.com/grpc-ecosystem/go-grpc-middleware v1.2.0/go.mod h1:mJzapYve32yjrKlk9GbyCZHuPgZsrbyIbyKhSzOpg6s= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.13.0 h1:sBDQoHXrOlfPobnKw69FIKa1wg9qsLLvvQ/Y19WtFgI= -github.com/grpc-ecosystem/grpc-gateway v1.13.0/go.mod h1:8XEsbTttt/W+VvjtQhLACqCisSPWTxCZ7sBRjU6iH9c= -github.com/grpc-ecosystem/grpc-gateway v1.14.1 h1:YuM9SXYy583fxvSOkzCDyBPCtY+/IMSHEG1dKFMLZsA= -github.com/grpc-ecosystem/grpc-gateway v1.14.1/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= -github.com/grpc-ecosystem/grpc-gateway v1.14.2 h1:SG3eXGmMVahaP4UtKsO/gPQpkovjXOmxXNd7sJlhxNs= -github.com/grpc-ecosystem/grpc-gateway v1.14.2/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/grpc-ecosystem/grpc-gateway v1.14.3 h1:OCJlWkOUoTnl0neNGlf4fUm3TmbEtguw7vR+nGtnDjY= github.com/grpc-ecosystem/grpc-gateway v1.14.3/go.mod h1:6CwZWGDSPRJidgKAtJVvND6soZe6fT7iteq8wDPdhb0= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -223,8 +206,6 @@ github.com/toorop/go-pusher v0.0.0-20180521062818-4521e2eb39fb h1:9kcmLvQdiIecpg github.com/toorop/go-pusher v0.0.0-20180521062818-4521e2eb39fb/go.mod h1:VTLqNCX1tXrur6pdIRCl8Q90FR7nw/mEBdyMkWMcsb0= github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= -github.com/urfave/cli v1.22.2 h1:gsqYFH8bb9ekPA12kRo0hfjngWQjkJPlN9R0N78BoUo= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/urfave/cli v1.22.3 h1:FpNT6zq26xNpHZy08emi755QwzLPs6Pukqjlc7RfOMU= github.com/urfave/cli v1.22.3/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/volatiletech/inflect v0.0.0-20170731032912-e7201282ae8d h1:gI4/tqP6lCY5k6Sg+4k9qSoBXmPwG+xXgMpK7jivD4M= @@ -304,8 +285,6 @@ google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ij google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.27.1 h1:zvIju4sqAGvwKspUQOhwnpcqSbzi7/H6QomNNjTL4sk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.28.0 h1:bO/TA4OxCOummhSf10siHuG7vJOiwh7SpRpFZDkOgl4= google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=