Initial kline trade converter && restructure wrapper functions (#454)

* Initial kline trade converter && restructure wrapper function

* Addr nits

* fix linter issues

* fix requested

* fix after merge interface issue with fakepassingexchange

* consistentizations

* Addr glorious nits

* Added in explicit interval strings for gctcli client (ease of use)

* rm value stutter

* Addr nits

* update protobuf and push regen

* go mod tidy

* change description of usage for granularity
This commit is contained in:
Ryan O'Hara-Reid
2020-03-16 10:31:07 +11:00
committed by GitHub
parent 99e8d2f167
commit 2c7e531c5c
67 changed files with 977 additions and 658 deletions

View File

@@ -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: "<exchange> <pair> <rangesize> <granularity>",
ArgsUsage: "<exchange> <pair> <asset> <rangesize> <granularity>",
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
}

View File

@@ -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 }

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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)
}
}

View File

@@ -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,

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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()

View File

@@ -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
}

View File

@@ -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

View File

@@ -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{}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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
}

132
exchanges/kline/kline.go Normal file
View File

@@ -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
}

View File

@@ -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.")
}
}

44
exchanges/kline/types.go Normal file
View File

@@ -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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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)

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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.

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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
}

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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 {

View File

@@ -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
}

View File

@@ -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{}

View File

@@ -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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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.

View File

@@ -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 {

View File

@@ -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",

2
go.mod
View File

@@ -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

25
go.sum
View File

@@ -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=