Merge pull request #7214 from sinsharat/support_put_ignore_lease

*: 'ignore_lease' to detach value with PutRequest
This commit is contained in:
Xiang Li 2017-01-24 14:53:51 -08:00 committed by GitHub
commit d7cc9be3fd
15 changed files with 544 additions and 238 deletions

View File

@ -617,6 +617,7 @@ Empty field.
| lease | lease is the lease ID to associate with the key in the key-value store. A lease value of 0 indicates no lease. | int64 |
| prev_kv | 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. | bool |
| ignore_value | If ignore_value is set, etcd updates the key using its current value. Returns an error if the key does not exist. | bool |
| ignore_lease | If ignore_lease is set, etcd updates the key using its current lease. Returns an error if the key does not exist. | bool |

View File

@ -1833,6 +1833,11 @@
"type": "boolean",
"format": "boolean",
"description": "If ignore_value is set, etcd updates the key using its current value.\nReturns an error if the key does not exist."
},
"ignore_lease": {
"type": "boolean",
"format": "boolean",
"description": "If ignore_lease is set, etcd updates the key using its current lease.\nReturns an error if the key does not exist."
}
}
},

View File

@ -146,6 +146,47 @@ func TestKVPutWithIgnoreValue(t *testing.T) {
}
}
// TestKVPutWithIgnoreLease ensures that Put with WithIgnoreLease does not affect the existing lease for the key.
func TestKVPutWithIgnoreLease(t *testing.T) {
defer testutil.AfterTest(t)
clus := integration.NewClusterV3(t, &integration.ClusterConfig{Size: 1})
defer clus.Terminate(t)
kv := clientv3.NewKV(clus.RandClient())
lapi := clientv3.NewLease(clus.RandClient())
defer lapi.Close()
resp, err := lapi.Grant(context.Background(), 10)
if err != nil {
t.Errorf("failed to create lease %v", err)
}
if _, err := kv.Put(context.TODO(), "zoo", "bar", clientv3.WithIgnoreLease()); err != rpctypes.ErrKeyNotFound {
t.Fatalf("err expected %v, got %v", rpctypes.ErrKeyNotFound, err)
}
if _, err := kv.Put(context.TODO(), "zoo", "bar", clientv3.WithLease(resp.ID)); err != nil {
t.Fatal(err)
}
if _, err := kv.Put(context.TODO(), "zoo", "bar1", clientv3.WithIgnoreLease()); err != nil {
t.Fatal(err)
}
rr, rerr := kv.Get(context.TODO(), "zoo")
if rerr != nil {
t.Fatal(rerr)
}
if len(rr.Kvs) != 1 {
t.Fatalf("len(rr.Kvs) expected 1, got %d", len(rr.Kvs))
}
if rr.Kvs[0].Lease != int64(resp.ID) {
t.Fatalf("lease expected %v, got %v", resp.ID, rr.Kvs[0].Lease)
}
}
func TestKVPutWithRequireLeader(t *testing.T) {
defer testutil.AfterTest(t)

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, IgnoreValue: op.ignoreValue}
r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease}
resp, err = kv.remote.Put(ctx, r)
if err == nil {
return OpResponse{put: (*PutResponse)(resp)}, nil

View File

@ -54,6 +54,7 @@ type Op struct {
// for put
ignoreValue bool
ignoreLease bool
// progressNotify is for progress updates.
progressNotify bool
@ -97,7 +98,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, IgnoreValue: op.ignoreValue}
r := &pb.PutRequest{Key: op.key, Value: op.val, Lease: int64(op.leaseID), PrevKv: op.prevKV, IgnoreValue: op.ignoreValue, IgnoreLease: op.ignoreLease}
return &pb.RequestOp{Request: &pb.RequestOp_RequestPut{RequestPut: r}}
case tDeleteRange:
r := &pb.DeleteRangeRequest{Key: op.key, RangeEnd: op.end, PrevKv: op.prevKV}
@ -372,6 +373,15 @@ func WithIgnoreValue() OpOption {
}
}
// WithIgnoreLease updates the key using its current lease.
// Empty lease should be passed when ignore_lease is set.
// Returns an error if the key does not exist.
func WithIgnoreLease() OpOption {
return func(op *Op) {
op.ignoreLease = true
}
}
// LeaseOp represents an Operation that lease can execute.
type LeaseOp struct {
id LeaseID

View File

@ -29,6 +29,7 @@ func TestCtlV3PutClientTLSFlagByEnv(t *testing.T) {
testCtl(t, putTest, withCfg(configClientTLS), withFlagByEnv())
}
func TestCtlV3PutIgnoreValue(t *testing.T) { testCtl(t, putTestIgnoreValue) }
func TestCtlV3PutIgnoreLease(t *testing.T) { testCtl(t, putTestIgnoreLease) }
func TestCtlV3Get(t *testing.T) { testCtl(t, getTest) }
func TestCtlV3GetNoTLS(t *testing.T) { testCtl(t, getTest, withCfg(configNoTLS)) }
@ -78,6 +79,31 @@ func putTestIgnoreValue(cx ctlCtx) {
}
}
func putTestIgnoreLease(cx ctlCtx) {
leaseID, err := ctlV3LeaseGrant(cx, 10)
if err != nil {
cx.t.Fatalf("putTestIgnoreLease: ctlV3LeaseGrant error (%v)", err)
}
if err := ctlV3Put(cx, "foo", "bar", leaseID); err != nil {
cx.t.Fatalf("putTestIgnoreLease: ctlV3Put error (%v)", err)
}
if err := ctlV3Get(cx, []string{"foo"}, kv{"foo", "bar"}); err != nil {
cx.t.Fatalf("putTestIgnoreLease: ctlV3Get error (%v)", err)
}
if err := ctlV3Put(cx, "foo", "bar1", "", "--ignore-lease"); err != nil {
cx.t.Fatalf("putTestIgnoreLease: ctlV3Put error (%v)", err)
}
if err := ctlV3Get(cx, []string{"foo"}, kv{"foo", "bar1"}); err != nil {
cx.t.Fatalf("putTestIgnoreLease: ctlV3Get error (%v)", err)
}
if err := ctlV3LeaseRevoke(cx, leaseID); err != nil {
cx.t.Fatalf("putTestIgnoreLease: ctlV3LeaseRevok error (%v)", err)
}
if err := ctlV3Get(cx, []string{"key"}); err != nil { // expect no output
cx.t.Fatalf("putTestIgnoreLease: ctlV3Get error (%v)", err)
}
}
func getTest(cx ctlCtx) {
var (
kvs = []kv{{"key1", "val1"}, {"key2", "val2"}, {"key3", "val3"}}
@ -245,17 +271,20 @@ func delTest(cx ctlCtx) {
func ctlV3Put(cx ctlCtx, key, value, leaseID string, flags ...string) error {
skipValue := false
skipLease := false
for _, f := range flags {
if f == "--ignore-value" {
skipValue = true
break
}
if f == "--ignore-lease" {
skipLease = true
}
}
cmdArgs := append(cx.PrefixArgs(), "put", key)
if !skipValue {
cmdArgs = append(cmdArgs, value)
}
if leaseID != "" {
if leaseID != "" && !skipLease {
cmdArgs = append(cmdArgs, "--lease", leaseID)
}
if len(flags) != 0 {

View File

@ -31,6 +31,8 @@ RPC: Put
- ignore-value -- updates the key using its current value.
- ignore-lease -- updates the key using its current lease.
#### Output
`OK`
@ -47,6 +49,16 @@ RPC: Put
# OK
```
```bash
./etcdctl put foo bar --lease=1234abcd
# OK
./etcdctl put foo bar1 --ignore-lease # to use existing lease 1234abcd
# OK
./etcdctl get foo
# foo
# bar1
```
```bash
./etcdctl put foo bar1 --prev-kv
# OK

View File

@ -24,9 +24,10 @@ import (
)
var (
leaseStr string
putPrevKV bool
putIgnoreVal bool
leaseStr string
putPrevKV bool
putIgnoreVal bool
putIgnoreLease bool
)
// NewPutCommand returns the cobra command for "put".
@ -46,6 +47,9 @@ $ put -- <key> <value>
If <value> isn't given as a command line argument and '--ignore-value' is not specified,
this command tries to read the value from standard input.
If <lease> isn't given as a command line argument and '--ignore-lease' is not specified,
this command tries to read the value from standard input.
For example,
$ cat file | put <key>
will store the content of the file to <key>.
@ -55,6 +59,7 @@ will store the content of the file to <key>.
cmd.Flags().StringVar(&leaseStr, "lease", "0", "lease ID (in hexadecimal) to attach to the key")
cmd.Flags().BoolVar(&putPrevKV, "prev-kv", false, "return the previous key-value pair before modification")
cmd.Flags().BoolVar(&putIgnoreVal, "ignore-value", false, "updates the key using its current value")
cmd.Flags().BoolVar(&putIgnoreLease, "ignore-lease", false, "updates the key using its current lease")
return cmd
}
@ -80,6 +85,7 @@ func getPutOp(cmd *cobra.Command, args []string) (string, string, []clientv3.OpO
if putIgnoreVal && len(args) > 1 {
ExitWithError(ExitBadArgs, fmt.Errorf("put command needs only 1 argument when 'ignore-value' is set."))
}
var value string
var err error
if !putIgnoreVal {
@ -104,6 +110,9 @@ func getPutOp(cmd *cobra.Command, args []string) (string, string, []clientv3.OpO
if putIgnoreVal {
opts = append(opts, clientv3.WithIgnoreValue())
}
if putIgnoreLease {
opts = append(opts, clientv3.WithIgnoreLease())
}
return key, value, opts
}

View File

@ -135,7 +135,10 @@ func checkPutRequest(r *pb.PutRequest) error {
return rpctypes.ErrGRPCEmptyKey
}
if r.IgnoreValue && len(r.Value) != 0 {
return rpctypes.ErrGRPCValue
return rpctypes.ErrGRPCValueProvided
}
if r.IgnoreLease && r.Lease != 0 {
return rpctypes.ErrGRPCLeaseProvided
}
return nil
}

View File

@ -21,14 +21,15 @@ 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")
ErrGRPCFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision")
ErrGRPCNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded")
ErrGRPCEmptyKey = grpc.Errorf(codes.InvalidArgument, "etcdserver: key is not provided")
ErrGRPCKeyNotFound = grpc.Errorf(codes.InvalidArgument, "etcdserver: key not found")
ErrGRPCValueProvided = grpc.Errorf(codes.InvalidArgument, "etcdserver: value is provided")
ErrGRPCLeaseProvided = grpc.Errorf(codes.InvalidArgument, "etcdserver: lease 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")
ErrGRPCFutureRev = grpc.Errorf(codes.OutOfRange, "etcdserver: mvcc: required revision is a future revision")
ErrGRPCNoSpace = grpc.Errorf(codes.ResourceExhausted, "etcdserver: mvcc: database space exceeded")
ErrGRPCLeaseNotFound = grpc.Errorf(codes.NotFound, "etcdserver: requested lease not found")
ErrGRPCLeaseExist = grpc.Errorf(codes.FailedPrecondition, "etcdserver: lease already exists")
@ -65,9 +66,11 @@ var (
ErrGRPCUnhealthy = grpc.Errorf(codes.Unavailable, "etcdserver: unhealthy cluster")
errStringToError = map[string]error{
grpc.ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey,
grpc.ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound,
grpc.ErrorDesc(ErrGRPCValue): ErrGRPCValue,
grpc.ErrorDesc(ErrGRPCEmptyKey): ErrGRPCEmptyKey,
grpc.ErrorDesc(ErrGRPCKeyNotFound): ErrGRPCKeyNotFound,
grpc.ErrorDesc(ErrGRPCValueProvided): ErrGRPCValueProvided,
grpc.ErrorDesc(ErrGRPCLeaseProvided): ErrGRPCLeaseProvided,
grpc.ErrorDesc(ErrGRPCTooManyOps): ErrGRPCTooManyOps,
grpc.ErrorDesc(ErrGRPCDuplicateKey): ErrGRPCDuplicateKey,
grpc.ErrorDesc(ErrGRPCCompacted): ErrGRPCCompacted,
@ -110,14 +113,15 @@ var (
}
// client-side error
ErrEmptyKey = Error(ErrGRPCEmptyKey)
ErrKeyNotFound = Error(ErrGRPCKeyNotFound)
ErrValue = Error(ErrGRPCValue)
ErrTooManyOps = Error(ErrGRPCTooManyOps)
ErrDuplicateKey = Error(ErrGRPCDuplicateKey)
ErrCompacted = Error(ErrGRPCCompacted)
ErrFutureRev = Error(ErrGRPCFutureRev)
ErrNoSpace = Error(ErrGRPCNoSpace)
ErrEmptyKey = Error(ErrGRPCEmptyKey)
ErrKeyNotFound = Error(ErrGRPCKeyNotFound)
ErrValueProvided = Error(ErrGRPCValueProvided)
ErrLeaseProvided = Error(ErrGRPCLeaseProvided)
ErrTooManyOps = Error(ErrGRPCTooManyOps)
ErrDuplicateKey = Error(ErrGRPCDuplicateKey)
ErrCompacted = Error(ErrGRPCCompacted)
ErrFutureRev = Error(ErrGRPCFutureRev)
ErrNoSpace = Error(ErrGRPCNoSpace)
ErrLeaseNotFound = Error(ErrGRPCLeaseNotFound)
ErrLeaseExist = Error(ErrGRPCLeaseExist)

View File

@ -161,7 +161,7 @@ func (a *applierV3backend) Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse,
)
var rr *mvcc.RangeResult
if p.PrevKv || p.IgnoreValue {
if p.PrevKv || p.IgnoreValue || p.IgnoreLease {
if txnID != noTxn {
rr, err = a.s.KV().TxnRange(txnID, p.Key, nil, mvcc.RangeOptions{})
if err != nil {
@ -183,6 +183,14 @@ func (a *applierV3backend) Put(txnID int64, p *pb.PutRequest) (*pb.PutResponse,
p.Value = rr.KVs[0].Value
}
if p.IgnoreLease {
if rr == nil || len(rr.KVs) == 0 {
// ignore_lease flag expects previous key-value pair
return nil, ErrKeyNotFound
}
p.Lease = rr.KVs[0].Lease
}
if txnID != noTxn {
rev, err = a.s.KV().TxnPut(txnID, p.Key, p.Value, lease.LeaseID(p.Lease))
if err != nil {
@ -767,7 +775,7 @@ func (a *applierV3backend) checkRequestPut(reqs []*pb.RequestOp) error {
if preq == nil {
continue
}
if preq.IgnoreValue {
if preq.IgnoreValue || preq.IgnoreLease {
// expects previous key-value, error if not exist
rr, err := a.s.KV().Range(preq.Key, nil, mvcc.RangeOptions{})
if err != nil {

View File

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

View File

@ -427,6 +427,10 @@ message PutRequest {
// If ignore_value is set, etcd updates the key using its current value.
// Returns an error if the key does not exist.
bool ignore_value = 5;
// If ignore_lease is set, etcd updates the key using its current lease.
// Returns an error if the key does not exist.
bool ignore_lease = 6;
}
message PutResponse {

View File

@ -395,7 +395,7 @@ func TestV3PutIgnoreValue(t *testing.T) {
_, err := kvc.Put(context.TODO(), &preq)
return err
},
rpctypes.ErrGRPCValue,
rpctypes.ErrGRPCValueProvided,
0,
},
{ // overwrite with previous value, ensure no prev-kv is returned and lease is detached
@ -448,6 +448,146 @@ func TestV3PutIgnoreValue(t *testing.T) {
}
}
// TestV3PutIgnoreLease ensures that writes with ignore_lease uses previous lease for the key overwrites.
func TestV3PutIgnoreLease(t *testing.T) {
defer testutil.AfterTest(t)
clus := NewClusterV3(t, &ClusterConfig{Size: 1})
defer clus.Terminate(t)
kvc := toGRPC(clus.RandClient()).KV
// create lease
lc := toGRPC(clus.RandClient()).Lease
lresp, err := lc.LeaseGrant(context.TODO(), &pb.LeaseGrantRequest{TTL: 30})
if err != nil {
t.Fatal(err)
}
if lresp.Error != "" {
t.Fatal(lresp.Error)
}
key, val, val1 := []byte("zoo"), []byte("bar"), []byte("bar1")
putReq := pb.PutRequest{Key: key, Value: val}
tests := []struct {
putFunc func() error
putErr error
wleaseID int64
wvalue []byte
}{
{ // put failure for non-existent key
func() error {
preq := putReq
preq.IgnoreLease = true
_, err := kvc.Put(context.TODO(), &preq)
return err
},
rpctypes.ErrGRPCKeyNotFound,
0,
nil,
},
{ // txn failure for non-existent key
func() error {
preq := putReq
preq.IgnoreLease = true
txn := &pb.TxnRequest{}
txn.Success = append(txn.Success, &pb.RequestOp{
Request: &pb.RequestOp_RequestPut{RequestPut: &preq}})
_, err := kvc.Txn(context.TODO(), txn)
return err
},
rpctypes.ErrGRPCKeyNotFound,
0,
nil,
},
{ // put success
func() error {
preq := putReq
preq.Lease = lresp.ID
_, err := kvc.Put(context.TODO(), &preq)
return err
},
nil,
lresp.ID,
val,
},
{ // txn success, modify value using 'ignore_lease' and ensure lease is not detached
func() error {
preq := putReq
preq.Value = val1
preq.IgnoreLease = true
txn := &pb.TxnRequest{}
txn.Success = append(txn.Success, &pb.RequestOp{
Request: &pb.RequestOp_RequestPut{RequestPut: &preq}})
_, err := kvc.Txn(context.TODO(), txn)
return err
},
nil,
lresp.ID,
val1,
},
{ // non-empty lease with ignore_lease should error
func() error {
preq := putReq
preq.Lease = lresp.ID
preq.IgnoreLease = true
_, err := kvc.Put(context.TODO(), &preq)
return err
},
rpctypes.ErrGRPCLeaseProvided,
0,
nil,
},
{ // overwrite with previous value, ensure no prev-kv is returned and lease is detached
func() error {
presp, err := kvc.Put(context.TODO(), &putReq)
if err != nil {
return err
}
if presp.PrevKv != nil && len(presp.PrevKv.Key) != 0 {
return fmt.Errorf("unexexpected previous key-value %v", presp.PrevKv)
}
return nil
},
nil,
0,
val,
},
{ // revoke lease, ensure detached key doesn't get deleted
func() error {
_, err := lc.LeaseRevoke(context.TODO(), &pb.LeaseRevokeRequest{ID: lresp.ID})
return err
},
nil,
0,
val,
},
}
for i, tt := range tests {
if err := tt.putFunc(); !eqErrGRPC(err, tt.putErr) {
t.Fatalf("#%d: err expected %v, got %v", i, tt.putErr, err)
}
if tt.putErr != nil {
continue
}
rr, err := kvc.Range(context.TODO(), &pb.RangeRequest{Key: key})
if err != nil {
t.Fatalf("#%d: %v", i, err)
}
if len(rr.Kvs) != 1 {
t.Fatalf("#%d: len(rr.KVs) expected 1, got %d", i, len(rr.Kvs))
}
if !bytes.Equal(rr.Kvs[0].Value, tt.wvalue) {
t.Fatalf("#%d: value expected %q, got %q", i, val, rr.Kvs[0].Value)
}
if rr.Kvs[0].Lease != tt.wleaseID {
t.Fatalf("#%d: lease ID expected %d, got %d", i, tt.wleaseID, rr.Kvs[0].Lease)
}
}
}
// TestV3PutMissingLease ensures that a Put on a key with a bogus lease fails.
func TestV3PutMissingLease(t *testing.T) {
defer testutil.AfterTest(t)

View File

@ -197,6 +197,9 @@ func PutRequestToOp(r *pb.PutRequest) clientv3.Op {
if r.IgnoreValue {
opts = append(opts, clientv3.WithIgnoreValue())
}
if r.IgnoreLease {
opts = append(opts, clientv3.WithIgnoreLease())
}
return clientv3.OpPut(string(r.Key), string(r.Value), opts...)
}