vendor: update etcd, dataframe

This commit is contained in:
Gyu-Ho Lee 2017-01-13 14:22:00 -08:00
parent 0ccc1a7a40
commit 3660dc0f90
17 changed files with 924 additions and 308 deletions

View File

@ -7,7 +7,9 @@ Distributed database tester
- Database agent and runner are implemented at https://github.com/coreos/dbtester/tree/master/agent
- Client is implemented at https://github.com/coreos/dbtester/tree/master/control
- System metrics are collected via https://github.com/gyuho/psn
- Data analysis is done via https://github.com/gyuho/dataframe and https://github.com/gonum/plot
- Data analysis is done via https://github.com/coreos/dbtester/tree/master/analyze
- https://github.com/gyuho/dataframe
- https://github.com/gonum/plot
For etcd, we also recommend [etcd benchmark tool](https://github.com/coreos/etcd/tree/master/tools/benchmark).

11
glide.lock generated
View File

@ -1,5 +1,5 @@
hash: 36954914126819f13ba66c1917307f6a9c1f943a62c29105b6217c92588cff59
updated: 2017-01-12T15:20:14.976246037-08:00
hash: f82efd3e82e7400ea8a6fc49ff27d6b1d503897fdb1dc5bfc16590fb4bc613a3
updated: 2017-01-13T16:50:25.345743055-08:00
imports:
- name: bitbucket.org/zombiezen/gopdf
version: 1c63dc69751bc45441c2ce1f56b631c55294b4d5
@ -25,7 +25,7 @@ imports:
- name: github.com/cheggaaa/pb
version: 6e9d17711bb763b26b68b3931d47f24c1323abab
- name: github.com/coreos/etcd
version: 0df543dbb38c9b4f5bd77868c30aa5520c8089a4
version: 118fd18eb64a7777593809a07c2bf7ceb175a866
subpackages:
- auth/authpb
- client
@ -34,6 +34,7 @@ imports:
- etcdserver/etcdserverpb
- mvcc/mvccpb
- pkg/pathutil
- pkg/report
- pkg/tlsutil
- pkg/types
- name: github.com/coreos/go-systemd
@ -94,7 +95,7 @@ imports:
- runtime/internal
- utilities
- name: github.com/gyuho/dataframe
version: 56f562d96950b2963bba85d2fad3c3de37ba7d2b
version: 93b7746e9c7a253625583ea4860733b6b94f56f1
- name: github.com/gyuho/psn
version: eb796de4d35872441498b7cd63d1a95246776163
subpackages:
@ -196,7 +197,7 @@ imports:
- storage/v1
- transport
- name: google.golang.org/appengine
version: 8758a385849434ba5eac8aeedcf5192c5a0f5f10
version: 9e2ad0873f358c54296ccdc5116b0652c98226d1
subpackages:
- internal
- internal/app_identity

View File

@ -9,7 +9,7 @@ import:
- package: github.com/cheggaaa/pb
version: 6e9d17711bb763b26b68b3931d47f24c1323abab
- package: github.com/coreos/etcd
version: 0df543dbb38c9b4f5bd77868c30aa5520c8089a4
version: 118fd18eb64a7777593809a07c2bf7ceb175a866
subpackages:
- auth/authpb
- client
@ -18,6 +18,7 @@ import:
- etcdserver/etcdserverpb
- mvcc/mvccpb
- pkg/pathutil
- pkg/report
- pkg/tlsutil
- pkg/types
- package: github.com/coreos/pkg
@ -51,7 +52,7 @@ import:
- vg/vgpdf
- vg/vgsvg
- package: github.com/gyuho/dataframe
version: 56f562d96950b2963bba85d2fad3c3de37ba7d2b
version: 93b7746e9c7a253625583ea4860733b6b94f56f1
- package: github.com/gyuho/psn
version: eb796de4d35872441498b7cd63d1a95246776163
subpackages:

View File

@ -21,6 +21,7 @@ import (
"net"
"net/url"
"strings"
"sync"
"time"
"github.com/coreos/etcd/etcdserver/api/v3rpc/rpctypes"
@ -46,11 +47,12 @@ type Client struct {
Auth
Maintenance
conn *grpc.ClientConn
cfg Config
creds *credentials.TransportCredentials
balancer *simpleBalancer
retryWrapper retryRpcFunc
conn *grpc.ClientConn
cfg Config
creds *credentials.TransportCredentials
balancer *simpleBalancer
retryWrapper retryRpcFunc
retryAuthWrapper retryRpcFunc
ctx context.Context
cancel context.CancelFunc
@ -59,6 +61,8 @@ type Client struct {
Username string
// Password is a password for authentication
Password string
// tokenCred is an instance of WithPerRPCCredentials()'s argument
tokenCred *authTokenCredential
}
// New creates a new etcdv3 client from a given configuration.
@ -144,7 +148,8 @@ func (c *Client) autoSync() {
}
type authTokenCredential struct {
token string
token string
tokenMu *sync.RWMutex
}
func (cred authTokenCredential) RequireTransportSecurity() bool {
@ -152,6 +157,8 @@ func (cred authTokenCredential) RequireTransportSecurity() bool {
}
func (cred authTokenCredential) GetRequestMetadata(ctx context.Context, s ...string) (map[string]string, error) {
cred.tokenMu.RLock()
defer cred.tokenMu.RUnlock()
return map[string]string{
"token": cred.token,
}, nil
@ -236,22 +243,50 @@ func (c *Client) Dial(endpoint string) (*grpc.ClientConn, error) {
return c.dial(endpoint)
}
func (c *Client) getToken(ctx context.Context) error {
var err error // return last error in a case of fail
var auth *authenticator
for i := 0; i < len(c.cfg.Endpoints); i++ {
endpoint := c.cfg.Endpoints[i]
host := getHost(endpoint)
// use dial options without dopts to avoid reusing the client balancer
auth, err = newAuthenticator(host, c.dialSetupOpts(endpoint))
if err != nil {
continue
}
defer auth.close()
var resp *AuthenticateResponse
resp, err = auth.authenticate(ctx, c.Username, c.Password)
if err != nil {
continue
}
c.tokenCred.tokenMu.Lock()
c.tokenCred.token = resp.Token
c.tokenCred.tokenMu.Unlock()
return nil
}
return err
}
func (c *Client) dial(endpoint string, dopts ...grpc.DialOption) (*grpc.ClientConn, error) {
opts := c.dialSetupOpts(endpoint, dopts...)
host := getHost(endpoint)
if c.Username != "" && c.Password != "" {
// use dial options without dopts to avoid reusing the client balancer
auth, err := newAuthenticator(host, c.dialSetupOpts(endpoint))
if err != nil {
return nil, err
c.tokenCred = &authTokenCredential{
tokenMu: &sync.RWMutex{},
}
defer auth.close()
resp, err := auth.authenticate(c.ctx, c.Username, c.Password)
err := c.getToken(context.TODO())
if err != nil {
return nil, err
}
opts = append(opts, grpc.WithPerRPCCredentials(authTokenCredential{token: resp.Token}))
opts = append(opts, grpc.WithPerRPCCredentials(c.tokenCred))
}
// add metrics options
@ -303,6 +338,7 @@ func newClient(cfg *Config) (*Client, error) {
}
client.conn = conn
client.retryWrapper = client.newRetryWrapper()
client.retryAuthWrapper = client.newAuthRetryWrapper()
// wait for a connection
if cfg.DialTimeout > 0 {

View File

@ -148,7 +148,7 @@ func (kv *kv) do(ctx context.Context, op Op) (OpResponse, error) {
}
case tPut:
var resp *pb.PutResponse
r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV}
r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue}
resp, err = kv.remote.Put(ctx, r)
if err == nil {
return OpResponse{put: (*PutResponse)(resp)}, nil

View File

@ -195,9 +195,6 @@ func (l *lessor) Revoke(ctx context.Context, id LeaseID) (*LeaseRevokeResponse,
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
}
if nerr := l.newStream(); nerr != nil {
return nil, nerr
}
}
}
@ -277,10 +274,6 @@ func (l *lessor) KeepAliveOnce(ctx context.Context, id LeaseID) (*LeaseKeepAlive
if isHaltErr(ctx, err) {
return nil, toErr(ctx, err)
}
if nerr := l.newStream(); nerr != nil {
return nil, nerr
}
}
}
@ -378,10 +371,23 @@ func (l *lessor) recvKeepAliveLoop() (gerr error) {
// resetRecv opens a new lease stream and starts sending LeaseKeepAliveRequests
func (l *lessor) resetRecv() (pb.Lease_LeaseKeepAliveClient, error) {
if err := l.newStream(); err != nil {
sctx, cancel := context.WithCancel(l.stopCtx)
stream, err := l.remote.LeaseKeepAlive(sctx, grpc.FailFast(false))
if err = toErr(sctx, err); err != nil {
cancel()
return nil, err
}
stream := l.getKeepAliveStream()
l.mu.Lock()
defer l.mu.Unlock()
if l.stream != nil && l.streamCancel != nil {
l.stream.CloseSend()
l.streamCancel()
}
l.streamCancel = cancel
l.stream = stream
go l.sendKeepAliveLoop(stream)
return stream, nil
}
@ -477,32 +483,6 @@ func (l *lessor) sendKeepAliveLoop(stream pb.Lease_LeaseKeepAliveClient) {
}
}
func (l *lessor) getKeepAliveStream() pb.Lease_LeaseKeepAliveClient {
l.mu.Lock()
defer l.mu.Unlock()
return l.stream
}
func (l *lessor) newStream() error {
sctx, cancel := context.WithCancel(l.stopCtx)
stream, err := l.remote.LeaseKeepAlive(sctx, grpc.FailFast(false))
if err != nil {
cancel()
return toErr(sctx, err)
}
l.mu.Lock()
defer l.mu.Unlock()
if l.stream != nil && l.streamCancel != nil {
l.stream.CloseSend()
l.streamCancel()
}
l.streamCancel = cancel
l.stream = stream
return nil
}
func (ka *keepAlive) Close() {
close(ka.donec)
for _, ch := range ka.chs {

View File

@ -52,6 +52,9 @@ type Op struct {
// for watch, put, delete
prevKV bool
// for put
ignoreValue bool
// progressNotify is for progress updates.
progressNotify bool
// createdNotify is for created event
@ -94,7 +97,7 @@ func (op Op) toRequestOp() *pb.RequestOp {
case tRange:
return &pb.RequestOp{Request: &pb.RequestOp_RequestRange{RequestRange: op.toRangeRequest()}}
case tPut:
r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV}
r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue}
return &pb.RequestOp{Request: &pb.RequestOp_RequestPut{RequestPut: r}}
case tDeleteRange:
r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV}
@ -360,6 +363,15 @@ func WithPrevKV() OpOption {
}
}
// WithIgnoreValue updates the key using its current value.
// Empty value should be passed when ignore_value is set.
// Returns an error if the key does not exist.
func WithIgnoreValue() OpOption {
return func(op *Op) {
op.ignoreValue = true
}
}
// LeaseOp represents an Operation that lease can execute.
type LeaseOp struct {
id LeaseID

View File

@ -33,13 +33,14 @@ func (c *Client) newRetryWrapper() retryRpcFunc {
return nil
}
// only retry if unavailable
if grpc.Code(err) != codes.Unavailable {
eErr := rpctypes.Error(err)
// always stop retry on etcd errors
if _, ok := eErr.(rpctypes.EtcdError); ok {
return err
}
// always stop retry on etcd errors
eErr := rpctypes.Error(err)
if _, ok := eErr.(rpctypes.EtcdError); ok {
// only retry if unavailable
if grpc.Code(err) != codes.Unavailable {
return err
}
@ -54,17 +55,52 @@ func (c *Client) newRetryWrapper() retryRpcFunc {
}
}
type retryKVClient struct {
pb.KVClient
retryf retryRpcFunc
func (c *Client) newAuthRetryWrapper() retryRpcFunc {
return func(rpcCtx context.Context, f rpcFunc) error {
for {
err := f(rpcCtx)
if err == nil {
return nil
}
// always stop retry on etcd errors other than invalid auth token
if rpctypes.Error(err) == rpctypes.ErrInvalidAuthToken {
gterr := c.getToken(rpcCtx)
if gterr != nil {
return err // return the original error for simplicity
}
continue
}
return err
}
}
}
// RetryKVClient implements a KVClient that uses the client's FailFast retry policy.
func RetryKVClient(c *Client) pb.KVClient {
return &retryKVClient{pb.NewKVClient(c.conn), c.retryWrapper}
retryWrite := &retryWriteKVClient{pb.NewKVClient(c.conn), c.retryWrapper}
return &retryKVClient{&retryWriteKVClient{retryWrite, c.retryAuthWrapper}}
}
func (rkv *retryKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) {
type retryKVClient struct {
*retryWriteKVClient
}
func (rkv *retryKVClient) Range(ctx context.Context, in *pb.RangeRequest, opts ...grpc.CallOption) (resp *pb.RangeResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.retryWriteKVClient.Range(rctx, in, opts...)
return err
})
return resp, err
}
type retryWriteKVClient struct {
pb.KVClient
retryf retryRpcFunc
}
func (rkv *retryWriteKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...grpc.CallOption) (resp *pb.PutResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.Put(rctx, in, opts...)
return err
@ -72,7 +108,7 @@ func (rkv *retryKVClient) Put(ctx context.Context, in *pb.PutRequest, opts ...gr
return resp, err
}
func (rkv *retryKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) {
func (rkv *retryWriteKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeRequest, opts ...grpc.CallOption) (resp *pb.DeleteRangeResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.DeleteRange(rctx, in, opts...)
return err
@ -80,7 +116,7 @@ func (rkv *retryKVClient) DeleteRange(ctx context.Context, in *pb.DeleteRangeReq
return resp, err
}
func (rkv *retryKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) {
func (rkv *retryWriteKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...grpc.CallOption) (resp *pb.TxnResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.Txn(rctx, in, opts...)
return err
@ -88,7 +124,7 @@ func (rkv *retryKVClient) Txn(ctx context.Context, in *pb.TxnRequest, opts ...gr
return resp, err
}
func (rkv *retryKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) {
func (rkv *retryWriteKVClient) Compact(ctx context.Context, in *pb.CompactionRequest, opts ...grpc.CallOption) (resp *pb.CompactionResponse, err error) {
err = rkv.retryf(ctx, func(rctx context.Context) error {
resp, err = rkv.KVClient.Compact(rctx, in, opts...)
return err
@ -103,7 +139,8 @@ type retryLeaseClient struct {
// RetryLeaseClient implements a LeaseClient that uses the client's FailFast retry policy.
func RetryLeaseClient(c *Client) pb.LeaseClient {
return &retryLeaseClient{pb.NewLeaseClient(c.conn), c.retryWrapper}
retry := &retryLeaseClient{pb.NewLeaseClient(c.conn), c.retryWrapper}
return &retryLeaseClient{retry, c.retryAuthWrapper}
}
func (rlc *retryLeaseClient) LeaseGrant(ctx context.Context, in *pb.LeaseGrantRequest, opts ...grpc.CallOption) (resp *pb.LeaseGrantResponse, err error) {

View File

@ -22,6 +22,8 @@ import (
var (
// server-side error
ErrGRPCEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided")
ErrGRPCKeyNotFound = grpc.Errorf(codes.InvalidArgument, "etcdserver: key not found")
ErrGRPCValue = grpc.Errorf(codes.InvalidArgument, "etcdserver: value is provided")
ErrGRPCTooManyOps = grpc.Errorf(codes.InvalidArgument, "etcdserver: too many operations in txn request")
ErrGRPCDuplicateKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: duplicate key given in txn request")
ErrGRPCCompacted = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision has been compacted")
@ -52,6 +54,7 @@ var (
ErrGRPCRoleNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: role is not granted to the user")
ErrGRPCPermissionNotGranted = grpc.Errorf(codes.FailedPrecondition, "etcdserver: permission is not granted to the role")
ErrGRPCAuthNotEnabled = grpc.Errorf(codes.FailedPrecondition, "etcdserver: authentication is not enabled")
ErrGRPCInvalidAuthToken = grpc.Errorf(codes.Unauthenticated, "etcdserver: invalid auth token")
ErrGRPCNoLeader = grpc.Errorf(codes.Unavailable, "etcdserver: no leader")
ErrGRPCNotCapable = grpc.Errorf(codes.Unavailable, "etcdserver: not capable")
@ -63,6 +66,8 @@ var (
errStringToError = map[string]error{
grpc.ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey,
grpc.ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound,
grpc.ErrorDesc(ErrGRPCValue): ErrGRPCValue,
grpc.ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps,
grpc.ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey,
grpc.ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted,
@ -93,6 +98,7 @@ var (
grpc.ErrorDesc(ErrGRPCRoleNotGranted): ErrGRPCRoleNotGranted,
grpc.ErrorDesc(ErrGRPCPermissionNotGranted): ErrGRPCPermissionNotGranted,
grpc.ErrorDesc(ErrGRPCAuthNotEnabled): ErrGRPCAuthNotEnabled,
grpc.ErrorDesc(ErrGRPCInvalidAuthToken): ErrGRPCInvalidAuthToken,
grpc.ErrorDesc(ErrGRPCNoLeader): ErrGRPCNoLeader,
grpc.ErrorDesc(ErrGRPCNotCapable): ErrGRPCNotCapable,
@ -105,6 +111,8 @@ var (
// client-side error
ErrEmptyKey = Error(ErrGRPCEmptyKey)
ErrKeyNotFound = Error(ErrGRPCKeyNotFound)
ErrValue = Error(ErrGRPCValue)
ErrTooManyOps = Error(ErrGRPCTooManyOps)
ErrDuplicateKey = Error(ErrGRPCDuplicateKey)
ErrCompacted = Error(ErrGRPCCompacted)
@ -135,6 +143,7 @@ var (
ErrRoleNotGranted = Error(ErrGRPCRoleNotGranted)
ErrPermissionNotGranted = Error(ErrGRPCPermissionNotGranted)
ErrAuthNotEnabled = Error(ErrGRPCAuthNotEnabled)
ErrInvalidAuthToken = Error(ErrGRPCInvalidAuthToken)
ErrNoLeader = Error(ErrGRPCNoLeader)
ErrNotCapable = Error(ErrGRPCNotCapable)

View File

@ -313,6 +313,9 @@ type PutRequest struct {
// If prev_kv is set, etcd gets the previous key-value pair before changing it.
// The previous key-value pair will be returned in the put response.
PrevKv bool `protobuf:"varint,4,opt,name=prev_kv,json=prevKv,proto3" json:"prev_kv,omitempty"`
// If ignore_value is set, etcd updates the key using its current value.
// Returns an error if the key does not exist.
IgnoreValue bool `protobuf:"varint,5,opt,name=ignore_value,json=ignoreValue,proto3" json:"ignore_value,omitempty"`
}
func (m *PutRequest) Reset() { *m = PutRequest{} }
@ -3941,6 +3944,16 @@ func (m *PutRequest) MarshalTo(dAtA []byte) (int, error) {
}
i++
}
if m.IgnoreValue {
dAtA[i] = 0x28
i++
if m.IgnoreValue {
dAtA[i] = 1
} else {
dAtA[i] = 0
}
i++
}
return i, nil
}
@ -6610,6 +6623,9 @@ func (m *PutRequest) Size() (n int) {
if m.PrevKv {
n += 2
}
if m.IgnoreValue {
n += 2
}
return n
}
@ -8413,6 +8429,26 @@ func (m *PutRequest) Unmarshal(dAtA []byte) error {
}
}
m.PrevKv = bool(v != 0)
case 5:
if wireType != 0 {
return fmt.Errorf("proto: wrong wireType = %d for field IgnoreValue", wireType)
}
var v int
for shift := uint(0); ; shift += 7 {
if shift >= 64 {
return ErrIntOverflowRpc
}
if iNdEx >= l {
return io.ErrUnexpectedEOF
}
b := dAtA[iNdEx]
iNdEx++
v |= (int(b) & 0x7F) << shift
if b < 0x80 {
break
}
}
m.IgnoreValue = bool(v != 0)
default:
iNdEx = preIndex
skippy, err := skipRpc(dAtA[iNdEx:])
@ -16041,218 +16077,219 @@ var (
func init() { proto.RegisterFile("rpc.proto", fileDescriptorRpc) }
var fileDescriptorRpc = []byte{
// 3401 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5b, 0xcb, 0x73, 0x1b, 0xc7,
0xd1, 0xe7, 0x02, 0x24, 0x40, 0x34, 0x1e, 0x84, 0x86, 0x94, 0x04, 0xae, 0x24, 0x8a, 0x1a, 0xbd,
0x28, 0xc9, 0x26, 0x6d, 0xda, 0xdf, 0x77, 0xd0, 0xe7, 0x72, 0x7d, 0x14, 0x09, 0x8b, 0x0c, 0x29,
0x52, 0x5e, 0x52, 0xb2, 0x53, 0xe5, 0x0a, 0x6a, 0x09, 0x8c, 0xc8, 0x2d, 0x02, 0xbb, 0xf0, 0xee,
0x02, 0x22, 0x9d, 0xa4, 0x2a, 0xe5, 0xd8, 0x95, 0x4a, 0x8e, 0xf1, 0x21, 0xaf, 0x63, 0x2a, 0x87,
0xfc, 0x01, 0xb9, 0xe5, 0x0f, 0x48, 0xe5, 0x92, 0x54, 0xe5, 0x1f, 0x48, 0x39, 0x39, 0xe4, 0x90,
0x7b, 0x4e, 0xa9, 0xa4, 0xe6, 0xb5, 0x3b, 0xbb, 0xd8, 0x05, 0xe5, 0x6c, 0x7c, 0x11, 0x77, 0x66,
0x7a, 0xfa, 0xd7, 0xdd, 0x33, 0xdd, 0xd3, 0xd3, 0x03, 0x41, 0xc9, 0xed, 0xb7, 0x97, 0xfb, 0xae,
0xe3, 0x3b, 0xa8, 0x42, 0xfc, 0x76, 0xc7, 0x23, 0xee, 0x90, 0xb8, 0xfd, 0x43, 0x7d, 0xee, 0xc8,
0x39, 0x72, 0xd8, 0xc0, 0x0a, 0xfd, 0xe2, 0x34, 0xfa, 0x3c, 0xa5, 0x59, 0xe9, 0x0d, 0xdb, 0x6d,
0xf6, 0x4f, 0xff, 0x70, 0xe5, 0x64, 0x28, 0x86, 0xae, 0xb0, 0x21, 0x73, 0xe0, 0x1f, 0xb3, 0x7f,
0xfa, 0x87, 0xec, 0x8f, 0x18, 0xbc, 0x7a, 0xe4, 0x38, 0x47, 0x5d, 0xb2, 0x62, 0xf6, 0xad, 0x15,
0xd3, 0xb6, 0x1d, 0xdf, 0xf4, 0x2d, 0xc7, 0xf6, 0xf8, 0x28, 0xfe, 0x5c, 0x83, 0x9a, 0x41, 0xbc,
0xbe, 0x63, 0x7b, 0x64, 0x93, 0x98, 0x1d, 0xe2, 0xa2, 0x6b, 0x00, 0xed, 0xee, 0xc0, 0xf3, 0x89,
0xdb, 0xb2, 0x3a, 0x0d, 0x6d, 0x51, 0x5b, 0x9a, 0x34, 0x4a, 0xa2, 0x67, 0xab, 0x83, 0xae, 0x40,
0xa9, 0x47, 0x7a, 0x87, 0x7c, 0x34, 0xc7, 0x46, 0xa7, 0x79, 0xc7, 0x56, 0x07, 0xe9, 0x30, 0xed,
0x92, 0xa1, 0xe5, 0x59, 0x8e, 0xdd, 0xc8, 0x2f, 0x6a, 0x4b, 0x79, 0x23, 0x68, 0xd3, 0x89, 0xae,
0xf9, 0xc2, 0x6f, 0xf9, 0xc4, 0xed, 0x35, 0x26, 0xf9, 0x44, 0xda, 0x71, 0x40, 0xdc, 0x1e, 0xfe,
0x6c, 0x0a, 0x2a, 0x86, 0x69, 0x1f, 0x11, 0x83, 0x7c, 0x3c, 0x20, 0x9e, 0x8f, 0xea, 0x90, 0x3f,
0x21, 0x67, 0x0c, 0xbe, 0x62, 0xd0, 0x4f, 0x3e, 0xdf, 0x3e, 0x22, 0x2d, 0x62, 0x73, 0xe0, 0x0a,
0x9d, 0x6f, 0x1f, 0x91, 0xa6, 0xdd, 0x41, 0x73, 0x30, 0xd5, 0xb5, 0x7a, 0x96, 0x2f, 0x50, 0x79,
0x23, 0x22, 0xce, 0x64, 0x4c, 0x9c, 0x75, 0x00, 0xcf, 0x71, 0xfd, 0x96, 0xe3, 0x76, 0x88, 0xdb,
0x98, 0x5a, 0xd4, 0x96, 0x6a, 0xab, 0xb7, 0x96, 0xd5, 0x85, 0x58, 0x56, 0x05, 0x5a, 0xde, 0x77,
0x5c, 0x7f, 0x8f, 0xd2, 0x1a, 0x25, 0x4f, 0x7e, 0xa2, 0xf7, 0xa0, 0xcc, 0x98, 0xf8, 0xa6, 0x7b,
0x44, 0xfc, 0x46, 0x81, 0x71, 0xb9, 0x7d, 0x0e, 0x97, 0x03, 0x46, 0x6c, 0x30, 0x78, 0xfe, 0x8d,
0x30, 0x54, 0x3c, 0xe2, 0x5a, 0x66, 0xd7, 0xfa, 0xc4, 0x3c, 0xec, 0x92, 0x46, 0x71, 0x51, 0x5b,
0x9a, 0x36, 0x22, 0x7d, 0x54, 0xff, 0x13, 0x72, 0xe6, 0xb5, 0x1c, 0xbb, 0x7b, 0xd6, 0x98, 0x66,
0x04, 0xd3, 0xb4, 0x63, 0xcf, 0xee, 0x9e, 0xb1, 0x45, 0x73, 0x06, 0xb6, 0xcf, 0x47, 0x4b, 0x6c,
0xb4, 0xc4, 0x7a, 0xd8, 0xf0, 0x12, 0xd4, 0x7b, 0x96, 0xdd, 0xea, 0x39, 0x9d, 0x56, 0x60, 0x10,
0x60, 0x06, 0xa9, 0xf5, 0x2c, 0xfb, 0x89, 0xd3, 0x31, 0xa4, 0x59, 0x28, 0xa5, 0x79, 0x1a, 0xa5,
0x2c, 0x0b, 0x4a, 0xf3, 0x54, 0xa5, 0x5c, 0x86, 0x59, 0xca, 0xb3, 0xed, 0x12, 0xd3, 0x27, 0x21,
0x71, 0x85, 0x11, 0x5f, 0xe8, 0x59, 0xf6, 0x3a, 0x1b, 0x89, 0xd0, 0x9b, 0xa7, 0x23, 0xf4, 0x55,
0x41, 0x6f, 0x9e, 0x46, 0xe9, 0xf1, 0x32, 0x94, 0x02, 0x9b, 0xa3, 0x69, 0x98, 0xdc, 0xdd, 0xdb,
0x6d, 0xd6, 0x27, 0x10, 0x40, 0x61, 0x6d, 0x7f, 0xbd, 0xb9, 0xbb, 0x51, 0xd7, 0x50, 0x19, 0x8a,
0x1b, 0x4d, 0xde, 0xc8, 0xe1, 0x47, 0x00, 0xa1, 0x75, 0x51, 0x11, 0xf2, 0xdb, 0xcd, 0x6f, 0xd6,
0x27, 0x28, 0xcd, 0xf3, 0xa6, 0xb1, 0xbf, 0xb5, 0xb7, 0x5b, 0xd7, 0xe8, 0xe4, 0x75, 0xa3, 0xb9,
0x76, 0xd0, 0xac, 0xe7, 0x28, 0xc5, 0x93, 0xbd, 0x8d, 0x7a, 0x1e, 0x95, 0x60, 0xea, 0xf9, 0xda,
0xce, 0xb3, 0x66, 0x7d, 0x12, 0x7f, 0xa1, 0x41, 0x55, 0xac, 0x17, 0xf7, 0x09, 0xf4, 0x36, 0x14,
0x8e, 0x99, 0x5f, 0xb0, 0xad, 0x58, 0x5e, 0xbd, 0x1a, 0x5b, 0xdc, 0x88, 0xef, 0x18, 0x82, 0x16,
0x61, 0xc8, 0x9f, 0x0c, 0xbd, 0x46, 0x6e, 0x31, 0xbf, 0x54, 0x5e, 0xad, 0x2f, 0x73, 0x87, 0x5d,
0xde, 0x26, 0x67, 0xcf, 0xcd, 0xee, 0x80, 0x18, 0x74, 0x10, 0x21, 0x98, 0xec, 0x39, 0x2e, 0x61,
0x3b, 0x76, 0xda, 0x60, 0xdf, 0x74, 0x1b, 0xb3, 0x45, 0x13, 0xbb, 0x95, 0x37, 0x70, 0x1b, 0xe0,
0xe9, 0xc0, 0x4f, 0xf7, 0x8c, 0x39, 0x98, 0x1a, 0x52, 0xbe, 0xc2, 0x2b, 0x78, 0x83, 0xb9, 0x04,
0x31, 0x3d, 0x12, 0xb8, 0x04, 0x6d, 0xa0, 0xcb, 0x50, 0xec, 0xbb, 0x64, 0xd8, 0x3a, 0x19, 0x32,
0x8c, 0x69, 0xa3, 0x40, 0x9b, 0xdb, 0x43, 0x6c, 0x43, 0x99, 0x81, 0x64, 0xd2, 0xfb, 0x5e, 0xc8,
0x3d, 0xc7, 0xa6, 0x8d, 0xea, 0x2e, 0xf1, 0x3e, 0x02, 0xb4, 0x41, 0xba, 0xc4, 0x27, 0x59, 0xdc,
0x5e, 0xd1, 0x26, 0x1f, 0xd1, 0xe6, 0xc7, 0x1a, 0xcc, 0x46, 0xd8, 0x67, 0x52, 0xab, 0x01, 0xc5,
0x0e, 0x63, 0xc6, 0x25, 0xc8, 0x1b, 0xb2, 0x89, 0x1e, 0xc0, 0xb4, 0x10, 0xc0, 0x6b, 0xe4, 0x53,
0x56, 0xbb, 0xc8, 0x65, 0xf2, 0xf0, 0xdf, 0x35, 0x28, 0x09, 0x45, 0xf7, 0xfa, 0x68, 0x0d, 0xaa,
0x2e, 0x6f, 0xb4, 0x98, 0x3e, 0x42, 0x22, 0x3d, 0x3d, 0x7a, 0x6c, 0x4e, 0x18, 0x15, 0x31, 0x85,
0x75, 0xa3, 0xff, 0x83, 0xb2, 0x64, 0xd1, 0x1f, 0xf8, 0xc2, 0xe4, 0x8d, 0x28, 0x83, 0x70, 0xe7,
0x6c, 0x4e, 0x18, 0x20, 0xc8, 0x9f, 0x0e, 0x7c, 0x74, 0x00, 0x73, 0x72, 0x32, 0xd7, 0x46, 0x88,
0x91, 0x67, 0x5c, 0x16, 0xa3, 0x5c, 0x46, 0x97, 0x6a, 0x73, 0xc2, 0x40, 0x62, 0xbe, 0x32, 0xf8,
0xa8, 0x04, 0x45, 0xd1, 0x8b, 0xff, 0xa1, 0x01, 0x48, 0x83, 0xee, 0xf5, 0xd1, 0x06, 0xd4, 0x5c,
0xd1, 0x8a, 0x28, 0x7c, 0x25, 0x51, 0x61, 0xb1, 0x0e, 0x13, 0x46, 0x55, 0x4e, 0xe2, 0x2a, 0xbf,
0x0b, 0x95, 0x80, 0x4b, 0xa8, 0xf3, 0x7c, 0x82, 0xce, 0x01, 0x87, 0xb2, 0x9c, 0x40, 0xb5, 0xfe,
0x00, 0x2e, 0x06, 0xf3, 0x13, 0xd4, 0xbe, 0x31, 0x46, 0xed, 0x80, 0xe1, 0xac, 0xe4, 0xa0, 0x2a,
0x0e, 0xf4, 0xac, 0xe1, 0xdd, 0xf8, 0xd7, 0x79, 0x28, 0xae, 0x3b, 0xbd, 0xbe, 0xe9, 0xd2, 0x35,
0x2a, 0xb8, 0xc4, 0x1b, 0x74, 0x7d, 0xa6, 0x6e, 0x6d, 0xf5, 0x66, 0x14, 0x41, 0x90, 0xc9, 0xbf,
0x06, 0x23, 0x35, 0xc4, 0x14, 0x3a, 0x59, 0x1c, 0x2d, 0xb9, 0x57, 0x98, 0x2c, 0x0e, 0x16, 0x31,
0x45, 0xfa, 0x52, 0x3e, 0xf4, 0x25, 0x1d, 0x8a, 0x43, 0xe2, 0x86, 0xc7, 0xe1, 0xe6, 0x84, 0x21,
0x3b, 0xd0, 0x3d, 0x98, 0x89, 0x87, 0xe6, 0x29, 0x41, 0x53, 0x6b, 0x47, 0x23, 0xf9, 0x4d, 0xa8,
0x44, 0xce, 0x87, 0x82, 0xa0, 0x2b, 0xf7, 0x94, 0xe3, 0xe1, 0x92, 0x0c, 0x4a, 0xf4, 0x2c, 0xab,
0x6c, 0x4e, 0x88, 0xb0, 0x84, 0xff, 0x1f, 0xaa, 0x11, 0x5d, 0x69, 0xf8, 0x6d, 0xbe, 0xff, 0x6c,
0x6d, 0x87, 0xc7, 0xea, 0xc7, 0x2c, 0x3c, 0x1b, 0x75, 0x8d, 0x86, 0xfc, 0x9d, 0xe6, 0xfe, 0x7e,
0x3d, 0x87, 0xaa, 0x50, 0xda, 0xdd, 0x3b, 0x68, 0x71, 0xaa, 0x3c, 0x7e, 0x27, 0xe0, 0x20, 0x62,
0xbd, 0x12, 0xe2, 0x27, 0x94, 0x10, 0xaf, 0xc9, 0x10, 0x9f, 0x0b, 0x43, 0x7c, 0xfe, 0x51, 0x0d,
0x2a, 0xdc, 0x3e, 0xad, 0x81, 0x4d, 0x8f, 0x99, 0x5f, 0x6a, 0x00, 0x07, 0xa7, 0xb6, 0x0c, 0x40,
0x2b, 0x50, 0x6c, 0x73, 0xe6, 0x0d, 0x8d, 0xf9, 0xf3, 0xc5, 0x44, 0x93, 0x1b, 0x92, 0x0a, 0xbd,
0x09, 0x45, 0x6f, 0xd0, 0x6e, 0x13, 0x4f, 0x86, 0xfb, 0xcb, 0xf1, 0x90, 0x22, 0x1c, 0xde, 0x90,
0x74, 0x74, 0xca, 0x0b, 0xd3, 0xea, 0x0e, 0x58, 0xf0, 0x1f, 0x3f, 0x45, 0xd0, 0xe1, 0x9f, 0x69,
0x50, 0x66, 0x52, 0x66, 0x8a, 0x63, 0x57, 0xa1, 0xc4, 0x64, 0x20, 0x1d, 0x11, 0xc9, 0xa6, 0x8d,
0xb0, 0x03, 0xfd, 0x2f, 0x94, 0xe4, 0x0e, 0x96, 0xc1, 0xac, 0x91, 0xcc, 0x76, 0xaf, 0x6f, 0x84,
0xa4, 0x78, 0x1b, 0x2e, 0x30, 0xab, 0xb4, 0x69, 0x62, 0x29, 0xed, 0xa8, 0xa6, 0x5e, 0x5a, 0x2c,
0xf5, 0xd2, 0x61, 0xba, 0x7f, 0x7c, 0xe6, 0x59, 0x6d, 0xb3, 0x2b, 0xa4, 0x08, 0xda, 0xf8, 0x1b,
0x80, 0x54, 0x66, 0x59, 0xd4, 0xc5, 0x55, 0x28, 0x6f, 0x9a, 0xde, 0xb1, 0x10, 0x09, 0x7f, 0x08,
0x15, 0xde, 0xcc, 0x64, 0x43, 0x04, 0x93, 0xc7, 0xa6, 0x77, 0xcc, 0x04, 0xaf, 0x1a, 0xec, 0x1b,
0x5f, 0x80, 0x99, 0x7d, 0xdb, 0xec, 0x7b, 0xc7, 0x8e, 0x8c, 0xb5, 0x34, 0xb1, 0xae, 0x87, 0x7d,
0x99, 0x10, 0xef, 0xc2, 0x8c, 0x4b, 0x7a, 0xa6, 0x65, 0x5b, 0xf6, 0x51, 0xeb, 0xf0, 0xcc, 0x27,
0x9e, 0xc8, 0xbb, 0x6b, 0x41, 0xf7, 0x23, 0xda, 0x4b, 0x45, 0x3b, 0xec, 0x3a, 0x87, 0xc2, 0xe3,
0xd9, 0x37, 0xfe, 0x8d, 0x06, 0x95, 0x0f, 0x4c, 0xbf, 0x2d, 0xad, 0x80, 0xb6, 0xa0, 0x16, 0xf8,
0x39, 0xeb, 0x11, 0xb2, 0xc4, 0x02, 0x3e, 0x9b, 0x23, 0x33, 0x32, 0x19, 0xf0, 0xab, 0x6d, 0xb5,
0x83, 0xb1, 0x32, 0xed, 0x36, 0xe9, 0x06, 0xac, 0x72, 0xe9, 0xac, 0x18, 0xa1, 0xca, 0x4a, 0xed,
0x78, 0x34, 0x13, 0x1e, 0x86, 0xdc, 0x2d, 0x7f, 0x9e, 0x03, 0x34, 0x2a, 0xc3, 0x57, 0xcd, 0x0f,
0x6e, 0x43, 0xcd, 0xf3, 0x4d, 0xd7, 0x6f, 0xc5, 0x6e, 0x25, 0x55, 0xd6, 0x1b, 0xc4, 0xaa, 0xbb,
0x30, 0xd3, 0x77, 0x9d, 0x23, 0x97, 0x78, 0x5e, 0xcb, 0x76, 0x7c, 0xeb, 0xc5, 0x99, 0x48, 0x8e,
0x6a, 0xb2, 0x7b, 0x97, 0xf5, 0xa2, 0x26, 0x14, 0x5f, 0x58, 0x5d, 0x9f, 0xb8, 0x5e, 0x63, 0x6a,
0x31, 0xbf, 0x54, 0x5b, 0x7d, 0x70, 0x9e, 0xd5, 0x96, 0xdf, 0x63, 0xf4, 0x07, 0x67, 0x7d, 0x62,
0xc8, 0xb9, 0x6a, 0xda, 0x52, 0x88, 0xa4, 0x2d, 0xb7, 0x01, 0x42, 0x7a, 0x1a, 0xb5, 0x76, 0xf7,
0x9e, 0x3e, 0x3b, 0xa8, 0x4f, 0xa0, 0x0a, 0x4c, 0xef, 0xee, 0x6d, 0x34, 0x77, 0x9a, 0x34, 0xae,
0xe1, 0x15, 0x69, 0x1b, 0xd5, 0x86, 0x68, 0x1e, 0xa6, 0x5f, 0xd2, 0x5e, 0x79, 0x6d, 0xcb, 0x1b,
0x45, 0xd6, 0xde, 0xea, 0xe0, 0xbf, 0x69, 0x50, 0x15, 0xbb, 0x20, 0xd3, 0x56, 0x54, 0x21, 0x72,
0x11, 0x08, 0x9a, 0x23, 0xf1, 0xdd, 0xd1, 0x11, 0xa9, 0x98, 0x6c, 0x52, 0x77, 0xe7, 0x8b, 0x4d,
0x3a, 0xc2, 0xac, 0x41, 0x1b, 0xdd, 0x83, 0x7a, 0x9b, 0xbb, 0x7b, 0xec, 0xd8, 0x31, 0x66, 0x44,
0x7f, 0xb0, 0x48, 0xb7, 0xa1, 0x40, 0x86, 0xc4, 0xf6, 0xbd, 0x46, 0x99, 0xc5, 0xa6, 0xaa, 0x4c,
0xb4, 0x9a, 0xb4, 0xd7, 0x10, 0x83, 0xf8, 0x7f, 0xe0, 0xc2, 0x0e, 0xcd, 0x74, 0x1f, 0xbb, 0xa6,
0xad, 0xe6, 0xcc, 0x07, 0x07, 0x3b, 0xc2, 0x2a, 0xf4, 0x13, 0xd5, 0x20, 0xb7, 0xb5, 0x21, 0x74,
0xc8, 0x6d, 0x6d, 0xe0, 0x4f, 0x35, 0x40, 0xea, 0xbc, 0x4c, 0x66, 0x8a, 0x31, 0x97, 0xf0, 0xf9,
0x10, 0x7e, 0x0e, 0xa6, 0x88, 0xeb, 0x3a, 0x2e, 0x33, 0x48, 0xc9, 0xe0, 0x0d, 0x7c, 0x4b, 0xc8,
0x60, 0x90, 0xa1, 0x73, 0x12, 0xec, 0x79, 0xce, 0x4d, 0x0b, 0x44, 0xdd, 0x86, 0xd9, 0x08, 0x55,
0xa6, 0x18, 0x79, 0x17, 0x2e, 0x32, 0x66, 0xdb, 0x84, 0xf4, 0xd7, 0xba, 0xd6, 0x30, 0x15, 0xb5,
0x0f, 0x97, 0xe2, 0x84, 0x5f, 0xaf, 0x8d, 0xf0, 0x3b, 0x02, 0xf1, 0xc0, 0xea, 0x91, 0x03, 0x67,
0x27, 0x5d, 0x36, 0x1a, 0xf8, 0xe8, 0x4d, 0x58, 0x1c, 0x26, 0xec, 0x1b, 0xff, 0x4a, 0x83, 0xcb,
0x23, 0xd3, 0xbf, 0xe6, 0x55, 0x5d, 0x00, 0x38, 0xa2, 0xdb, 0x87, 0x74, 0xe8, 0x00, 0xbf, 0xc3,
0x29, 0x3d, 0x81, 0x9c, 0x34, 0x76, 0x54, 0x84, 0x9c, 0xc7, 0x50, 0x78, 0xc2, 0xca, 0x27, 0x8a,
0x56, 0x93, 0x52, 0x2b, 0xdb, 0xec, 0xf1, 0x5b, 0x5d, 0xc9, 0x60, 0xdf, 0xec, 0xe8, 0x24, 0xc4,
0x7d, 0x66, 0xec, 0xf0, 0x23, 0xba, 0x64, 0x04, 0x6d, 0x8a, 0xde, 0xee, 0x5a, 0xc4, 0xf6, 0xd9,
0xe8, 0x24, 0x1b, 0x55, 0x7a, 0xf0, 0x32, 0xd4, 0x39, 0xd2, 0x5a, 0xa7, 0xa3, 0x1c, 0xd3, 0x01,
0x3f, 0x2d, 0xca, 0x0f, 0xbf, 0x84, 0x0b, 0x0a, 0x7d, 0x26, 0xd3, 0xbd, 0x06, 0x05, 0x5e, 0x23,
0x12, 0x27, 0xc4, 0x5c, 0x74, 0x16, 0x87, 0x31, 0x04, 0x0d, 0xbe, 0x0d, 0xb3, 0xa2, 0x87, 0xf4,
0x9c, 0xa4, 0x55, 0x67, 0xf6, 0xc1, 0x3b, 0x30, 0x17, 0x25, 0xcb, 0xe4, 0x08, 0x6b, 0x12, 0xf4,
0x59, 0xbf, 0xa3, 0x1c, 0x38, 0xf1, 0x45, 0x51, 0x0d, 0x96, 0x8b, 0x19, 0x2c, 0x10, 0x48, 0xb2,
0xc8, 0x24, 0xd0, 0xac, 0x34, 0xff, 0x8e, 0xe5, 0x05, 0x69, 0xc5, 0x27, 0x80, 0xd4, 0xce, 0x4c,
0x8b, 0xb2, 0x0c, 0x45, 0x6e, 0x70, 0x99, 0xb9, 0x26, 0xaf, 0x8a, 0x24, 0xa2, 0x02, 0x6d, 0x90,
0x17, 0xae, 0x79, 0xd4, 0x23, 0x41, 0x64, 0xa5, 0xf9, 0x9a, 0xda, 0x99, 0x49, 0xe3, 0x3f, 0x68,
0x50, 0x59, 0xeb, 0x9a, 0x6e, 0x4f, 0x1a, 0xff, 0x5d, 0x28, 0xf0, 0x44, 0x50, 0xdc, 0x9d, 0xee,
0x44, 0xd9, 0xa8, 0xb4, 0xbc, 0xb1, 0xc6, 0xd3, 0x46, 0x31, 0x8b, 0x2e, 0x96, 0x28, 0x4d, 0x6e,
0xc4, 0x4a, 0x95, 0x1b, 0xe8, 0x75, 0x98, 0x32, 0xe9, 0x14, 0xe6, 0xbf, 0xb5, 0x78, 0x0a, 0xce,
0xb8, 0xb1, 0x43, 0x9b, 0x53, 0xe1, 0xb7, 0xa1, 0xac, 0x20, 0xd0, 0x9b, 0xc5, 0xe3, 0xa6, 0x38,
0x98, 0xd7, 0xd6, 0x0f, 0xb6, 0x9e, 0xf3, 0x0b, 0x47, 0x0d, 0x60, 0xa3, 0x19, 0xb4, 0x73, 0xf8,
0x43, 0x31, 0x4b, 0x78, 0xb8, 0x2a, 0x8f, 0x96, 0x26, 0x4f, 0xee, 0x95, 0xe4, 0x39, 0x85, 0xaa,
0x50, 0x3f, 0xd3, 0x1e, 0x78, 0x13, 0x0a, 0x8c, 0x9f, 0xdc, 0x02, 0xf3, 0x09, 0xb0, 0xd2, 0x3b,
0x39, 0x21, 0x9e, 0x81, 0xea, 0xbe, 0x6f, 0xfa, 0x03, 0x4f, 0x6e, 0x81, 0xdf, 0x6b, 0x50, 0x93,
0x3d, 0x59, 0xcb, 0x2c, 0xf2, 0x7a, 0xca, 0x63, 0x5e, 0x70, 0x39, 0xbd, 0x04, 0x85, 0xce, 0xe1,
0xbe, 0xf5, 0x89, 0x2c, 0x66, 0x89, 0x16, 0xed, 0xef, 0x72, 0x1c, 0x5e, 0x50, 0x16, 0x2d, 0x7a,
0xd1, 0x71, 0xcd, 0x17, 0xfe, 0x96, 0xdd, 0x21, 0xa7, 0x2c, 0x9f, 0x98, 0x34, 0xc2, 0x0e, 0x76,
0x37, 0x11, 0x85, 0x67, 0x96, 0x7f, 0xa9, 0x85, 0xe8, 0x59, 0xb8, 0xb0, 0x36, 0xf0, 0x8f, 0x9b,
0xb6, 0x79, 0xd8, 0x95, 0x41, 0x00, 0xcf, 0x01, 0xa2, 0x9d, 0x1b, 0x96, 0xa7, 0xf6, 0x36, 0x61,
0x96, 0xf6, 0x12, 0xdb, 0xb7, 0xda, 0x4a, 0xc4, 0x90, 0x61, 0x5b, 0x8b, 0x85, 0x6d, 0xd3, 0xf3,
0x5e, 0x3a, 0x6e, 0x47, 0xa8, 0x16, 0xb4, 0xf1, 0x06, 0x67, 0xfe, 0xcc, 0x8b, 0x04, 0xe6, 0xaf,
0xca, 0x65, 0x29, 0xe4, 0xf2, 0x98, 0xf8, 0x63, 0xb8, 0xe0, 0x07, 0x70, 0x51, 0x52, 0x8a, 0xfa,
0xc5, 0x18, 0xe2, 0x3d, 0xb8, 0x26, 0x89, 0xd7, 0x8f, 0x69, 0x56, 0xfd, 0x54, 0x00, 0xfe, 0xa7,
0x72, 0x3e, 0x82, 0x46, 0x20, 0x27, 0xcb, 0xb4, 0x9c, 0xae, 0x2a, 0xc0, 0xc0, 0x13, 0x7b, 0xa6,
0x64, 0xb0, 0x6f, 0xda, 0xe7, 0x3a, 0xdd, 0xe0, 0x10, 0xa4, 0xdf, 0x78, 0x1d, 0xe6, 0x25, 0x0f,
0x91, 0x03, 0x45, 0x99, 0x8c, 0x08, 0x94, 0xc4, 0x44, 0x18, 0x8c, 0x4e, 0x1d, 0x6f, 0x76, 0x95,
0x32, 0x6a, 0x5a, 0xc6, 0x53, 0x53, 0x78, 0x5e, 0xe4, 0x3b, 0x82, 0x0a, 0xa6, 0x06, 0x6d, 0xd1,
0x4d, 0x19, 0xa8, 0xdd, 0x62, 0x21, 0x68, 0xf7, 0xc8, 0x42, 0x8c, 0xb0, 0xfe, 0x08, 0x16, 0x02,
0x21, 0xa8, 0xdd, 0x9e, 0x12, 0xb7, 0x67, 0x79, 0x9e, 0x72, 0xe3, 0x4e, 0x52, 0xfc, 0x0e, 0x4c,
0xf6, 0x89, 0x88, 0x29, 0xe5, 0x55, 0xb4, 0xcc, 0x9f, 0x87, 0x96, 0x95, 0xc9, 0x6c, 0x1c, 0x77,
0xe0, 0xba, 0xe4, 0xce, 0x2d, 0x9a, 0xc8, 0x3e, 0x2e, 0x94, 0xbc, 0x8d, 0x71, 0xb3, 0x8e, 0xde,
0xc6, 0xf2, 0x7c, 0xed, 0xe5, 0x6d, 0x8c, 0x9e, 0x15, 0xaa, 0x6f, 0x65, 0x3a, 0x2b, 0xb6, 0xb9,
0x4d, 0x03, 0x97, 0xcc, 0xc4, 0xec, 0x10, 0xe6, 0xa2, 0x9e, 0x9c, 0x29, 0x8c, 0xcd, 0xc1, 0x94,
0xef, 0x9c, 0x10, 0x19, 0xc4, 0x78, 0x43, 0x0a, 0x1c, 0xb8, 0x79, 0x26, 0x81, 0xcd, 0x90, 0x19,
0xdb, 0x92, 0x59, 0xe5, 0xa5, 0xab, 0x29, 0xf3, 0x19, 0xde, 0xc0, 0xbb, 0x70, 0x29, 0x1e, 0x26,
0x32, 0x89, 0xfc, 0x9c, 0x6f, 0xe0, 0xa4, 0x48, 0x92, 0x89, 0xef, 0xfb, 0x61, 0x30, 0x50, 0x02,
0x4a, 0x26, 0x96, 0x06, 0xe8, 0x49, 0xf1, 0xe5, 0xbf, 0xb1, 0x5f, 0x83, 0x70, 0x93, 0x89, 0x99,
0x17, 0x32, 0xcb, 0xbe, 0xfc, 0x61, 0x8c, 0xc8, 0x8f, 0x8d, 0x11, 0xc2, 0x49, 0xc2, 0x28, 0xf6,
0x35, 0x6c, 0x3a, 0x81, 0x11, 0x06, 0xd0, 0xac, 0x18, 0xf4, 0x0c, 0x09, 0x30, 0x58, 0x43, 0x6e,
0x6c, 0x35, 0xec, 0x66, 0x5a, 0x8c, 0x0f, 0xc2, 0xd8, 0x39, 0x12, 0x99, 0x33, 0x31, 0xfe, 0x10,
0x16, 0xd3, 0x83, 0x72, 0x16, 0xce, 0xf7, 0x31, 0x94, 0x82, 0x84, 0x52, 0x79, 0x5a, 0x2d, 0x43,
0x71, 0x77, 0x6f, 0xff, 0xe9, 0xda, 0x7a, 0xb3, 0xae, 0xad, 0xfe, 0x33, 0x0f, 0xb9, 0xed, 0xe7,
0xe8, 0x5b, 0x30, 0xc5, 0x1f, 0x5e, 0xc6, 0xbc, 0x4b, 0xe9, 0xe3, 0x9e, 0x70, 0xf0, 0xd5, 0x4f,
0xff, 0xf4, 0xd7, 0x2f, 0x72, 0x97, 0xf0, 0x85, 0x95, 0xe1, 0x5b, 0x66, 0xb7, 0x7f, 0x6c, 0xae,
0x9c, 0x0c, 0x57, 0xd8, 0x99, 0xf0, 0x50, 0xbb, 0x8f, 0x9e, 0x43, 0xfe, 0xe9, 0xc0, 0x47, 0xa9,
0x8f, 0x56, 0x7a, 0xfa, 0xd3, 0x0e, 0xd6, 0x19, 0xe7, 0x39, 0x3c, 0xa3, 0x72, 0xee, 0x0f, 0x7c,
0xca, 0x77, 0x08, 0x65, 0xe5, 0x75, 0x06, 0x9d, 0xfb, 0x9c, 0xa5, 0x9f, 0xff, 0xf2, 0x83, 0x31,
0xc3, 0xbb, 0x8a, 0x2f, 0xab, 0x78, 0xfc, 0x11, 0x49, 0xd5, 0xe7, 0xe0, 0xd4, 0x8e, 0xeb, 0x13,
0x3e, 0x30, 0xc4, 0xf5, 0x51, 0x8a, 0xfa, 0xc9, 0xfa, 0xf8, 0xa7, 0x36, 0xe5, 0xeb, 0x88, 0x17,
0xa5, 0xb6, 0x8f, 0xae, 0x27, 0xbc, 0x48, 0xa8, 0xb5, 0x77, 0x7d, 0x31, 0x9d, 0x40, 0x20, 0xdd,
0x60, 0x48, 0x57, 0xf0, 0x25, 0x15, 0xa9, 0x1d, 0xd0, 0x3d, 0xd4, 0xee, 0xaf, 0x1e, 0xc3, 0x14,
0xab, 0x18, 0xa2, 0x96, 0xfc, 0xd0, 0x13, 0x6a, 0x9d, 0x29, 0x3b, 0x20, 0x52, 0x6b, 0xc4, 0xf3,
0x0c, 0x6d, 0x16, 0xd7, 0x02, 0x34, 0x56, 0x34, 0x7c, 0xa8, 0xdd, 0x5f, 0xd2, 0xde, 0xd0, 0x56,
0xbf, 0x3f, 0x09, 0x53, 0xac, 0x52, 0x83, 0xfa, 0x00, 0x61, 0x0d, 0x2e, 0xae, 0xe7, 0x48, 0x55,
0x2f, 0xae, 0xe7, 0x68, 0xf9, 0x0e, 0x5f, 0x67, 0xc8, 0xf3, 0x78, 0x2e, 0x40, 0x66, 0xaf, 0xe0,
0x2b, 0xac, 0x26, 0x43, 0xcd, 0xfa, 0x12, 0xca, 0x4a, 0x2d, 0x0d, 0x25, 0x71, 0x8c, 0x14, 0xe3,
0xe2, 0xdb, 0x24, 0xa1, 0x10, 0x87, 0x6f, 0x32, 0xd0, 0x6b, 0xb8, 0xa1, 0x1a, 0x97, 0xe3, 0xba,
0x8c, 0x92, 0x02, 0x7f, 0xa6, 0x41, 0x2d, 0x5a, 0x4f, 0x43, 0x37, 0x13, 0x58, 0xc7, 0xcb, 0x72,
0xfa, 0xad, 0xf1, 0x44, 0xa9, 0x22, 0x70, 0xfc, 0x13, 0x42, 0xfa, 0x26, 0xa5, 0x14, 0xb6, 0x47,
0x3f, 0xd0, 0x60, 0x26, 0x56, 0x25, 0x43, 0x49, 0x10, 0x23, 0x35, 0x38, 0xfd, 0xf6, 0x39, 0x54,
0x42, 0x92, 0xbb, 0x4c, 0x92, 0x1b, 0xf8, 0xea, 0xa8, 0x31, 0x7c, 0xab, 0x47, 0x7c, 0x47, 0x48,
0xb3, 0xfa, 0xaf, 0x3c, 0x14, 0xd7, 0xf9, 0xaf, 0x8c, 0x90, 0x0f, 0xa5, 0xa0, 0xf2, 0x84, 0x16,
0x92, 0xaa, 0x12, 0x61, 0xca, 0xae, 0x5f, 0x4f, 0x1d, 0x17, 0x22, 0xdc, 0x61, 0x22, 0x2c, 0xe2,
0x2b, 0x81, 0x08, 0xe2, 0xd7, 0x4c, 0x2b, 0xfc, 0xf2, 0xbd, 0x62, 0x76, 0x3a, 0x74, 0x49, 0xbe,
0xa7, 0x41, 0x45, 0x2d, 0x28, 0xa1, 0x1b, 0x89, 0xf5, 0x10, 0xb5, 0x26, 0xa5, 0xe3, 0x71, 0x24,
0x02, 0xff, 0x1e, 0xc3, 0xbf, 0x89, 0x17, 0xd2, 0xf0, 0x5d, 0x46, 0x1f, 0x15, 0x81, 0x97, 0x90,
0x92, 0x45, 0x88, 0x54, 0xa8, 0x92, 0x45, 0x88, 0x56, 0xa0, 0xce, 0x17, 0x61, 0xc0, 0xe8, 0xa9,
0x08, 0xa7, 0x00, 0x61, 0x85, 0x09, 0x25, 0x1a, 0x57, 0xb9, 0xc4, 0xc4, 0x7d, 0x70, 0xb4, 0x38,
0x95, 0xb0, 0x03, 0x62, 0xd8, 0x5d, 0xcb, 0xa3, 0xbe, 0xb8, 0xfa, 0xdb, 0x49, 0x28, 0x3f, 0x31,
0x2d, 0xdb, 0x27, 0xb6, 0x69, 0xb7, 0x09, 0x3a, 0x82, 0x29, 0x76, 0x4a, 0xc5, 0x03, 0x8f, 0x5a,
0xf6, 0x89, 0x07, 0x9e, 0x48, 0x4d, 0x04, 0xdf, 0x66, 0xd0, 0xd7, 0xb1, 0x1e, 0x40, 0xf7, 0x42,
0xfe, 0x2b, 0xac, 0x9e, 0x41, 0x55, 0x3e, 0x81, 0x02, 0xaf, 0x5f, 0xa0, 0x18, 0xb7, 0x48, 0x9d,
0x43, 0xbf, 0x9a, 0x3c, 0x98, 0xba, 0xcb, 0x54, 0x2c, 0x8f, 0x11, 0x53, 0xb0, 0x6f, 0x03, 0x84,
0x05, 0xb3, 0xb8, 0x7d, 0x47, 0xea, 0x6b, 0xfa, 0x62, 0x3a, 0x81, 0x00, 0xbe, 0xcf, 0x80, 0x6f,
0xe1, 0xeb, 0x89, 0xc0, 0x9d, 0x60, 0x02, 0x05, 0x6f, 0xc3, 0xe4, 0xa6, 0xe9, 0x1d, 0xa3, 0xd8,
0x21, 0xa4, 0xbc, 0x92, 0xea, 0x7a, 0xd2, 0x90, 0x80, 0xba, 0xc5, 0xa0, 0x16, 0xf0, 0x7c, 0x22,
0xd4, 0xb1, 0xe9, 0xd1, 0x98, 0x8e, 0x06, 0x30, 0x2d, 0x5f, 0x3e, 0xd1, 0xb5, 0x98, 0xcd, 0xa2,
0xaf, 0xa4, 0xfa, 0x42, 0xda, 0xb0, 0x00, 0x5c, 0x62, 0x80, 0x18, 0x5f, 0x4b, 0x36, 0xaa, 0x20,
0x7f, 0xa8, 0xdd, 0x7f, 0x43, 0x5b, 0xfd, 0x51, 0x1d, 0x26, 0x69, 0xbe, 0x44, 0x4f, 0x91, 0xf0,
0x9a, 0x19, 0xb7, 0xf0, 0x48, 0x71, 0x27, 0x6e, 0xe1, 0xd1, 0x1b, 0x6a, 0xc2, 0x29, 0xc2, 0x7e,
0x6b, 0x49, 0x18, 0x15, 0xd5, 0xd8, 0x87, 0xb2, 0x72, 0x19, 0x45, 0x09, 0x1c, 0xa3, 0xa5, 0xa3,
0xf8, 0x29, 0x92, 0x70, 0x93, 0xc5, 0x8b, 0x0c, 0x54, 0xc7, 0x17, 0xa3, 0xa0, 0x1d, 0x4e, 0x46,
0x51, 0xbf, 0x03, 0x15, 0xf5, 0xd6, 0x8a, 0x12, 0x98, 0xc6, 0x6a, 0x53, 0xf1, 0x58, 0x91, 0x74,
0xe9, 0x4d, 0x70, 0x9a, 0xe0, 0x97, 0xa5, 0x92, 0x96, 0xa2, 0x7f, 0x0c, 0x45, 0x71, 0x97, 0x4d,
0xd2, 0x37, 0x5a, 0xcd, 0x4a, 0xd2, 0x37, 0x76, 0x11, 0x4e, 0x48, 0x49, 0x18, 0x2c, 0xcd, 0xd9,
0x65, 0x80, 0x16, 0x90, 0x8f, 0x89, 0x9f, 0x06, 0x19, 0xd6, 0x67, 0xd2, 0x20, 0x95, 0xfb, 0xd2,
0x58, 0xc8, 0x23, 0xe2, 0x8b, 0xbd, 0x2c, 0x2f, 0x23, 0x28, 0x85, 0xa3, 0x1a, 0x0d, 0xf1, 0x38,
0x92, 0xd4, 0x2c, 0x32, 0x44, 0x15, 0xa1, 0x10, 0x7d, 0x17, 0x20, 0xbc, 0x78, 0xc7, 0x13, 0x83,
0xc4, 0xea, 0x5d, 0x3c, 0x31, 0x48, 0xbe, 0xbb, 0x27, 0x78, 0x70, 0x08, 0xce, 0x33, 0x59, 0x0a,
0xff, 0x13, 0x0d, 0xd0, 0xe8, 0x45, 0x1d, 0x3d, 0x48, 0x86, 0x48, 0x2c, 0x0c, 0xea, 0xaf, 0xbd,
0x1a, 0x71, 0x6a, 0xf4, 0x0c, 0xe5, 0x6a, 0xb3, 0x29, 0xfd, 0x97, 0x54, 0xb2, 0xcf, 0x35, 0xa8,
0x46, 0xae, 0xfa, 0xe8, 0x4e, 0xca, 0x3a, 0xc7, 0x8a, 0x8b, 0xfa, 0xdd, 0x73, 0xe9, 0x52, 0x73,
0x27, 0x65, 0x57, 0xc8, 0xbc, 0xf1, 0x87, 0x1a, 0xd4, 0xa2, 0xf5, 0x01, 0x94, 0x02, 0x30, 0x52,
0xa1, 0xd4, 0x97, 0xce, 0x27, 0x7c, 0x85, 0xd5, 0x0a, 0x53, 0xc9, 0x8f, 0xa1, 0x28, 0xca, 0x0a,
0x49, 0x6e, 0x11, 0x2d, 0x70, 0x26, 0xb9, 0x45, 0xac, 0x26, 0x91, 0xe6, 0x16, 0xf4, 0x86, 0xae,
0x78, 0xa2, 0x28, 0x3e, 0xa4, 0x41, 0x8e, 0xf7, 0xc4, 0x58, 0xe5, 0x62, 0x2c, 0x64, 0xe8, 0x89,
0xb2, 0xf4, 0x80, 0x52, 0x38, 0x9e, 0xe3, 0x89, 0xf1, 0xca, 0x45, 0x9a, 0x27, 0x32, 0x54, 0xc5,
0x13, 0xc3, 0x4a, 0x41, 0x92, 0x27, 0x8e, 0x94, 0x6f, 0x93, 0x3c, 0x71, 0xb4, 0xd8, 0x90, 0xb6,
0xb6, 0x0c, 0x3c, 0xe2, 0x89, 0xb3, 0x09, 0x95, 0x05, 0xf4, 0x5a, 0x8a, 0x4d, 0x13, 0x4b, 0xc3,
0xfa, 0xeb, 0xaf, 0x48, 0x3d, 0xde, 0x03, 0xf8, 0x6a, 0x48, 0x0f, 0xf8, 0x85, 0x06, 0x73, 0x49,
0xa5, 0x09, 0x94, 0x02, 0x96, 0x52, 0x57, 0xd6, 0x97, 0x5f, 0x95, 0xfc, 0x15, 0xec, 0x16, 0xf8,
0xc4, 0xa3, 0xfa, 0xef, 0xbe, 0x5c, 0xd0, 0xfe, 0xf8, 0xe5, 0x82, 0xf6, 0xe7, 0x2f, 0x17, 0xb4,
0x9f, 0xfe, 0x65, 0x61, 0xe2, 0xb0, 0xc0, 0xfe, 0xc3, 0xc3, 0x5b, 0xff, 0x0e, 0x00, 0x00, 0xff,
0xff, 0x73, 0x7e, 0xb4, 0xb4, 0x77, 0x31, 0x00, 0x00,
// 3423 bytes of a gzipped FileDescriptorProto
0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x5b, 0xcd, 0x73, 0x1b, 0xc7,
0xb1, 0xe7, 0x02, 0x04, 0x40, 0x34, 0x3e, 0x08, 0x0d, 0x29, 0x09, 0x84, 0x24, 0x8a, 0x1a, 0x7d,
0x51, 0x92, 0x4d, 0xda, 0xb4, 0xdf, 0x3b, 0xe8, 0xb9, 0x5c, 0x8f, 0x22, 0x61, 0x91, 0x8f, 0x14,
0x29, 0x2f, 0x29, 0xd9, 0xaf, 0xca, 0x15, 0xd4, 0x12, 0x18, 0x81, 0x5b, 0x04, 0x76, 0xe1, 0xdd,
0x05, 0x44, 0x3a, 0x49, 0x55, 0xca, 0xb1, 0x93, 0x4a, 0x8e, 0xf1, 0x21, 0x5f, 0xc7, 0x54, 0x0e,
0xf9, 0x03, 0x72, 0xcb, 0x1f, 0x90, 0xca, 0x25, 0xa9, 0xca, 0x3f, 0x90, 0x72, 0x72, 0xc8, 0x21,
0xf7, 0x9c, 0x52, 0x49, 0xcd, 0xd7, 0xee, 0xec, 0x62, 0x17, 0x94, 0xb3, 0xf1, 0x45, 0xdc, 0xe9,
0xe9, 0xe9, 0x5f, 0x4f, 0xcf, 0x74, 0x4f, 0x4f, 0x0f, 0x04, 0x45, 0x67, 0xd0, 0x5e, 0x19, 0x38,
0xb6, 0x67, 0xa3, 0x32, 0xf1, 0xda, 0x1d, 0x97, 0x38, 0x23, 0xe2, 0x0c, 0x8e, 0x1a, 0xf3, 0x5d,
0xbb, 0x6b, 0xb3, 0x8e, 0x55, 0xfa, 0xc5, 0x79, 0x1a, 0x0b, 0x94, 0x67, 0xb5, 0x3f, 0x6a, 0xb7,
0xd9, 0x3f, 0x83, 0xa3, 0xd5, 0x93, 0x91, 0xe8, 0xba, 0xc2, 0xba, 0x8c, 0xa1, 0x77, 0xcc, 0xfe,
0x19, 0x1c, 0xb1, 0x3f, 0xa2, 0xf3, 0x6a, 0xd7, 0xb6, 0xbb, 0x3d, 0xb2, 0x6a, 0x0c, 0xcc, 0x55,
0xc3, 0xb2, 0x6c, 0xcf, 0xf0, 0x4c, 0xdb, 0x72, 0x79, 0x2f, 0xfe, 0x5c, 0x83, 0xaa, 0x4e, 0xdc,
0x81, 0x6d, 0xb9, 0x64, 0x8b, 0x18, 0x1d, 0xe2, 0xa0, 0x6b, 0x00, 0xed, 0xde, 0xd0, 0xf5, 0x88,
0xd3, 0x32, 0x3b, 0x75, 0x6d, 0x49, 0x5b, 0x9e, 0xd6, 0x8b, 0x82, 0xb2, 0xdd, 0x41, 0x57, 0xa0,
0xd8, 0x27, 0xfd, 0x23, 0xde, 0x9b, 0x61, 0xbd, 0x33, 0x9c, 0xb0, 0xdd, 0x41, 0x0d, 0x98, 0x71,
0xc8, 0xc8, 0x74, 0x4d, 0xdb, 0xaa, 0x67, 0x97, 0xb4, 0xe5, 0xac, 0xee, 0xb7, 0xe9, 0x40, 0xc7,
0x78, 0xe1, 0xb5, 0x3c, 0xe2, 0xf4, 0xeb, 0xd3, 0x7c, 0x20, 0x25, 0x1c, 0x12, 0xa7, 0x8f, 0x3f,
0xcb, 0x41, 0x59, 0x37, 0xac, 0x2e, 0xd1, 0xc9, 0xc7, 0x43, 0xe2, 0x7a, 0xa8, 0x06, 0xd9, 0x13,
0x72, 0xc6, 0xe0, 0xcb, 0x3a, 0xfd, 0xe4, 0xe3, 0xad, 0x2e, 0x69, 0x11, 0x8b, 0x03, 0x97, 0xe9,
0x78, 0xab, 0x4b, 0x9a, 0x56, 0x07, 0xcd, 0x43, 0xae, 0x67, 0xf6, 0x4d, 0x4f, 0xa0, 0xf2, 0x46,
0x48, 0x9d, 0xe9, 0x88, 0x3a, 0x1b, 0x00, 0xae, 0xed, 0x78, 0x2d, 0xdb, 0xe9, 0x10, 0xa7, 0x9e,
0x5b, 0xd2, 0x96, 0xab, 0x6b, 0xb7, 0x56, 0xd4, 0x85, 0x58, 0x51, 0x15, 0x5a, 0x39, 0xb0, 0x1d,
0x6f, 0x9f, 0xf2, 0xea, 0x45, 0x57, 0x7e, 0xa2, 0xf7, 0xa0, 0xc4, 0x84, 0x78, 0x86, 0xd3, 0x25,
0x5e, 0x3d, 0xcf, 0xa4, 0xdc, 0x3e, 0x47, 0xca, 0x21, 0x63, 0xd6, 0x19, 0x3c, 0xff, 0x46, 0x18,
0xca, 0x2e, 0x71, 0x4c, 0xa3, 0x67, 0x7e, 0x62, 0x1c, 0xf5, 0x48, 0xbd, 0xb0, 0xa4, 0x2d, 0xcf,
0xe8, 0x21, 0x1a, 0x9d, 0xff, 0x09, 0x39, 0x73, 0x5b, 0xb6, 0xd5, 0x3b, 0xab, 0xcf, 0x30, 0x86,
0x19, 0x4a, 0xd8, 0xb7, 0x7a, 0x67, 0x6c, 0xd1, 0xec, 0xa1, 0xe5, 0xf1, 0xde, 0x22, 0xeb, 0x2d,
0x32, 0x0a, 0xeb, 0x5e, 0x86, 0x5a, 0xdf, 0xb4, 0x5a, 0x7d, 0xbb, 0xd3, 0xf2, 0x0d, 0x02, 0xcc,
0x20, 0xd5, 0xbe, 0x69, 0x3d, 0xb1, 0x3b, 0xba, 0x34, 0x0b, 0xe5, 0x34, 0x4e, 0xc3, 0x9c, 0x25,
0xc1, 0x69, 0x9c, 0xaa, 0x9c, 0x2b, 0x30, 0x47, 0x65, 0xb6, 0x1d, 0x62, 0x78, 0x24, 0x60, 0x2e,
0x33, 0xe6, 0x0b, 0x7d, 0xd3, 0xda, 0x60, 0x3d, 0x21, 0x7e, 0xe3, 0x74, 0x8c, 0xbf, 0x22, 0xf8,
0x8d, 0xd3, 0x30, 0x3f, 0x5e, 0x81, 0xa2, 0x6f, 0x73, 0x34, 0x03, 0xd3, 0x7b, 0xfb, 0x7b, 0xcd,
0xda, 0x14, 0x02, 0xc8, 0xaf, 0x1f, 0x6c, 0x34, 0xf7, 0x36, 0x6b, 0x1a, 0x2a, 0x41, 0x61, 0xb3,
0xc9, 0x1b, 0x19, 0xfc, 0x08, 0x20, 0xb0, 0x2e, 0x2a, 0x40, 0x76, 0xa7, 0xf9, 0xff, 0xb5, 0x29,
0xca, 0xf3, 0xbc, 0xa9, 0x1f, 0x6c, 0xef, 0xef, 0xd5, 0x34, 0x3a, 0x78, 0x43, 0x6f, 0xae, 0x1f,
0x36, 0x6b, 0x19, 0xca, 0xf1, 0x64, 0x7f, 0xb3, 0x96, 0x45, 0x45, 0xc8, 0x3d, 0x5f, 0xdf, 0x7d,
0xd6, 0xac, 0x4d, 0xe3, 0x2f, 0x34, 0xa8, 0x88, 0xf5, 0xe2, 0x3e, 0x81, 0xde, 0x86, 0xfc, 0x31,
0xf3, 0x0b, 0xb6, 0x15, 0x4b, 0x6b, 0x57, 0x23, 0x8b, 0x1b, 0xf2, 0x1d, 0x5d, 0xf0, 0x22, 0x0c,
0xd9, 0x93, 0x91, 0x5b, 0xcf, 0x2c, 0x65, 0x97, 0x4b, 0x6b, 0xb5, 0x15, 0xee, 0xb0, 0x2b, 0x3b,
0xe4, 0xec, 0xb9, 0xd1, 0x1b, 0x12, 0x9d, 0x76, 0x22, 0x04, 0xd3, 0x7d, 0xdb, 0x21, 0x6c, 0xc7,
0xce, 0xe8, 0xec, 0x9b, 0x6e, 0x63, 0xb6, 0x68, 0x62, 0xb7, 0xf2, 0x06, 0xfe, 0x9e, 0x06, 0xf0,
0x74, 0xe8, 0x25, 0xbb, 0xc6, 0x3c, 0xe4, 0x46, 0x54, 0xb0, 0x70, 0x0b, 0xde, 0x60, 0x3e, 0x41,
0x0c, 0x97, 0xf8, 0x3e, 0x41, 0x1b, 0xe8, 0x32, 0x14, 0x06, 0x0e, 0x19, 0xb5, 0x4e, 0x46, 0x0c,
0x64, 0x46, 0xcf, 0xd3, 0xe6, 0xce, 0x08, 0xdd, 0x80, 0xb2, 0xd9, 0xb5, 0x6c, 0x87, 0xb4, 0xb8,
0xac, 0x1c, 0xeb, 0x2d, 0x71, 0x1a, 0xd3, 0x1b, 0x5b, 0x50, 0x62, 0x7a, 0xa4, 0xb2, 0xcd, 0xbd,
0x40, 0x81, 0x0c, 0x1b, 0x36, 0x6e, 0x1f, 0xa1, 0x12, 0xfe, 0x08, 0xd0, 0x26, 0xe9, 0x11, 0x8f,
0xa4, 0x09, 0x0d, 0xca, 0x84, 0xb3, 0xea, 0x84, 0xf1, 0x8f, 0x34, 0x98, 0x0b, 0x89, 0x4f, 0x35,
0xad, 0x3a, 0x14, 0x3a, 0x4c, 0x18, 0xd7, 0x20, 0xab, 0xcb, 0x26, 0x7a, 0x00, 0x33, 0x42, 0x01,
0xb7, 0x9e, 0x4d, 0xd8, 0x11, 0x05, 0xae, 0x93, 0x8b, 0xff, 0xa6, 0x41, 0x51, 0x4c, 0x74, 0x7f,
0x80, 0xd6, 0xa1, 0xe2, 0xf0, 0x46, 0x8b, 0xcd, 0x47, 0x68, 0xd4, 0x48, 0x8e, 0x30, 0x5b, 0x53,
0x7a, 0x59, 0x0c, 0x61, 0x64, 0xf4, 0x3f, 0x50, 0x92, 0x22, 0x06, 0x43, 0x4f, 0x98, 0xbc, 0x1e,
0x16, 0x10, 0x6c, 0xae, 0xad, 0x29, 0x1d, 0x04, 0xfb, 0xd3, 0xa1, 0x87, 0x0e, 0x61, 0x5e, 0x0e,
0xe6, 0xb3, 0x11, 0x6a, 0x64, 0x99, 0x94, 0xa5, 0xb0, 0x94, 0xf1, 0xa5, 0xda, 0x9a, 0xd2, 0x91,
0x18, 0xaf, 0x74, 0x3e, 0x2a, 0x42, 0x41, 0x50, 0xf1, 0xdf, 0x35, 0x00, 0x69, 0xd0, 0xfd, 0x01,
0xda, 0x84, 0xaa, 0x23, 0x5a, 0xa1, 0x09, 0x5f, 0x89, 0x9d, 0xb0, 0x58, 0x87, 0x29, 0xbd, 0x22,
0x07, 0xf1, 0x29, 0xbf, 0x0b, 0x65, 0x5f, 0x4a, 0x30, 0xe7, 0x85, 0x98, 0x39, 0xfb, 0x12, 0x4a,
0x72, 0x00, 0x9d, 0xf5, 0x07, 0x70, 0xd1, 0x1f, 0x1f, 0x33, 0xed, 0x1b, 0x13, 0xa6, 0xed, 0x0b,
0x9c, 0x93, 0x12, 0xd4, 0x89, 0x03, 0x3d, 0x8f, 0x38, 0x19, 0xff, 0x2a, 0x0b, 0x85, 0x0d, 0xbb,
0x3f, 0x30, 0x1c, 0xba, 0x46, 0x79, 0x87, 0xb8, 0xc3, 0x9e, 0xc7, 0xa6, 0x5b, 0x5d, 0xbb, 0x19,
0x46, 0x10, 0x6c, 0xf2, 0xaf, 0xce, 0x58, 0x75, 0x31, 0x84, 0x0e, 0x16, 0xc7, 0x4f, 0xe6, 0x15,
0x06, 0x8b, 0xc3, 0x47, 0x0c, 0x91, 0xbe, 0x94, 0x0d, 0x7c, 0xa9, 0x01, 0x85, 0x11, 0x71, 0x82,
0x23, 0x73, 0x6b, 0x4a, 0x97, 0x04, 0x74, 0x0f, 0x66, 0xa3, 0xe1, 0x3b, 0x27, 0x78, 0xaa, 0xed,
0x70, 0xb4, 0xbf, 0x09, 0xe5, 0xd0, 0x19, 0x92, 0x17, 0x7c, 0xa5, 0xbe, 0x72, 0x84, 0x5c, 0x92,
0x71, 0x8b, 0x9e, 0x77, 0xe5, 0xad, 0x29, 0x11, 0xb9, 0xf0, 0xff, 0x42, 0x25, 0x34, 0x57, 0x1a,
0xa2, 0x9b, 0xef, 0x3f, 0x5b, 0xdf, 0xe5, 0xf1, 0xfc, 0x31, 0x0b, 0xe1, 0x7a, 0x4d, 0xa3, 0xc7,
0xc2, 0x6e, 0xf3, 0xe0, 0xa0, 0x96, 0x41, 0x15, 0x28, 0xee, 0xed, 0x1f, 0xb6, 0x38, 0x57, 0x16,
0xbf, 0xe3, 0x4b, 0x10, 0xe7, 0x81, 0x72, 0x0c, 0x4c, 0x29, 0xc7, 0x80, 0x26, 0x8f, 0x81, 0x4c,
0x70, 0x0c, 0x64, 0x1f, 0x55, 0xa1, 0xcc, 0xed, 0xd3, 0x1a, 0x5a, 0xf4, 0x28, 0xfa, 0x85, 0x06,
0x70, 0x78, 0x6a, 0xc9, 0x00, 0xb4, 0x0a, 0x85, 0x36, 0x17, 0x5e, 0xd7, 0x98, 0x3f, 0x5f, 0x8c,
0x35, 0xb9, 0x2e, 0xb9, 0xd0, 0x9b, 0x50, 0x70, 0x87, 0xed, 0x36, 0x71, 0xe5, 0x91, 0x70, 0x39,
0x1a, 0x52, 0x84, 0xc3, 0xeb, 0x92, 0x8f, 0x0e, 0x79, 0x61, 0x98, 0xbd, 0x21, 0x3b, 0x20, 0x26,
0x0f, 0x11, 0x7c, 0xf8, 0xa7, 0x1a, 0x94, 0x98, 0x96, 0xa9, 0xe2, 0xd8, 0x55, 0x28, 0x32, 0x1d,
0x48, 0x47, 0x44, 0xb2, 0x19, 0x3d, 0x20, 0xa0, 0xff, 0x86, 0xa2, 0xdc, 0xc1, 0x32, 0x98, 0xd5,
0xe3, 0xc5, 0xee, 0x0f, 0xf4, 0x80, 0x15, 0xef, 0xc0, 0x05, 0x66, 0x95, 0x36, 0x4d, 0x3e, 0xa5,
0x1d, 0xd5, 0xf4, 0x4c, 0x8b, 0xa4, 0x67, 0x0d, 0x98, 0x19, 0x1c, 0x9f, 0xb9, 0x66, 0xdb, 0xe8,
0x09, 0x2d, 0xfc, 0x36, 0xfe, 0x3f, 0x40, 0xaa, 0xb0, 0x34, 0xd3, 0xc5, 0x15, 0x28, 0x6d, 0x19,
0xee, 0xb1, 0x50, 0x09, 0x7f, 0x08, 0x65, 0xde, 0x4c, 0x65, 0x43, 0x04, 0xd3, 0xc7, 0x86, 0x7b,
0xcc, 0x14, 0xaf, 0xe8, 0xec, 0x1b, 0x5f, 0x80, 0xd9, 0x03, 0xcb, 0x18, 0xb8, 0xc7, 0xb6, 0x8c,
0xb5, 0x34, 0xf9, 0xae, 0x05, 0xb4, 0x54, 0x88, 0x77, 0x61, 0xd6, 0x21, 0x7d, 0xc3, 0xb4, 0x4c,
0xab, 0xdb, 0x3a, 0x3a, 0xf3, 0x88, 0x2b, 0x72, 0xf3, 0xaa, 0x4f, 0x7e, 0x44, 0xa9, 0x54, 0xb5,
0xa3, 0x9e, 0x7d, 0x24, 0x3c, 0x9e, 0x7d, 0xe3, 0x5f, 0x6b, 0x50, 0xfe, 0xc0, 0xf0, 0xda, 0xd2,
0x0a, 0x68, 0x1b, 0xaa, 0xbe, 0x9f, 0x33, 0x8a, 0xd0, 0x25, 0x12, 0xf0, 0xd9, 0x18, 0x99, 0xb5,
0xc9, 0x80, 0x5f, 0x69, 0xab, 0x04, 0x26, 0xca, 0xb0, 0xda, 0xa4, 0xe7, 0x8b, 0xca, 0x24, 0x8b,
0x62, 0x8c, 0xaa, 0x28, 0x95, 0xf0, 0x68, 0x36, 0x38, 0x0c, 0xb9, 0x5b, 0xfe, 0x2c, 0x03, 0x68,
0x5c, 0x87, 0xaf, 0x9a, 0x1f, 0xdc, 0x86, 0xaa, 0xeb, 0x19, 0x8e, 0xd7, 0x8a, 0xdc, 0x5c, 0x2a,
0x8c, 0xea, 0xc7, 0xaa, 0xbb, 0x30, 0x3b, 0x70, 0xec, 0xae, 0x43, 0x5c, 0xb7, 0x65, 0xd9, 0x9e,
0xf9, 0xe2, 0x4c, 0xe4, 0x4f, 0x55, 0x49, 0xde, 0x63, 0x54, 0xd4, 0x84, 0xc2, 0x0b, 0xb3, 0xe7,
0x11, 0xc7, 0xad, 0xe7, 0x96, 0xb2, 0xcb, 0xd5, 0xb5, 0x07, 0xe7, 0x59, 0x6d, 0xe5, 0x3d, 0xc6,
0x7f, 0x78, 0x36, 0x20, 0xba, 0x1c, 0xab, 0xa6, 0x2d, 0xf9, 0x50, 0xda, 0x72, 0x1b, 0x20, 0xe0,
0xa7, 0x51, 0x6b, 0x6f, 0xff, 0xe9, 0xb3, 0xc3, 0xda, 0x14, 0x2a, 0xc3, 0xcc, 0xde, 0xfe, 0x66,
0x73, 0xb7, 0x49, 0xe3, 0x1a, 0x5e, 0x95, 0xb6, 0x51, 0x6d, 0x88, 0x16, 0x60, 0xe6, 0x25, 0xa5,
0xca, 0xab, 0x5d, 0x56, 0x2f, 0xb0, 0xf6, 0x76, 0x07, 0xff, 0x55, 0x83, 0x8a, 0xd8, 0x05, 0xa9,
0xb6, 0xa2, 0x0a, 0x91, 0x09, 0x41, 0xd0, 0x1c, 0x89, 0xef, 0x8e, 0x8e, 0x48, 0xc5, 0x64, 0x93,
0xba, 0x3b, 0x5f, 0x6c, 0xd2, 0x11, 0x66, 0xf5, 0xdb, 0xe8, 0x1e, 0xd4, 0xda, 0xdc, 0xdd, 0x23,
0xc7, 0x8e, 0x3e, 0x2b, 0xe8, 0xfe, 0x22, 0xdd, 0x86, 0x3c, 0x19, 0x11, 0xcb, 0x73, 0xeb, 0x25,
0x16, 0x9b, 0x2a, 0x32, 0xd1, 0x6a, 0x52, 0xaa, 0x2e, 0x3a, 0xf1, 0x7f, 0xc1, 0x85, 0x5d, 0x9a,
0x0c, 0x3f, 0x76, 0x0c, 0x4b, 0x4d, 0xab, 0x0f, 0x0f, 0x77, 0x85, 0x55, 0xe8, 0x27, 0xaa, 0x42,
0x66, 0x7b, 0x53, 0xcc, 0x21, 0xb3, 0xbd, 0x89, 0x3f, 0xd5, 0x00, 0xa9, 0xe3, 0x52, 0x99, 0x29,
0x22, 0x5c, 0xc2, 0x67, 0x03, 0xf8, 0x79, 0xc8, 0x11, 0xc7, 0xb1, 0x1d, 0x66, 0x90, 0xa2, 0xce,
0x1b, 0xf8, 0x96, 0xd0, 0x41, 0x27, 0x23, 0xfb, 0xc4, 0xdf, 0xf3, 0x5c, 0x9a, 0xe6, 0xab, 0xba,
0x03, 0x73, 0x21, 0xae, 0x54, 0x31, 0xf2, 0x2e, 0x5c, 0x64, 0xc2, 0x76, 0x08, 0x19, 0xac, 0xf7,
0xcc, 0x51, 0x22, 0xea, 0x00, 0x2e, 0x45, 0x19, 0xbf, 0x5e, 0x1b, 0xe1, 0x77, 0x04, 0xe2, 0xa1,
0xd9, 0x27, 0x87, 0xf6, 0x6e, 0xb2, 0x6e, 0x34, 0xf0, 0xd1, 0xdb, 0xb2, 0x38, 0x4c, 0xd8, 0x37,
0xfe, 0xa5, 0x06, 0x97, 0xc7, 0x86, 0x7f, 0xcd, 0xab, 0xba, 0x08, 0xd0, 0xa5, 0xdb, 0x87, 0x74,
0x68, 0x07, 0xbf, 0xe7, 0x29, 0x14, 0x5f, 0x4f, 0x1a, 0x3b, 0xca, 0x42, 0xcf, 0x63, 0xc8, 0x3f,
0x61, 0x25, 0x16, 0x65, 0x56, 0xd3, 0x72, 0x56, 0x96, 0xd1, 0xe7, 0x17, 0xbf, 0xa2, 0xce, 0xbe,
0xd9, 0xd1, 0x49, 0x88, 0xf3, 0x4c, 0xdf, 0xe5, 0x47, 0x74, 0x51, 0xf7, 0xdb, 0x14, 0xbd, 0xdd,
0x33, 0x89, 0xe5, 0xb1, 0xde, 0x69, 0xd6, 0xab, 0x50, 0xf0, 0x0a, 0xd4, 0x38, 0xd2, 0x7a, 0xa7,
0xa3, 0x1c, 0xd3, 0xbe, 0x3c, 0x2d, 0x2c, 0x0f, 0xbf, 0x84, 0x0b, 0x0a, 0x7f, 0x2a, 0xd3, 0xbd,
0x06, 0x79, 0x5e, 0x47, 0x12, 0x27, 0xc4, 0x7c, 0x78, 0x14, 0x87, 0xd1, 0x05, 0x0f, 0xbe, 0x0d,
0x73, 0x82, 0x42, 0xfa, 0x76, 0xdc, 0xaa, 0x33, 0xfb, 0xe0, 0x5d, 0x98, 0x0f, 0xb3, 0xa5, 0x72,
0x84, 0x75, 0x09, 0xfa, 0x6c, 0xd0, 0x51, 0x0e, 0x9c, 0xe8, 0xa2, 0xa8, 0x06, 0xcb, 0x44, 0x0c,
0xe6, 0x2b, 0x24, 0x45, 0xa4, 0x52, 0x68, 0x4e, 0x9a, 0x7f, 0xd7, 0x74, 0xfd, 0xb4, 0xe2, 0x13,
0x40, 0x2a, 0x31, 0xd5, 0xa2, 0xac, 0x40, 0x81, 0x1b, 0x5c, 0x66, 0xae, 0xf1, 0xab, 0x22, 0x99,
0xa8, 0x42, 0x9b, 0xe4, 0x85, 0x63, 0x74, 0xfb, 0xc4, 0x8f, 0xac, 0x34, 0x5f, 0x53, 0x89, 0xa9,
0x66, 0xfc, 0x7b, 0x0d, 0xca, 0xeb, 0x3d, 0xc3, 0xe9, 0x4b, 0xe3, 0xbf, 0x0b, 0x79, 0x9e, 0x08,
0x8a, 0xbb, 0xd3, 0x9d, 0xb0, 0x18, 0x95, 0x97, 0x37, 0xd6, 0x79, 0xda, 0x28, 0x46, 0xd1, 0xc5,
0x12, 0xe5, 0xcb, 0xcd, 0x48, 0x39, 0x73, 0x13, 0xbd, 0x0e, 0x39, 0x83, 0x0e, 0x61, 0xfe, 0x5b,
0x8d, 0xa6, 0xe0, 0x4c, 0x1a, 0x3b, 0xb4, 0x39, 0x17, 0x7e, 0x1b, 0x4a, 0x0a, 0x02, 0xbd, 0x59,
0x3c, 0x6e, 0x8a, 0x83, 0x79, 0x7d, 0xe3, 0x70, 0xfb, 0x39, 0xbf, 0x70, 0x54, 0x01, 0x36, 0x9b,
0x7e, 0x3b, 0x83, 0x3f, 0x14, 0xa3, 0x84, 0x87, 0xab, 0xfa, 0x68, 0x49, 0xfa, 0x64, 0x5e, 0x49,
0x9f, 0x53, 0xa8, 0x88, 0xe9, 0xa7, 0xda, 0x03, 0x6f, 0x42, 0x9e, 0xc9, 0x93, 0x5b, 0x60, 0x21,
0x06, 0x56, 0x7a, 0x27, 0x67, 0xc4, 0xb3, 0x50, 0x39, 0xf0, 0x0c, 0x6f, 0xe8, 0xca, 0x2d, 0xf0,
0x3b, 0x0d, 0xaa, 0x92, 0x92, 0xb6, 0xcc, 0x22, 0xaf, 0xa7, 0x3c, 0xe6, 0xf9, 0x97, 0xd3, 0x4b,
0x90, 0xef, 0x1c, 0x1d, 0x98, 0x9f, 0xc8, 0x7a, 0x97, 0x68, 0x51, 0x7a, 0x8f, 0xe3, 0xf0, 0xa2,
0xb3, 0x68, 0xd1, 0x8b, 0x8e, 0x63, 0xbc, 0xf0, 0xb6, 0xad, 0x0e, 0x39, 0x65, 0xf9, 0xc4, 0xb4,
0x1e, 0x10, 0xd8, 0xdd, 0x44, 0x14, 0xa7, 0x59, 0xfe, 0xa5, 0x16, 0xab, 0xe7, 0xe0, 0xc2, 0xfa,
0xd0, 0x3b, 0x6e, 0x5a, 0xc6, 0x51, 0x4f, 0x06, 0x01, 0x3c, 0x0f, 0x88, 0x12, 0x37, 0x4d, 0x57,
0xa5, 0x36, 0x61, 0x8e, 0x52, 0x89, 0xe5, 0x99, 0x6d, 0x25, 0x62, 0xc8, 0xb0, 0xad, 0x45, 0xc2,
0xb6, 0xe1, 0xba, 0x2f, 0x6d, 0xa7, 0x23, 0xa6, 0xe6, 0xb7, 0xf1, 0x26, 0x17, 0xfe, 0xcc, 0x0d,
0x05, 0xe6, 0xaf, 0x2a, 0x65, 0x39, 0x90, 0xf2, 0x98, 0x78, 0x13, 0xa4, 0xe0, 0x07, 0x70, 0x51,
0x72, 0x8a, 0xfa, 0xc5, 0x04, 0xe6, 0x7d, 0xb8, 0x26, 0x99, 0x37, 0x8e, 0x69, 0x56, 0xfd, 0x54,
0x00, 0xfe, 0xbb, 0x7a, 0x3e, 0x82, 0xba, 0xaf, 0x27, 0xcb, 0xb4, 0xec, 0x9e, 0xaa, 0xc0, 0xd0,
0x15, 0x7b, 0xa6, 0xa8, 0xb3, 0x6f, 0x4a, 0x73, 0xec, 0x9e, 0x7f, 0x08, 0xd2, 0x6f, 0xbc, 0x01,
0x0b, 0x52, 0x86, 0xc8, 0x81, 0xc2, 0x42, 0xc6, 0x14, 0x8a, 0x13, 0x22, 0x0c, 0x46, 0x87, 0x4e,
0x36, 0xbb, 0xca, 0x19, 0x36, 0x2d, 0x93, 0xa9, 0x29, 0x32, 0x2f, 0xf2, 0x1d, 0x41, 0x15, 0x53,
0x83, 0xb6, 0x20, 0x53, 0x01, 0x2a, 0x59, 0x2c, 0x04, 0x25, 0x8f, 0x2d, 0xc4, 0x98, 0xe8, 0x8f,
0x60, 0xd1, 0x57, 0x82, 0xda, 0xed, 0x29, 0x71, 0xfa, 0xa6, 0xeb, 0x2a, 0x37, 0xee, 0xb8, 0x89,
0xdf, 0x81, 0xe9, 0x01, 0x11, 0x31, 0xa5, 0xb4, 0x86, 0x56, 0xf8, 0x13, 0xd2, 0x8a, 0x32, 0x98,
0xf5, 0xe3, 0x0e, 0x5c, 0x97, 0xd2, 0xb9, 0x45, 0x63, 0xc5, 0x47, 0x95, 0x92, 0xb7, 0x31, 0x6e,
0xd6, 0xf1, 0xdb, 0x58, 0x96, 0xaf, 0xbd, 0xbc, 0x8d, 0xd1, 0xb3, 0x42, 0xf5, 0xad, 0x54, 0x67,
0xc5, 0x0e, 0xb7, 0xa9, 0xef, 0x92, 0xa9, 0x84, 0x1d, 0xc1, 0x7c, 0xd8, 0x93, 0x53, 0x85, 0xb1,
0x79, 0xc8, 0x79, 0xf6, 0x09, 0x91, 0x41, 0x8c, 0x37, 0xa4, 0xc2, 0xbe, 0x9b, 0xa7, 0x52, 0xd8,
0x08, 0x84, 0xb1, 0x2d, 0x99, 0x56, 0x5f, 0xba, 0x9a, 0x32, 0x9f, 0xe1, 0x0d, 0xbc, 0x07, 0x97,
0xa2, 0x61, 0x22, 0x95, 0xca, 0xcf, 0xf9, 0x06, 0x8e, 0x8b, 0x24, 0xa9, 0xe4, 0xbe, 0x1f, 0x04,
0x03, 0x25, 0xa0, 0xa4, 0x12, 0xa9, 0x43, 0x23, 0x2e, 0xbe, 0xfc, 0x27, 0xf6, 0xab, 0x1f, 0x6e,
0x52, 0x09, 0x73, 0x03, 0x61, 0xe9, 0x97, 0x3f, 0x88, 0x11, 0xd9, 0x89, 0x31, 0x42, 0x38, 0x49,
0x10, 0xc5, 0xbe, 0x86, 0x4d, 0x27, 0x30, 0x82, 0x00, 0x9a, 0x16, 0x83, 0x9e, 0x21, 0x3e, 0x06,
0x6b, 0xc8, 0x8d, 0xad, 0x86, 0xdd, 0x54, 0x8b, 0xf1, 0x41, 0x10, 0x3b, 0xc7, 0x22, 0x73, 0x2a,
0xc1, 0x1f, 0xc2, 0x52, 0x72, 0x50, 0x4e, 0x23, 0xf9, 0x3e, 0x86, 0xa2, 0x9f, 0x50, 0x2a, 0xcf,
0xaf, 0x25, 0x28, 0xec, 0xed, 0x1f, 0x3c, 0x5d, 0xdf, 0x68, 0xd6, 0xb4, 0xb5, 0x7f, 0x64, 0x21,
0xb3, 0xf3, 0x1c, 0x7d, 0x03, 0x72, 0xfc, 0xe1, 0x65, 0xc2, 0xbb, 0x54, 0x63, 0xd2, 0x13, 0x0e,
0xbe, 0xfa, 0xe9, 0x1f, 0xff, 0xf2, 0x45, 0xe6, 0x12, 0xbe, 0xb0, 0x3a, 0x7a, 0xcb, 0xe8, 0x0d,
0x8e, 0x8d, 0xd5, 0x93, 0xd1, 0x2a, 0x3b, 0x13, 0x1e, 0x6a, 0xf7, 0xd1, 0x73, 0xc8, 0x3e, 0x1d,
0x7a, 0x28, 0xf1, 0xd1, 0xaa, 0x91, 0xfc, 0xb4, 0x83, 0x1b, 0x4c, 0xf2, 0x3c, 0x9e, 0x55, 0x25,
0x0f, 0x86, 0x1e, 0x95, 0x3b, 0x82, 0x92, 0xf2, 0x3a, 0x83, 0xce, 0x7d, 0xce, 0x6a, 0x9c, 0xff,
0xf2, 0x83, 0x31, 0xc3, 0xbb, 0x8a, 0x2f, 0xab, 0x78, 0xfc, 0x11, 0x49, 0x9d, 0xcf, 0xe1, 0xa9,
0x15, 0x9d, 0x4f, 0xf0, 0xc0, 0x10, 0x9d, 0x8f, 0x52, 0xd4, 0x8f, 0x9f, 0x8f, 0x77, 0x6a, 0x51,
0xb9, 0xb6, 0x78, 0x51, 0x6a, 0x7b, 0xe8, 0x7a, 0xcc, 0x8b, 0x84, 0x5a, 0x7b, 0x6f, 0x2c, 0x25,
0x33, 0x08, 0xa4, 0x1b, 0x0c, 0xe9, 0x0a, 0xbe, 0xa4, 0x22, 0xb5, 0x7d, 0xbe, 0x87, 0xda, 0xfd,
0xb5, 0x63, 0xc8, 0xb1, 0x8a, 0x21, 0x6a, 0xc9, 0x8f, 0x46, 0x4c, 0xad, 0x33, 0x61, 0x07, 0x84,
0x6a, 0x8d, 0x78, 0x81, 0xa1, 0xcd, 0xe1, 0xaa, 0x8f, 0xc6, 0x8a, 0x86, 0x0f, 0xb5, 0xfb, 0xcb,
0xda, 0x1b, 0xda, 0xda, 0x77, 0xa7, 0x21, 0xc7, 0x2a, 0x35, 0x68, 0x00, 0x10, 0xd4, 0xe0, 0xa2,
0xf3, 0x1c, 0xab, 0xea, 0x45, 0xe7, 0x39, 0x5e, 0xbe, 0xc3, 0xd7, 0x19, 0xf2, 0x02, 0x9e, 0xf7,
0x91, 0xd9, 0x43, 0xf9, 0x2a, 0xab, 0xc9, 0x50, 0xb3, 0xbe, 0x84, 0x92, 0x52, 0x4b, 0x43, 0x71,
0x12, 0x43, 0xc5, 0xb8, 0xe8, 0x36, 0x89, 0x29, 0xc4, 0xe1, 0x9b, 0x0c, 0xf4, 0x1a, 0xae, 0xab,
0xc6, 0xe5, 0xb8, 0x0e, 0xe3, 0xa4, 0xc0, 0x9f, 0x69, 0x50, 0x0d, 0xd7, 0xd3, 0xd0, 0xcd, 0x18,
0xd1, 0xd1, 0xb2, 0x5c, 0xe3, 0xd6, 0x64, 0xa6, 0x44, 0x15, 0x38, 0xfe, 0x09, 0x21, 0x03, 0x83,
0x72, 0x0a, 0xdb, 0xa3, 0xef, 0x6b, 0x30, 0x1b, 0xa9, 0x92, 0xa1, 0x38, 0x88, 0xb1, 0x1a, 0x5c,
0xe3, 0xf6, 0x39, 0x5c, 0x42, 0x93, 0xbb, 0x4c, 0x93, 0x1b, 0xf8, 0xea, 0xb8, 0x31, 0x3c, 0xb3,
0x4f, 0x3c, 0x5b, 0x68, 0xb3, 0xf6, 0xcf, 0x2c, 0x14, 0x36, 0xf8, 0x2f, 0x91, 0x90, 0x07, 0x45,
0xbf, 0xf2, 0x84, 0x16, 0xe3, 0xaa, 0x12, 0x41, 0xca, 0xde, 0xb8, 0x9e, 0xd8, 0x2f, 0x54, 0xb8,
0xc3, 0x54, 0x58, 0xc2, 0x57, 0x7c, 0x15, 0xc4, 0x2f, 0x9e, 0x56, 0xf9, 0xe5, 0x7b, 0xd5, 0xe8,
0x74, 0xe8, 0x92, 0x7c, 0x47, 0x83, 0xb2, 0x5a, 0x50, 0x42, 0x37, 0x62, 0xeb, 0x21, 0x6a, 0x4d,
0xaa, 0x81, 0x27, 0xb1, 0x08, 0xfc, 0x7b, 0x0c, 0xff, 0x26, 0x5e, 0x4c, 0xc2, 0x77, 0x18, 0x7f,
0x58, 0x05, 0x5e, 0x42, 0x8a, 0x57, 0x21, 0x54, 0xa1, 0x8a, 0x57, 0x21, 0x5c, 0x81, 0x3a, 0x5f,
0x85, 0x21, 0xe3, 0xa7, 0x2a, 0x9c, 0x02, 0x04, 0x15, 0x26, 0x14, 0x6b, 0x5c, 0xe5, 0x12, 0x13,
0xf5, 0xc1, 0xf1, 0xe2, 0x54, 0xcc, 0x0e, 0x88, 0x60, 0xf7, 0x4c, 0x97, 0xfa, 0xe2, 0xda, 0x6f,
0xa6, 0xa1, 0xf4, 0xc4, 0x30, 0x2d, 0x8f, 0x58, 0x86, 0xd5, 0x26, 0xa8, 0x0b, 0x39, 0x76, 0x4a,
0x45, 0x03, 0x8f, 0x5a, 0xf6, 0x89, 0x06, 0x9e, 0x50, 0x4d, 0x04, 0xdf, 0x66, 0xd0, 0xd7, 0x71,
0xc3, 0x87, 0xee, 0x07, 0xf2, 0x57, 0x59, 0x3d, 0x83, 0x4e, 0xf9, 0x04, 0xf2, 0xbc, 0x7e, 0x81,
0x22, 0xd2, 0x42, 0x75, 0x8e, 0xc6, 0xd5, 0xf8, 0xce, 0xc4, 0x5d, 0xa6, 0x62, 0xb9, 0x8c, 0x99,
0x82, 0x7d, 0x13, 0x20, 0x28, 0x98, 0x45, 0xed, 0x3b, 0x56, 0x5f, 0x6b, 0x2c, 0x25, 0x33, 0x08,
0xe0, 0xfb, 0x0c, 0xf8, 0x16, 0xbe, 0x1e, 0x0b, 0xdc, 0xf1, 0x07, 0x50, 0xf0, 0x36, 0x4c, 0x6f,
0x19, 0xee, 0x31, 0x8a, 0x1c, 0x42, 0xca, 0x2b, 0x69, 0xa3, 0x11, 0xd7, 0x25, 0xa0, 0x6e, 0x31,
0xa8, 0x45, 0xbc, 0x10, 0x0b, 0x75, 0x6c, 0xb8, 0x34, 0xa6, 0xa3, 0x21, 0xcc, 0xc8, 0x97, 0x4f,
0x74, 0x2d, 0x62, 0xb3, 0xf0, 0x2b, 0x69, 0x63, 0x31, 0xa9, 0x5b, 0x00, 0x2e, 0x33, 0x40, 0x8c,
0xaf, 0xc5, 0x1b, 0x55, 0xb0, 0x3f, 0xd4, 0xee, 0xbf, 0xa1, 0xad, 0xfd, 0xb0, 0x06, 0xd3, 0x34,
0x5f, 0xa2, 0xa7, 0x48, 0x70, 0xcd, 0x8c, 0x5a, 0x78, 0xac, 0xb8, 0x13, 0xb5, 0xf0, 0xf8, 0x0d,
0x35, 0xe6, 0x14, 0x61, 0xbf, 0xc7, 0x24, 0x8c, 0x8b, 0xce, 0xd8, 0x83, 0x92, 0x72, 0x19, 0x45,
0x31, 0x12, 0xc3, 0xa5, 0xa3, 0xe8, 0x29, 0x12, 0x73, 0x93, 0xc5, 0x4b, 0x0c, 0xb4, 0x81, 0x2f,
0x86, 0x41, 0x3b, 0x9c, 0x8d, 0xa2, 0x7e, 0x0b, 0xca, 0xea, 0xad, 0x15, 0xc5, 0x08, 0x8d, 0xd4,
0xa6, 0xa2, 0xb1, 0x22, 0xee, 0xd2, 0x1b, 0xe3, 0x34, 0xfe, 0xaf, 0x4f, 0x25, 0x2f, 0x45, 0xff,
0x18, 0x0a, 0xe2, 0x2e, 0x1b, 0x37, 0xdf, 0x70, 0x35, 0x2b, 0x6e, 0xbe, 0x91, 0x8b, 0x70, 0x4c,
0x4a, 0xc2, 0x60, 0x69, 0xce, 0x2e, 0x03, 0xb4, 0x80, 0x7c, 0x4c, 0xbc, 0x24, 0xc8, 0xa0, 0x3e,
0x93, 0x04, 0xa9, 0xdc, 0x97, 0x26, 0x42, 0x76, 0x89, 0x27, 0xf6, 0xb2, 0xbc, 0x8c, 0xa0, 0x04,
0x89, 0x6a, 0x34, 0xc4, 0x93, 0x58, 0x12, 0xb3, 0xc8, 0x00, 0x55, 0x84, 0x42, 0xf4, 0x6d, 0x80,
0xe0, 0xe2, 0x1d, 0x4d, 0x0c, 0x62, 0xab, 0x77, 0xd1, 0xc4, 0x20, 0xfe, 0xee, 0x1e, 0xe3, 0xc1,
0x01, 0x38, 0xcf, 0x64, 0x29, 0xfc, 0x8f, 0x35, 0x40, 0xe3, 0x17, 0x75, 0xf4, 0x20, 0x1e, 0x22,
0xb6, 0x30, 0xd8, 0x78, 0xed, 0xd5, 0x98, 0x13, 0xa3, 0x67, 0xa0, 0x57, 0x9b, 0x0d, 0x19, 0xbc,
0xa4, 0x9a, 0x7d, 0xae, 0x41, 0x25, 0x74, 0xd5, 0x47, 0x77, 0x12, 0xd6, 0x39, 0x52, 0x5c, 0x6c,
0xdc, 0x3d, 0x97, 0x2f, 0x31, 0x77, 0x52, 0x76, 0x85, 0xcc, 0x1b, 0x7f, 0xa0, 0x41, 0x35, 0x5c,
0x1f, 0x40, 0x09, 0x00, 0x63, 0x15, 0xca, 0xc6, 0xf2, 0xf9, 0x8c, 0xaf, 0xb0, 0x5a, 0x41, 0x2a,
0xf9, 0x31, 0x14, 0x44, 0x59, 0x21, 0xce, 0x2d, 0xc2, 0x05, 0xce, 0x38, 0xb7, 0x88, 0xd4, 0x24,
0x92, 0xdc, 0x82, 0xde, 0xd0, 0x15, 0x4f, 0x14, 0xc5, 0x87, 0x24, 0xc8, 0xc9, 0x9e, 0x18, 0xa9,
0x5c, 0x4c, 0x84, 0x0c, 0x3c, 0x51, 0x96, 0x1e, 0x50, 0x82, 0xc4, 0x73, 0x3c, 0x31, 0x5a, 0xb9,
0x48, 0xf2, 0x44, 0x86, 0xaa, 0x78, 0x62, 0x50, 0x29, 0x88, 0xf3, 0xc4, 0xb1, 0xf2, 0x6d, 0x9c,
0x27, 0x8e, 0x17, 0x1b, 0x92, 0xd6, 0x96, 0x81, 0x87, 0x3c, 0x71, 0x2e, 0xa6, 0xb2, 0x80, 0x5e,
0x4b, 0xb0, 0x69, 0x6c, 0x69, 0xb8, 0xf1, 0xfa, 0x2b, 0x72, 0x4f, 0xf6, 0x00, 0xbe, 0x1a, 0xd2,
0x03, 0x7e, 0xae, 0xc1, 0x7c, 0x5c, 0x69, 0x02, 0x25, 0x80, 0x25, 0xd4, 0x95, 0x1b, 0x2b, 0xaf,
0xca, 0xfe, 0x0a, 0x76, 0xf3, 0x7d, 0xe2, 0x51, 0xed, 0xb7, 0x5f, 0x2e, 0x6a, 0x7f, 0xf8, 0x72,
0x51, 0xfb, 0xd3, 0x97, 0x8b, 0xda, 0x4f, 0xfe, 0xbc, 0x38, 0x75, 0x94, 0x67, 0xff, 0x29, 0xe2,
0xad, 0x7f, 0x05, 0x00, 0x00, 0xff, 0xff, 0x89, 0x96, 0x81, 0x80, 0x9b, 0x31, 0x00, 0x00,
}

16
vendor/github.com/coreos/etcd/pkg/report/doc.go generated vendored Normal file
View File

@ -0,0 +1,16 @@
// Copyright 2016 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Package report generates human-readable benchmark reports.
package report

284
vendor/github.com/coreos/etcd/pkg/report/report.go generated vendored Normal file
View File

@ -0,0 +1,284 @@
// Copyright 2014 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// the file is borrowed from github.com/rakyll/boom/boomer/print.go
package report
import (
"fmt"
"math"
"sort"
"strings"
"time"
)
const (
barChar = "∎"
)
// Result describes the timings for an operation.
type Result struct {
Start time.Time
End time.Time
Err error
}
func (res *Result) Duration() time.Duration { return res.End.Sub(res.Start) }
type report struct {
results chan Result
precision string
avgTotal float64
fastest float64
slowest float64
average float64
stddev float64
rps float64
total time.Duration
errorDist map[string]int
lats []float64
sps *secondPoints
}
// Stats exposes results raw data.
type Stats struct {
AvgTotal float64
Fastest float64
Slowest float64
Average float64
Stddev float64
RPS float64
Total time.Duration
ErrorDist map[string]int
Lats []float64
TimeSeries TimeSeries
}
// Report processes a result stream until it is closed, then produces a
// string with information about the consumed result data.
type Report interface {
Results() chan<- Result
// Run returns results in print-friendly format.
Run() <-chan string
// Stats returns results in raw data.
Stats() <-chan Stats
}
func NewReport(precision string) Report {
return &report{
results: make(chan Result, 16),
precision: precision,
errorDist: make(map[string]int),
}
}
func NewReportSample(precision string) Report {
r := NewReport(precision).(*report)
r.sps = newSecondPoints()
return r
}
func (r *report) Results() chan<- Result { return r.results }
func (r *report) Run() <-chan string {
donec := make(chan string, 1)
go func() {
defer close(donec)
r.processResults()
donec <- r.String()
}()
return donec
}
func (r *report) Stats() <-chan Stats {
donec := make(chan Stats, 1)
go func() {
defer close(donec)
r.processResults()
donec <- Stats{
AvgTotal: r.avgTotal,
Fastest: r.fastest,
Slowest: r.slowest,
Average: r.average,
Stddev: r.stddev,
RPS: r.rps,
Total: r.total,
ErrorDist: copyMap(r.errorDist),
Lats: copyFloats(r.lats),
TimeSeries: r.sps.getTimeSeries(),
}
}()
return donec
}
func copyMap(m map[string]int) (c map[string]int) {
c = make(map[string]int, len(m))
for k, v := range m {
c[k] = v
}
return
}
func copyFloats(s []float64) (c []float64) {
c = make([]float64, len(s))
copy(c, s)
return
}
func (r *report) String() (s string) {
if len(r.lats) > 0 {
s += fmt.Sprintf("\nSummary:\n")
s += fmt.Sprintf(" Total:\t%s.\n", r.sec2str(r.total.Seconds()))
s += fmt.Sprintf(" Slowest:\t%s.\n", r.sec2str(r.slowest))
s += fmt.Sprintf(" Fastest:\t%s.\n", r.sec2str(r.fastest))
s += fmt.Sprintf(" Average:\t%s.\n", r.sec2str(r.average))
s += fmt.Sprintf(" Stddev:\t%s.\n", r.sec2str(r.stddev))
s += fmt.Sprintf(" Requests/sec:\t"+r.precision+"\n", r.rps)
s += r.histogram()
s += r.sprintLatencies()
if r.sps != nil {
s += fmt.Sprintf("%v\n", r.sps.getTimeSeries())
}
}
if len(r.errorDist) > 0 {
s += r.errors()
}
return s
}
func (r *report) sec2str(sec float64) string { return fmt.Sprintf(r.precision+" secs", sec) }
type reportRate struct{ *report }
func NewReportRate(precision string) Report {
return &reportRate{NewReport(precision).(*report)}
}
func (r *reportRate) String() string {
return fmt.Sprintf(" Requests/sec:\t"+r.precision+"\n", r.rps)
}
func (r *report) processResult(res *Result) {
if res.Err != nil {
r.errorDist[res.Err.Error()]++
return
}
dur := res.Duration()
r.lats = append(r.lats, dur.Seconds())
r.avgTotal += dur.Seconds()
if r.sps != nil {
r.sps.Add(res.Start, dur)
}
}
func (r *report) processResults() {
st := time.Now()
for res := range r.results {
r.processResult(&res)
}
r.total = time.Since(st)
r.rps = float64(len(r.lats)) / r.total.Seconds()
r.average = r.avgTotal / float64(len(r.lats))
for i := range r.lats {
dev := r.lats[i] - r.average
r.stddev += dev * dev
}
r.stddev = math.Sqrt(r.stddev / float64(len(r.lats)))
sort.Float64s(r.lats)
if len(r.lats) > 0 {
r.fastest = r.lats[0]
r.slowest = r.lats[len(r.lats)-1]
}
}
var pctls = []float64{10, 25, 50, 75, 90, 95, 99, 99.9}
// Percentiles returns percentile distribution of float64 slice.
func Percentiles(nums []float64) (pcs []float64, data []float64) {
return pctls, percentiles(nums)
}
func percentiles(nums []float64) (data []float64) {
data = make([]float64, len(pctls))
j := 0
n := len(nums)
for i := 0; i < n && j < len(pctls); i++ {
current := float64(i) * 100.0 / float64(n)
if current >= pctls[j] {
data[j] = nums[i]
j++
}
}
return
}
func (r *report) sprintLatencies() string {
data := percentiles(r.lats)
s := fmt.Sprintf("\nLatency distribution:\n")
for i := 0; i < len(pctls); i++ {
if data[i] > 0 {
s += fmt.Sprintf(" %v%% in %s.\n", pctls[i], r.sec2str(data[i]))
}
}
return s
}
func (r *report) histogram() string {
bc := 10
buckets := make([]float64, bc+1)
counts := make([]int, bc+1)
bs := (r.slowest - r.fastest) / float64(bc)
for i := 0; i < bc; i++ {
buckets[i] = r.fastest + bs*float64(i)
}
buckets[bc] = r.slowest
var bi int
var max int
for i := 0; i < len(r.lats); {
if r.lats[i] <= buckets[bi] {
i++
counts[bi]++
if max < counts[bi] {
max = counts[bi]
}
} else if bi < len(buckets)-1 {
bi++
}
}
s := fmt.Sprintf("\nResponse time histogram:\n")
for i := 0; i < len(buckets); i++ {
// Normalize bar lengths.
var barLen int
if max > 0 {
barLen = counts[i] * 40 / max
}
s += fmt.Sprintf(" "+r.precision+" [%v]\t|%v\n", buckets[i], counts[i], strings.Repeat(barChar, barLen))
}
return s
}
func (r *report) errors() string {
s := fmt.Sprintf("\nError distribution:\n")
for err, num := range r.errorDist {
s += fmt.Sprintf(" [%d]\t%s\n", num, err)
}
return s
}

134
vendor/github.com/coreos/etcd/pkg/report/timeseries.go generated vendored Normal file
View File

@ -0,0 +1,134 @@
// Copyright 2016 The etcd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package report
import (
"bytes"
"encoding/csv"
"fmt"
"log"
"math"
"sort"
"sync"
"time"
)
type DataPoint struct {
Timestamp int64
AvgLatency time.Duration
ThroughPut int64
}
type TimeSeries []DataPoint
func (t TimeSeries) Swap(i, j int) { t[i], t[j] = t[j], t[i] }
func (t TimeSeries) Len() int { return len(t) }
func (t TimeSeries) Less(i, j int) bool { return t[i].Timestamp < t[j].Timestamp }
type secondPoint struct {
totalLatency time.Duration
count int64
}
type secondPoints struct {
mu sync.Mutex
tm map[int64]secondPoint
}
func newSecondPoints() *secondPoints {
return &secondPoints{tm: make(map[int64]secondPoint)}
}
func (sp *secondPoints) Add(ts time.Time, lat time.Duration) {
sp.mu.Lock()
defer sp.mu.Unlock()
tk := ts.Unix()
if v, ok := sp.tm[tk]; !ok {
sp.tm[tk] = secondPoint{totalLatency: lat, count: 1}
} else {
v.totalLatency += lat
v.count += 1
sp.tm[tk] = v
}
}
func (sp *secondPoints) getTimeSeries() TimeSeries {
sp.mu.Lock()
defer sp.mu.Unlock()
var (
minTs int64 = math.MaxInt64
maxTs int64 = -1
)
for k := range sp.tm {
if minTs > k {
minTs = k
}
if maxTs < k {
maxTs = k
}
}
for ti := minTs; ti < maxTs; ti++ {
if _, ok := sp.tm[ti]; !ok { // fill-in empties
sp.tm[ti] = secondPoint{totalLatency: 0, count: 0}
}
}
var (
tslice = make(TimeSeries, len(sp.tm))
i int
)
for k, v := range sp.tm {
var lat time.Duration
if v.count > 0 {
lat = time.Duration(v.totalLatency) / time.Duration(v.count)
}
tslice[i] = DataPoint{
Timestamp: k,
AvgLatency: lat,
ThroughPut: v.count,
}
i++
}
sort.Sort(tslice)
return tslice
}
func (ts TimeSeries) String() string {
buf := new(bytes.Buffer)
wr := csv.NewWriter(buf)
if err := wr.Write([]string{"UNIX-TS", "AVG-LATENCY-MS", "AVG-THROUGHPUT"}); err != nil {
log.Fatal(err)
}
rows := [][]string{}
for i := range ts {
row := []string{
fmt.Sprintf("%d", ts[i].Timestamp),
fmt.Sprintf("%s", ts[i].AvgLatency),
fmt.Sprintf("%d", ts[i].ThroughPut),
}
rows = append(rows, row)
}
if err := wr.WriteAll(rows); err != nil {
log.Fatal(err)
}
wr.Flush()
if err := wr.Error(); err != nil {
log.Fatal(err)
}
return fmt.Sprintf("\nSample in one second (unix latency throughput):\n%s", buf.String())
}

View File

@ -8,12 +8,15 @@ import (
// Column represents column-based data.
type Column interface {
// CountRow returns the number of rows of the Column.
CountRow() int
// Count returns the number of rows of the Column.
Count() int
// Header returns the header of the Column.
Header() string
// Rows returns all the data in string slice.
Rows() []string
// UpdateHeader updates the header of the Column.
UpdateHeader(header string)
@ -106,7 +109,7 @@ func NewColumn(hd string) Column {
}
}
func (c *column) CountRow() int {
func (c *column) Count() int {
c.mu.Lock()
defer c.mu.Unlock()
@ -120,6 +123,18 @@ func (c *column) Header() string {
return c.header
}
func (c *column) Rows() (rows []string) {
c.mu.Lock()
defer c.mu.Unlock()
rows = make([]string, len(c.data))
for i := range c.data {
v, _ := c.data[i].String()
rows[i] = v
}
return
}
func (c *column) UpdateHeader(header string) {
c.mu.Lock()
defer c.mu.Unlock()

View File

@ -3,7 +3,6 @@ package dataframe
import (
"encoding/csv"
"fmt"
"os"
"sync"
)
@ -36,6 +35,11 @@ type Frame interface {
// CSV saves the Frame to a CSV file.
CSV(fpath string) error
// CSVHorizontal saves the Frame to a CSV file
// in a horizontal way. The first column is header.
// And data are aligned from left to right.
CSVHorizontal(fpath string) error
// Rows returns the header and data slices.
Rows() ([]string, [][]string)
@ -126,7 +130,7 @@ func NewFromRows(header []string, rows [][]string) (Frame, error) {
// NewFromCSV creates a new Frame from CSV.
func NewFromCSV(header []string, fpath string) (Frame, error) {
f, err := os.OpenFile(fpath, os.O_RDONLY, 0444)
f, err := openToRead(fpath)
if err != nil {
return nil, err
}
@ -134,7 +138,12 @@ func NewFromCSV(header []string, fpath string) (Frame, error) {
rd := csv.NewReader(f)
// TODO: make this configurable
// FieldsPerRecord is the number of expected fields per record.
// If FieldsPerRecord is positive, Read requires each record to
// have the given number of fields. If FieldsPerRecord is 0, Read sets it to
// the number of fields in the first record, so that future records must
// have the same field count. If FieldsPerRecord is negative, no check is
// made and records may have a variable number of fields.
rd.FieldsPerRecord = -1
rows, err := rd.ReadAll()
@ -156,10 +165,10 @@ func NewFromColumns(zero Value, cols ...Column) (Frame, error) {
columns[i] = col.Copy()
if i == 0 {
maxEndIndex = col.CountRow()
maxEndIndex = col.Count()
}
if maxEndIndex < col.CountRow() {
maxEndIndex = col.CountRow()
if maxEndIndex < col.Count() {
maxEndIndex = col.Count()
}
}
// this is index, so decrement by 1 to make it as valid index
@ -169,7 +178,7 @@ func NewFromColumns(zero Value, cols ...Column) (Frame, error) {
if zero != nil {
// make all columns have same row number
for _, col := range columns {
rNum := col.CountRow()
rNum := col.Count()
if rNum < maxSize { // fill-in with zero values
for i := 0; i < maxSize-rNum; i++ {
col.PushBack(zero)
@ -180,10 +189,10 @@ func NewFromColumns(zero Value, cols ...Column) (Frame, error) {
}
}
// double-check
rNum := columns[0].CountRow()
rNum := columns[0].Count()
for _, col := range columns {
if rNum != col.CountRow() {
return nil, fmt.Errorf("%q has %d rows (expected %d rows as %q)", col.Header(), col.CountRow(), rNum, columns[0].Header())
if rNum != col.Count() {
return nil, fmt.Errorf("%q has %d rows (expected %d rows as %q)", col.Header(), col.Count(), rNum, columns[0].Header())
}
}
}
@ -370,7 +379,7 @@ func (f *frame) Rows() ([]string, [][]string) {
var rowN int
for _, col := range f.columns {
n := col.CountRow()
n := col.Count()
if rowN < n {
rowN = n
}
@ -395,16 +404,13 @@ func (f *frame) Rows() ([]string, [][]string) {
}
func (f *frame) CSV(fpath string) error {
fi, err := os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC, 0777)
file, err := openToOverwrite(fpath)
if err != nil {
fi, err = os.Create(fpath)
if err != nil {
return err
}
return err
}
defer fi.Close()
defer file.Close()
wr := csv.NewWriter(fi)
wr := csv.NewWriter(file)
headers, rows := f.Rows()
if err := wr.Write(headers); err != nil {
@ -418,6 +424,29 @@ func (f *frame) CSV(fpath string) error {
return wr.Error()
}
func (f *frame) CSVHorizontal(fpath string) error {
var rows [][]string
for _, col := range f.columns {
row := []string{col.Header()}
row = append(row, col.Rows()...)
rows = append(rows, row)
}
file, err := openToOverwrite(fpath)
if err != nil {
return err
}
defer file.Close()
wr := csv.NewWriter(file)
if err := wr.WriteAll(rows); err != nil {
return err
}
wr.Flush()
return wr.Error()
}
// Sort sorts the data frame.
// TODO: use tree?
func (f *frame) Sort(header string, st SortType, so SortOption) error {

19
vendor/github.com/gyuho/dataframe/util.go generated vendored Normal file
View File

@ -0,0 +1,19 @@
package dataframe
import "os"
func openToRead(fpath string) (*os.File, error) {
f, err := os.OpenFile(fpath, os.O_RDONLY, 0444)
if err != nil {
return nil, err
}
return f, nil
}
func openToOverwrite(fpath string) (*os.File, error) {
f, err := os.OpenFile(fpath, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0777)
if err != nil {
return nil, err
}
return f, nil
}

View File

@ -22,7 +22,11 @@ func Main() {
port = s
}
if err := http.ListenAndServe(":"+port, http.HandlerFunc(handleHTTP)); err != nil {
host := ""
if IsDevAppServer() {
host = "127.0.0.1"
}
if err := http.ListenAndServe(host+":"+port, http.HandlerFunc(handleHTTP)); err != nil {
log.Fatalf("http.ListenAndServe: %v", err)
}
}