From 0ecae5f377d1ec8399f6065ed7bd36d2516390a7 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Wed, 4 Nov 2020 16:45:57 +0530 Subject: [PATCH 01/14] write DROP operations to backup manifest --- edgraph/server.go | 39 ++ protos/pb.proto | 17 +- protos/pb/pb.pb.go | 1063 +++++++++++++++++++++++++----------- schema/schema.go | 5 +- worker/backup_common.go | 3 + worker/backup_ee.go | 14 +- worker/backup_processor.go | 103 +++- x/keys.go | 23 +- 8 files changed, 932 insertions(+), 335 deletions(-) diff --git a/edgraph/server.go b/edgraph/server.go index 3b88f1f5511..0c9907eaaf2 100644 --- a/edgraph/server.go +++ b/edgraph/server.go @@ -289,6 +289,21 @@ func parseSchemaFromAlterOperation(op *api.Operation) (*schema.ParsedSchema, err return result, nil } +func insertDropRecord(ctx context.Context, restoreOp string) error { + _, err := (&Server{}).Query(context.WithValue(ctx, IsGraphql, true), + &api.Request{ + Mutations: []*api.Mutation{{ + Set: []*api.NQuad{{ + Subject: "_:r", + Predicate: "dgraph.drop.op", + ObjectValue: &api.Value{Val: &api.Value_StrVal{StrVal: restoreOp}}, + }}, + }}, + CommitNow: true, + }) + return err +} + // Alter handles requests to change the schema or remove parts or all of the data. func (s *Server) Alter(ctx context.Context, op *api.Operation) (*api.Payload, error) { ctx, span := otrace.StartSpan(ctx, "Server.Alter") @@ -321,6 +336,12 @@ func (s *Server) Alter(ctx context.Context, op *api.Operation) (*api.Payload, er return empty, err } + // insert a helper record for backup & restore, indicating that drop_all was done + err = insertDropRecord(ctx, "DROP_ALL;") + if err != nil { + return empty, err + } + // insert empty GraphQL schema, so all alphas get notified to // reset their in-memory GraphQL schema _, err = UpdateGQLSchema(ctx, "", "") @@ -347,6 +368,12 @@ func (s *Server) Alter(ctx context.Context, op *api.Operation) (*api.Payload, er return empty, err } + // insert a helper record for backup & restore, indicating that drop_data was done + err = insertDropRecord(ctx, "DROP_DATA;") + if err != nil { + return empty, err + } + // just reinsert the GraphQL schema, no need to alter dgraph schema as this was drop_data _, err = UpdateGQLSchema(ctx, graphQLSchema, "") // recreate the admin account after a drop data operation @@ -386,6 +413,12 @@ func (s *Server) Alter(ctx context.Context, op *api.Operation) (*api.Payload, er edges := []*pb.DirectedEdge{edge} m.Edges = edges _, err = query.ApplyMutations(ctx, m) + if err != nil { + return empty, err + } + + // insert a helper record for backup & restore, indicating that drop_attr was done + err = insertDropRecord(ctx, "DROP_ATTR;"+attr) return empty, err } @@ -403,6 +436,12 @@ func (s *Server) Alter(ctx context.Context, op *api.Operation) (*api.Payload, er m.DropOp = pb.Mutations_TYPE m.DropValue = op.DropValue _, err := query.ApplyMutations(ctx, m) + if err != nil { + return empty, err + } + + // insert a helper record for backup & restore, indicating that drop_attr was done + err = insertDropRecord(ctx, "DROP_TYPE;"+op.DropValue) return empty, err } diff --git a/protos/pb.proto b/protos/pb.proto index a02e812246f..5129a125043 100644 --- a/protos/pb.proto +++ b/protos/pb.proto @@ -537,7 +537,7 @@ service Worker { rpc StreamSnapshot (stream Snapshot) returns (stream KVS) {} rpc Sort (SortMessage) returns (SortResult) {} rpc Schema (SchemaRequest) returns (SchemaResult) {} - rpc Backup (BackupRequest) returns (Status) {} + rpc Backup (BackupRequest) returns (BackupResponse) {} rpc Restore (RestoreRequest) returns (Status) {} rpc Export (ExportRequest) returns (ExportResponse) {} rpc ReceivePredicate(stream KVS) returns (api.Payload) {} @@ -599,6 +599,21 @@ message BackupRequest { repeated string predicates = 10; } +message BackupResponse { + repeated DropOperation drop_operations = 1; +} + +message DropOperation { + enum DropOp { + ALL = 0; + DATA = 1; + TYPE = 2; + ATTR = 3; + } + DropOp drop_op = 1; + string drop_value = 2; +} + message ExportRequest { uint32 group_id = 1; // Group id to back up. uint64 read_ts = 2; diff --git a/protos/pb/pb.pb.go b/protos/pb/pb.pb.go index 484f87a8dcb..92a2c2d337f 100644 --- a/protos/pb/pb.pb.go +++ b/protos/pb/pb.pb.go @@ -230,6 +230,37 @@ func (SchemaUpdate_Directive) EnumDescriptor() ([]byte, []int) { return fileDescriptor_f80abaa17e25ccc8, []int{39, 0} } +type DropOperation_DropOp int32 + +const ( + DropOperation_ALL DropOperation_DropOp = 0 + DropOperation_DATA DropOperation_DropOp = 1 + DropOperation_TYPE DropOperation_DropOp = 2 + DropOperation_ATTR DropOperation_DropOp = 3 +) + +var DropOperation_DropOp_name = map[int32]string{ + 0: "ALL", + 1: "DATA", + 2: "TYPE", + 3: "ATTR", +} + +var DropOperation_DropOp_value = map[string]int32{ + "ALL": 0, + "DATA": 1, + "TYPE": 2, + "ATTR": 3, +} + +func (x DropOperation_DropOp) String() string { + return proto.EnumName(DropOperation_DropOp_name, int32(x)) +} + +func (DropOperation_DropOp) EnumDescriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{56, 0} +} + type BackupKey_KeyType int32 const ( @@ -270,7 +301,7 @@ func (x BackupKey_KeyType) String() string { } func (BackupKey_KeyType) EnumDescriptor() ([]byte, []int) { - return fileDescriptor_f80abaa17e25ccc8, []int{57, 0} + return fileDescriptor_f80abaa17e25ccc8, []int{59, 0} } type List struct { @@ -4444,6 +4475,108 @@ func (m *BackupRequest) GetPredicates() []string { return nil } +type BackupResponse struct { + DropOperations []*DropOperation `protobuf:"bytes,1,rep,name=drop_operations,json=dropOperations,proto3" json:"drop_operations,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *BackupResponse) Reset() { *m = BackupResponse{} } +func (m *BackupResponse) String() string { return proto.CompactTextString(m) } +func (*BackupResponse) ProtoMessage() {} +func (*BackupResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{55} +} +func (m *BackupResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *BackupResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_BackupResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *BackupResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_BackupResponse.Merge(m, src) +} +func (m *BackupResponse) XXX_Size() int { + return m.Size() +} +func (m *BackupResponse) XXX_DiscardUnknown() { + xxx_messageInfo_BackupResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_BackupResponse proto.InternalMessageInfo + +func (m *BackupResponse) GetDropOperations() []*DropOperation { + if m != nil { + return m.DropOperations + } + return nil +} + +type DropOperation struct { + DropOp DropOperation_DropOp `protobuf:"varint,1,opt,name=drop_op,json=dropOp,proto3,enum=pb.DropOperation_DropOp" json:"drop_op,omitempty"` + DropValue string `protobuf:"bytes,2,opt,name=drop_value,json=dropValue,proto3" json:"drop_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DropOperation) Reset() { *m = DropOperation{} } +func (m *DropOperation) String() string { return proto.CompactTextString(m) } +func (*DropOperation) ProtoMessage() {} +func (*DropOperation) Descriptor() ([]byte, []int) { + return fileDescriptor_f80abaa17e25ccc8, []int{56} +} +func (m *DropOperation) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DropOperation) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DropOperation.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DropOperation) XXX_Merge(src proto.Message) { + xxx_messageInfo_DropOperation.Merge(m, src) +} +func (m *DropOperation) XXX_Size() int { + return m.Size() +} +func (m *DropOperation) XXX_DiscardUnknown() { + xxx_messageInfo_DropOperation.DiscardUnknown(m) +} + +var xxx_messageInfo_DropOperation proto.InternalMessageInfo + +func (m *DropOperation) GetDropOp() DropOperation_DropOp { + if m != nil { + return m.DropOp + } + return DropOperation_ALL +} + +func (m *DropOperation) GetDropValue() string { + if m != nil { + return m.DropValue + } + return "" +} + type ExportRequest struct { GroupId uint32 `protobuf:"varint,1,opt,name=group_id,json=groupId,proto3" json:"group_id,omitempty"` ReadTs uint64 `protobuf:"varint,2,opt,name=read_ts,json=readTs,proto3" json:"read_ts,omitempty"` @@ -4464,7 +4597,7 @@ func (m *ExportRequest) Reset() { *m = ExportRequest{} } func (m *ExportRequest) String() string { return proto.CompactTextString(m) } func (*ExportRequest) ProtoMessage() {} func (*ExportRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f80abaa17e25ccc8, []int{55} + return fileDescriptor_f80abaa17e25ccc8, []int{57} } func (m *ExportRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4570,7 +4703,7 @@ func (m *ExportResponse) Reset() { *m = ExportResponse{} } func (m *ExportResponse) String() string { return proto.CompactTextString(m) } func (*ExportResponse) ProtoMessage() {} func (*ExportResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f80abaa17e25ccc8, []int{56} + return fileDescriptor_f80abaa17e25ccc8, []int{58} } func (m *ExportResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4637,7 +4770,7 @@ func (m *BackupKey) Reset() { *m = BackupKey{} } func (m *BackupKey) String() string { return proto.CompactTextString(m) } func (*BackupKey) ProtoMessage() {} func (*BackupKey) Descriptor() ([]byte, []int) { - return fileDescriptor_f80abaa17e25ccc8, []int{57} + return fileDescriptor_f80abaa17e25ccc8, []int{59} } func (m *BackupKey) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4724,7 +4857,7 @@ func (m *BackupPostingList) Reset() { *m = BackupPostingList{} } func (m *BackupPostingList) String() string { return proto.CompactTextString(m) } func (*BackupPostingList) ProtoMessage() {} func (*BackupPostingList) Descriptor() ([]byte, []int) { - return fileDescriptor_f80abaa17e25ccc8, []int{58} + return fileDescriptor_f80abaa17e25ccc8, []int{60} } func (m *BackupPostingList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4802,7 +4935,7 @@ func (m *UpdateGraphQLSchemaRequest) Reset() { *m = UpdateGraphQLSchemaR func (m *UpdateGraphQLSchemaRequest) String() string { return proto.CompactTextString(m) } func (*UpdateGraphQLSchemaRequest) ProtoMessage() {} func (*UpdateGraphQLSchemaRequest) Descriptor() ([]byte, []int) { - return fileDescriptor_f80abaa17e25ccc8, []int{59} + return fileDescriptor_f80abaa17e25ccc8, []int{61} } func (m *UpdateGraphQLSchemaRequest) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4870,7 +5003,7 @@ func (m *UpdateGraphQLSchemaResponse) Reset() { *m = UpdateGraphQLSchema func (m *UpdateGraphQLSchemaResponse) String() string { return proto.CompactTextString(m) } func (*UpdateGraphQLSchemaResponse) ProtoMessage() {} func (*UpdateGraphQLSchemaResponse) Descriptor() ([]byte, []int) { - return fileDescriptor_f80abaa17e25ccc8, []int{60} + return fileDescriptor_f80abaa17e25ccc8, []int{62} } func (m *UpdateGraphQLSchemaResponse) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4913,6 +5046,7 @@ func init() { proto.RegisterEnum("pb.Posting_ValType", Posting_ValType_name, Posting_ValType_value) proto.RegisterEnum("pb.Posting_PostingType", Posting_PostingType_name, Posting_PostingType_value) proto.RegisterEnum("pb.SchemaUpdate_Directive", SchemaUpdate_Directive_name, SchemaUpdate_Directive_value) + proto.RegisterEnum("pb.DropOperation_DropOp", DropOperation_DropOp_name, DropOperation_DropOp_value) proto.RegisterEnum("pb.BackupKey_KeyType", BackupKey_KeyType_name, BackupKey_KeyType_value) proto.RegisterType((*List)(nil), "pb.List") proto.RegisterType((*TaskValue)(nil), "pb.TaskValue") @@ -4976,6 +5110,8 @@ func init() { proto.RegisterType((*SnapshotMeta)(nil), "pb.SnapshotMeta") proto.RegisterType((*Status)(nil), "pb.Status") proto.RegisterType((*BackupRequest)(nil), "pb.BackupRequest") + proto.RegisterType((*BackupResponse)(nil), "pb.BackupResponse") + proto.RegisterType((*DropOperation)(nil), "pb.DropOperation") proto.RegisterType((*ExportRequest)(nil), "pb.ExportRequest") proto.RegisterType((*ExportResponse)(nil), "pb.ExportResponse") proto.RegisterType((*BackupKey)(nil), "pb.BackupKey") @@ -4987,300 +5123,305 @@ func init() { func init() { proto.RegisterFile("pb.proto", fileDescriptor_f80abaa17e25ccc8) } var fileDescriptor_f80abaa17e25ccc8 = []byte{ - // 4685 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x3a, 0x4d, 0x6f, 0x1c, 0x57, - 0x72, 0x9a, 0xef, 0xe9, 0x9a, 0x19, 0x6a, 0xf4, 0xa4, 0x95, 0x67, 0x47, 0xb6, 0x48, 0xb7, 0xad, - 0x35, 0x6d, 0x59, 0x94, 0x4c, 0x6f, 0x90, 0xb5, 0x17, 0x01, 0x42, 0x8a, 0x43, 0x99, 0x16, 0x45, - 0xd2, 0xcd, 0xa1, 0xbc, 0xeb, 0x43, 0x06, 0x3d, 0xdd, 0x8f, 0x64, 0x2f, 0x7b, 0xba, 0x7b, 0xbb, - 0x7b, 0xb8, 0x43, 0x9f, 0x12, 0x04, 0xc8, 0x29, 0x39, 0x05, 0x41, 0xf6, 0x94, 0x04, 0xf9, 0x03, - 0x41, 0x72, 0x0a, 0x72, 0x0e, 0x82, 0x20, 0x87, 0x20, 0xbf, 0x40, 0x09, 0x9c, 0x9c, 0x04, 0xe4, - 0x10, 0x04, 0xc8, 0x31, 0x08, 0xaa, 0xea, 0xf5, 0xd7, 0x70, 0x28, 0xd9, 0x0b, 0xec, 0x21, 0xa7, - 0x7e, 0x55, 0xf5, 0x3e, 0xeb, 0xd5, 0xf7, 0x6b, 0x68, 0x06, 0xe3, 0xb5, 0x20, 0xf4, 0x63, 0x5f, - 0x94, 0x83, 0x71, 0x5f, 0x33, 0x03, 0x87, 0xc1, 0xfe, 0x07, 0x27, 0x4e, 0x7c, 0x3a, 0x1d, 0xaf, - 0x59, 0xfe, 0xe4, 0xa1, 0x7d, 0x12, 0x9a, 0xc1, 0xe9, 0x03, 0xc7, 0x7f, 0x38, 0x36, 0xed, 0x13, - 0x19, 0x3e, 0x3c, 0x5f, 0x7f, 0x18, 0x8c, 0x1f, 0x26, 0x43, 0xfb, 0x0f, 0x72, 0x7d, 0x4f, 0xfc, - 0x13, 0xff, 0x21, 0xa1, 0xc7, 0xd3, 0x63, 0x82, 0x08, 0xa0, 0x16, 0x77, 0xd7, 0xfb, 0x50, 0xdd, - 0x75, 0xa2, 0x58, 0x08, 0xa8, 0x4e, 0x1d, 0x3b, 0xea, 0x95, 0x56, 0x2a, 0xab, 0x75, 0x83, 0xda, - 0xfa, 0x33, 0xd0, 0x86, 0x66, 0x74, 0xf6, 0xdc, 0x74, 0xa7, 0x52, 0x74, 0xa1, 0x72, 0x6e, 0xba, - 0xbd, 0xd2, 0x4a, 0x69, 0xb5, 0x6d, 0x60, 0x53, 0xac, 0x41, 0xf3, 0xdc, 0x74, 0x47, 0xf1, 0x45, - 0x20, 0x7b, 0xe5, 0x95, 0xd2, 0xea, 0xd2, 0xfa, 0xcd, 0xb5, 0x60, 0xbc, 0x76, 0xe0, 0x47, 0xb1, - 0xe3, 0x9d, 0xac, 0x3d, 0x37, 0xdd, 0xe1, 0x45, 0x20, 0x8d, 0xc6, 0x39, 0x37, 0xf4, 0x7d, 0x68, - 0x1d, 0x86, 0xd6, 0xf6, 0xd4, 0xb3, 0x62, 0xc7, 0xf7, 0x70, 0x45, 0xcf, 0x9c, 0x48, 0x9a, 0x51, - 0x33, 0xa8, 0x8d, 0x38, 0x33, 0x3c, 0x89, 0x7a, 0x95, 0x95, 0x0a, 0xe2, 0xb0, 0x2d, 0x7a, 0xd0, - 0x70, 0xa2, 0xc7, 0xfe, 0xd4, 0x8b, 0x7b, 0xd5, 0x95, 0xd2, 0x6a, 0xd3, 0x48, 0x40, 0xfd, 0xcf, - 0x2b, 0x50, 0xfb, 0x62, 0x2a, 0xc3, 0x0b, 0x1a, 0x17, 0xc7, 0x61, 0x32, 0x17, 0xb6, 0xc5, 0x2d, - 0xa8, 0xb9, 0xa6, 0x77, 0x12, 0xf5, 0xca, 0x34, 0x19, 0x03, 0xe2, 0x0e, 0x68, 0xe6, 0x71, 0x2c, - 0xc3, 0xd1, 0xd4, 0xb1, 0x7b, 0x95, 0x95, 0xd2, 0x6a, 0xdd, 0x68, 0x12, 0xe2, 0xc8, 0xb1, 0xc5, - 0xf7, 0xa1, 0x69, 0xfb, 0x23, 0x2b, 0xbf, 0x96, 0xed, 0xd3, 0x5a, 0xe2, 0x1d, 0x68, 0x4e, 0x1d, - 0x7b, 0xe4, 0x3a, 0x51, 0xdc, 0xab, 0xad, 0x94, 0x56, 0x5b, 0xeb, 0x4d, 0x3c, 0x2c, 0xf2, 0xce, - 0x68, 0x4c, 0x1d, 0x9b, 0x98, 0xf8, 0x01, 0x34, 0xa3, 0xd0, 0x1a, 0x1d, 0x4f, 0x3d, 0xab, 0x57, - 0xa7, 0x4e, 0xd7, 0xb1, 0x53, 0xee, 0xd4, 0x46, 0x23, 0x62, 0x00, 0x8f, 0x15, 0xca, 0x73, 0x19, - 0x46, 0xb2, 0xd7, 0xe0, 0xa5, 0x14, 0x28, 0x1e, 0x41, 0xeb, 0xd8, 0xb4, 0x64, 0x3c, 0x0a, 0xcc, - 0xd0, 0x9c, 0xf4, 0x9a, 0xd9, 0x44, 0xdb, 0x88, 0x3e, 0x40, 0x6c, 0x64, 0xc0, 0x71, 0x0a, 0x88, - 0x8f, 0xa1, 0x43, 0x50, 0x34, 0x3a, 0x76, 0xdc, 0x58, 0x86, 0x3d, 0x8d, 0xc6, 0x2c, 0xd1, 0x18, - 0xc2, 0x0c, 0x43, 0x29, 0x8d, 0x36, 0x77, 0x62, 0x8c, 0x78, 0x0b, 0x40, 0xce, 0x02, 0xd3, 0xb3, - 0x47, 0xa6, 0xeb, 0xf6, 0x80, 0xf6, 0xa0, 0x31, 0x66, 0xc3, 0x75, 0xc5, 0x1b, 0xb8, 0x3f, 0xd3, - 0x1e, 0xc5, 0x51, 0xaf, 0xb3, 0x52, 0x5a, 0xad, 0x1a, 0x75, 0x04, 0x87, 0x11, 0xf2, 0xd5, 0x32, - 0xad, 0x53, 0xd9, 0x5b, 0x5a, 0x29, 0xad, 0xd6, 0x0c, 0x06, 0x10, 0x7b, 0xec, 0x84, 0x51, 0xdc, - 0xbb, 0xce, 0x58, 0x02, 0xf4, 0x75, 0xd0, 0x48, 0x7a, 0x88, 0x3b, 0xf7, 0xa0, 0x7e, 0x8e, 0x00, - 0x0b, 0x59, 0x6b, 0xbd, 0x83, 0xdb, 0x4b, 0x05, 0xcc, 0x50, 0x44, 0xfd, 0x2e, 0x34, 0x77, 0x4d, - 0xef, 0x24, 0x91, 0x4a, 0xbc, 0x36, 0x1a, 0xa0, 0x19, 0xd4, 0xd6, 0x7f, 0x59, 0x86, 0xba, 0x21, - 0xa3, 0xa9, 0x1b, 0x8b, 0xf7, 0x00, 0xf0, 0x52, 0x26, 0x66, 0x1c, 0x3a, 0x33, 0x35, 0x6b, 0x76, - 0x2d, 0xda, 0xd4, 0xb1, 0x9f, 0x11, 0x49, 0x3c, 0x82, 0x36, 0xcd, 0x9e, 0x74, 0x2d, 0x67, 0x1b, - 0x48, 0xf7, 0x67, 0xb4, 0xa8, 0x8b, 0x1a, 0x71, 0x1b, 0xea, 0x24, 0x07, 0x2c, 0x8b, 0x1d, 0x43, - 0x41, 0xe2, 0x1e, 0x2c, 0x39, 0x5e, 0x8c, 0xf7, 0x64, 0xc5, 0x23, 0x5b, 0x46, 0x89, 0xa0, 0x74, - 0x52, 0xec, 0x96, 0x8c, 0x62, 0xf1, 0x11, 0x30, 0xb3, 0x93, 0x05, 0x6b, 0xb4, 0xe0, 0x52, 0x7a, - 0x89, 0x11, 0xaf, 0x48, 0x7d, 0xd4, 0x8a, 0x0f, 0xa0, 0x85, 0xe7, 0x4b, 0x46, 0xd4, 0x69, 0x44, - 0x9b, 0x4e, 0xa3, 0xd8, 0x61, 0x00, 0x76, 0x50, 0xdd, 0x91, 0x35, 0x28, 0x8c, 0x2c, 0x3c, 0xd4, - 0xd6, 0x07, 0x50, 0xdb, 0x0f, 0x6d, 0x19, 0x2e, 0xd4, 0x07, 0x01, 0x55, 0x5b, 0x46, 0x16, 0xa9, - 0x6a, 0xd3, 0xa0, 0x76, 0xa6, 0x23, 0x95, 0x9c, 0x8e, 0xe8, 0x7f, 0x56, 0x82, 0xd6, 0xa1, 0x1f, - 0xc6, 0xcf, 0x64, 0x14, 0x99, 0x27, 0x52, 0x2c, 0x43, 0xcd, 0xc7, 0x69, 0x15, 0x87, 0x35, 0xdc, - 0x13, 0xad, 0x63, 0x30, 0x7e, 0xee, 0x1e, 0xca, 0x57, 0xdf, 0x03, 0xca, 0x0e, 0x69, 0x57, 0x45, - 0xc9, 0x0e, 0xe9, 0xd6, 0x6d, 0xa8, 0xfb, 0xc7, 0xc7, 0x91, 0x64, 0x5e, 0xd6, 0x0c, 0x05, 0x5d, - 0x29, 0x82, 0xfa, 0x6f, 0x00, 0xe0, 0xfe, 0xbe, 0xa3, 0x14, 0xe8, 0xa7, 0xd0, 0x32, 0xcc, 0xe3, - 0xf8, 0xb1, 0xef, 0xc5, 0x72, 0x16, 0x8b, 0x25, 0x28, 0x3b, 0x36, 0xb1, 0xa8, 0x6e, 0x94, 0x1d, - 0x1b, 0x37, 0x77, 0x12, 0xfa, 0xd3, 0x80, 0x38, 0xd4, 0x31, 0x18, 0x20, 0x56, 0xda, 0x76, 0x48, - 0x3b, 0x46, 0x56, 0xda, 0x76, 0x28, 0x96, 0xa1, 0x15, 0x79, 0x66, 0x10, 0x9d, 0xfa, 0x31, 0x6e, - 0xae, 0x4a, 0x9b, 0x83, 0x04, 0x35, 0x8c, 0xf4, 0xff, 0x2c, 0x43, 0xfd, 0x99, 0x9c, 0x8c, 0x65, - 0x78, 0x69, 0x95, 0x47, 0xd0, 0xa4, 0x89, 0x47, 0x8e, 0xcd, 0x0b, 0x6d, 0x7e, 0xef, 0xe5, 0x8b, - 0xe5, 0x1b, 0x84, 0xdb, 0xb1, 0x3f, 0xf4, 0x27, 0x4e, 0x2c, 0x27, 0x41, 0x7c, 0x61, 0x34, 0x14, - 0x6a, 0xe1, 0x0e, 0x6e, 0x43, 0xdd, 0x95, 0x26, 0xde, 0x09, 0x8b, 0x9f, 0x82, 0xc4, 0x03, 0x68, - 0x98, 0x93, 0x91, 0x2d, 0x4d, 0x9b, 0xac, 0x54, 0x73, 0xf3, 0xd6, 0xcb, 0x17, 0xcb, 0x5d, 0x73, - 0xb2, 0x25, 0xcd, 0xfc, 0xdc, 0x75, 0xc6, 0x88, 0x4f, 0x50, 0xe6, 0xa2, 0x78, 0x34, 0x0d, 0x6c, - 0x33, 0x96, 0x64, 0xb3, 0xaa, 0x9b, 0xbd, 0x97, 0x2f, 0x96, 0x6f, 0x21, 0xfa, 0x88, 0xb0, 0xb9, - 0x61, 0x90, 0x61, 0xc5, 0x0e, 0xdc, 0xb0, 0xdc, 0x69, 0x84, 0xa6, 0xd4, 0xf1, 0x8e, 0xfd, 0x91, - 0xef, 0xb9, 0x17, 0x74, 0x4d, 0xcd, 0xcd, 0xb7, 0x5e, 0xbe, 0x58, 0xfe, 0xbe, 0x22, 0xee, 0x78, - 0xc7, 0xfe, 0xbe, 0xe7, 0x5e, 0xe4, 0x66, 0xb9, 0x3e, 0x47, 0x12, 0xbf, 0x0d, 0x4b, 0xc7, 0x7e, - 0x68, 0xc9, 0x51, 0xca, 0x98, 0x25, 0x9a, 0xa7, 0xff, 0xf2, 0xc5, 0xf2, 0x6d, 0xa2, 0x3c, 0xb9, - 0xc4, 0x9d, 0x76, 0x1e, 0xaf, 0xff, 0x6d, 0x19, 0x6a, 0xd4, 0x16, 0x8f, 0xa0, 0x31, 0x21, 0xc6, - 0x27, 0x56, 0xe6, 0x36, 0x4a, 0x02, 0xd1, 0xd6, 0xf8, 0x46, 0xa2, 0x81, 0x17, 0x87, 0x17, 0x46, - 0xd2, 0x0d, 0x47, 0xc4, 0xe6, 0xd8, 0x95, 0x71, 0xa4, 0x24, 0x37, 0x37, 0x62, 0xc8, 0x04, 0x35, - 0x42, 0x75, 0x9b, 0xbf, 0xfe, 0xca, 0xfc, 0xf5, 0x8b, 0x3e, 0x34, 0xad, 0x53, 0x69, 0x9d, 0x45, - 0xd3, 0x89, 0x12, 0x8e, 0x14, 0xee, 0x6f, 0x43, 0x3b, 0xbf, 0x0f, 0xf4, 0xab, 0x67, 0xf2, 0x82, - 0x04, 0xa4, 0x6a, 0x60, 0x53, 0xac, 0x40, 0x8d, 0x2c, 0x11, 0x89, 0x47, 0x6b, 0x1d, 0x70, 0x3b, - 0x3c, 0xc4, 0x60, 0xc2, 0xa7, 0xe5, 0x1f, 0x95, 0x70, 0x9e, 0xfc, 0xee, 0xf2, 0xf3, 0x68, 0x57, - 0xcf, 0xc3, 0x43, 0x72, 0xf3, 0xe8, 0x3e, 0x34, 0x76, 0x1d, 0x4b, 0x7a, 0x11, 0x79, 0xdf, 0x69, - 0x24, 0x53, 0xab, 0x81, 0x6d, 0x3c, 0xca, 0xc4, 0x9c, 0xed, 0xf9, 0xb6, 0x8c, 0x68, 0x9e, 0xaa, - 0x91, 0xc2, 0x48, 0x93, 0xb3, 0xc0, 0x09, 0x2f, 0x86, 0xcc, 0x84, 0x8a, 0x91, 0xc2, 0xe8, 0xde, - 0xa4, 0x87, 0x8b, 0xd9, 0x89, 0x27, 0x55, 0xa0, 0xfe, 0x17, 0x15, 0x68, 0x7f, 0x25, 0x43, 0xff, - 0x20, 0xf4, 0x03, 0x3f, 0x32, 0x5d, 0xb1, 0x51, 0x64, 0x27, 0x5f, 0xdb, 0x0a, 0xee, 0x36, 0xdf, - 0x6d, 0xed, 0x30, 0xe5, 0x2f, 0x5f, 0x47, 0x9e, 0xe1, 0x3a, 0xd4, 0xf9, 0x3a, 0x17, 0xf0, 0x4c, - 0x51, 0xb0, 0x0f, 0x5f, 0x20, 0xed, 0xb5, 0xc8, 0x0f, 0x45, 0x11, 0x77, 0x01, 0x26, 0xe6, 0x6c, - 0x57, 0x9a, 0x91, 0xdc, 0xb1, 0x13, 0xbd, 0xce, 0x30, 0x8a, 0x1b, 0xc3, 0x99, 0x37, 0x8c, 0x48, - 0xbf, 0x98, 0x1b, 0x04, 0x8b, 0x37, 0x41, 0x9b, 0x98, 0x33, 0x34, 0x30, 0x3b, 0x36, 0x6b, 0x92, - 0x91, 0x21, 0xc4, 0xdb, 0x50, 0x89, 0x67, 0x1e, 0x59, 0x6b, 0x74, 0xe6, 0x18, 0xdb, 0x0d, 0x67, - 0x9e, 0x32, 0x45, 0x06, 0xd2, 0x92, 0x1b, 0x6c, 0x66, 0x37, 0xd8, 0x85, 0x8a, 0xe5, 0xd8, 0xe4, - 0xcd, 0x35, 0x03, 0x9b, 0xe2, 0x1e, 0x34, 0x5c, 0xbe, 0x2d, 0xf2, 0xd8, 0xad, 0xf5, 0x16, 0x1b, - 0x3a, 0x42, 0x19, 0x09, 0xad, 0xff, 0x5b, 0x70, 0x7d, 0x8e, 0x5d, 0x79, 0xf9, 0xe8, 0xf0, 0xec, - 0xb7, 0xf2, 0xf2, 0x51, 0xcd, 0xcb, 0xc4, 0xbf, 0x56, 0xe0, 0xba, 0x12, 0xd2, 0x53, 0x27, 0x38, - 0x8c, 0x51, 0xdf, 0x7b, 0xd0, 0x20, 0x6b, 0xad, 0xe4, 0xa3, 0x6a, 0x24, 0xa0, 0xf8, 0x4d, 0xa8, - 0x93, 0xe2, 0x26, 0xfa, 0xb3, 0x9c, 0x31, 0x3f, 0x1d, 0xce, 0xfa, 0xa4, 0x6e, 0x4e, 0x75, 0x17, - 0x3f, 0x84, 0xda, 0xd7, 0x32, 0xf4, 0xd9, 0xfb, 0xb4, 0xd6, 0xef, 0x2e, 0x1a, 0x87, 0x22, 0xa0, - 0x86, 0x71, 0xe7, 0x5f, 0xe3, 0x1d, 0xbd, 0x8b, 0xfe, 0x66, 0xe2, 0x9f, 0x4b, 0xbb, 0xd7, 0xa0, - 0x1d, 0xe5, 0xc5, 0x28, 0x21, 0x25, 0x97, 0xd2, 0x5c, 0x78, 0x29, 0xda, 0x2b, 0x2e, 0x65, 0x0b, - 0x5a, 0x39, 0x2e, 0x2c, 0xb8, 0x90, 0xe5, 0xa2, 0xc2, 0x6a, 0xa9, 0x1d, 0xca, 0xeb, 0xfd, 0x16, - 0x40, 0xc6, 0x93, 0x5f, 0xd5, 0x7a, 0xe8, 0xbf, 0x57, 0x82, 0xeb, 0x8f, 0x7d, 0xcf, 0x93, 0x14, - 0x95, 0xf2, 0x0d, 0x67, 0x4a, 0x54, 0xba, 0x52, 0x89, 0xde, 0x87, 0x5a, 0x84, 0x9d, 0xd5, 0xec, - 0x37, 0x17, 0x5c, 0x99, 0xc1, 0x3d, 0xd0, 0x4a, 0x4e, 0xcc, 0xd9, 0x28, 0x90, 0x9e, 0xed, 0x78, - 0x27, 0x89, 0x95, 0x9c, 0x98, 0xb3, 0x03, 0xc6, 0xe8, 0x7f, 0x52, 0x06, 0xf8, 0x4c, 0x9a, 0x6e, - 0x7c, 0x8a, 0x9e, 0x00, 0xef, 0xcd, 0xf1, 0xa2, 0xd8, 0xf4, 0xac, 0x24, 0x27, 0x48, 0x61, 0x14, - 0x3e, 0x74, 0x7b, 0x32, 0x62, 0x23, 0xa4, 0x19, 0x09, 0x88, 0x8e, 0x10, 0x97, 0x9b, 0x46, 0xca, - 0x3d, 0x2a, 0x28, 0x73, 0xe6, 0x55, 0x42, 0x2b, 0x67, 0xde, 0x83, 0x06, 0xc6, 0xd8, 0x8e, 0xef, - 0x91, 0x68, 0x68, 0x46, 0x02, 0xe2, 0x3c, 0xd3, 0x20, 0x76, 0x26, 0xec, 0x04, 0x2b, 0x86, 0x82, - 0x70, 0x57, 0xe8, 0xf4, 0x06, 0xd6, 0xa9, 0x4f, 0xca, 0x5b, 0x31, 0x52, 0x18, 0x67, 0xf3, 0xbd, - 0x13, 0x1f, 0x4f, 0xd7, 0xa4, 0xf8, 0x29, 0x01, 0xf9, 0x2c, 0xb6, 0x9c, 0x21, 0x49, 0x23, 0x52, - 0x0a, 0x23, 0x5f, 0xa4, 0x1c, 0x1d, 0x4b, 0x33, 0x9e, 0x86, 0x32, 0xea, 0x01, 0x91, 0x41, 0xca, - 0x6d, 0x85, 0xd1, 0x7f, 0xb7, 0x0c, 0x75, 0xb6, 0x4b, 0x85, 0x60, 0xa1, 0xf4, 0xad, 0x82, 0x85, - 0x37, 0x41, 0x0b, 0x42, 0x69, 0x3b, 0x56, 0x72, 0x49, 0x9a, 0x91, 0x21, 0x28, 0x4a, 0x47, 0xbf, - 0x49, 0xcc, 0x6a, 0x1a, 0x0c, 0x20, 0x36, 0x0a, 0x4c, 0x4b, 0xaa, 0x03, 0x32, 0x80, 0x1c, 0x61, - 0x91, 0x27, 0x51, 0x6f, 0x1a, 0x0a, 0x12, 0x1f, 0x83, 0x46, 0x51, 0x19, 0x39, 0x7c, 0x8d, 0x1c, - 0xf5, 0xed, 0x97, 0x2f, 0x96, 0x05, 0x22, 0xe7, 0x3c, 0x7d, 0x33, 0xc1, 0x61, 0x5c, 0x82, 0x83, - 0xd1, 0xbe, 0x03, 0x05, 0x19, 0x14, 0x97, 0x20, 0x6a, 0x18, 0xe5, 0xe3, 0x12, 0xc6, 0xe8, 0xff, - 0x5c, 0x86, 0xf6, 0x96, 0x13, 0x4a, 0x2b, 0x96, 0xf6, 0xc0, 0x3e, 0xa1, 0xcd, 0x48, 0x2f, 0x76, - 0xe2, 0x0b, 0x15, 0x49, 0x29, 0x28, 0x0d, 0x74, 0xcb, 0xc5, 0xc4, 0x8f, 0x35, 0xa0, 0x42, 0xb9, - 0x2a, 0x03, 0x62, 0x1d, 0x80, 0x53, 0x00, 0xca, 0x57, 0xab, 0x57, 0xe7, 0xab, 0x1a, 0x75, 0xc3, - 0x26, 0xe6, 0x83, 0x3c, 0xc6, 0xe1, 0x70, 0xaa, 0x4e, 0xc9, 0xec, 0x14, 0xad, 0x0c, 0x45, 0xce, - 0x63, 0xe9, 0x92, 0xb8, 0x50, 0xe4, 0x3c, 0x96, 0x6e, 0x9a, 0xaf, 0x34, 0x78, 0x3b, 0xd8, 0x16, - 0xef, 0x40, 0xd9, 0x0f, 0x88, 0x87, 0x6a, 0xc1, 0xfc, 0xc1, 0xd6, 0xf6, 0x03, 0xa3, 0xec, 0x07, - 0xa8, 0x7b, 0x9c, 0x9c, 0x91, 0xb8, 0xa0, 0xee, 0xa1, 0x87, 0xa0, 0x54, 0xc1, 0x50, 0x14, 0xa1, - 0x43, 0xdb, 0x74, 0x5d, 0xff, 0x17, 0xd2, 0x3e, 0x08, 0xa5, 0x9d, 0x48, 0x4e, 0x01, 0xa7, 0xdf, - 0x86, 0xf2, 0x7e, 0x20, 0x1a, 0x50, 0x39, 0x1c, 0x0c, 0xbb, 0xd7, 0xb0, 0xb1, 0x35, 0xd8, 0xed, - 0x96, 0xf4, 0x6f, 0xca, 0xa0, 0x3d, 0x9b, 0xc6, 0x26, 0x6a, 0x7b, 0x84, 0xe7, 0x2a, 0x8a, 0x55, - 0x26, 0x3f, 0xdf, 0x87, 0x66, 0x14, 0x9b, 0x21, 0x79, 0x62, 0xf6, 0x0b, 0x0d, 0x82, 0x87, 0x91, - 0xf8, 0x01, 0xd4, 0xa4, 0x7d, 0x22, 0x13, 0x73, 0xdd, 0x9d, 0x3f, 0x8b, 0xc1, 0x64, 0xb1, 0x0a, - 0xf5, 0xc8, 0x3a, 0x95, 0x13, 0xb3, 0x57, 0xcd, 0x3a, 0x1e, 0x12, 0x86, 0x63, 0x47, 0x43, 0xd1, - 0xc5, 0xbb, 0x50, 0xc3, 0xdb, 0x88, 0x54, 0xb2, 0x43, 0xe9, 0x11, 0x32, 0x5e, 0x75, 0x63, 0x22, - 0xca, 0x8e, 0x1d, 0xfa, 0xc1, 0xc8, 0x0f, 0x88, 0xaf, 0x4b, 0xeb, 0xb7, 0xc8, 0xea, 0x24, 0xa7, - 0x59, 0xdb, 0x0a, 0xfd, 0x60, 0x3f, 0x30, 0xea, 0x36, 0x7d, 0x31, 0xaf, 0xa5, 0xee, 0x2c, 0x03, - 0x6c, 0xa6, 0x35, 0xc4, 0x70, 0x1d, 0x63, 0x15, 0x9a, 0x13, 0x19, 0x9b, 0xb6, 0x19, 0x9b, 0xca, - 0x5a, 0xb7, 0xd9, 0x88, 0x31, 0xce, 0x48, 0xa9, 0xfa, 0x43, 0xa8, 0xf3, 0xd4, 0xa2, 0x09, 0xd5, - 0xbd, 0xfd, 0xbd, 0x01, 0x33, 0x74, 0x63, 0x77, 0xb7, 0x5b, 0x42, 0xd4, 0xd6, 0xc6, 0x70, 0xa3, - 0x5b, 0xc6, 0xd6, 0xf0, 0xa7, 0x07, 0x83, 0x6e, 0x45, 0xff, 0xa7, 0x12, 0x34, 0x93, 0x79, 0xc4, - 0xa7, 0x00, 0xa8, 0x77, 0xa3, 0x53, 0xc7, 0x4b, 0x83, 0x9a, 0x3b, 0xf9, 0x95, 0xd6, 0xf0, 0xc6, - 0x3e, 0x43, 0x2a, 0xbb, 0x37, 0x52, 0x53, 0x82, 0xfb, 0x87, 0xb0, 0x54, 0x24, 0x2e, 0x88, 0xee, - 0xee, 0xe7, 0xed, 0xfc, 0xd2, 0xfa, 0xf7, 0x0a, 0x53, 0xe3, 0x48, 0x12, 0xe6, 0x9c, 0xc9, 0x7f, - 0x00, 0xcd, 0x04, 0x2d, 0x5a, 0xd0, 0xd8, 0x1a, 0x6c, 0x6f, 0x1c, 0xed, 0xa2, 0x90, 0x00, 0xd4, - 0x0f, 0x77, 0xf6, 0x9e, 0xec, 0x0e, 0xf8, 0x58, 0xbb, 0x3b, 0x87, 0xc3, 0x6e, 0x59, 0xff, 0xe3, - 0x12, 0x34, 0x93, 0x18, 0x42, 0xbc, 0x8f, 0xce, 0x9f, 0x42, 0x15, 0xe5, 0x1b, 0xa8, 0x1c, 0x91, - 0x4b, 0xa6, 0x8c, 0x84, 0x8e, 0x8a, 0x41, 0xa6, 0x2e, 0x89, 0x2a, 0x08, 0xc8, 0xa7, 0x72, 0x95, - 0x42, 0x35, 0x01, 0xb3, 0x52, 0xdf, 0x93, 0x2a, 0x48, 0xa4, 0x36, 0xc9, 0xa0, 0xe3, 0x59, 0x64, - 0x2d, 0x6a, 0x4a, 0x06, 0x11, 0x1e, 0x46, 0xfa, 0x5f, 0x57, 0x61, 0xc9, 0x90, 0x51, 0xec, 0x87, - 0xd2, 0x90, 0x3f, 0x9f, 0x62, 0xaa, 0xfd, 0x0a, 0x61, 0x7e, 0x0b, 0x20, 0xe4, 0xce, 0x99, 0x38, - 0x6b, 0x0a, 0xc3, 0x61, 0xba, 0xeb, 0x5b, 0x24, 0x45, 0xca, 0x7b, 0xa4, 0xb0, 0xb8, 0x03, 0xda, - 0xd8, 0xb4, 0xce, 0x78, 0x5a, 0xf6, 0x21, 0x4d, 0x46, 0xf0, 0xbc, 0xa6, 0x65, 0xc9, 0x28, 0x1a, - 0xe1, 0xa5, 0xb0, 0x27, 0xd1, 0x18, 0xf3, 0x54, 0x5e, 0x20, 0x39, 0x92, 0x56, 0x28, 0x63, 0x22, - 0xb3, 0x81, 0xd0, 0x18, 0x83, 0xe4, 0x77, 0xa0, 0x13, 0xc9, 0x08, 0xbd, 0xce, 0x28, 0xf6, 0xcf, - 0xa4, 0xa7, 0xac, 0x45, 0x5b, 0x21, 0x87, 0x88, 0x43, 0x3b, 0x6e, 0x7a, 0xbe, 0x77, 0x31, 0xf1, - 0xa7, 0x91, 0x32, 0xc0, 0x19, 0x42, 0xac, 0xc1, 0x4d, 0xe9, 0x59, 0xe1, 0x45, 0x80, 0x7b, 0xc5, - 0x55, 0x46, 0xc7, 0x8e, 0x2b, 0x55, 0xa0, 0x78, 0x23, 0x23, 0x3d, 0x95, 0x17, 0xdb, 0x8e, 0x2b, - 0x71, 0x47, 0xe7, 0xe6, 0xd4, 0x8d, 0x47, 0x94, 0x48, 0x02, 0xef, 0x88, 0x30, 0x1b, 0x98, 0x4d, - 0x7e, 0x00, 0x37, 0x98, 0x1c, 0xfa, 0xae, 0x74, 0x6c, 0x9e, 0xac, 0x45, 0xbd, 0xae, 0x13, 0xc1, - 0x20, 0x3c, 0x4d, 0xb5, 0x06, 0x37, 0xb9, 0x2f, 0x1f, 0x28, 0xe9, 0xdd, 0xe6, 0xa5, 0x89, 0x74, - 0xa8, 0x28, 0xc5, 0xa5, 0x03, 0x33, 0x3e, 0xa5, 0x04, 0x31, 0x59, 0xfa, 0xc0, 0x8c, 0x4f, 0xd1, - 0x1b, 0x32, 0xf9, 0xd8, 0x91, 0x2e, 0x27, 0x7e, 0x9a, 0xc1, 0x23, 0xb6, 0x11, 0x23, 0xde, 0x86, - 0xb6, 0xea, 0xe0, 0x87, 0x13, 0x93, 0xeb, 0x4b, 0x9a, 0xc1, 0x83, 0xb6, 0x09, 0x85, 0x4b, 0xa8, - 0xbb, 0xf2, 0xa6, 0x93, 0x5e, 0x97, 0xaf, 0x99, 0x31, 0x7b, 0xd3, 0x89, 0xfe, 0xbf, 0x65, 0x68, - 0xa6, 0xc9, 0xc6, 0x7d, 0xd0, 0x26, 0x89, 0xe5, 0x50, 0x41, 0x4c, 0xa7, 0x60, 0x4e, 0x8c, 0x8c, - 0x2e, 0xde, 0x82, 0xf2, 0xd9, 0xb9, 0xb2, 0x62, 0x9d, 0x35, 0xae, 0xb7, 0x06, 0xe3, 0xf5, 0xb5, - 0xa7, 0xcf, 0x8d, 0xf2, 0xd9, 0x79, 0x16, 0x0c, 0xd5, 0x5e, 0x1b, 0x0c, 0xbd, 0x07, 0xd7, 0x2d, - 0x57, 0x9a, 0xde, 0x28, 0x73, 0xce, 0x2c, 0x17, 0x4b, 0x84, 0x3e, 0x48, 0x3d, 0xb4, 0x52, 0xf4, - 0x46, 0xa6, 0xe8, 0xf7, 0xa0, 0x66, 0x4b, 0x37, 0x36, 0xf3, 0x85, 0xc0, 0xfd, 0xd0, 0xb4, 0x5c, - 0xb9, 0x85, 0x68, 0x83, 0xa9, 0x68, 0xd7, 0x92, 0x84, 0x28, 0x6f, 0xd7, 0x12, 0x15, 0x36, 0x52, - 0x6a, 0xa6, 0xa1, 0x90, 0xd7, 0xd0, 0xfb, 0x70, 0x43, 0xce, 0x02, 0x32, 0xe6, 0xa3, 0x34, 0x79, - 0x6d, 0x51, 0x8f, 0x6e, 0x42, 0x78, 0xac, 0xf0, 0xe2, 0x43, 0x54, 0x67, 0x52, 0x23, 0xba, 0xf8, - 0xd6, 0xba, 0x20, 0x7b, 0x50, 0x50, 0x4c, 0x23, 0xe9, 0xa2, 0x7b, 0x50, 0x79, 0xfa, 0xfc, 0x50, - 0x71, 0xb3, 0x74, 0x15, 0x37, 0x13, 0x4b, 0x50, 0xce, 0x59, 0x82, 0xbb, 0x6c, 0x44, 0x89, 0x35, - 0x49, 0x91, 0x2a, 0x87, 0xc1, 0xa3, 0xb0, 0x03, 0xa9, 0x72, 0xfd, 0x8a, 0x00, 0xfd, 0x7f, 0x2a, - 0xd0, 0x50, 0x5e, 0x1d, 0xf9, 0x39, 0x4d, 0xeb, 0x2f, 0xd8, 0x2c, 0xa6, 0x3d, 0x69, 0x78, 0x90, - 0x2f, 0x66, 0x57, 0x5e, 0x5f, 0xcc, 0x16, 0x9f, 0x42, 0x3b, 0x60, 0x5a, 0x3e, 0xa0, 0x78, 0x23, - 0x3f, 0x46, 0x7d, 0x69, 0x5c, 0x2b, 0xc8, 0x00, 0xb4, 0x58, 0x54, 0xe9, 0x8b, 0xcd, 0x13, 0x12, - 0x9d, 0xb6, 0xd1, 0x40, 0x78, 0x68, 0x9e, 0x5c, 0x11, 0x56, 0x7c, 0x9b, 0xe8, 0x60, 0x89, 0xc2, - 0x8c, 0x36, 0x19, 0x40, 0x8c, 0x28, 0xf2, 0x8e, 0xbc, 0x53, 0x74, 0xe4, 0x77, 0x40, 0xb3, 0xfc, - 0xc9, 0xc4, 0x21, 0xda, 0x92, 0xaa, 0x4f, 0x10, 0x62, 0x18, 0xe9, 0x7f, 0x50, 0x82, 0x86, 0x3a, - 0xed, 0x25, 0x37, 0xb1, 0xb9, 0xb3, 0xb7, 0x61, 0xfc, 0xb4, 0x5b, 0x42, 0x37, 0xb8, 0xb3, 0x37, - 0xec, 0x96, 0x85, 0x06, 0xb5, 0xed, 0xdd, 0xfd, 0x8d, 0x61, 0xb7, 0x82, 0xae, 0x63, 0x73, 0x7f, - 0x7f, 0xb7, 0x5b, 0x15, 0x6d, 0x68, 0x6e, 0x6d, 0x0c, 0x07, 0xc3, 0x9d, 0x67, 0x83, 0x6e, 0x0d, - 0xfb, 0x3e, 0x19, 0xec, 0x77, 0xeb, 0xd8, 0x38, 0xda, 0xd9, 0xea, 0x36, 0x90, 0x7e, 0xb0, 0x71, - 0x78, 0xf8, 0xe5, 0xbe, 0xb1, 0xd5, 0x6d, 0x92, 0xfb, 0x19, 0x1a, 0x3b, 0x7b, 0x4f, 0xba, 0x1a, - 0xb6, 0xf7, 0x37, 0x3f, 0x1f, 0x3c, 0x1e, 0x76, 0x41, 0xff, 0x08, 0x5a, 0x39, 0x0e, 0xe2, 0x68, - 0x63, 0xb0, 0xdd, 0xbd, 0x86, 0x4b, 0x3e, 0xdf, 0xd8, 0x3d, 0x42, 0x6f, 0xb5, 0x04, 0x40, 0xcd, - 0xd1, 0xee, 0xc6, 0xde, 0x93, 0x6e, 0x59, 0xff, 0x02, 0x9a, 0x47, 0x8e, 0xbd, 0xe9, 0xfa, 0xd6, - 0x19, 0x8a, 0xd3, 0xd8, 0x8c, 0xa4, 0x4a, 0x8d, 0xa8, 0x8d, 0x51, 0x24, 0x29, 0x4b, 0xa4, 0xee, - 0x5e, 0x41, 0xc8, 0x2b, 0x6f, 0x3a, 0x19, 0xd1, 0x03, 0x48, 0x85, 0x5d, 0x88, 0x37, 0x9d, 0x1c, - 0x39, 0x76, 0xa4, 0x9f, 0x41, 0xe3, 0xc8, 0xb1, 0x0f, 0x4c, 0xeb, 0x8c, 0xcc, 0x0c, 0x4e, 0x3d, - 0x8a, 0x9c, 0xaf, 0xa5, 0x72, 0x35, 0x1a, 0x61, 0x0e, 0x9d, 0xaf, 0xa5, 0x78, 0x17, 0xea, 0x04, - 0x24, 0x69, 0x30, 0xa9, 0x5f, 0xb2, 0x1d, 0x43, 0xd1, 0xe8, 0xfd, 0xc1, 0x75, 0x7d, 0x6b, 0x14, - 0xca, 0xe3, 0xde, 0x1b, 0xcc, 0x7b, 0x42, 0x18, 0xf2, 0x58, 0xff, 0xc3, 0x52, 0x7a, 0x66, 0x2a, - 0x7f, 0x2f, 0x43, 0x35, 0x30, 0xad, 0x33, 0xe5, 0x73, 0x5b, 0x6a, 0x42, 0xdc, 0x8c, 0x41, 0x04, - 0xf1, 0x1e, 0x34, 0x95, 0x60, 0x25, 0xab, 0xb6, 0x72, 0x12, 0x68, 0xa4, 0xc4, 0xe2, 0x95, 0x57, - 0x8a, 0x57, 0x4e, 0x39, 0x54, 0xe0, 0x3a, 0x31, 0xab, 0x51, 0xd5, 0x50, 0x90, 0xfe, 0x43, 0x80, - 0xec, 0xc5, 0x61, 0x41, 0x08, 0x72, 0x0b, 0x6a, 0xa6, 0xeb, 0x98, 0x49, 0x4e, 0xc6, 0x80, 0xbe, - 0x07, 0xad, 0xdc, 0x3b, 0x05, 0xf2, 0xd6, 0x74, 0x5d, 0xf4, 0x51, 0x11, 0x8d, 0x6d, 0x1a, 0x0d, - 0xd3, 0x75, 0x9f, 0xca, 0x8b, 0x08, 0xc3, 0x3f, 0x7e, 0xe2, 0x28, 0xcf, 0x55, 0xc7, 0x69, 0xa8, - 0xc1, 0x44, 0xfd, 0x43, 0xa8, 0x6f, 0x27, 0x01, 0x70, 0xa2, 0x06, 0xa5, 0xab, 0xd4, 0x40, 0xff, - 0x44, 0xed, 0x99, 0x0a, 0xec, 0xe2, 0xbe, 0x7a, 0x4a, 0x89, 0xf8, 0xe1, 0xa6, 0x94, 0x65, 0xf5, - 0xdc, 0x49, 0xbd, 0xa2, 0x50, 0x67, 0x7d, 0x0b, 0x9a, 0xaf, 0x7c, 0x9c, 0x52, 0x0c, 0x28, 0x67, - 0x0c, 0x58, 0xf0, 0x5c, 0xa5, 0xff, 0x0c, 0x20, 0x7b, 0x72, 0x51, 0x5a, 0xc9, 0xb3, 0xa0, 0x56, - 0x7e, 0x00, 0x4d, 0xeb, 0xd4, 0x71, 0xed, 0x50, 0x7a, 0x85, 0x53, 0x67, 0x8f, 0x34, 0x29, 0x5d, - 0xac, 0x40, 0x95, 0x5e, 0x92, 0x2a, 0x99, 0x35, 0x4f, 0x9f, 0x91, 0x88, 0xa2, 0xcf, 0xa0, 0xc3, - 0x71, 0xf5, 0xb7, 0x88, 0x85, 0x8a, 0xa6, 0xb4, 0x7c, 0xc9, 0x94, 0xde, 0x86, 0x3a, 0xb9, 0xe0, - 0xe4, 0x34, 0x0a, 0xba, 0xc2, 0xc4, 0xfe, 0x7e, 0x19, 0x80, 0x97, 0xde, 0xf3, 0x6d, 0x59, 0xcc, - 0x3a, 0x4b, 0xf3, 0x59, 0xa7, 0x80, 0x6a, 0xfa, 0x48, 0xa8, 0x19, 0xd4, 0xce, 0x9c, 0x90, 0xca, - 0x44, 0xd9, 0x09, 0xbd, 0x09, 0x1a, 0x85, 0x44, 0xce, 0xd7, 0x54, 0xd9, 0xc6, 0x05, 0x33, 0x44, - 0xfe, 0xc9, 0xac, 0x56, 0x7c, 0x32, 0x4b, 0xdf, 0x15, 0xea, 0x3c, 0x1b, 0xbf, 0x2b, 0x2c, 0x78, - 0x22, 0xe1, 0x3c, 0x3f, 0x92, 0x61, 0x9c, 0x64, 0xb5, 0x0c, 0xa5, 0x99, 0x9b, 0xa6, 0xfa, 0x9a, - 0x9c, 0xa9, 0x7b, 0xfe, 0xc8, 0xf2, 0xbd, 0x63, 0xd7, 0xb1, 0x62, 0xf5, 0x44, 0x06, 0x9e, 0xff, - 0x58, 0x61, 0xf4, 0x4f, 0xa1, 0x9d, 0xf0, 0x9f, 0x5e, 0x22, 0x3e, 0x48, 0x33, 0x9f, 0x52, 0x76, - 0xb7, 0x19, 0x9b, 0x36, 0xcb, 0xbd, 0x52, 0x92, 0xfb, 0xe8, 0xff, 0x5d, 0x49, 0x06, 0xab, 0x82, - 0xfa, 0xab, 0x79, 0x58, 0x4c, 0x5f, 0xcb, 0xdf, 0x2a, 0x7d, 0xfd, 0x11, 0x68, 0x36, 0xe5, 0x67, - 0xce, 0x79, 0xe2, 0xd4, 0xfa, 0xf3, 0xb9, 0x98, 0xca, 0xe0, 0x9c, 0x73, 0x69, 0x64, 0x9d, 0x5f, - 0x73, 0x0f, 0x29, 0xb7, 0x6b, 0x8b, 0xb8, 0x5d, 0xff, 0x15, 0xb9, 0xfd, 0x36, 0xb4, 0x3d, 0xdf, - 0x1b, 0x79, 0x53, 0xd7, 0x35, 0xc7, 0xae, 0x54, 0xec, 0x6e, 0x79, 0xbe, 0xb7, 0xa7, 0x50, 0x18, - 0xa7, 0xe6, 0xbb, 0xb0, 0x52, 0xb7, 0xa8, 0xdf, 0xf5, 0x5c, 0x3f, 0x52, 0xfd, 0x55, 0xe8, 0xfa, - 0xe3, 0x9f, 0x49, 0x2b, 0x26, 0x8e, 0x8d, 0x48, 0x9b, 0x39, 0x48, 0x5d, 0x62, 0x3c, 0xb2, 0x68, - 0x0f, 0xf5, 0x7a, 0xee, 0x9a, 0x3b, 0x97, 0xae, 0xf9, 0x13, 0xd0, 0x52, 0x2e, 0xe5, 0x72, 0x41, - 0x0d, 0x6a, 0x3b, 0x7b, 0x5b, 0x83, 0x9f, 0x74, 0x4b, 0xe8, 0x28, 0x8d, 0xc1, 0xf3, 0x81, 0x71, - 0x38, 0xe8, 0x96, 0xd1, 0x89, 0x6d, 0x0d, 0x76, 0x07, 0xc3, 0x41, 0xb7, 0xf2, 0x79, 0xb5, 0xd9, - 0xe8, 0x36, 0xa9, 0x2c, 0xee, 0x3a, 0x96, 0x13, 0xeb, 0x87, 0x00, 0x59, 0x82, 0x8b, 0x56, 0x39, - 0xdb, 0x9c, 0xaa, 0x79, 0xc5, 0xc9, 0xb6, 0x56, 0x53, 0x85, 0x2c, 0x5f, 0x95, 0x46, 0x33, 0x5d, - 0x5f, 0x07, 0xed, 0x99, 0x19, 0x7c, 0xc6, 0x2f, 0x40, 0xf7, 0x60, 0x29, 0x30, 0xc3, 0xd8, 0x49, - 0x32, 0x03, 0x36, 0x96, 0x6d, 0xa3, 0x93, 0x62, 0xd1, 0xf6, 0xea, 0x7f, 0x53, 0x82, 0x5b, 0xcf, - 0xfc, 0x73, 0x99, 0x46, 0x9e, 0x07, 0xe6, 0x85, 0xeb, 0x9b, 0xf6, 0x6b, 0xc4, 0x10, 0x53, 0x1b, - 0x7f, 0x4a, 0x6f, 0x35, 0xc9, 0xfb, 0x95, 0xa1, 0x31, 0xe6, 0x89, 0x7a, 0x40, 0x97, 0x51, 0x4c, - 0x44, 0xe5, 0x48, 0x11, 0x46, 0xd2, 0xf7, 0xa0, 0x1e, 0xcf, 0xbc, 0xec, 0xb9, 0xac, 0x16, 0x53, - 0x45, 0x76, 0x61, 0xd8, 0x59, 0x5b, 0x1c, 0x76, 0xea, 0x8f, 0x41, 0x1b, 0xce, 0xa8, 0x5a, 0x39, - 0x8d, 0x0a, 0x01, 0x4e, 0xe9, 0x15, 0x01, 0x4e, 0x79, 0x2e, 0xc0, 0xf9, 0x8f, 0x12, 0xb4, 0x72, - 0xf1, 0xb3, 0x78, 0x1b, 0xaa, 0xf1, 0xcc, 0x2b, 0x3e, 0x4a, 0x27, 0x8b, 0x18, 0x44, 0x42, 0xd1, - 0x9c, 0x98, 0xb3, 0x91, 0x19, 0x45, 0xce, 0x89, 0x27, 0x6d, 0x35, 0x65, 0x6b, 0x62, 0xce, 0x36, - 0x14, 0x4a, 0xec, 0xc2, 0x75, 0xb6, 0xbc, 0xc9, 0x21, 0x92, 0x32, 0xc9, 0x3b, 0x73, 0xf1, 0x3a, - 0x57, 0x74, 0x93, 0x23, 0xa9, 0xdc, 0x7f, 0xe9, 0xa4, 0x80, 0xec, 0x6f, 0xc0, 0xcd, 0x05, 0xdd, - 0xbe, 0x53, 0x0d, 0x7f, 0x19, 0x3a, 0xc3, 0x99, 0x37, 0x74, 0x26, 0x32, 0x8a, 0xcd, 0x49, 0x40, - 0x01, 0xa2, 0xf2, 0x9c, 0x55, 0xa3, 0x1c, 0x47, 0xfa, 0x0f, 0xa0, 0x7d, 0x20, 0x65, 0x68, 0xc8, - 0x28, 0xf0, 0x3d, 0x0e, 0x8e, 0x54, 0x25, 0x95, 0xdd, 0xb4, 0x82, 0xf4, 0xdf, 0x01, 0x0d, 0x13, - 0xfd, 0x4d, 0x33, 0xb6, 0x4e, 0xbf, 0x4b, 0x21, 0xe0, 0x07, 0xd0, 0x08, 0x58, 0xa6, 0x54, 0x9e, - 0xd5, 0x26, 0x77, 0xad, 0xe4, 0xcc, 0x48, 0x88, 0xfa, 0x47, 0x70, 0xf3, 0x70, 0x3a, 0x8e, 0xac, - 0xd0, 0xa1, 0x94, 0x35, 0x71, 0x65, 0x7d, 0x68, 0x06, 0xa1, 0x3c, 0x76, 0x66, 0x32, 0x91, 0xe0, - 0x14, 0xd6, 0x7f, 0x0c, 0xb7, 0x8a, 0x43, 0xd4, 0x11, 0xde, 0x81, 0xca, 0xd9, 0x79, 0xa4, 0x76, - 0x76, 0xa3, 0x90, 0x62, 0xd0, 0x5b, 0x30, 0x52, 0x75, 0x03, 0x2a, 0x7b, 0xd3, 0x49, 0xfe, 0x7f, - 0x96, 0x2a, 0xff, 0xcf, 0x72, 0x27, 0x5f, 0xd8, 0xe4, 0x2c, 0x24, 0x2b, 0x60, 0xbe, 0x09, 0xda, - 0xb1, 0x1f, 0xfe, 0xc2, 0x0c, 0x6d, 0x69, 0x2b, 0x9f, 0x95, 0x21, 0xf4, 0xaf, 0xa0, 0x95, 0x48, - 0xc2, 0x8e, 0x4d, 0x8f, 0x5f, 0x24, 0x8a, 0x3b, 0x76, 0x41, 0x32, 0xb9, 0x6c, 0x28, 0x3d, 0x7b, - 0x27, 0x11, 0x21, 0x06, 0x8a, 0x2b, 0xab, 0x37, 0x8b, 0x64, 0x65, 0x7d, 0x1b, 0xda, 0x49, 0x12, - 0xf7, 0x4c, 0xc6, 0x26, 0x09, 0xb7, 0xeb, 0x48, 0x2f, 0x27, 0xf8, 0x4d, 0x46, 0x0c, 0x8b, 0x95, - 0xbd, 0x72, 0x21, 0x00, 0xd0, 0xd7, 0xa0, 0xae, 0x34, 0x47, 0x40, 0xd5, 0xf2, 0x6d, 0xd6, 0xee, - 0x9a, 0x41, 0x6d, 0x64, 0xc7, 0x24, 0x3a, 0x49, 0x82, 0x9b, 0x49, 0x74, 0xa2, 0xff, 0x5d, 0x19, - 0x3a, 0x9b, 0x94, 0x44, 0x27, 0x57, 0x92, 0x2b, 0xe2, 0x94, 0x0a, 0x45, 0x9c, 0x7c, 0xc1, 0xa6, - 0x5c, 0x28, 0xd8, 0x14, 0x36, 0x54, 0x29, 0x46, 0x24, 0x6f, 0x40, 0x63, 0xea, 0x39, 0xb3, 0xc4, - 0x24, 0x68, 0x46, 0x1d, 0xc1, 0x61, 0x24, 0x56, 0xa0, 0x85, 0x56, 0xc3, 0xf1, 0xb8, 0x34, 0xc3, - 0xf5, 0x95, 0x3c, 0x6a, 0xae, 0x00, 0x53, 0x7f, 0x75, 0x01, 0xa6, 0xf1, 0xda, 0x02, 0x4c, 0xf3, - 0x75, 0x05, 0x18, 0x6d, 0xbe, 0x00, 0x53, 0x8c, 0xa6, 0x60, 0x3e, 0x9a, 0xd2, 0xff, 0xb4, 0x0c, - 0x9d, 0xc1, 0x2c, 0xa0, 0x9f, 0x14, 0x5e, 0x1b, 0x9a, 0xe5, 0xf8, 0x5a, 0x2e, 0xf0, 0x35, 0xc7, - 0xa1, 0x8a, 0x7a, 0x95, 0x60, 0x0e, 0x61, 0xb0, 0xc6, 0xe5, 0x10, 0xc5, 0x39, 0x86, 0xfe, 0x1f, - 0x70, 0x4e, 0xdf, 0x85, 0xa5, 0x84, 0x31, 0x4a, 0x6b, 0xbf, 0x95, 0x38, 0xf2, 0x0f, 0x46, 0x6e, - 0x5a, 0x05, 0x60, 0x40, 0xff, 0xa3, 0x32, 0x68, 0x2c, 0xa4, 0xb8, 0xbd, 0xf7, 0x55, 0xa0, 0x59, - 0xca, 0x4a, 0xa2, 0x29, 0x71, 0xed, 0xa9, 0xbc, 0xa0, 0x00, 0x89, 0xe3, 0xcf, 0x45, 0x0f, 0x07, - 0xaa, 0x56, 0xc0, 0xe9, 0x11, 0xd5, 0x0a, 0xee, 0x80, 0xc6, 0x3e, 0x66, 0xea, 0x24, 0x4f, 0x8d, - 0xec, 0x74, 0x8e, 0x1c, 0xfa, 0x2f, 0x23, 0x96, 0xe1, 0x44, 0x71, 0x99, 0xda, 0xc5, 0x40, 0xb4, - 0xa3, 0x42, 0x23, 0xfd, 0x14, 0x1a, 0x6a, 0x75, 0x8c, 0x14, 0x8e, 0xf6, 0x9e, 0xee, 0xed, 0x7f, - 0xb9, 0xd7, 0xbd, 0x96, 0x16, 0x91, 0x4b, 0x59, 0x2c, 0x51, 0xce, 0xc7, 0x12, 0x15, 0xc4, 0x3f, - 0xde, 0x3f, 0xda, 0x1b, 0x76, 0xab, 0xa2, 0x03, 0x1a, 0x35, 0x47, 0xc6, 0xe0, 0x79, 0xb7, 0x46, - 0x69, 0xf3, 0xe3, 0xcf, 0x06, 0xcf, 0x36, 0xba, 0xf5, 0xb4, 0x04, 0xdd, 0xd0, 0xff, 0xb2, 0x04, - 0x37, 0xf8, 0xc8, 0xf9, 0x3c, 0x32, 0xff, 0x73, 0x5f, 0x95, 0x7f, 0xee, 0xfb, 0xf5, 0xa6, 0x8e, - 0x38, 0x68, 0xea, 0xd8, 0xa3, 0xf1, 0x05, 0xaa, 0x07, 0xd7, 0x38, 0x9a, 0x53, 0xc7, 0xde, 0x44, - 0x58, 0xff, 0x87, 0x12, 0xf4, 0x39, 0x84, 0x79, 0x12, 0x9a, 0xc1, 0xe9, 0x17, 0xbb, 0x97, 0x92, - 0x98, 0xab, 0x1c, 0xfb, 0x3d, 0x58, 0xa2, 0xdf, 0x1f, 0x7f, 0xee, 0x8e, 0x54, 0xa0, 0xcd, 0xf7, - 0xd7, 0x51, 0x58, 0x9e, 0x48, 0x7c, 0x0c, 0x6d, 0xfe, 0x4d, 0x92, 0xca, 0x6d, 0x85, 0x07, 0x8b, - 0x42, 0x00, 0xd5, 0xe2, 0x5e, 0xf4, 0x74, 0x22, 0x3e, 0x4a, 0x07, 0x65, 0xf9, 0xce, 0xe5, 0x37, - 0x09, 0x35, 0x64, 0x48, 0x59, 0xd0, 0x43, 0xb8, 0xb3, 0xf0, 0x1c, 0x4a, 0xb0, 0x73, 0xb5, 0x27, - 0x96, 0xa7, 0xf5, 0xbf, 0x2f, 0x41, 0x15, 0x9d, 0xa5, 0x78, 0x00, 0xda, 0x67, 0xd2, 0x0c, 0xe3, - 0xb1, 0x34, 0x63, 0x51, 0x70, 0x8c, 0x7d, 0x5a, 0x31, 0x7b, 0x17, 0xd5, 0xaf, 0x3d, 0x2a, 0x89, - 0x35, 0xfe, 0x73, 0x29, 0xf9, 0x21, 0xab, 0x93, 0x38, 0x5d, 0x72, 0xca, 0xfd, 0xc2, 0x78, 0xfd, - 0xda, 0x2a, 0xf5, 0xff, 0xdc, 0x77, 0xbc, 0xc7, 0xfc, 0xa3, 0x8d, 0x98, 0x77, 0xd2, 0xf3, 0x23, - 0xc4, 0x03, 0xa8, 0xef, 0x44, 0x18, 0x0d, 0x5c, 0xee, 0x4a, 0x5c, 0xcb, 0x07, 0x0a, 0xfa, 0xb5, - 0xf5, 0xbf, 0xaa, 0x40, 0xf5, 0x2b, 0x19, 0xfa, 0xe2, 0x43, 0x68, 0xa8, 0x57, 0x64, 0x91, 0x7b, - 0x2d, 0xee, 0x53, 0x62, 0x32, 0xf7, 0xbc, 0x4c, 0xab, 0x74, 0x99, 0x5d, 0x59, 0x91, 0x54, 0x64, - 0x8f, 0xdc, 0x97, 0x36, 0xf5, 0x09, 0x74, 0x0f, 0xe3, 0x50, 0x9a, 0x93, 0x5c, 0xf7, 0x22, 0xab, - 0x16, 0x55, 0x5c, 0x89, 0x5f, 0xf7, 0xa1, 0xce, 0x21, 0xd7, 0xdc, 0x80, 0xf9, 0xe2, 0x29, 0x75, - 0x7e, 0x0f, 0x5a, 0x87, 0xa7, 0xfe, 0xd4, 0xb5, 0x0f, 0x65, 0x78, 0x2e, 0x45, 0xee, 0xbf, 0x90, - 0x7e, 0xae, 0xad, 0x5f, 0x13, 0xab, 0x00, 0xec, 0xe5, 0x8f, 0x50, 0x81, 0x1a, 0x48, 0xdb, 0x9b, - 0x4e, 0x78, 0xd2, 0x9c, 0xfb, 0xe7, 0x9e, 0xb9, 0xc8, 0xeb, 0x55, 0x3d, 0x3f, 0x86, 0xce, 0x63, - 0x52, 0xa6, 0xfd, 0x70, 0x63, 0xec, 0x87, 0xb1, 0x98, 0xff, 0x37, 0xa4, 0x3f, 0x8f, 0xd0, 0xaf, - 0x89, 0x47, 0xd0, 0x1c, 0x86, 0x17, 0xdc, 0xff, 0x86, 0x0a, 0x58, 0xb3, 0xf5, 0x16, 0x9c, 0x72, - 0xfd, 0xbf, 0xaa, 0x50, 0xff, 0xd2, 0x0f, 0xcf, 0x64, 0x88, 0x49, 0x2a, 0x15, 0xbb, 0x95, 0x18, - 0xa5, 0x85, 0xef, 0x45, 0x0b, 0xbd, 0x0b, 0x1a, 0x31, 0x65, 0x68, 0x46, 0x67, 0x7c, 0x55, 0xf4, - 0xbf, 0x2d, 0xf3, 0x85, 0x93, 0x5e, 0xba, 0xd7, 0x25, 0xbe, 0xa8, 0xf4, 0xbd, 0xa8, 0x50, 0x7a, - 0xee, 0xd3, 0xf9, 0x9f, 0x3e, 0x3f, 0x44, 0xd1, 0x7c, 0x54, 0x42, 0x2b, 0x7d, 0xc8, 0x27, 0xc5, - 0x4e, 0xd9, 0x7f, 0x86, 0x2c, 0xf9, 0xd9, 0x8f, 0x7d, 0xfa, 0x35, 0xf1, 0x10, 0xea, 0x4a, 0xa5, - 0x6f, 0x64, 0xca, 0xab, 0xec, 0x44, 0xbf, 0x9b, 0x47, 0xa9, 0x01, 0xef, 0x43, 0x9d, 0xcd, 0x1f, - 0x0f, 0x28, 0xc4, 0x2f, 0xbc, 0x6b, 0x8e, 0x81, 0xf4, 0x6b, 0xe2, 0x3e, 0x34, 0x54, 0xc1, 0x5a, - 0x2c, 0xa8, 0x5e, 0xcf, 0x75, 0xfe, 0x08, 0xea, 0xec, 0xb5, 0x78, 0xde, 0x82, 0x6b, 0xef, 0x8b, - 0x3c, 0x2a, 0x51, 0x12, 0x94, 0x76, 0x43, 0x5a, 0xd2, 0xc9, 0xe5, 0x58, 0x22, 0xe1, 0xc4, 0x02, - 0x95, 0xfd, 0x04, 0x3a, 0x85, 0x7c, 0x4c, 0xf4, 0xe8, 0x76, 0x16, 0xa4, 0x68, 0x97, 0x14, 0xe5, - 0xc7, 0xa0, 0xa9, 0x70, 0x78, 0x2c, 0x05, 0x95, 0xa0, 0x17, 0x04, 0xd4, 0xfd, 0xcb, 0xf1, 0x30, - 0x49, 0xff, 0x4f, 0xe0, 0xe6, 0x02, 0x1b, 0x26, 0xe8, 0x67, 0x9c, 0xab, 0x8d, 0x74, 0x7f, 0xf9, - 0x4a, 0x7a, 0xc2, 0x80, 0xcd, 0xee, 0x3f, 0x7e, 0x73, 0xb7, 0xf4, 0x2f, 0xdf, 0xdc, 0x2d, 0xfd, - 0xdb, 0x37, 0x77, 0x4b, 0xbf, 0xfc, 0xf7, 0xbb, 0xd7, 0xc6, 0x75, 0xfa, 0xe7, 0xfc, 0xe3, 0xff, - 0x0b, 0x00, 0x00, 0xff, 0xff, 0x1c, 0x42, 0x30, 0xc0, 0xe9, 0x2e, 0x00, 0x00, + // 4759 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x7a, 0xcd, 0x6f, 0x1c, 0x57, + 0x72, 0xb8, 0xe6, 0x7b, 0xba, 0xe6, 0x43, 0xa3, 0x27, 0xad, 0x3c, 0x3b, 0xb2, 0x45, 0xba, 0x6d, + 0xad, 0xb9, 0x96, 0x45, 0x49, 0xf4, 0xfe, 0xf0, 0x5b, 0x7b, 0x11, 0x20, 0xa4, 0x38, 0x94, 0xb9, + 0xa2, 0x48, 0xba, 0x39, 0x94, 0x77, 0x7d, 0xc8, 0xa0, 0xd9, 0xfd, 0x48, 0xf6, 0xb2, 0xa7, 0xbb, + 0xb7, 0xbb, 0x87, 0x3b, 0xf4, 0x29, 0x41, 0x80, 0x9c, 0x92, 0x4b, 0x82, 0x20, 0x7b, 0x4a, 0x82, + 0xfc, 0x03, 0x41, 0x72, 0x0a, 0x72, 0x0e, 0x82, 0x20, 0x87, 0x20, 0x7f, 0x81, 0x12, 0x38, 0x39, + 0x09, 0xc8, 0x29, 0x40, 0x80, 0x5c, 0x82, 0xa0, 0xaa, 0x5e, 0x7f, 0x0d, 0x87, 0x92, 0xbd, 0xc0, + 0x1e, 0x72, 0xea, 0x57, 0x55, 0xef, 0xb3, 0x5e, 0x7d, 0xbf, 0x86, 0x66, 0x70, 0xb4, 0x1a, 0x84, + 0x7e, 0xec, 0x8b, 0x72, 0x70, 0x34, 0xd0, 0xcc, 0xc0, 0x61, 0x70, 0xf0, 0xe1, 0x89, 0x13, 0x9f, + 0x4e, 0x8f, 0x56, 0x2d, 0x7f, 0xf2, 0xd0, 0x3e, 0x09, 0xcd, 0xe0, 0xf4, 0x81, 0xe3, 0x3f, 0x3c, + 0x32, 0xed, 0x13, 0x19, 0x3e, 0x3c, 0x5f, 0x7b, 0x18, 0x1c, 0x3d, 0x4c, 0x86, 0x0e, 0x1e, 0xe4, + 0xfa, 0x9e, 0xf8, 0x27, 0xfe, 0x43, 0x42, 0x1f, 0x4d, 0x8f, 0x09, 0x22, 0x80, 0x5a, 0xdc, 0x5d, + 0x1f, 0x40, 0x75, 0xc7, 0x89, 0x62, 0x21, 0xa0, 0x3a, 0x75, 0xec, 0xa8, 0x5f, 0x5a, 0xae, 0xac, + 0xd4, 0x0d, 0x6a, 0xeb, 0xcf, 0x41, 0x1b, 0x99, 0xd1, 0xd9, 0x0b, 0xd3, 0x9d, 0x4a, 0xd1, 0x83, + 0xca, 0xb9, 0xe9, 0xf6, 0x4b, 0xcb, 0xa5, 0x95, 0xb6, 0x81, 0x4d, 0xb1, 0x0a, 0xcd, 0x73, 0xd3, + 0x1d, 0xc7, 0x17, 0x81, 0xec, 0x97, 0x97, 0x4b, 0x2b, 0xdd, 0xb5, 0x9b, 0xab, 0xc1, 0xd1, 0xea, + 0xbe, 0x1f, 0xc5, 0x8e, 0x77, 0xb2, 0xfa, 0xc2, 0x74, 0x47, 0x17, 0x81, 0x34, 0x1a, 0xe7, 0xdc, + 0xd0, 0xf7, 0xa0, 0x75, 0x10, 0x5a, 0x5b, 0x53, 0xcf, 0x8a, 0x1d, 0xdf, 0xc3, 0x15, 0x3d, 0x73, + 0x22, 0x69, 0x46, 0xcd, 0xa0, 0x36, 0xe2, 0xcc, 0xf0, 0x24, 0xea, 0x57, 0x96, 0x2b, 0x88, 0xc3, + 0xb6, 0xe8, 0x43, 0xc3, 0x89, 0x9e, 0xf8, 0x53, 0x2f, 0xee, 0x57, 0x97, 0x4b, 0x2b, 0x4d, 0x23, + 0x01, 0xf5, 0x3f, 0xab, 0x40, 0xed, 0xf3, 0xa9, 0x0c, 0x2f, 0x68, 0x5c, 0x1c, 0x87, 0xc9, 0x5c, + 0xd8, 0x16, 0xb7, 0xa0, 0xe6, 0x9a, 0xde, 0x49, 0xd4, 0x2f, 0xd3, 0x64, 0x0c, 0x88, 0x3b, 0xa0, + 0x99, 0xc7, 0xb1, 0x0c, 0xc7, 0x53, 0xc7, 0xee, 0x57, 0x96, 0x4b, 0x2b, 0x75, 0xa3, 0x49, 0x88, + 0x43, 0xc7, 0x16, 0xdf, 0x85, 0xa6, 0xed, 0x8f, 0xad, 0xfc, 0x5a, 0xb6, 0x4f, 0x6b, 0x89, 0xf7, + 0xa0, 0x39, 0x75, 0xec, 0xb1, 0xeb, 0x44, 0x71, 0xbf, 0xb6, 0x5c, 0x5a, 0x69, 0xad, 0x35, 0xf1, + 0xb0, 0xc8, 0x3b, 0xa3, 0x31, 0x75, 0x6c, 0x62, 0xe2, 0x87, 0xd0, 0x8c, 0x42, 0x6b, 0x7c, 0x3c, + 0xf5, 0xac, 0x7e, 0x9d, 0x3a, 0x5d, 0xc7, 0x4e, 0xb9, 0x53, 0x1b, 0x8d, 0x88, 0x01, 0x3c, 0x56, + 0x28, 0xcf, 0x65, 0x18, 0xc9, 0x7e, 0x83, 0x97, 0x52, 0xa0, 0x78, 0x04, 0xad, 0x63, 0xd3, 0x92, + 0xf1, 0x38, 0x30, 0x43, 0x73, 0xd2, 0x6f, 0x66, 0x13, 0x6d, 0x21, 0x7a, 0x1f, 0xb1, 0x91, 0x01, + 0xc7, 0x29, 0x20, 0x3e, 0x86, 0x0e, 0x41, 0xd1, 0xf8, 0xd8, 0x71, 0x63, 0x19, 0xf6, 0x35, 0x1a, + 0xd3, 0xa5, 0x31, 0x84, 0x19, 0x85, 0x52, 0x1a, 0x6d, 0xee, 0xc4, 0x18, 0xf1, 0x0e, 0x80, 0x9c, + 0x05, 0xa6, 0x67, 0x8f, 0x4d, 0xd7, 0xed, 0x03, 0xed, 0x41, 0x63, 0xcc, 0xba, 0xeb, 0x8a, 0xb7, + 0x70, 0x7f, 0xa6, 0x3d, 0x8e, 0xa3, 0x7e, 0x67, 0xb9, 0xb4, 0x52, 0x35, 0xea, 0x08, 0x8e, 0x22, + 0xe4, 0xab, 0x65, 0x5a, 0xa7, 0xb2, 0xdf, 0x5d, 0x2e, 0xad, 0xd4, 0x0c, 0x06, 0x10, 0x7b, 0xec, + 0x84, 0x51, 0xdc, 0xbf, 0xce, 0x58, 0x02, 0xf4, 0x35, 0xd0, 0x48, 0x7a, 0x88, 0x3b, 0xf7, 0xa0, + 0x7e, 0x8e, 0x00, 0x0b, 0x59, 0x6b, 0xad, 0x83, 0xdb, 0x4b, 0x05, 0xcc, 0x50, 0x44, 0xfd, 0x2e, + 0x34, 0x77, 0x4c, 0xef, 0x24, 0x91, 0x4a, 0xbc, 0x36, 0x1a, 0xa0, 0x19, 0xd4, 0xd6, 0x7f, 0x59, + 0x86, 0xba, 0x21, 0xa3, 0xa9, 0x1b, 0x8b, 0x0f, 0x00, 0xf0, 0x52, 0x26, 0x66, 0x1c, 0x3a, 0x33, + 0x35, 0x6b, 0x76, 0x2d, 0xda, 0xd4, 0xb1, 0x9f, 0x13, 0x49, 0x3c, 0x82, 0x36, 0xcd, 0x9e, 0x74, + 0x2d, 0x67, 0x1b, 0x48, 0xf7, 0x67, 0xb4, 0xa8, 0x8b, 0x1a, 0x71, 0x1b, 0xea, 0x24, 0x07, 0x2c, + 0x8b, 0x1d, 0x43, 0x41, 0xe2, 0x1e, 0x74, 0x1d, 0x2f, 0xc6, 0x7b, 0xb2, 0xe2, 0xb1, 0x2d, 0xa3, + 0x44, 0x50, 0x3a, 0x29, 0x76, 0x53, 0x46, 0xb1, 0x78, 0x0c, 0xcc, 0xec, 0x64, 0xc1, 0x1a, 0x2d, + 0xd8, 0x4d, 0x2f, 0x31, 0xe2, 0x15, 0xa9, 0x8f, 0x5a, 0xf1, 0x01, 0xb4, 0xf0, 0x7c, 0xc9, 0x88, + 0x3a, 0x8d, 0x68, 0xd3, 0x69, 0x14, 0x3b, 0x0c, 0xc0, 0x0e, 0xaa, 0x3b, 0xb2, 0x06, 0x85, 0x91, + 0x85, 0x87, 0xda, 0xfa, 0x10, 0x6a, 0x7b, 0xa1, 0x2d, 0xc3, 0x85, 0xfa, 0x20, 0xa0, 0x6a, 0xcb, + 0xc8, 0x22, 0x55, 0x6d, 0x1a, 0xd4, 0xce, 0x74, 0xa4, 0x92, 0xd3, 0x11, 0xfd, 0x4f, 0x4b, 0xd0, + 0x3a, 0xf0, 0xc3, 0xf8, 0xb9, 0x8c, 0x22, 0xf3, 0x44, 0x8a, 0x25, 0xa8, 0xf9, 0x38, 0xad, 0xe2, + 0xb0, 0x86, 0x7b, 0xa2, 0x75, 0x0c, 0xc6, 0xcf, 0xdd, 0x43, 0xf9, 0xea, 0x7b, 0x40, 0xd9, 0x21, + 0xed, 0xaa, 0x28, 0xd9, 0x21, 0xdd, 0xba, 0x0d, 0x75, 0xff, 0xf8, 0x38, 0x92, 0xcc, 0xcb, 0x9a, + 0xa1, 0xa0, 0x2b, 0x45, 0x50, 0xff, 0x7f, 0x00, 0xb8, 0xbf, 0x6f, 0x29, 0x05, 0xfa, 0x29, 0xb4, + 0x0c, 0xf3, 0x38, 0x7e, 0xe2, 0x7b, 0xb1, 0x9c, 0xc5, 0xa2, 0x0b, 0x65, 0xc7, 0x26, 0x16, 0xd5, + 0x8d, 0xb2, 0x63, 0xe3, 0xe6, 0x4e, 0x42, 0x7f, 0x1a, 0x10, 0x87, 0x3a, 0x06, 0x03, 0xc4, 0x4a, + 0xdb, 0x0e, 0x69, 0xc7, 0xc8, 0x4a, 0xdb, 0x0e, 0xc5, 0x12, 0xb4, 0x22, 0xcf, 0x0c, 0xa2, 0x53, + 0x3f, 0xc6, 0xcd, 0x55, 0x69, 0x73, 0x90, 0xa0, 0x46, 0x91, 0xfe, 0x1f, 0x65, 0xa8, 0x3f, 0x97, + 0x93, 0x23, 0x19, 0x5e, 0x5a, 0xe5, 0x11, 0x34, 0x69, 0xe2, 0xb1, 0x63, 0xf3, 0x42, 0x1b, 0xdf, + 0x79, 0xf5, 0x72, 0xe9, 0x06, 0xe1, 0xb6, 0xed, 0x8f, 0xfc, 0x89, 0x13, 0xcb, 0x49, 0x10, 0x5f, + 0x18, 0x0d, 0x85, 0x5a, 0xb8, 0x83, 0xdb, 0x50, 0x77, 0xa5, 0x89, 0x77, 0xc2, 0xe2, 0xa7, 0x20, + 0xf1, 0x00, 0x1a, 0xe6, 0x64, 0x6c, 0x4b, 0xd3, 0x26, 0x2b, 0xd5, 0xdc, 0xb8, 0xf5, 0xea, 0xe5, + 0x52, 0xcf, 0x9c, 0x6c, 0x4a, 0x33, 0x3f, 0x77, 0x9d, 0x31, 0xe2, 0x13, 0x94, 0xb9, 0x28, 0x1e, + 0x4f, 0x03, 0xdb, 0x8c, 0x25, 0xd9, 0xac, 0xea, 0x46, 0xff, 0xd5, 0xcb, 0xa5, 0x5b, 0x88, 0x3e, + 0x24, 0x6c, 0x6e, 0x18, 0x64, 0x58, 0xb1, 0x0d, 0x37, 0x2c, 0x77, 0x1a, 0xa1, 0x29, 0x75, 0xbc, + 0x63, 0x7f, 0xec, 0x7b, 0xee, 0x05, 0x5d, 0x53, 0x73, 0xe3, 0x9d, 0x57, 0x2f, 0x97, 0xbe, 0xab, + 0x88, 0xdb, 0xde, 0xb1, 0xbf, 0xe7, 0xb9, 0x17, 0xb9, 0x59, 0xae, 0xcf, 0x91, 0xc4, 0x6f, 0x42, + 0xf7, 0xd8, 0x0f, 0x2d, 0x39, 0x4e, 0x19, 0xd3, 0xa5, 0x79, 0x06, 0xaf, 0x5e, 0x2e, 0xdd, 0x26, + 0xca, 0xd3, 0x4b, 0xdc, 0x69, 0xe7, 0xf1, 0xfa, 0xdf, 0x94, 0xa1, 0x46, 0x6d, 0xf1, 0x08, 0x1a, + 0x13, 0x62, 0x7c, 0x62, 0x65, 0x6e, 0xa3, 0x24, 0x10, 0x6d, 0x95, 0x6f, 0x24, 0x1a, 0x7a, 0x71, + 0x78, 0x61, 0x24, 0xdd, 0x70, 0x44, 0x6c, 0x1e, 0xb9, 0x32, 0x8e, 0x94, 0xe4, 0xe6, 0x46, 0x8c, + 0x98, 0xa0, 0x46, 0xa8, 0x6e, 0xf3, 0xd7, 0x5f, 0x99, 0xbf, 0x7e, 0x31, 0x80, 0xa6, 0x75, 0x2a, + 0xad, 0xb3, 0x68, 0x3a, 0x51, 0xc2, 0x91, 0xc2, 0x83, 0x2d, 0x68, 0xe7, 0xf7, 0x81, 0x7e, 0xf5, + 0x4c, 0x5e, 0x90, 0x80, 0x54, 0x0d, 0x6c, 0x8a, 0x65, 0xa8, 0x91, 0x25, 0x22, 0xf1, 0x68, 0xad, + 0x01, 0x6e, 0x87, 0x87, 0x18, 0x4c, 0xf8, 0xb4, 0xfc, 0xc3, 0x12, 0xce, 0x93, 0xdf, 0x5d, 0x7e, + 0x1e, 0xed, 0xea, 0x79, 0x78, 0x48, 0x6e, 0x1e, 0xdd, 0x87, 0xc6, 0x8e, 0x63, 0x49, 0x2f, 0x22, + 0xef, 0x3b, 0x8d, 0x64, 0x6a, 0x35, 0xb0, 0x8d, 0x47, 0x99, 0x98, 0xb3, 0x5d, 0xdf, 0x96, 0x11, + 0xcd, 0x53, 0x35, 0x52, 0x18, 0x69, 0x72, 0x16, 0x38, 0xe1, 0xc5, 0x88, 0x99, 0x50, 0x31, 0x52, + 0x18, 0xdd, 0x9b, 0xf4, 0x70, 0x31, 0x3b, 0xf1, 0xa4, 0x0a, 0xd4, 0xff, 0xbc, 0x02, 0xed, 0x2f, + 0x65, 0xe8, 0xef, 0x87, 0x7e, 0xe0, 0x47, 0xa6, 0x2b, 0xd6, 0x8b, 0xec, 0xe4, 0x6b, 0x5b, 0xc6, + 0xdd, 0xe6, 0xbb, 0xad, 0x1e, 0xa4, 0xfc, 0xe5, 0xeb, 0xc8, 0x33, 0x5c, 0x87, 0x3a, 0x5f, 0xe7, + 0x02, 0x9e, 0x29, 0x0a, 0xf6, 0xe1, 0x0b, 0xa4, 0xbd, 0x16, 0xf9, 0xa1, 0x28, 0xe2, 0x2e, 0xc0, + 0xc4, 0x9c, 0xed, 0x48, 0x33, 0x92, 0xdb, 0x76, 0xa2, 0xd7, 0x19, 0x46, 0x71, 0x63, 0x34, 0xf3, + 0x46, 0x11, 0xe9, 0x17, 0x73, 0x83, 0x60, 0xf1, 0x36, 0x68, 0x13, 0x73, 0x86, 0x06, 0x66, 0xdb, + 0x66, 0x4d, 0x32, 0x32, 0x84, 0x78, 0x17, 0x2a, 0xf1, 0xcc, 0x23, 0x6b, 0x8d, 0xce, 0x1c, 0x63, + 0xbb, 0xd1, 0xcc, 0x53, 0xa6, 0xc8, 0x40, 0x5a, 0x72, 0x83, 0xcd, 0xec, 0x06, 0x7b, 0x50, 0xb1, + 0x1c, 0x9b, 0xbc, 0xb9, 0x66, 0x60, 0x53, 0xdc, 0x83, 0x86, 0xcb, 0xb7, 0x45, 0x1e, 0xbb, 0xb5, + 0xd6, 0x62, 0x43, 0x47, 0x28, 0x23, 0xa1, 0x0d, 0x7e, 0x03, 0xae, 0xcf, 0xb1, 0x2b, 0x2f, 0x1f, + 0x1d, 0x9e, 0xfd, 0x56, 0x5e, 0x3e, 0xaa, 0x79, 0x99, 0xf8, 0x97, 0x0a, 0x5c, 0x57, 0x42, 0x7a, + 0xea, 0x04, 0x07, 0x31, 0xea, 0x7b, 0x1f, 0x1a, 0x64, 0xad, 0x95, 0x7c, 0x54, 0x8d, 0x04, 0x14, + 0xff, 0x1f, 0xea, 0xa4, 0xb8, 0x89, 0xfe, 0x2c, 0x65, 0xcc, 0x4f, 0x87, 0xb3, 0x3e, 0xa9, 0x9b, + 0x53, 0xdd, 0xc5, 0x0f, 0xa0, 0xf6, 0x95, 0x0c, 0x7d, 0xf6, 0x3e, 0xad, 0xb5, 0xbb, 0x8b, 0xc6, + 0xa1, 0x08, 0xa8, 0x61, 0xdc, 0xf9, 0xd7, 0x78, 0x47, 0xef, 0xa3, 0xbf, 0x99, 0xf8, 0xe7, 0xd2, + 0xee, 0x37, 0x68, 0x47, 0x79, 0x31, 0x4a, 0x48, 0xc9, 0xa5, 0x34, 0x17, 0x5e, 0x8a, 0xf6, 0x9a, + 0x4b, 0xd9, 0x84, 0x56, 0x8e, 0x0b, 0x0b, 0x2e, 0x64, 0xa9, 0xa8, 0xb0, 0x5a, 0x6a, 0x87, 0xf2, + 0x7a, 0xbf, 0x09, 0x90, 0xf1, 0xe4, 0x57, 0xb5, 0x1e, 0xfa, 0xef, 0x94, 0xe0, 0xfa, 0x13, 0xdf, + 0xf3, 0x24, 0x45, 0xa5, 0x7c, 0xc3, 0x99, 0x12, 0x95, 0xae, 0x54, 0xa2, 0xef, 0x43, 0x2d, 0xc2, + 0xce, 0x6a, 0xf6, 0x9b, 0x0b, 0xae, 0xcc, 0xe0, 0x1e, 0x68, 0x25, 0x27, 0xe6, 0x6c, 0x1c, 0x48, + 0xcf, 0x76, 0xbc, 0x93, 0xc4, 0x4a, 0x4e, 0xcc, 0xd9, 0x3e, 0x63, 0xf4, 0x3f, 0x2e, 0x03, 0x7c, + 0x26, 0x4d, 0x37, 0x3e, 0x45, 0x4f, 0x80, 0xf7, 0xe6, 0x78, 0x51, 0x6c, 0x7a, 0x56, 0x92, 0x13, + 0xa4, 0x30, 0x0a, 0x1f, 0xba, 0x3d, 0x19, 0xb1, 0x11, 0xd2, 0x8c, 0x04, 0x44, 0x47, 0x88, 0xcb, + 0x4d, 0x23, 0xe5, 0x1e, 0x15, 0x94, 0x39, 0xf3, 0x2a, 0xa1, 0x95, 0x33, 0xef, 0x43, 0x03, 0x63, + 0x6c, 0xc7, 0xf7, 0x48, 0x34, 0x34, 0x23, 0x01, 0x71, 0x9e, 0x69, 0x10, 0x3b, 0x13, 0x76, 0x82, + 0x15, 0x43, 0x41, 0xb8, 0x2b, 0x74, 0x7a, 0x43, 0xeb, 0xd4, 0x27, 0xe5, 0xad, 0x18, 0x29, 0x8c, + 0xb3, 0xf9, 0xde, 0x89, 0x8f, 0xa7, 0x6b, 0x52, 0xfc, 0x94, 0x80, 0x7c, 0x16, 0x5b, 0xce, 0x90, + 0xa4, 0x11, 0x29, 0x85, 0x91, 0x2f, 0x52, 0x8e, 0x8f, 0xa5, 0x19, 0x4f, 0x43, 0x19, 0xf5, 0x81, + 0xc8, 0x20, 0xe5, 0x96, 0xc2, 0xe8, 0xbf, 0x5d, 0x86, 0x3a, 0xdb, 0xa5, 0x42, 0xb0, 0x50, 0xfa, + 0x46, 0xc1, 0xc2, 0xdb, 0xa0, 0x05, 0xa1, 0xb4, 0x1d, 0x2b, 0xb9, 0x24, 0xcd, 0xc8, 0x10, 0x14, + 0xa5, 0xa3, 0xdf, 0x24, 0x66, 0x35, 0x0d, 0x06, 0x10, 0x1b, 0x05, 0xa6, 0x25, 0xd5, 0x01, 0x19, + 0x40, 0x8e, 0xb0, 0xc8, 0x93, 0xa8, 0x37, 0x0d, 0x05, 0x89, 0x8f, 0x41, 0xa3, 0xa8, 0x8c, 0x1c, + 0xbe, 0x46, 0x8e, 0xfa, 0xf6, 0xab, 0x97, 0x4b, 0x02, 0x91, 0x73, 0x9e, 0xbe, 0x99, 0xe0, 0x30, + 0x2e, 0xc1, 0xc1, 0x68, 0xdf, 0x81, 0x82, 0x0c, 0x8a, 0x4b, 0x10, 0x35, 0x8a, 0xf2, 0x71, 0x09, + 0x63, 0xf4, 0x7f, 0x2a, 0x43, 0x7b, 0xd3, 0x09, 0xa5, 0x15, 0x4b, 0x7b, 0x68, 0x9f, 0xd0, 0x66, + 0xa4, 0x17, 0x3b, 0xf1, 0x85, 0x8a, 0xa4, 0x14, 0x94, 0x06, 0xba, 0xe5, 0x62, 0xe2, 0xc7, 0x1a, + 0x50, 0xa1, 0x5c, 0x95, 0x01, 0xb1, 0x06, 0xc0, 0x29, 0x00, 0xe5, 0xab, 0xd5, 0xab, 0xf3, 0x55, + 0x8d, 0xba, 0x61, 0x13, 0xf3, 0x41, 0x1e, 0xe3, 0x70, 0x38, 0x55, 0xa7, 0x64, 0x76, 0x8a, 0x56, + 0x86, 0x22, 0xe7, 0x23, 0xe9, 0x92, 0xb8, 0x50, 0xe4, 0x7c, 0x24, 0xdd, 0x34, 0x5f, 0x69, 0xf0, + 0x76, 0xb0, 0x2d, 0xde, 0x83, 0xb2, 0x1f, 0x10, 0x0f, 0xd5, 0x82, 0xf9, 0x83, 0xad, 0xee, 0x05, + 0x46, 0xd9, 0x0f, 0x50, 0xf7, 0x38, 0x39, 0x23, 0x71, 0x41, 0xdd, 0x43, 0x0f, 0x41, 0xa9, 0x82, + 0xa1, 0x28, 0x42, 0x87, 0xb6, 0xe9, 0xba, 0xfe, 0x2f, 0xa4, 0xbd, 0x1f, 0x4a, 0x3b, 0x91, 0x9c, + 0x02, 0x4e, 0xbf, 0x0d, 0xe5, 0xbd, 0x40, 0x34, 0xa0, 0x72, 0x30, 0x1c, 0xf5, 0xae, 0x61, 0x63, + 0x73, 0xb8, 0xd3, 0x2b, 0xe9, 0x5f, 0x97, 0x41, 0x7b, 0x3e, 0x8d, 0x4d, 0xd4, 0xf6, 0x08, 0xcf, + 0x55, 0x14, 0xab, 0x4c, 0x7e, 0xbe, 0x0b, 0xcd, 0x28, 0x36, 0x43, 0xf2, 0xc4, 0xec, 0x17, 0x1a, + 0x04, 0x8f, 0x22, 0xf1, 0x3d, 0xa8, 0x49, 0xfb, 0x44, 0x26, 0xe6, 0xba, 0x37, 0x7f, 0x16, 0x83, + 0xc9, 0x62, 0x05, 0xea, 0x91, 0x75, 0x2a, 0x27, 0x66, 0xbf, 0x9a, 0x75, 0x3c, 0x20, 0x0c, 0xc7, + 0x8e, 0x86, 0xa2, 0x8b, 0xf7, 0xa1, 0x86, 0xb7, 0x11, 0xa9, 0x64, 0x87, 0xd2, 0x23, 0x64, 0xbc, + 0xea, 0xc6, 0x44, 0x94, 0x1d, 0x3b, 0xf4, 0x83, 0xb1, 0x1f, 0x10, 0x5f, 0xbb, 0x6b, 0xb7, 0xc8, + 0xea, 0x24, 0xa7, 0x59, 0xdd, 0x0c, 0xfd, 0x60, 0x2f, 0x30, 0xea, 0x36, 0x7d, 0x31, 0xaf, 0xa5, + 0xee, 0x2c, 0x03, 0x6c, 0xa6, 0x35, 0xc4, 0x70, 0x1d, 0x63, 0x05, 0x9a, 0x13, 0x19, 0x9b, 0xb6, + 0x19, 0x9b, 0xca, 0x5a, 0xb7, 0xd9, 0x88, 0x31, 0xce, 0x48, 0xa9, 0xfa, 0x43, 0xa8, 0xf3, 0xd4, + 0xa2, 0x09, 0xd5, 0xdd, 0xbd, 0xdd, 0x21, 0x33, 0x74, 0x7d, 0x67, 0xa7, 0x57, 0x42, 0xd4, 0xe6, + 0xfa, 0x68, 0xbd, 0x57, 0xc6, 0xd6, 0xe8, 0xa7, 0xfb, 0xc3, 0x5e, 0x45, 0xff, 0xc7, 0x12, 0x34, + 0x93, 0x79, 0xc4, 0xa7, 0x00, 0xa8, 0x77, 0xe3, 0x53, 0xc7, 0x4b, 0x83, 0x9a, 0x3b, 0xf9, 0x95, + 0x56, 0xf1, 0xc6, 0x3e, 0x43, 0x2a, 0xbb, 0x37, 0x52, 0x53, 0x82, 0x07, 0x07, 0xd0, 0x2d, 0x12, + 0x17, 0x44, 0x77, 0xf7, 0xf3, 0x76, 0xbe, 0xbb, 0xf6, 0x9d, 0xc2, 0xd4, 0x38, 0x92, 0x84, 0x39, + 0x67, 0xf2, 0x1f, 0x40, 0x33, 0x41, 0x8b, 0x16, 0x34, 0x36, 0x87, 0x5b, 0xeb, 0x87, 0x3b, 0x28, + 0x24, 0x00, 0xf5, 0x83, 0xed, 0xdd, 0xa7, 0x3b, 0x43, 0x3e, 0xd6, 0xce, 0xf6, 0xc1, 0xa8, 0x57, + 0xd6, 0xff, 0xa8, 0x04, 0xcd, 0x24, 0x86, 0x10, 0xdf, 0x47, 0xe7, 0x4f, 0xa1, 0x8a, 0xf2, 0x0d, + 0x54, 0x8e, 0xc8, 0x25, 0x53, 0x46, 0x42, 0x47, 0xc5, 0x20, 0x53, 0x97, 0x44, 0x15, 0x04, 0xe4, + 0x53, 0xb9, 0x4a, 0xa1, 0x9a, 0x80, 0x59, 0xa9, 0xef, 0x49, 0x15, 0x24, 0x52, 0x9b, 0x64, 0xd0, + 0xf1, 0x2c, 0xb2, 0x16, 0x35, 0x25, 0x83, 0x08, 0x8f, 0x22, 0xfd, 0xaf, 0xaa, 0xd0, 0x35, 0x64, + 0x14, 0xfb, 0xa1, 0x34, 0xe4, 0xcf, 0xa7, 0x98, 0x6a, 0xbf, 0x46, 0x98, 0xdf, 0x01, 0x08, 0xb9, + 0x73, 0x26, 0xce, 0x9a, 0xc2, 0x70, 0x98, 0xee, 0xfa, 0x16, 0x49, 0x91, 0xf2, 0x1e, 0x29, 0x2c, + 0xee, 0x80, 0x76, 0x64, 0x5a, 0x67, 0x3c, 0x2d, 0xfb, 0x90, 0x26, 0x23, 0x78, 0x5e, 0xd3, 0xb2, + 0x64, 0x14, 0x8d, 0xf1, 0x52, 0xd8, 0x93, 0x68, 0x8c, 0x79, 0x26, 0x2f, 0x90, 0x1c, 0x49, 0x2b, + 0x94, 0x31, 0x91, 0xd9, 0x40, 0x68, 0x8c, 0x41, 0xf2, 0x7b, 0xd0, 0x89, 0x64, 0x84, 0x5e, 0x67, + 0x1c, 0xfb, 0x67, 0xd2, 0x53, 0xd6, 0xa2, 0xad, 0x90, 0x23, 0xc4, 0xa1, 0x1d, 0x37, 0x3d, 0xdf, + 0xbb, 0x98, 0xf8, 0xd3, 0x48, 0x19, 0xe0, 0x0c, 0x21, 0x56, 0xe1, 0xa6, 0xf4, 0xac, 0xf0, 0x22, + 0xc0, 0xbd, 0xe2, 0x2a, 0xe3, 0x63, 0xc7, 0x95, 0x2a, 0x50, 0xbc, 0x91, 0x91, 0x9e, 0xc9, 0x8b, + 0x2d, 0xc7, 0x95, 0xb8, 0xa3, 0x73, 0x73, 0xea, 0xc6, 0x63, 0x4a, 0x24, 0x81, 0x77, 0x44, 0x98, + 0x75, 0xcc, 0x26, 0x3f, 0x84, 0x1b, 0x4c, 0x0e, 0x7d, 0x57, 0x3a, 0x36, 0x4f, 0xd6, 0xa2, 0x5e, + 0xd7, 0x89, 0x60, 0x10, 0x9e, 0xa6, 0x5a, 0x85, 0x9b, 0xdc, 0x97, 0x0f, 0x94, 0xf4, 0x6e, 0xf3, + 0xd2, 0x44, 0x3a, 0x50, 0x94, 0xe2, 0xd2, 0x81, 0x19, 0x9f, 0x52, 0x82, 0x98, 0x2c, 0xbd, 0x6f, + 0xc6, 0xa7, 0xe8, 0x0d, 0x99, 0x7c, 0xec, 0x48, 0x97, 0x13, 0x3f, 0xcd, 0xe0, 0x11, 0x5b, 0x88, + 0x11, 0xef, 0x42, 0x5b, 0x75, 0xf0, 0xc3, 0x89, 0xc9, 0xf5, 0x25, 0xcd, 0xe0, 0x41, 0x5b, 0x84, + 0xc2, 0x25, 0xd4, 0x5d, 0x79, 0xd3, 0x49, 0xbf, 0xc7, 0xd7, 0xcc, 0x98, 0xdd, 0xe9, 0x44, 0xff, + 0x9f, 0x32, 0x34, 0xd3, 0x64, 0xe3, 0x3e, 0x68, 0x93, 0xc4, 0x72, 0xa8, 0x20, 0xa6, 0x53, 0x30, + 0x27, 0x46, 0x46, 0x17, 0xef, 0x40, 0xf9, 0xec, 0x5c, 0x59, 0xb1, 0xce, 0x2a, 0xd7, 0x5b, 0x83, + 0xa3, 0xb5, 0xd5, 0x67, 0x2f, 0x8c, 0xf2, 0xd9, 0x79, 0x16, 0x0c, 0xd5, 0xde, 0x18, 0x0c, 0x7d, + 0x00, 0xd7, 0x2d, 0x57, 0x9a, 0xde, 0x38, 0x73, 0xce, 0x2c, 0x17, 0x5d, 0x42, 0xef, 0xa7, 0x1e, + 0x5a, 0x29, 0x7a, 0x23, 0x53, 0xf4, 0x7b, 0x50, 0xb3, 0xa5, 0x1b, 0x9b, 0xf9, 0x42, 0xe0, 0x5e, + 0x68, 0x5a, 0xae, 0xdc, 0x44, 0xb4, 0xc1, 0x54, 0xb4, 0x6b, 0x49, 0x42, 0x94, 0xb7, 0x6b, 0x89, + 0x0a, 0x1b, 0x29, 0x35, 0xd3, 0x50, 0xc8, 0x6b, 0xe8, 0x7d, 0xb8, 0x21, 0x67, 0x01, 0x19, 0xf3, + 0x71, 0x9a, 0xbc, 0xb6, 0xa8, 0x47, 0x2f, 0x21, 0x3c, 0x51, 0x78, 0xf1, 0x11, 0xaa, 0x33, 0xa9, + 0x11, 0x5d, 0x7c, 0x6b, 0x4d, 0x90, 0x3d, 0x28, 0x28, 0xa6, 0x91, 0x74, 0xd1, 0x3d, 0xa8, 0x3c, + 0x7b, 0x71, 0xa0, 0xb8, 0x59, 0xba, 0x8a, 0x9b, 0x89, 0x25, 0x28, 0xe7, 0x2c, 0xc1, 0x5d, 0x36, + 0xa2, 0xc4, 0x9a, 0xa4, 0x48, 0x95, 0xc3, 0xe0, 0x51, 0xd8, 0x81, 0x54, 0xb9, 0x7e, 0x45, 0x80, + 0xfe, 0x5f, 0x15, 0x68, 0x28, 0xaf, 0x8e, 0xfc, 0x9c, 0xa6, 0xf5, 0x17, 0x6c, 0x16, 0xd3, 0x9e, + 0x34, 0x3c, 0xc8, 0x17, 0xb3, 0x2b, 0x6f, 0x2e, 0x66, 0x8b, 0x4f, 0xa1, 0x1d, 0x30, 0x2d, 0x1f, + 0x50, 0xbc, 0x95, 0x1f, 0xa3, 0xbe, 0x34, 0xae, 0x15, 0x64, 0x00, 0x5a, 0x2c, 0xaa, 0xf4, 0xc5, + 0xe6, 0x09, 0x89, 0x4e, 0xdb, 0x68, 0x20, 0x3c, 0x32, 0x4f, 0xae, 0x08, 0x2b, 0xbe, 0x49, 0x74, + 0xd0, 0xa5, 0x30, 0xa3, 0x4d, 0x06, 0x10, 0x23, 0x8a, 0xbc, 0x23, 0xef, 0x14, 0x1d, 0xf9, 0x1d, + 0xd0, 0x2c, 0x7f, 0x32, 0x71, 0x88, 0xd6, 0x55, 0xf5, 0x09, 0x42, 0x8c, 0x22, 0xfd, 0xf7, 0x4a, + 0xd0, 0x50, 0xa7, 0xbd, 0xe4, 0x26, 0x36, 0xb6, 0x77, 0xd7, 0x8d, 0x9f, 0xf6, 0x4a, 0xe8, 0x06, + 0xb7, 0x77, 0x47, 0xbd, 0xb2, 0xd0, 0xa0, 0xb6, 0xb5, 0xb3, 0xb7, 0x3e, 0xea, 0x55, 0xd0, 0x75, + 0x6c, 0xec, 0xed, 0xed, 0xf4, 0xaa, 0xa2, 0x0d, 0xcd, 0xcd, 0xf5, 0xd1, 0x70, 0xb4, 0xfd, 0x7c, + 0xd8, 0xab, 0x61, 0xdf, 0xa7, 0xc3, 0xbd, 0x5e, 0x1d, 0x1b, 0x87, 0xdb, 0x9b, 0xbd, 0x06, 0xd2, + 0xf7, 0xd7, 0x0f, 0x0e, 0xbe, 0xd8, 0x33, 0x36, 0x7b, 0x4d, 0x72, 0x3f, 0x23, 0x63, 0x7b, 0xf7, + 0x69, 0x4f, 0xc3, 0xf6, 0xde, 0xc6, 0x8f, 0x87, 0x4f, 0x46, 0x3d, 0xd0, 0x1f, 0x43, 0x2b, 0xc7, + 0x41, 0x1c, 0x6d, 0x0c, 0xb7, 0x7a, 0xd7, 0x70, 0xc9, 0x17, 0xeb, 0x3b, 0x87, 0xe8, 0xad, 0xba, + 0x00, 0xd4, 0x1c, 0xef, 0xac, 0xef, 0x3e, 0xed, 0x95, 0xf5, 0xcf, 0xa1, 0x79, 0xe8, 0xd8, 0x1b, + 0xae, 0x6f, 0x9d, 0xa1, 0x38, 0x1d, 0x99, 0x91, 0x54, 0xa9, 0x11, 0xb5, 0x31, 0x8a, 0x24, 0x65, + 0x89, 0xd4, 0xdd, 0x2b, 0x08, 0x79, 0xe5, 0x4d, 0x27, 0x63, 0x7a, 0x00, 0xa9, 0xb0, 0x0b, 0xf1, + 0xa6, 0x93, 0x43, 0xc7, 0x8e, 0xf4, 0x33, 0x68, 0x1c, 0x3a, 0xf6, 0xbe, 0x69, 0x9d, 0x91, 0x99, + 0xc1, 0xa9, 0xc7, 0x91, 0xf3, 0x95, 0x54, 0xae, 0x46, 0x23, 0xcc, 0x81, 0xf3, 0x95, 0x14, 0xef, + 0x43, 0x9d, 0x80, 0x24, 0x0d, 0x26, 0xf5, 0x4b, 0xb6, 0x63, 0x28, 0x1a, 0xbd, 0x3f, 0xb8, 0xae, + 0x6f, 0x8d, 0x43, 0x79, 0xdc, 0x7f, 0x8b, 0x79, 0x4f, 0x08, 0x43, 0x1e, 0xeb, 0xbf, 0x5f, 0x4a, + 0xcf, 0x4c, 0xe5, 0xef, 0x25, 0xa8, 0x06, 0xa6, 0x75, 0xa6, 0x7c, 0x6e, 0x4b, 0x4d, 0x88, 0x9b, + 0x31, 0x88, 0x20, 0x3e, 0x80, 0xa6, 0x12, 0xac, 0x64, 0xd5, 0x56, 0x4e, 0x02, 0x8d, 0x94, 0x58, + 0xbc, 0xf2, 0x4a, 0xf1, 0xca, 0x29, 0x87, 0x0a, 0x5c, 0x27, 0x66, 0x35, 0xaa, 0x1a, 0x0a, 0xd2, + 0x7f, 0x00, 0x90, 0xbd, 0x38, 0x2c, 0x08, 0x41, 0x6e, 0x41, 0xcd, 0x74, 0x1d, 0x33, 0xc9, 0xc9, + 0x18, 0xd0, 0x77, 0xa1, 0x95, 0x7b, 0xa7, 0x40, 0xde, 0x9a, 0xae, 0x8b, 0x3e, 0x2a, 0xa2, 0xb1, + 0x4d, 0xa3, 0x61, 0xba, 0xee, 0x33, 0x79, 0x11, 0x61, 0xf8, 0xc7, 0x4f, 0x1c, 0xe5, 0xb9, 0xea, + 0x38, 0x0d, 0x35, 0x98, 0xa8, 0x7f, 0x04, 0xf5, 0xad, 0x24, 0x00, 0x4e, 0xd4, 0xa0, 0x74, 0x95, + 0x1a, 0xe8, 0x9f, 0xa8, 0x3d, 0x53, 0x81, 0x5d, 0xdc, 0x57, 0x4f, 0x29, 0x11, 0x3f, 0xdc, 0x94, + 0xb2, 0xac, 0x9e, 0x3b, 0xa9, 0x57, 0x14, 0xea, 0xac, 0x6f, 0x42, 0xf3, 0xb5, 0x8f, 0x53, 0x8a, + 0x01, 0xe5, 0x8c, 0x01, 0x0b, 0x9e, 0xab, 0xf4, 0x9f, 0x01, 0x64, 0x4f, 0x2e, 0x4a, 0x2b, 0x79, + 0x16, 0xd4, 0xca, 0x0f, 0xa1, 0x69, 0x9d, 0x3a, 0xae, 0x1d, 0x4a, 0xaf, 0x70, 0xea, 0xec, 0x91, + 0x26, 0xa5, 0x8b, 0x65, 0xa8, 0xd2, 0x4b, 0x52, 0x25, 0xb3, 0xe6, 0xe9, 0x33, 0x12, 0x51, 0xf4, + 0x19, 0x74, 0x38, 0xae, 0xfe, 0x06, 0xb1, 0x50, 0xd1, 0x94, 0x96, 0x2f, 0x99, 0xd2, 0xdb, 0x50, + 0x27, 0x17, 0x9c, 0x9c, 0x46, 0x41, 0x57, 0x98, 0xd8, 0xdf, 0x2d, 0x03, 0xf0, 0xd2, 0xbb, 0xbe, + 0x2d, 0x8b, 0x59, 0x67, 0x69, 0x3e, 0xeb, 0x14, 0x50, 0x4d, 0x1f, 0x09, 0x35, 0x83, 0xda, 0x99, + 0x13, 0x52, 0x99, 0x28, 0x3b, 0xa1, 0xb7, 0x41, 0xa3, 0x90, 0xc8, 0xf9, 0x8a, 0x2a, 0xdb, 0xb8, + 0x60, 0x86, 0xc8, 0x3f, 0x99, 0xd5, 0x8a, 0x4f, 0x66, 0xe9, 0xbb, 0x42, 0x9d, 0x67, 0xe3, 0x77, + 0x85, 0x05, 0x4f, 0x24, 0x9c, 0xe7, 0x47, 0x32, 0x8c, 0x93, 0xac, 0x96, 0xa1, 0x34, 0x73, 0xd3, + 0x54, 0x5f, 0x93, 0x33, 0x75, 0xcf, 0x1f, 0x5b, 0xbe, 0x77, 0xec, 0x3a, 0x56, 0xac, 0x9e, 0xc8, + 0xc0, 0xf3, 0x9f, 0x28, 0x8c, 0xfe, 0x29, 0xb4, 0x13, 0xfe, 0xd3, 0x4b, 0xc4, 0x87, 0x69, 0xe6, + 0x53, 0xca, 0xee, 0x36, 0x63, 0xd3, 0x46, 0xb9, 0x5f, 0x4a, 0x72, 0x1f, 0xfd, 0x3f, 0x2b, 0xc9, + 0x60, 0x55, 0x50, 0x7f, 0x3d, 0x0f, 0x8b, 0xe9, 0x6b, 0xf9, 0x1b, 0xa5, 0xaf, 0x3f, 0x04, 0xcd, + 0xa6, 0xfc, 0xcc, 0x39, 0x4f, 0x9c, 0xda, 0x60, 0x3e, 0x17, 0x53, 0x19, 0x9c, 0x73, 0x2e, 0x8d, + 0xac, 0xf3, 0x1b, 0xee, 0x21, 0xe5, 0x76, 0x6d, 0x11, 0xb7, 0xeb, 0xbf, 0x22, 0xb7, 0xdf, 0x85, + 0xb6, 0xe7, 0x7b, 0x63, 0x6f, 0xea, 0xba, 0xe6, 0x91, 0x2b, 0x15, 0xbb, 0x5b, 0x9e, 0xef, 0xed, + 0x2a, 0x14, 0xc6, 0xa9, 0xf9, 0x2e, 0xac, 0xd4, 0x2d, 0xea, 0x77, 0x3d, 0xd7, 0x8f, 0x54, 0x7f, + 0x05, 0x7a, 0xfe, 0xd1, 0xcf, 0xa4, 0x15, 0x13, 0xc7, 0xc6, 0xa4, 0xcd, 0x1c, 0xa4, 0x76, 0x19, + 0x8f, 0x2c, 0xda, 0x45, 0xbd, 0x9e, 0xbb, 0xe6, 0xce, 0xa5, 0x6b, 0xfe, 0x04, 0xb4, 0x94, 0x4b, + 0xb9, 0x5c, 0x50, 0x83, 0xda, 0xf6, 0xee, 0xe6, 0xf0, 0x27, 0xbd, 0x12, 0x3a, 0x4a, 0x63, 0xf8, + 0x62, 0x68, 0x1c, 0x0c, 0x7b, 0x65, 0x74, 0x62, 0x9b, 0xc3, 0x9d, 0xe1, 0x68, 0xd8, 0xab, 0xfc, + 0xb8, 0xda, 0x6c, 0xf4, 0x9a, 0x54, 0x16, 0x77, 0x1d, 0xcb, 0x89, 0xf5, 0x03, 0x80, 0x2c, 0xc1, + 0x45, 0xab, 0x9c, 0x6d, 0x4e, 0xd5, 0xbc, 0xe2, 0x64, 0x5b, 0x2b, 0xa9, 0x42, 0x96, 0xaf, 0x4a, + 0xa3, 0x99, 0xae, 0xaf, 0x81, 0xf6, 0xdc, 0x0c, 0x3e, 0xe3, 0x17, 0xa0, 0x7b, 0xd0, 0x0d, 0xcc, + 0x30, 0x76, 0x92, 0xcc, 0x80, 0x8d, 0x65, 0xdb, 0xe8, 0xa4, 0x58, 0xb4, 0xbd, 0xfa, 0x5f, 0x97, + 0xe0, 0xd6, 0x73, 0xff, 0x5c, 0xa6, 0x91, 0xe7, 0xbe, 0x79, 0xe1, 0xfa, 0xa6, 0xfd, 0x06, 0x31, + 0xc4, 0xd4, 0xc6, 0x9f, 0xd2, 0x5b, 0x4d, 0xf2, 0x7e, 0x65, 0x68, 0x8c, 0x79, 0xaa, 0x1e, 0xd0, + 0x65, 0x14, 0x13, 0x51, 0x39, 0x52, 0x84, 0x91, 0xf4, 0x1d, 0xa8, 0xc7, 0x33, 0x2f, 0x7b, 0x2e, + 0xab, 0xc5, 0x54, 0x91, 0x5d, 0x18, 0x76, 0xd6, 0x16, 0x87, 0x9d, 0xfa, 0x13, 0xd0, 0x46, 0x33, + 0xaa, 0x56, 0x4e, 0xa3, 0x42, 0x80, 0x53, 0x7a, 0x4d, 0x80, 0x53, 0x9e, 0x0b, 0x70, 0xfe, 0xbd, + 0x04, 0xad, 0x5c, 0xfc, 0x2c, 0xde, 0x85, 0x6a, 0x3c, 0xf3, 0x8a, 0x8f, 0xd2, 0xc9, 0x22, 0x06, + 0x91, 0x50, 0x34, 0x27, 0xe6, 0x6c, 0x6c, 0x46, 0x91, 0x73, 0xe2, 0x49, 0x5b, 0x4d, 0xd9, 0x9a, + 0x98, 0xb3, 0x75, 0x85, 0x12, 0x3b, 0x70, 0x9d, 0x2d, 0x6f, 0x72, 0x88, 0xa4, 0x4c, 0xf2, 0xde, + 0x5c, 0xbc, 0xce, 0x15, 0xdd, 0xe4, 0x48, 0x2a, 0xf7, 0xef, 0x9e, 0x14, 0x90, 0x83, 0x75, 0xb8, + 0xb9, 0xa0, 0xdb, 0xb7, 0xaa, 0xe1, 0x2f, 0x41, 0x67, 0x34, 0xf3, 0x46, 0xce, 0x44, 0x46, 0xb1, + 0x39, 0x09, 0x28, 0x40, 0x54, 0x9e, 0xb3, 0x6a, 0x94, 0xe3, 0x48, 0xff, 0x1e, 0xb4, 0xf7, 0xa5, + 0x0c, 0x0d, 0x19, 0x05, 0xbe, 0xc7, 0xc1, 0x91, 0xaa, 0xa4, 0xb2, 0x9b, 0x56, 0x90, 0xfe, 0x5b, + 0xa0, 0x61, 0xa2, 0xbf, 0x61, 0xc6, 0xd6, 0xe9, 0xb7, 0x29, 0x04, 0x7c, 0x0f, 0x1a, 0x01, 0xcb, + 0x94, 0xca, 0xb3, 0xda, 0xe4, 0xae, 0x95, 0x9c, 0x19, 0x09, 0x51, 0x7f, 0x0c, 0x37, 0x0f, 0xa6, + 0x47, 0x91, 0x15, 0x3a, 0x94, 0xb2, 0x26, 0xae, 0x6c, 0x00, 0xcd, 0x20, 0x94, 0xc7, 0xce, 0x4c, + 0x26, 0x12, 0x9c, 0xc2, 0xfa, 0x8f, 0xe0, 0x56, 0x71, 0x88, 0x3a, 0xc2, 0x7b, 0x50, 0x39, 0x3b, + 0x8f, 0xd4, 0xce, 0x6e, 0x14, 0x52, 0x0c, 0x7a, 0x0b, 0x46, 0xaa, 0x6e, 0x40, 0x65, 0x77, 0x3a, + 0xc9, 0xff, 0xcf, 0x52, 0xe5, 0xff, 0x59, 0xee, 0xe4, 0x0b, 0x9b, 0x9c, 0x85, 0x64, 0x05, 0xcc, + 0xb7, 0x41, 0x3b, 0xf6, 0xc3, 0x5f, 0x98, 0xa1, 0x2d, 0x6d, 0xe5, 0xb3, 0x32, 0x84, 0xfe, 0x25, + 0xb4, 0x12, 0x49, 0xd8, 0xb6, 0xe9, 0xf1, 0x8b, 0x44, 0x71, 0xdb, 0x2e, 0x48, 0x26, 0x97, 0x0d, + 0xa5, 0x67, 0x6f, 0x27, 0x22, 0xc4, 0x40, 0x71, 0x65, 0xf5, 0x66, 0x91, 0xac, 0xac, 0x6f, 0x41, + 0x3b, 0x49, 0xe2, 0x9e, 0xcb, 0xd8, 0x24, 0xe1, 0x76, 0x1d, 0xe9, 0xe5, 0x04, 0xbf, 0xc9, 0x88, + 0x51, 0xb1, 0xb2, 0x57, 0x2e, 0x04, 0x00, 0xfa, 0x2a, 0xd4, 0x95, 0xe6, 0x08, 0xa8, 0x5a, 0xbe, + 0xcd, 0xda, 0x5d, 0x33, 0xa8, 0x8d, 0xec, 0x98, 0x44, 0x27, 0x49, 0x70, 0x33, 0x89, 0x4e, 0xf4, + 0xbf, 0x2d, 0x43, 0x67, 0x83, 0x92, 0xe8, 0xe4, 0x4a, 0x72, 0x45, 0x9c, 0x52, 0xa1, 0x88, 0x93, + 0x2f, 0xd8, 0x94, 0x0b, 0x05, 0x9b, 0xc2, 0x86, 0x2a, 0xc5, 0x88, 0xe4, 0x2d, 0x68, 0x4c, 0x3d, + 0x67, 0x96, 0x98, 0x04, 0xcd, 0xa8, 0x23, 0x38, 0x8a, 0xc4, 0x32, 0xb4, 0xd0, 0x6a, 0x38, 0x1e, + 0x97, 0x66, 0xb8, 0xbe, 0x92, 0x47, 0xcd, 0x15, 0x60, 0xea, 0xaf, 0x2f, 0xc0, 0x34, 0xde, 0x58, + 0x80, 0x69, 0xbe, 0xa9, 0x00, 0xa3, 0xcd, 0x17, 0x60, 0x8a, 0xd1, 0x14, 0xcc, 0x47, 0x53, 0xfa, + 0x0e, 0x74, 0x13, 0xde, 0x29, 0xd9, 0xfc, 0x14, 0xae, 0xab, 0x2a, 0xa6, 0x0c, 0x55, 0xf9, 0x81, + 0x2d, 0xce, 0x0d, 0xaa, 0xa3, 0x52, 0xa1, 0x51, 0x51, 0x8c, 0xae, 0x9d, 0x07, 0x23, 0xfd, 0x0f, + 0x4b, 0xd0, 0x29, 0xf4, 0x10, 0x8f, 0xb3, 0x9a, 0x68, 0x89, 0x1c, 0x7b, 0xff, 0xd2, 0x2c, 0xaf, + 0xaf, 0x8b, 0x96, 0xe7, 0xea, 0xa2, 0xb9, 0x6a, 0xa7, 0xaa, 0x71, 0x5e, 0x4b, 0x6b, 0x9c, 0xa5, + 0xb4, 0xc6, 0x49, 0xd5, 0xce, 0xf5, 0xd1, 0xc8, 0xe8, 0x55, 0xf4, 0x3f, 0x29, 0x43, 0x67, 0x38, + 0x0b, 0xe8, 0x3f, 0x8c, 0x37, 0x46, 0x9f, 0x39, 0xd1, 0x29, 0x17, 0x44, 0x27, 0x27, 0x04, 0x15, + 0xf5, 0xf0, 0xc2, 0x42, 0x80, 0xf1, 0x28, 0x57, 0x7c, 0x94, 0x70, 0x30, 0xf4, 0x7f, 0x40, 0x38, + 0xf0, 0xf2, 0x13, 0xc6, 0xa8, 0xcb, 0xff, 0x46, 0x1a, 0xc7, 0xff, 0x50, 0xb9, 0x69, 0xa1, 0x83, + 0x01, 0xfd, 0x0f, 0xca, 0xa0, 0xb1, 0x2c, 0xe1, 0xf6, 0xbe, 0xaf, 0x62, 0xe9, 0x52, 0x56, 0xf5, + 0x4d, 0x89, 0xab, 0xcf, 0xe4, 0x05, 0xc5, 0x80, 0x1c, 0x62, 0x2f, 0x7a, 0x1b, 0x51, 0xe5, 0x10, + 0xce, 0x00, 0xa9, 0x1c, 0x72, 0x07, 0x34, 0x76, 0xa3, 0x53, 0x27, 0x79, 0x4d, 0x65, 0xbf, 0x7a, + 0xe8, 0xd0, 0xaf, 0x27, 0xb1, 0x0c, 0x27, 0x8a, 0xcb, 0xd4, 0x2e, 0xc6, 0xda, 0x1d, 0x15, 0xfd, + 0xe9, 0xa7, 0xd0, 0x50, 0xab, 0x63, 0x30, 0x74, 0xb8, 0xfb, 0x6c, 0x77, 0xef, 0x8b, 0xdd, 0x82, + 0x0c, 0xa5, 0xe1, 0x52, 0x39, 0x1f, 0x2e, 0x55, 0x10, 0xff, 0x64, 0xef, 0x70, 0x77, 0xd4, 0xab, + 0x8a, 0x0e, 0x68, 0xd4, 0x1c, 0x1b, 0xc3, 0x17, 0xbd, 0x1a, 0x55, 0x06, 0x9e, 0x7c, 0x36, 0x7c, + 0xbe, 0xde, 0xab, 0xa7, 0x12, 0xd8, 0xd0, 0xff, 0xa2, 0x04, 0x37, 0xf8, 0xc8, 0xf9, 0x54, 0x39, + 0xff, 0xff, 0x62, 0x95, 0xff, 0x5f, 0xfc, 0xf5, 0x66, 0xc7, 0x38, 0x68, 0xea, 0xd8, 0xe3, 0xa3, + 0x0b, 0xb4, 0x00, 0x5c, 0xc6, 0x69, 0x4e, 0x1d, 0x7b, 0x03, 0x61, 0xfd, 0xef, 0x4b, 0x30, 0xe0, + 0x28, 0xed, 0x69, 0x68, 0x06, 0xa7, 0x9f, 0xef, 0x5c, 0xca, 0xd3, 0xae, 0x8a, 0x5d, 0xee, 0x41, + 0x97, 0xfe, 0xf0, 0xfc, 0xb9, 0x3b, 0x56, 0xb9, 0x04, 0xdf, 0x5f, 0x47, 0x61, 0x79, 0x22, 0xf1, + 0x31, 0xb4, 0xf9, 0x4f, 0x50, 0xaa, 0x28, 0x16, 0xde, 0x64, 0x0a, 0x31, 0x62, 0x8b, 0x7b, 0xd1, + 0xeb, 0x90, 0x78, 0x9c, 0x0e, 0xca, 0x52, 0xba, 0xcb, 0xcf, 0x2e, 0x6a, 0xc8, 0x88, 0x12, 0xbd, + 0x87, 0x70, 0x67, 0xe1, 0x39, 0x94, 0x60, 0xe7, 0xca, 0x6b, 0x2c, 0x4f, 0x6b, 0x7f, 0x57, 0x82, + 0x2a, 0xc6, 0x03, 0xe2, 0x01, 0x68, 0x9f, 0x49, 0x33, 0x8c, 0x8f, 0xa4, 0x19, 0x8b, 0x82, 0xef, + 0x1f, 0xd0, 0x8a, 0xd9, 0xd3, 0xaf, 0x7e, 0xed, 0x51, 0x49, 0xac, 0xf2, 0xcf, 0x59, 0xc9, 0x3f, + 0x67, 0x9d, 0x24, 0xae, 0xa0, 0xb8, 0x63, 0x50, 0x18, 0xaf, 0x5f, 0x5b, 0xa1, 0xfe, 0x3f, 0xf6, + 0x1d, 0xef, 0x09, 0xff, 0x4b, 0x24, 0xe6, 0xe3, 0x90, 0xf9, 0x11, 0xe2, 0x01, 0xd4, 0xb7, 0x23, + 0x0c, 0x78, 0x2e, 0x77, 0x25, 0xae, 0xe5, 0x63, 0x21, 0xfd, 0xda, 0xda, 0x5f, 0x56, 0xa0, 0xfa, + 0xa5, 0x0c, 0x7d, 0xf1, 0x11, 0x34, 0xd4, 0x43, 0xb9, 0xc8, 0x3d, 0x88, 0x0f, 0x28, 0xf7, 0x9a, + 0x7b, 0x41, 0xa7, 0x55, 0x7a, 0xcc, 0xae, 0xac, 0x0e, 0x2c, 0xb2, 0x77, 0xfc, 0x4b, 0x9b, 0xfa, + 0x04, 0x7a, 0x07, 0x71, 0x28, 0xcd, 0x49, 0xae, 0x7b, 0x91, 0x55, 0x8b, 0x8a, 0xca, 0xc4, 0xaf, + 0xfb, 0x50, 0xe7, 0xa8, 0x72, 0x6e, 0xc0, 0x7c, 0x7d, 0x98, 0x3a, 0x7f, 0x00, 0xad, 0x83, 0x53, + 0x7f, 0xea, 0xda, 0x07, 0x32, 0x3c, 0x97, 0x22, 0xf7, 0xeb, 0xcb, 0x20, 0xd7, 0xd6, 0xaf, 0x89, + 0x15, 0x00, 0x0e, 0x64, 0x0e, 0x51, 0x81, 0x1a, 0x48, 0xdb, 0x9d, 0x4e, 0x78, 0xd2, 0x5c, 0x84, + 0xc3, 0x3d, 0x73, 0xc1, 0xe5, 0xeb, 0x7a, 0x7e, 0x0c, 0x9d, 0x27, 0xa4, 0x4c, 0x7b, 0xe1, 0xfa, + 0x91, 0x1f, 0xc6, 0x62, 0xfe, 0xf7, 0x97, 0xc1, 0x3c, 0x42, 0xbf, 0x26, 0x1e, 0x41, 0x73, 0x14, + 0x5e, 0x70, 0xff, 0x1b, 0x2a, 0x26, 0xcf, 0xd6, 0x5b, 0x70, 0xca, 0xb5, 0xff, 0xae, 0x42, 0xfd, + 0x0b, 0x3f, 0x3c, 0x93, 0x21, 0xe6, 0xe1, 0x54, 0xcf, 0x57, 0x62, 0x94, 0xd6, 0xf6, 0x17, 0x2d, + 0xf4, 0x3e, 0x68, 0xc4, 0x94, 0x91, 0x19, 0x9d, 0xf1, 0x55, 0xd1, 0x2f, 0xc5, 0xcc, 0x17, 0xce, + 0xeb, 0xe9, 0x5e, 0xbb, 0x7c, 0x51, 0xe9, 0x93, 0x58, 0xa1, 0xba, 0x3e, 0xa0, 0xf3, 0x3f, 0x7b, + 0x71, 0x80, 0xa2, 0xf9, 0xa8, 0x84, 0x56, 0xfa, 0x80, 0x4f, 0x8a, 0x9d, 0xb2, 0x5f, 0x29, 0x59, + 0xf2, 0xb3, 0x7f, 0x17, 0xf5, 0x6b, 0xe2, 0x21, 0xd4, 0x95, 0x4a, 0xdf, 0xc8, 0x94, 0x57, 0xd9, + 0x89, 0x41, 0x2f, 0x8f, 0x52, 0x03, 0x1e, 0x43, 0x9d, 0xcd, 0x1f, 0x0f, 0x28, 0x84, 0x68, 0x03, + 0x91, 0x47, 0x25, 0xc2, 0x2c, 0xee, 0x43, 0x43, 0xd5, 0xe6, 0xc5, 0x82, 0x42, 0x3d, 0x1f, 0x95, + 0x63, 0x43, 0x9e, 0x9f, 0xbd, 0x17, 0xcf, 0x5f, 0x70, 0xf1, 0x3c, 0x7f, 0xd1, 0xb9, 0xb1, 0xd4, + 0x1b, 0xd2, 0x92, 0x4e, 0x2e, 0x9d, 0x14, 0x09, 0x47, 0x16, 0xa8, 0xee, 0x27, 0xd0, 0x29, 0xa4, + 0x9e, 0x82, 0x82, 0x97, 0x45, 0xd9, 0xe8, 0x25, 0x85, 0xf9, 0x11, 0x68, 0x2a, 0xf2, 0x3f, 0x92, + 0x82, 0xaa, 0xed, 0x0b, 0x72, 0x87, 0xc1, 0xe5, 0xd0, 0x9f, 0xb4, 0xe0, 0x27, 0x70, 0x73, 0x81, + 0x2d, 0x13, 0xf4, 0xdf, 0xd1, 0xd5, 0xc6, 0x7a, 0xb0, 0x74, 0x25, 0x3d, 0x61, 0xc0, 0x46, 0xef, + 0x1f, 0xbe, 0xbe, 0x5b, 0xfa, 0xe7, 0xaf, 0xef, 0x96, 0xfe, 0xf5, 0xeb, 0xbb, 0xa5, 0x5f, 0xfe, + 0xdb, 0xdd, 0x6b, 0x47, 0x75, 0xfa, 0xbd, 0xfe, 0xe3, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x0d, + 0x35, 0xa4, 0x91, 0xd4, 0x2f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -5960,7 +6101,7 @@ type WorkerClient interface { StreamSnapshot(ctx context.Context, opts ...grpc.CallOption) (Worker_StreamSnapshotClient, error) Sort(ctx context.Context, in *SortMessage, opts ...grpc.CallOption) (*SortResult, error) Schema(ctx context.Context, in *SchemaRequest, opts ...grpc.CallOption) (*SchemaResult, error) - Backup(ctx context.Context, in *BackupRequest, opts ...grpc.CallOption) (*Status, error) + Backup(ctx context.Context, in *BackupRequest, opts ...grpc.CallOption) (*BackupResponse, error) Restore(ctx context.Context, in *RestoreRequest, opts ...grpc.CallOption) (*Status, error) Export(ctx context.Context, in *ExportRequest, opts ...grpc.CallOption) (*ExportResponse, error) ReceivePredicate(ctx context.Context, opts ...grpc.CallOption) (Worker_ReceivePredicateClient, error) @@ -6044,8 +6185,8 @@ func (c *workerClient) Schema(ctx context.Context, in *SchemaRequest, opts ...gr return out, nil } -func (c *workerClient) Backup(ctx context.Context, in *BackupRequest, opts ...grpc.CallOption) (*Status, error) { - out := new(Status) +func (c *workerClient) Backup(ctx context.Context, in *BackupRequest, opts ...grpc.CallOption) (*BackupResponse, error) { + out := new(BackupResponse) err := c.cc.Invoke(ctx, "/pb.Worker/Backup", in, out, opts...) if err != nil { return nil, err @@ -6163,7 +6304,7 @@ type WorkerServer interface { StreamSnapshot(Worker_StreamSnapshotServer) error Sort(context.Context, *SortMessage) (*SortResult, error) Schema(context.Context, *SchemaRequest) (*SchemaResult, error) - Backup(context.Context, *BackupRequest) (*Status, error) + Backup(context.Context, *BackupRequest) (*BackupResponse, error) Restore(context.Context, *RestoreRequest) (*Status, error) Export(context.Context, *ExportRequest) (*ExportResponse, error) ReceivePredicate(Worker_ReceivePredicateServer) error @@ -6191,7 +6332,7 @@ func (*UnimplementedWorkerServer) Sort(ctx context.Context, req *SortMessage) (* func (*UnimplementedWorkerServer) Schema(ctx context.Context, req *SchemaRequest) (*SchemaResult, error) { return nil, status.Errorf(codes.Unimplemented, "method Schema not implemented") } -func (*UnimplementedWorkerServer) Backup(ctx context.Context, req *BackupRequest) (*Status, error) { +func (*UnimplementedWorkerServer) Backup(ctx context.Context, req *BackupRequest) (*BackupResponse, error) { return nil, status.Errorf(codes.Unimplemented, "method Backup not implemented") } func (*UnimplementedWorkerServer) Restore(ctx context.Context, req *RestoreRequest) (*Status, error) { @@ -10161,6 +10302,86 @@ func (m *BackupRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *BackupResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *BackupResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *BackupResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.DropOperations) > 0 { + for iNdEx := len(m.DropOperations) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.DropOperations[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintPb(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *DropOperation) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DropOperation) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DropOperation) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.DropValue) > 0 { + i -= len(m.DropValue) + copy(dAtA[i:], m.DropValue) + i = encodeVarintPb(dAtA, i, uint64(len(m.DropValue))) + i-- + dAtA[i] = 0x12 + } + if m.DropOp != 0 { + i = encodeVarintPb(dAtA, i, uint64(m.DropOp)) + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + func (m *ExportRequest) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -12238,6 +12459,43 @@ func (m *BackupRequest) Size() (n int) { return n } +func (m *BackupResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.DropOperations) > 0 { + for _, e := range m.DropOperations { + l = e.Size() + n += 1 + l + sovPb(uint64(l)) + } + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *DropOperation) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.DropOp != 0 { + n += 1 + sovPb(uint64(m.DropOp)) + } + l = len(m.DropValue) + if l > 0 { + n += 1 + l + sovPb(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + func (m *ExportRequest) Size() (n int) { if m == nil { return 0 @@ -22702,6 +22960,199 @@ func (m *BackupRequest) Unmarshal(dAtA []byte) error { } return nil } +func (m *BackupResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: BackupResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: BackupResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DropOperations", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DropOperations = append(m.DropOperations, &DropOperation{}) + if err := m.DropOperations[len(m.DropOperations)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DropOperation) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DropOperation: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DropOperation: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field DropOp", wireType) + } + m.DropOp = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.DropOp |= DropOperation_DropOp(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field DropValue", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowPb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthPb + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthPb + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.DropValue = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipPb(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) < 0 { + return ErrInvalidLengthPb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *ExportRequest) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/schema/schema.go b/schema/schema.go index f0f2b65b7c4..0d13bf5c565 100644 --- a/schema/schema.go +++ b/schema/schema.go @@ -674,6 +674,9 @@ func initialSchemaInternal(all bool) []*pb.SchemaUpdate { Directive: pb.SchemaUpdate_INDEX, Tokenizer: []string{"exact"}, List: true, + }, &pb.SchemaUpdate{ + Predicate: "dgraph.drop.op", + ValueType: pb.Posting_STRING, }, &pb.SchemaUpdate{ Predicate: "dgraph.graphql.schema", ValueType: pb.Posting_STRING, @@ -743,7 +746,7 @@ func initialSchemaInternal(all bool) []*pb.SchemaUpdate { // IsPreDefPredChanged returns true if the initial update for the pre-defined // predicate is different than the passed update. -//If the passed update is not a pre-defined predicate then it just returns false. +// If the passed update is not a pre-defined predicate then it just returns false. func IsPreDefPredChanged(update *pb.SchemaUpdate) bool { // Return false for non-pre-defined predicates. if !x.IsPreDefinedPredicate(update.Predicate) { diff --git a/worker/backup_common.go b/worker/backup_common.go index ec3f3feeec5..916e2b31e15 100644 --- a/worker/backup_common.go +++ b/worker/backup_common.go @@ -60,6 +60,9 @@ type Manifest struct { Path string `json:"-"` // Encrypted indicates whether this backup was encrypted or not. Encrypted bool `json:"encrypted"` + // DropOperations lists the various DROP operations that took place since the last backup. + // These are used during restore to redo those operations before applying the backup. + DropOperations []*pb.DropOperation `json:"drop_operations"` } func (m *Manifest) getPredsInGroup(gid uint32) predicateSet { diff --git a/worker/backup_ee.go b/worker/backup_ee.go index e76f227578c..58596022378 100644 --- a/worker/backup_ee.go +++ b/worker/backup_ee.go @@ -29,12 +29,12 @@ import ( ) // Backup handles a request coming from another node. -func (w *grpcWorker) Backup(ctx context.Context, req *pb.BackupRequest) (*pb.Status, error) { +func (w *grpcWorker) Backup(ctx context.Context, req *pb.BackupRequest) (*pb.BackupResponse, error) { glog.V(2).Infof("Received backup request via Grpc: %+v", req) return backupCurrentGroup(ctx, req) } -func backupCurrentGroup(ctx context.Context, req *pb.BackupRequest) (*pb.Status, error) { +func backupCurrentGroup(ctx context.Context, req *pb.BackupRequest) (*pb.BackupResponse, error) { glog.Infof("Backup request: group %d at %d", req.GroupId, req.ReadTs) if err := ctx.Err(); err != nil { glog.Errorf("Context error during backup: %v\n", err) @@ -61,7 +61,7 @@ func backupCurrentGroup(ctx context.Context, req *pb.BackupRequest) (*pb.Status, } // BackupGroup backs up the group specified in the backup request. -func BackupGroup(ctx context.Context, in *pb.BackupRequest) (*pb.Status, error) { +func BackupGroup(ctx context.Context, in *pb.BackupRequest) (*pb.BackupResponse, error) { glog.V(2).Infof("Sending backup request: %+v\n", in) if groups().groupId() == in.GroupId { return backupCurrentGroup(ctx, in) @@ -171,12 +171,16 @@ func ProcessBackupRequest(ctx context.Context, req *pb.BackupRequest, forceFull defer cancel() errCh := make(chan error, len(state.Groups)) + var dropOperations []*pb.DropOperation for _, gid := range groups { br := proto.Clone(req).(*pb.BackupRequest) br.GroupId = gid br.Predicates = predMap[gid] go func(req *pb.BackupRequest) { - _, err := BackupGroup(ctx, req) + res, err := BackupGroup(ctx, req) + if res != nil && len(res.DropOperations) > 0 { + dropOperations = append(dropOperations, res.DropOperations...) + } errCh <- err }(br) } @@ -188,7 +192,7 @@ func ProcessBackupRequest(ctx context.Context, req *pb.BackupRequest, forceFull } } - m := Manifest{Since: req.ReadTs, Groups: predMap} + m := Manifest{Since: req.ReadTs, Groups: predMap, DropOperations: dropOperations} if req.SinceTs == 0 { m.Type = "full" m.BackupId = x.GetRandomName(1) diff --git a/worker/backup_processor.go b/worker/backup_processor.go index e8c0abaf7aa..e410e56a2fc 100644 --- a/worker/backup_processor.go +++ b/worker/backup_processor.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net/url" + "strings" "github.com/dgraph-io/badger/v2" bpb "github.com/dgraph-io/badger/v2/pb" @@ -88,8 +89,8 @@ type LoadResult struct { // retrieval to stream.Orchestrate. The writer will create all the fd's needed to // collect the data and later move to the target. // Returns errors on failure, nil on success. -func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.Status, error) { - var emptyRes pb.Status +func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.BackupResponse, error) { + var response pb.BackupResponse if err := ctx.Err(); err != nil { return nil, err @@ -97,16 +98,16 @@ func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.Status, error) uri, err := url.Parse(pr.Request.Destination) if err != nil { - return &emptyRes, err + return &response, err } handler, err := NewUriHandler(uri, GetCredentialsFromRequest(pr.Request)) if err != nil { - return &emptyRes, err + return &response, err } if err := handler.CreateBackupFile(uri, pr.Request); err != nil { - return &emptyRes, err + return &response, err } glog.V(3).Infof("Backup manifest version: %d", pr.Request.SinceTs) @@ -120,7 +121,7 @@ func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.Status, error) newhandler, err := enc.GetWriter(x.WorkerConfig.EncryptionKey, handler) if err != nil { - return &emptyRes, err + return &response, err } gzWriter := gzip.NewWriter(newhandler) @@ -131,7 +132,11 @@ func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.Status, error) stream.KeyToList = func(key []byte, itr *badger.Iterator) (*bpb.KVList, error) { tl := pr.threads[itr.ThreadId] tl.alloc = stream.Allocator(itr.ThreadId) - return tl.toBackupList(key, itr) + kvList, dropOp, err := tl.toBackupList(key, itr) + if dropOp != nil { + response.DropOperations = append(response.DropOperations, dropOp) + } + return kvList, err } stream.ChooseKey = func(item *badger.Item) bool { @@ -167,7 +172,7 @@ func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.Status, error) if err := stream.Orchestrate(context.Background()); err != nil { glog.Errorf("While taking backup: %v", err) - return &emptyRes, err + return &response, err } if maxVersion > pr.Request.ReadTs { @@ -178,15 +183,15 @@ func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.Status, error) glog.V(2).Infof("Backup group %d version: %d", pr.Request.GroupId, pr.Request.ReadTs) if err = gzWriter.Close(); err != nil { glog.Errorf("While closing gzipped writer: %v", err) - return &emptyRes, err + return &response, err } if err = handler.Close(); err != nil { glog.Errorf("While closing handler: %v", err) - return &emptyRes, err + return &response, err } glog.Infof("Backup complete: group %d at %d", pr.Request.GroupId, pr.Request.ReadTs) - return &emptyRes, nil + return &response, nil } // CompleteBackup will finalize a backup by writing the manifest at the backup destination. @@ -227,8 +232,9 @@ func (m *Manifest) GoString() string { } func (tl *threadLocal) toBackupList(key []byte, itr *badger.Iterator) ( - *bpb.KVList, error) { + *bpb.KVList, *pb.DropOperation, error) { list := &bpb.KVList{} + var dropOp *pb.DropOperation item := itr.Item() if item.UserMeta() != posting.BitSchemaPosting && @@ -237,26 +243,33 @@ func (tl *threadLocal) toBackupList(key []byte, itr *badger.Iterator) ( // the given key by returning an empty list. // Do not do this for schema and type keys. Those keys always have a // version of one so they would be incorrectly rejected by above check. - return list, nil + return list, nil, nil } switch item.UserMeta() { case posting.BitEmptyPosting, posting.BitCompletePosting, posting.BitDeltaPosting: l, err := posting.ReadPostingList(key, itr) if err != nil { - return nil, errors.Wrapf(err, "while reading posting list") + return nil, nil, errors.Wrapf(err, "while reading posting list") } // Don't allocate kv on tl.alloc, because we don't need it by the end of this func. kv, err := l.ToBackupPostingList(&tl.bpl, tl.alloc) if err != nil { - return nil, errors.Wrapf(err, "while rolling up list") + return nil, nil, errors.Wrapf(err, "while rolling up list") } backupKey, err := tl.toBackupKey(kv.Key) if err != nil { - return nil, err + return nil, nil, err } + + // check if this key was storing a DROP operation record. If yes, get the drop operation. + dropOp, err = checkAndGetDropOp(key, l, tl.Request.ReadTs) + if err != nil { + return nil, nil, err + } + kv.Key = backupKey list.Kv = append(list.Kv, kv) @@ -266,12 +279,12 @@ func (tl *threadLocal) toBackupList(key []byte, itr *badger.Iterator) ( kv.Value = tl.alloc.Copy(val) return nil }); err != nil { - return nil, errors.Wrapf(err, "while copying value") + return nil, nil, errors.Wrapf(err, "while copying value") } backupKey, err := tl.toBackupKey(key) if err != nil { - return nil, err + return nil, nil, err } kv.Key = backupKey @@ -281,10 +294,10 @@ func (tl *threadLocal) toBackupList(key []byte, itr *badger.Iterator) ( list.Kv = append(list.Kv, kv) default: - return nil, errors.Errorf( + return nil, nil, errors.Errorf( "Unexpected meta: %d for key: %s", item.UserMeta(), hex.Dump(key)) } - return list, nil + return list, dropOp, nil } func (tl *threadLocal) toBackupKey(key []byte) ([]byte, error) { @@ -310,3 +323,53 @@ func writeKVList(list *bpb.KVList, w io.Writer) error { _, err = w.Write(buf) return err } + +func checkAndGetDropOp(key []byte, l *posting.List, readTs uint64) (*pb.DropOperation, error) { + isDropOpKey, err := x.IsDropOpKey(key) + if err != nil || !isDropOpKey { + return nil, err + } + + vals, err := l.AllValues(readTs) + if err != nil { + return nil, errors.Wrapf(err, "cannot read value of dgraph.drop.op") + } + switch len(vals) { + case 0: + // do nothing, it means this one was deleted with S * * deletion. + // So, no need to consider it. + return nil, nil + case 1: + val, ok := vals[0].Value.([]byte) + if !ok { + return nil, errors.Errorf("cannot convert value of dgraph.drop.op to byte array") + } + // A dgraph.drop.op record can have values in only one of following formats: + // * DROP_ALL; + // * DROP_DATA; + // * DROP_TYPE;typeName + // * DROP_ATTR;attrName + // So, accordingly construct the *pb.DropOperation. + dropOp := &pb.DropOperation{} + dropInfo := strings.Split(string(val), ";") + if len(dropInfo) != 2 { + return nil, errors.Errorf("Unexpected value: %s for dgraph.drop.op", val) + } + switch dropInfo[0] { + case "DROP_ALL": + dropOp.DropOp = pb.DropOperation_ALL + case "DROP_DATA": + dropOp.DropOp = pb.DropOperation_DATA + case "DROP_TYPE": + dropOp.DropOp = pb.DropOperation_TYPE + dropOp.DropValue = dropInfo[1] + case "DROP_ATTR": + dropOp.DropOp = pb.DropOperation_ATTR + dropOp.DropValue = dropInfo[1] + } + return dropOp, nil + default: + // getting more than one values for a non-list predicate is an error + return nil, errors.Errorf("found multiple values for dgraph.drop.op") + } +} diff --git a/x/keys.go b/x/keys.go index ce0b066e344..460829a812c 100644 --- a/x/keys.go +++ b/x/keys.go @@ -18,6 +18,7 @@ package x import ( "encoding/binary" + "encoding/hex" "math" "strings" @@ -526,6 +527,18 @@ func Parse(key []byte) (ParsedKey, error) { return p, nil } +func IsDropOpKey(key []byte) (bool, error) { + pk, err := Parse(key) + if err != nil { + return false, errors.Wrapf(err, "could not parse key %s", hex.Dump(key)) + } + + if pk.IsData() && pk.Attr == "dgraph.drop.op" { + return true, nil + } + return false, nil +} + // These predicates appear for queries that have * as predicate in them. var starAllPredicateMap = map[string]struct{}{ "dgraph.type": {}, @@ -544,6 +557,7 @@ var graphqlReservedPredicate = map[string]struct{}{ "dgraph.graphql.xid": {}, "dgraph.graphql.schema": {}, "dgraph.cors": {}, + "dgraph.drop.op": {}, "dgraph.graphql.schema_history": {}, "dgraph.graphql.schema_created_at": {}, "dgraph.graphql.p_query": {}, @@ -552,7 +566,8 @@ var graphqlReservedPredicate = map[string]struct{}{ // internalPredicateMap stores a set of Dgraph's internal predicate. An internal // predicate is a predicate that has a special meaning in Dgraph and its query -// language and should not be allowed as a user-defined predicate. +// language and should not be allowed either as a user-defined predicate or as a +// predicate in initial internal schema. var internalPredicateMap = map[string]struct{}{ "uid": {}, } @@ -567,6 +582,8 @@ var preDefinedTypeMap = map[string]struct{}{ } // IsGraphqlReservedPredicate returns true if it is the predicate is reserved by graphql. +// These are a subset of PreDefined predicates, so follow all their properties. In addition, +// the value for these predicates is also not allowed to be mutated directly by the users. func IsGraphqlReservedPredicate(pred string) bool { _, ok := graphqlReservedPredicate[pred] return ok @@ -592,7 +609,9 @@ func IsReservedPredicate(pred string) bool { return isReservedName(pred) } -// IsPreDefinedPredicate returns true only if the predicate has been defined by dgraph internally. +// IsPreDefinedPredicate returns true only if the predicate has been defined by dgraph internally +// in the initial schema. These are not allowed to be dropped, as well as any schema update which +// is different than the initial internal schema is also not allowed for these. // For example, `dgraph.type` or ACL predicates or GraphQL predicates are defined in the initial // internal schema. // From 9e4fe72f07cd95ef83702641fef336a76707dcb7 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Wed, 4 Nov 2020 23:47:07 +0530 Subject: [PATCH 02/14] read and apply DROP operations during restore --- worker/backup.go | 2 +- worker/backup_handler.go | 3 ++- worker/file_handler.go | 4 ++-- worker/online_restore_ee.go | 6 +++--- worker/restore.go | 31 +++++++++++++++++++++++++++---- worker/s3_handler.go | 2 +- 6 files changed, 36 insertions(+), 12 deletions(-) diff --git a/worker/backup.go b/worker/backup.go index fa731882b53..82c1ac137b7 100644 --- a/worker/backup.go +++ b/worker/backup.go @@ -27,7 +27,7 @@ import ( ) // Backup implements the Worker interface. -func (w *grpcWorker) Backup(ctx context.Context, req *pb.BackupRequest) (*pb.Status, error) { +func (w *grpcWorker) Backup(ctx context.Context, req *pb.BackupRequest) (*pb.BackupResponse, error) { glog.Warningf("Backup failed: %v", x.ErrNotSupported) return nil, x.ErrNotSupported } diff --git a/worker/backup_handler.go b/worker/backup_handler.go index 492192a58f2..f387c79fe64 100644 --- a/worker/backup_handler.go +++ b/worker/backup_handler.go @@ -147,7 +147,8 @@ func NewUriHandler(uri *url.URL, creds *Credentials) (UriHandler, error) { // loadFn is a function that will receive the current file being read. // A reader, the backup groupId, and a map whose keys are the predicates to restore // are passed as arguments. -type loadFn func(reader io.Reader, groupId uint32, preds predicateSet) (uint64, error) +type loadFn func(reader io.Reader, groupId uint32, preds predicateSet, + dropOperations []*pb.DropOperation) (uint64, error) // LoadBackup will scan location l for backup files in the given backup series and load them // sequentially. Returns the maximum Since value on success, otherwise an error. diff --git a/worker/file_handler.go b/worker/file_handler.go index 0ed9b385de6..a0c7df75cb7 100644 --- a/worker/file_handler.go +++ b/worker/file_handler.go @@ -183,7 +183,7 @@ func (h *fileHandler) Load(uri *url.URL, backupId string, backupNum uint64, fn l // of the last backup. predSet := manifests[len(manifests)-1].getPredsInGroup(gid) - groupMaxUid, err := fn(fp, gid, predSet) + groupMaxUid, err := fn(fp, gid, predSet, manifest.DropOperations) if err != nil { return LoadResult{0, 0, err} } @@ -303,7 +303,7 @@ func (h *fileHandler) ExportBackup(backupDir, exportDir, format string, return 0, errors.Wrapf(err, "cannot open DB at %s", dir) } defer db.Close() - _, err = loadFromBackup(db, gzReader, 0, preds) + _, err = loadFromBackup(db, gzReader, 0, preds, nil) if err != nil { return 0, errors.Wrapf(err, "cannot load backup") } diff --git a/worker/online_restore_ee.go b/worker/online_restore_ee.go index b081dfd26e9..cf229a1a1b7 100644 --- a/worker/online_restore_ee.go +++ b/worker/online_restore_ee.go @@ -297,8 +297,8 @@ func getCredentialsFromRestoreRequest(req *pb.RestoreRequest) *Credentials { func writeBackup(ctx context.Context, req *pb.RestoreRequest) error { res := LoadBackup(req.Location, req.BackupId, req.BackupNum, - getCredentialsFromRestoreRequest(req), - func(r io.Reader, groupId uint32, preds predicateSet) (uint64, error) { + getCredentialsFromRestoreRequest(req), func(r io.Reader, groupId uint32, + preds predicateSet, dropOperations []*pb.DropOperation) (uint64, error) { if groupId != req.GroupId { // LoadBackup will try to call the backup function for every group. // Exit here if the group is not the one indicated by the request. @@ -322,7 +322,7 @@ func writeBackup(ctx context.Context, req *pb.RestoreRequest) error { return 0, errors.Wrapf(err, "couldn't create gzip reader") } - maxUid, err := loadFromBackup(pstore, gzReader, req.RestoreTs, preds) + maxUid, err := loadFromBackup(pstore, gzReader, req.RestoreTs, preds, dropOperations) if err != nil { return 0, errors.Wrapf(err, "cannot write backup") } diff --git a/worker/restore.go b/worker/restore.go index f31bad66e8d..ae4e7b12f8a 100644 --- a/worker/restore.go +++ b/worker/restore.go @@ -44,7 +44,8 @@ func RunRestore(pdir, location, backupId string, key x.SensitiveByteSlice) LoadR // Scan location for backup files and load them. Each file represents a node group, // and we create a new p dir for each. return LoadBackup(location, backupId, 0, nil, - func(r io.Reader, groupId uint32, preds predicateSet) (uint64, error) { + func(r io.Reader, groupId uint32, preds predicateSet, + dropOperations []*pb.DropOperation) (uint64, error) { dir := filepath.Join(pdir, fmt.Sprintf("p%d", groupId)) r, err := enc.GetReader(key, r) @@ -76,7 +77,7 @@ func RunRestore(pdir, location, backupId string, key x.SensitiveByteSlice) LoadR if !pathExist(dir) { fmt.Println("Creating new db:", dir) } - maxUid, err := loadFromBackup(db, gzReader, 0, preds) + maxUid, err := loadFromBackup(db, gzReader, 0, preds, dropOperations) if err != nil { return 0, err } @@ -90,11 +91,17 @@ func RunRestore(pdir, location, backupId string, key x.SensitiveByteSlice) LoadR // If restoreTs is greater than zero, the key-value pairs will be written with that timestamp. // Otherwise, the original value is used. // TODO(DGRAPH-1234): Check whether restoreTs can be removed. -func loadFromBackup(db *badger.DB, r io.Reader, restoreTs uint64, preds predicateSet) ( - uint64, error) { +func loadFromBackup(db *badger.DB, r io.Reader, restoreTs uint64, preds predicateSet, + dropOperations []*pb.DropOperation) (uint64, error) { br := bufio.NewReaderSize(r, 16<<10) unmarshalBuf := make([]byte, 1<<10) + // if there were any DROP operations that need to be applied before loading the backup into + // the db, then apply them here + if err := applyDropOperationsBeforeRestore(db, dropOperations); err != nil { + return 0, errors.Wrapf(err, "cannot apply DROP operations while loading backup") + } + // Delete schemas and types. Each backup file should have a complete copy of the schema. if err := db.DropPrefix([]byte{x.ByteSchema}); err != nil { return 0, err @@ -221,6 +228,22 @@ func loadFromBackup(db *badger.DB, r io.Reader, restoreTs uint64, preds predicat return maxUid, nil } +func applyDropOperationsBeforeRestore(db *badger.DB, dropOperations []*pb.DropOperation) error { + for _, operation := range dropOperations { + switch operation.DropOp { + case pb.DropOperation_ALL: + return db.DropAll() + case pb.DropOperation_DATA: + return db.DropPrefix([]byte{x.DefaultPrefix}) + case pb.DropOperation_TYPE: + // TODO: check if there is anything to be done here + case pb.DropOperation_ATTR: + return db.DropPrefix(x.PredicatePrefix(operation.DropValue)) + } + } + return nil +} + func fromBackupKey(key []byte) ([]byte, error) { backupKey := &pb.BackupKey{} if err := backupKey.Unmarshal(key); err != nil { diff --git a/worker/s3_handler.go b/worker/s3_handler.go index ce56990e976..d50a29792bc 100644 --- a/worker/s3_handler.go +++ b/worker/s3_handler.go @@ -251,7 +251,7 @@ func (h *s3Handler) Load(uri *url.URL, backupId string, backupNum uint64, fn loa // of the last backup. predSet := manifests[len(manifests)-1].getPredsInGroup(gid) - groupMaxUid, err := fn(reader, gid, predSet) + groupMaxUid, err := fn(reader, gid, predSet, manifest.DropOperations) if err != nil { return LoadResult{0, 0, err} } From 488010fda89ae6b1a26000bcd6d59e05838ef99a Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Thu, 5 Nov 2020 00:04:05 +0530 Subject: [PATCH 03/14] cleanup --- edgraph/server.go | 10 +- protos/pb.proto | 3 +- protos/pb/pb.pb.go | 605 ++++++++++++++++++------------------- worker/backup_processor.go | 4 - worker/restore.go | 2 - 5 files changed, 304 insertions(+), 320 deletions(-) diff --git a/edgraph/server.go b/edgraph/server.go index 0c9907eaaf2..5fe7115d33f 100644 --- a/edgraph/server.go +++ b/edgraph/server.go @@ -289,14 +289,14 @@ func parseSchemaFromAlterOperation(op *api.Operation) (*schema.ParsedSchema, err return result, nil } -func insertDropRecord(ctx context.Context, restoreOp string) error { +func insertDropRecord(ctx context.Context, dropOp string) error { _, err := (&Server{}).Query(context.WithValue(ctx, IsGraphql, true), &api.Request{ Mutations: []*api.Mutation{{ Set: []*api.NQuad{{ Subject: "_:r", Predicate: "dgraph.drop.op", - ObjectValue: &api.Value{Val: &api.Value_StrVal{StrVal: restoreOp}}, + ObjectValue: &api.Value{Val: &api.Value_StrVal{StrVal: dropOp}}, }}, }}, CommitNow: true, @@ -436,12 +436,6 @@ func (s *Server) Alter(ctx context.Context, op *api.Operation) (*api.Payload, er m.DropOp = pb.Mutations_TYPE m.DropValue = op.DropValue _, err := query.ApplyMutations(ctx, m) - if err != nil { - return empty, err - } - - // insert a helper record for backup & restore, indicating that drop_attr was done - err = insertDropRecord(ctx, "DROP_TYPE;"+op.DropValue) return empty, err } diff --git a/protos/pb.proto b/protos/pb.proto index 5129a125043..469b38d6eec 100644 --- a/protos/pb.proto +++ b/protos/pb.proto @@ -607,8 +607,7 @@ message DropOperation { enum DropOp { ALL = 0; DATA = 1; - TYPE = 2; - ATTR = 3; + ATTR = 2; } DropOp drop_op = 1; string drop_value = 2; diff --git a/protos/pb/pb.pb.go b/protos/pb/pb.pb.go index 92a2c2d337f..53289ab677a 100644 --- a/protos/pb/pb.pb.go +++ b/protos/pb/pb.pb.go @@ -235,22 +235,19 @@ type DropOperation_DropOp int32 const ( DropOperation_ALL DropOperation_DropOp = 0 DropOperation_DATA DropOperation_DropOp = 1 - DropOperation_TYPE DropOperation_DropOp = 2 - DropOperation_ATTR DropOperation_DropOp = 3 + DropOperation_ATTR DropOperation_DropOp = 2 ) var DropOperation_DropOp_name = map[int32]string{ 0: "ALL", 1: "DATA", - 2: "TYPE", - 3: "ATTR", + 2: "ATTR", } var DropOperation_DropOp_value = map[string]int32{ "ALL": 0, "DATA": 1, - "TYPE": 2, - "ATTR": 3, + "ATTR": 2, } func (x DropOperation_DropOp) String() string { @@ -5123,305 +5120,305 @@ func init() { func init() { proto.RegisterFile("pb.proto", fileDescriptor_f80abaa17e25ccc8) } var fileDescriptor_f80abaa17e25ccc8 = []byte{ - // 4759 bytes of a gzipped FileDescriptorProto + // 4758 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xd4, 0x7a, 0xcd, 0x6f, 0x1c, 0x57, - 0x72, 0xb8, 0xe6, 0x7b, 0xba, 0xe6, 0x43, 0xa3, 0x27, 0xad, 0x3c, 0x3b, 0xb2, 0x45, 0xba, 0x6d, - 0xad, 0xb9, 0x96, 0x45, 0x49, 0xf4, 0xfe, 0xf0, 0x5b, 0x7b, 0x11, 0x20, 0xa4, 0x38, 0x94, 0xb9, - 0xa2, 0x48, 0xba, 0x39, 0x94, 0x77, 0x7d, 0xc8, 0xa0, 0xd9, 0xfd, 0x48, 0xf6, 0xb2, 0xa7, 0xbb, - 0xb7, 0xbb, 0x87, 0x3b, 0xf4, 0x29, 0x41, 0x80, 0x9c, 0x92, 0x4b, 0x82, 0x20, 0x7b, 0x4a, 0x82, - 0xfc, 0x03, 0x41, 0x72, 0x0a, 0x72, 0x0e, 0x82, 0x20, 0x87, 0x20, 0x7f, 0x81, 0x12, 0x38, 0x39, - 0x09, 0xc8, 0x29, 0x40, 0x80, 0x5c, 0x82, 0xa0, 0xaa, 0x5e, 0x7f, 0x0d, 0x87, 0x92, 0xbd, 0xc0, - 0x1e, 0x72, 0xea, 0x57, 0x55, 0xef, 0xb3, 0x5e, 0x7d, 0xbf, 0x86, 0x66, 0x70, 0xb4, 0x1a, 0x84, - 0x7e, 0xec, 0x8b, 0x72, 0x70, 0x34, 0xd0, 0xcc, 0xc0, 0x61, 0x70, 0xf0, 0xe1, 0x89, 0x13, 0x9f, - 0x4e, 0x8f, 0x56, 0x2d, 0x7f, 0xf2, 0xd0, 0x3e, 0x09, 0xcd, 0xe0, 0xf4, 0x81, 0xe3, 0x3f, 0x3c, - 0x32, 0xed, 0x13, 0x19, 0x3e, 0x3c, 0x5f, 0x7b, 0x18, 0x1c, 0x3d, 0x4c, 0x86, 0x0e, 0x1e, 0xe4, - 0xfa, 0x9e, 0xf8, 0x27, 0xfe, 0x43, 0x42, 0x1f, 0x4d, 0x8f, 0x09, 0x22, 0x80, 0x5a, 0xdc, 0x5d, - 0x1f, 0x40, 0x75, 0xc7, 0x89, 0x62, 0x21, 0xa0, 0x3a, 0x75, 0xec, 0xa8, 0x5f, 0x5a, 0xae, 0xac, - 0xd4, 0x0d, 0x6a, 0xeb, 0xcf, 0x41, 0x1b, 0x99, 0xd1, 0xd9, 0x0b, 0xd3, 0x9d, 0x4a, 0xd1, 0x83, - 0xca, 0xb9, 0xe9, 0xf6, 0x4b, 0xcb, 0xa5, 0x95, 0xb6, 0x81, 0x4d, 0xb1, 0x0a, 0xcd, 0x73, 0xd3, - 0x1d, 0xc7, 0x17, 0x81, 0xec, 0x97, 0x97, 0x4b, 0x2b, 0xdd, 0xb5, 0x9b, 0xab, 0xc1, 0xd1, 0xea, - 0xbe, 0x1f, 0xc5, 0x8e, 0x77, 0xb2, 0xfa, 0xc2, 0x74, 0x47, 0x17, 0x81, 0x34, 0x1a, 0xe7, 0xdc, - 0xd0, 0xf7, 0xa0, 0x75, 0x10, 0x5a, 0x5b, 0x53, 0xcf, 0x8a, 0x1d, 0xdf, 0xc3, 0x15, 0x3d, 0x73, - 0x22, 0x69, 0x46, 0xcd, 0xa0, 0x36, 0xe2, 0xcc, 0xf0, 0x24, 0xea, 0x57, 0x96, 0x2b, 0x88, 0xc3, - 0xb6, 0xe8, 0x43, 0xc3, 0x89, 0x9e, 0xf8, 0x53, 0x2f, 0xee, 0x57, 0x97, 0x4b, 0x2b, 0x4d, 0x23, - 0x01, 0xf5, 0x3f, 0xab, 0x40, 0xed, 0xf3, 0xa9, 0x0c, 0x2f, 0x68, 0x5c, 0x1c, 0x87, 0xc9, 0x5c, - 0xd8, 0x16, 0xb7, 0xa0, 0xe6, 0x9a, 0xde, 0x49, 0xd4, 0x2f, 0xd3, 0x64, 0x0c, 0x88, 0x3b, 0xa0, - 0x99, 0xc7, 0xb1, 0x0c, 0xc7, 0x53, 0xc7, 0xee, 0x57, 0x96, 0x4b, 0x2b, 0x75, 0xa3, 0x49, 0x88, - 0x43, 0xc7, 0x16, 0xdf, 0x85, 0xa6, 0xed, 0x8f, 0xad, 0xfc, 0x5a, 0xb6, 0x4f, 0x6b, 0x89, 0xf7, - 0xa0, 0x39, 0x75, 0xec, 0xb1, 0xeb, 0x44, 0x71, 0xbf, 0xb6, 0x5c, 0x5a, 0x69, 0xad, 0x35, 0xf1, - 0xb0, 0xc8, 0x3b, 0xa3, 0x31, 0x75, 0x6c, 0x62, 0xe2, 0x87, 0xd0, 0x8c, 0x42, 0x6b, 0x7c, 0x3c, - 0xf5, 0xac, 0x7e, 0x9d, 0x3a, 0x5d, 0xc7, 0x4e, 0xb9, 0x53, 0x1b, 0x8d, 0x88, 0x01, 0x3c, 0x56, - 0x28, 0xcf, 0x65, 0x18, 0xc9, 0x7e, 0x83, 0x97, 0x52, 0xa0, 0x78, 0x04, 0xad, 0x63, 0xd3, 0x92, - 0xf1, 0x38, 0x30, 0x43, 0x73, 0xd2, 0x6f, 0x66, 0x13, 0x6d, 0x21, 0x7a, 0x1f, 0xb1, 0x91, 0x01, - 0xc7, 0x29, 0x20, 0x3e, 0x86, 0x0e, 0x41, 0xd1, 0xf8, 0xd8, 0x71, 0x63, 0x19, 0xf6, 0x35, 0x1a, - 0xd3, 0xa5, 0x31, 0x84, 0x19, 0x85, 0x52, 0x1a, 0x6d, 0xee, 0xc4, 0x18, 0xf1, 0x0e, 0x80, 0x9c, - 0x05, 0xa6, 0x67, 0x8f, 0x4d, 0xd7, 0xed, 0x03, 0xed, 0x41, 0x63, 0xcc, 0xba, 0xeb, 0x8a, 0xb7, - 0x70, 0x7f, 0xa6, 0x3d, 0x8e, 0xa3, 0x7e, 0x67, 0xb9, 0xb4, 0x52, 0x35, 0xea, 0x08, 0x8e, 0x22, - 0xe4, 0xab, 0x65, 0x5a, 0xa7, 0xb2, 0xdf, 0x5d, 0x2e, 0xad, 0xd4, 0x0c, 0x06, 0x10, 0x7b, 0xec, - 0x84, 0x51, 0xdc, 0xbf, 0xce, 0x58, 0x02, 0xf4, 0x35, 0xd0, 0x48, 0x7a, 0x88, 0x3b, 0xf7, 0xa0, - 0x7e, 0x8e, 0x00, 0x0b, 0x59, 0x6b, 0xad, 0x83, 0xdb, 0x4b, 0x05, 0xcc, 0x50, 0x44, 0xfd, 0x2e, - 0x34, 0x77, 0x4c, 0xef, 0x24, 0x91, 0x4a, 0xbc, 0x36, 0x1a, 0xa0, 0x19, 0xd4, 0xd6, 0x7f, 0x59, - 0x86, 0xba, 0x21, 0xa3, 0xa9, 0x1b, 0x8b, 0x0f, 0x00, 0xf0, 0x52, 0x26, 0x66, 0x1c, 0x3a, 0x33, - 0x35, 0x6b, 0x76, 0x2d, 0xda, 0xd4, 0xb1, 0x9f, 0x13, 0x49, 0x3c, 0x82, 0x36, 0xcd, 0x9e, 0x74, - 0x2d, 0x67, 0x1b, 0x48, 0xf7, 0x67, 0xb4, 0xa8, 0x8b, 0x1a, 0x71, 0x1b, 0xea, 0x24, 0x07, 0x2c, - 0x8b, 0x1d, 0x43, 0x41, 0xe2, 0x1e, 0x74, 0x1d, 0x2f, 0xc6, 0x7b, 0xb2, 0xe2, 0xb1, 0x2d, 0xa3, - 0x44, 0x50, 0x3a, 0x29, 0x76, 0x53, 0x46, 0xb1, 0x78, 0x0c, 0xcc, 0xec, 0x64, 0xc1, 0x1a, 0x2d, - 0xd8, 0x4d, 0x2f, 0x31, 0xe2, 0x15, 0xa9, 0x8f, 0x5a, 0xf1, 0x01, 0xb4, 0xf0, 0x7c, 0xc9, 0x88, - 0x3a, 0x8d, 0x68, 0xd3, 0x69, 0x14, 0x3b, 0x0c, 0xc0, 0x0e, 0xaa, 0x3b, 0xb2, 0x06, 0x85, 0x91, - 0x85, 0x87, 0xda, 0xfa, 0x10, 0x6a, 0x7b, 0xa1, 0x2d, 0xc3, 0x85, 0xfa, 0x20, 0xa0, 0x6a, 0xcb, - 0xc8, 0x22, 0x55, 0x6d, 0x1a, 0xd4, 0xce, 0x74, 0xa4, 0x92, 0xd3, 0x11, 0xfd, 0x4f, 0x4b, 0xd0, - 0x3a, 0xf0, 0xc3, 0xf8, 0xb9, 0x8c, 0x22, 0xf3, 0x44, 0x8a, 0x25, 0xa8, 0xf9, 0x38, 0xad, 0xe2, - 0xb0, 0x86, 0x7b, 0xa2, 0x75, 0x0c, 0xc6, 0xcf, 0xdd, 0x43, 0xf9, 0xea, 0x7b, 0x40, 0xd9, 0x21, - 0xed, 0xaa, 0x28, 0xd9, 0x21, 0xdd, 0xba, 0x0d, 0x75, 0xff, 0xf8, 0x38, 0x92, 0xcc, 0xcb, 0x9a, - 0xa1, 0xa0, 0x2b, 0x45, 0x50, 0xff, 0x7f, 0x00, 0xb8, 0xbf, 0x6f, 0x29, 0x05, 0xfa, 0x29, 0xb4, - 0x0c, 0xf3, 0x38, 0x7e, 0xe2, 0x7b, 0xb1, 0x9c, 0xc5, 0xa2, 0x0b, 0x65, 0xc7, 0x26, 0x16, 0xd5, - 0x8d, 0xb2, 0x63, 0xe3, 0xe6, 0x4e, 0x42, 0x7f, 0x1a, 0x10, 0x87, 0x3a, 0x06, 0x03, 0xc4, 0x4a, - 0xdb, 0x0e, 0x69, 0xc7, 0xc8, 0x4a, 0xdb, 0x0e, 0xc5, 0x12, 0xb4, 0x22, 0xcf, 0x0c, 0xa2, 0x53, - 0x3f, 0xc6, 0xcd, 0x55, 0x69, 0x73, 0x90, 0xa0, 0x46, 0x91, 0xfe, 0x1f, 0x65, 0xa8, 0x3f, 0x97, - 0x93, 0x23, 0x19, 0x5e, 0x5a, 0xe5, 0x11, 0x34, 0x69, 0xe2, 0xb1, 0x63, 0xf3, 0x42, 0x1b, 0xdf, - 0x79, 0xf5, 0x72, 0xe9, 0x06, 0xe1, 0xb6, 0xed, 0x8f, 0xfc, 0x89, 0x13, 0xcb, 0x49, 0x10, 0x5f, - 0x18, 0x0d, 0x85, 0x5a, 0xb8, 0x83, 0xdb, 0x50, 0x77, 0xa5, 0x89, 0x77, 0xc2, 0xe2, 0xa7, 0x20, - 0xf1, 0x00, 0x1a, 0xe6, 0x64, 0x6c, 0x4b, 0xd3, 0x26, 0x2b, 0xd5, 0xdc, 0xb8, 0xf5, 0xea, 0xe5, - 0x52, 0xcf, 0x9c, 0x6c, 0x4a, 0x33, 0x3f, 0x77, 0x9d, 0x31, 0xe2, 0x13, 0x94, 0xb9, 0x28, 0x1e, - 0x4f, 0x03, 0xdb, 0x8c, 0x25, 0xd9, 0xac, 0xea, 0x46, 0xff, 0xd5, 0xcb, 0xa5, 0x5b, 0x88, 0x3e, - 0x24, 0x6c, 0x6e, 0x18, 0x64, 0x58, 0xb1, 0x0d, 0x37, 0x2c, 0x77, 0x1a, 0xa1, 0x29, 0x75, 0xbc, - 0x63, 0x7f, 0xec, 0x7b, 0xee, 0x05, 0x5d, 0x53, 0x73, 0xe3, 0x9d, 0x57, 0x2f, 0x97, 0xbe, 0xab, - 0x88, 0xdb, 0xde, 0xb1, 0xbf, 0xe7, 0xb9, 0x17, 0xb9, 0x59, 0xae, 0xcf, 0x91, 0xc4, 0x6f, 0x42, - 0xf7, 0xd8, 0x0f, 0x2d, 0x39, 0x4e, 0x19, 0xd3, 0xa5, 0x79, 0x06, 0xaf, 0x5e, 0x2e, 0xdd, 0x26, - 0xca, 0xd3, 0x4b, 0xdc, 0x69, 0xe7, 0xf1, 0xfa, 0xdf, 0x94, 0xa1, 0x46, 0x6d, 0xf1, 0x08, 0x1a, - 0x13, 0x62, 0x7c, 0x62, 0x65, 0x6e, 0xa3, 0x24, 0x10, 0x6d, 0x95, 0x6f, 0x24, 0x1a, 0x7a, 0x71, - 0x78, 0x61, 0x24, 0xdd, 0x70, 0x44, 0x6c, 0x1e, 0xb9, 0x32, 0x8e, 0x94, 0xe4, 0xe6, 0x46, 0x8c, - 0x98, 0xa0, 0x46, 0xa8, 0x6e, 0xf3, 0xd7, 0x5f, 0x99, 0xbf, 0x7e, 0x31, 0x80, 0xa6, 0x75, 0x2a, - 0xad, 0xb3, 0x68, 0x3a, 0x51, 0xc2, 0x91, 0xc2, 0x83, 0x2d, 0x68, 0xe7, 0xf7, 0x81, 0x7e, 0xf5, - 0x4c, 0x5e, 0x90, 0x80, 0x54, 0x0d, 0x6c, 0x8a, 0x65, 0xa8, 0x91, 0x25, 0x22, 0xf1, 0x68, 0xad, - 0x01, 0x6e, 0x87, 0x87, 0x18, 0x4c, 0xf8, 0xb4, 0xfc, 0xc3, 0x12, 0xce, 0x93, 0xdf, 0x5d, 0x7e, - 0x1e, 0xed, 0xea, 0x79, 0x78, 0x48, 0x6e, 0x1e, 0xdd, 0x87, 0xc6, 0x8e, 0x63, 0x49, 0x2f, 0x22, - 0xef, 0x3b, 0x8d, 0x64, 0x6a, 0x35, 0xb0, 0x8d, 0x47, 0x99, 0x98, 0xb3, 0x5d, 0xdf, 0x96, 0x11, - 0xcd, 0x53, 0x35, 0x52, 0x18, 0x69, 0x72, 0x16, 0x38, 0xe1, 0xc5, 0x88, 0x99, 0x50, 0x31, 0x52, - 0x18, 0xdd, 0x9b, 0xf4, 0x70, 0x31, 0x3b, 0xf1, 0xa4, 0x0a, 0xd4, 0xff, 0xbc, 0x02, 0xed, 0x2f, - 0x65, 0xe8, 0xef, 0x87, 0x7e, 0xe0, 0x47, 0xa6, 0x2b, 0xd6, 0x8b, 0xec, 0xe4, 0x6b, 0x5b, 0xc6, - 0xdd, 0xe6, 0xbb, 0xad, 0x1e, 0xa4, 0xfc, 0xe5, 0xeb, 0xc8, 0x33, 0x5c, 0x87, 0x3a, 0x5f, 0xe7, - 0x02, 0x9e, 0x29, 0x0a, 0xf6, 0xe1, 0x0b, 0xa4, 0xbd, 0x16, 0xf9, 0xa1, 0x28, 0xe2, 0x2e, 0xc0, - 0xc4, 0x9c, 0xed, 0x48, 0x33, 0x92, 0xdb, 0x76, 0xa2, 0xd7, 0x19, 0x46, 0x71, 0x63, 0x34, 0xf3, - 0x46, 0x11, 0xe9, 0x17, 0x73, 0x83, 0x60, 0xf1, 0x36, 0x68, 0x13, 0x73, 0x86, 0x06, 0x66, 0xdb, - 0x66, 0x4d, 0x32, 0x32, 0x84, 0x78, 0x17, 0x2a, 0xf1, 0xcc, 0x23, 0x6b, 0x8d, 0xce, 0x1c, 0x63, - 0xbb, 0xd1, 0xcc, 0x53, 0xa6, 0xc8, 0x40, 0x5a, 0x72, 0x83, 0xcd, 0xec, 0x06, 0x7b, 0x50, 0xb1, - 0x1c, 0x9b, 0xbc, 0xb9, 0x66, 0x60, 0x53, 0xdc, 0x83, 0x86, 0xcb, 0xb7, 0x45, 0x1e, 0xbb, 0xb5, - 0xd6, 0x62, 0x43, 0x47, 0x28, 0x23, 0xa1, 0x0d, 0x7e, 0x03, 0xae, 0xcf, 0xb1, 0x2b, 0x2f, 0x1f, - 0x1d, 0x9e, 0xfd, 0x56, 0x5e, 0x3e, 0xaa, 0x79, 0x99, 0xf8, 0x97, 0x0a, 0x5c, 0x57, 0x42, 0x7a, - 0xea, 0x04, 0x07, 0x31, 0xea, 0x7b, 0x1f, 0x1a, 0x64, 0xad, 0x95, 0x7c, 0x54, 0x8d, 0x04, 0x14, - 0xff, 0x1f, 0xea, 0xa4, 0xb8, 0x89, 0xfe, 0x2c, 0x65, 0xcc, 0x4f, 0x87, 0xb3, 0x3e, 0xa9, 0x9b, - 0x53, 0xdd, 0xc5, 0x0f, 0xa0, 0xf6, 0x95, 0x0c, 0x7d, 0xf6, 0x3e, 0xad, 0xb5, 0xbb, 0x8b, 0xc6, - 0xa1, 0x08, 0xa8, 0x61, 0xdc, 0xf9, 0xd7, 0x78, 0x47, 0xef, 0xa3, 0xbf, 0x99, 0xf8, 0xe7, 0xd2, - 0xee, 0x37, 0x68, 0x47, 0x79, 0x31, 0x4a, 0x48, 0xc9, 0xa5, 0x34, 0x17, 0x5e, 0x8a, 0xf6, 0x9a, - 0x4b, 0xd9, 0x84, 0x56, 0x8e, 0x0b, 0x0b, 0x2e, 0x64, 0xa9, 0xa8, 0xb0, 0x5a, 0x6a, 0x87, 0xf2, - 0x7a, 0xbf, 0x09, 0x90, 0xf1, 0xe4, 0x57, 0xb5, 0x1e, 0xfa, 0xef, 0x94, 0xe0, 0xfa, 0x13, 0xdf, - 0xf3, 0x24, 0x45, 0xa5, 0x7c, 0xc3, 0x99, 0x12, 0x95, 0xae, 0x54, 0xa2, 0xef, 0x43, 0x2d, 0xc2, - 0xce, 0x6a, 0xf6, 0x9b, 0x0b, 0xae, 0xcc, 0xe0, 0x1e, 0x68, 0x25, 0x27, 0xe6, 0x6c, 0x1c, 0x48, - 0xcf, 0x76, 0xbc, 0x93, 0xc4, 0x4a, 0x4e, 0xcc, 0xd9, 0x3e, 0x63, 0xf4, 0x3f, 0x2e, 0x03, 0x7c, - 0x26, 0x4d, 0x37, 0x3e, 0x45, 0x4f, 0x80, 0xf7, 0xe6, 0x78, 0x51, 0x6c, 0x7a, 0x56, 0x92, 0x13, - 0xa4, 0x30, 0x0a, 0x1f, 0xba, 0x3d, 0x19, 0xb1, 0x11, 0xd2, 0x8c, 0x04, 0x44, 0x47, 0x88, 0xcb, - 0x4d, 0x23, 0xe5, 0x1e, 0x15, 0x94, 0x39, 0xf3, 0x2a, 0xa1, 0x95, 0x33, 0xef, 0x43, 0x03, 0x63, - 0x6c, 0xc7, 0xf7, 0x48, 0x34, 0x34, 0x23, 0x01, 0x71, 0x9e, 0x69, 0x10, 0x3b, 0x13, 0x76, 0x82, - 0x15, 0x43, 0x41, 0xb8, 0x2b, 0x74, 0x7a, 0x43, 0xeb, 0xd4, 0x27, 0xe5, 0xad, 0x18, 0x29, 0x8c, - 0xb3, 0xf9, 0xde, 0x89, 0x8f, 0xa7, 0x6b, 0x52, 0xfc, 0x94, 0x80, 0x7c, 0x16, 0x5b, 0xce, 0x90, - 0xa4, 0x11, 0x29, 0x85, 0x91, 0x2f, 0x52, 0x8e, 0x8f, 0xa5, 0x19, 0x4f, 0x43, 0x19, 0xf5, 0x81, - 0xc8, 0x20, 0xe5, 0x96, 0xc2, 0xe8, 0xbf, 0x5d, 0x86, 0x3a, 0xdb, 0xa5, 0x42, 0xb0, 0x50, 0xfa, - 0x46, 0xc1, 0xc2, 0xdb, 0xa0, 0x05, 0xa1, 0xb4, 0x1d, 0x2b, 0xb9, 0x24, 0xcd, 0xc8, 0x10, 0x14, - 0xa5, 0xa3, 0xdf, 0x24, 0x66, 0x35, 0x0d, 0x06, 0x10, 0x1b, 0x05, 0xa6, 0x25, 0xd5, 0x01, 0x19, - 0x40, 0x8e, 0xb0, 0xc8, 0x93, 0xa8, 0x37, 0x0d, 0x05, 0x89, 0x8f, 0x41, 0xa3, 0xa8, 0x8c, 0x1c, - 0xbe, 0x46, 0x8e, 0xfa, 0xf6, 0xab, 0x97, 0x4b, 0x02, 0x91, 0x73, 0x9e, 0xbe, 0x99, 0xe0, 0x30, - 0x2e, 0xc1, 0xc1, 0x68, 0xdf, 0x81, 0x82, 0x0c, 0x8a, 0x4b, 0x10, 0x35, 0x8a, 0xf2, 0x71, 0x09, - 0x63, 0xf4, 0x7f, 0x2a, 0x43, 0x7b, 0xd3, 0x09, 0xa5, 0x15, 0x4b, 0x7b, 0x68, 0x9f, 0xd0, 0x66, - 0xa4, 0x17, 0x3b, 0xf1, 0x85, 0x8a, 0xa4, 0x14, 0x94, 0x06, 0xba, 0xe5, 0x62, 0xe2, 0xc7, 0x1a, - 0x50, 0xa1, 0x5c, 0x95, 0x01, 0xb1, 0x06, 0xc0, 0x29, 0x00, 0xe5, 0xab, 0xd5, 0xab, 0xf3, 0x55, - 0x8d, 0xba, 0x61, 0x13, 0xf3, 0x41, 0x1e, 0xe3, 0x70, 0x38, 0x55, 0xa7, 0x64, 0x76, 0x8a, 0x56, - 0x86, 0x22, 0xe7, 0x23, 0xe9, 0x92, 0xb8, 0x50, 0xe4, 0x7c, 0x24, 0xdd, 0x34, 0x5f, 0x69, 0xf0, - 0x76, 0xb0, 0x2d, 0xde, 0x83, 0xb2, 0x1f, 0x10, 0x0f, 0xd5, 0x82, 0xf9, 0x83, 0xad, 0xee, 0x05, - 0x46, 0xd9, 0x0f, 0x50, 0xf7, 0x38, 0x39, 0x23, 0x71, 0x41, 0xdd, 0x43, 0x0f, 0x41, 0xa9, 0x82, - 0xa1, 0x28, 0x42, 0x87, 0xb6, 0xe9, 0xba, 0xfe, 0x2f, 0xa4, 0xbd, 0x1f, 0x4a, 0x3b, 0x91, 0x9c, - 0x02, 0x4e, 0xbf, 0x0d, 0xe5, 0xbd, 0x40, 0x34, 0xa0, 0x72, 0x30, 0x1c, 0xf5, 0xae, 0x61, 0x63, - 0x73, 0xb8, 0xd3, 0x2b, 0xe9, 0x5f, 0x97, 0x41, 0x7b, 0x3e, 0x8d, 0x4d, 0xd4, 0xf6, 0x08, 0xcf, - 0x55, 0x14, 0xab, 0x4c, 0x7e, 0xbe, 0x0b, 0xcd, 0x28, 0x36, 0x43, 0xf2, 0xc4, 0xec, 0x17, 0x1a, - 0x04, 0x8f, 0x22, 0xf1, 0x3d, 0xa8, 0x49, 0xfb, 0x44, 0x26, 0xe6, 0xba, 0x37, 0x7f, 0x16, 0x83, - 0xc9, 0x62, 0x05, 0xea, 0x91, 0x75, 0x2a, 0x27, 0x66, 0xbf, 0x9a, 0x75, 0x3c, 0x20, 0x0c, 0xc7, - 0x8e, 0x86, 0xa2, 0x8b, 0xf7, 0xa1, 0x86, 0xb7, 0x11, 0xa9, 0x64, 0x87, 0xd2, 0x23, 0x64, 0xbc, - 0xea, 0xc6, 0x44, 0x94, 0x1d, 0x3b, 0xf4, 0x83, 0xb1, 0x1f, 0x10, 0x5f, 0xbb, 0x6b, 0xb7, 0xc8, - 0xea, 0x24, 0xa7, 0x59, 0xdd, 0x0c, 0xfd, 0x60, 0x2f, 0x30, 0xea, 0x36, 0x7d, 0x31, 0xaf, 0xa5, - 0xee, 0x2c, 0x03, 0x6c, 0xa6, 0x35, 0xc4, 0x70, 0x1d, 0x63, 0x05, 0x9a, 0x13, 0x19, 0x9b, 0xb6, - 0x19, 0x9b, 0xca, 0x5a, 0xb7, 0xd9, 0x88, 0x31, 0xce, 0x48, 0xa9, 0xfa, 0x43, 0xa8, 0xf3, 0xd4, - 0xa2, 0x09, 0xd5, 0xdd, 0xbd, 0xdd, 0x21, 0x33, 0x74, 0x7d, 0x67, 0xa7, 0x57, 0x42, 0xd4, 0xe6, - 0xfa, 0x68, 0xbd, 0x57, 0xc6, 0xd6, 0xe8, 0xa7, 0xfb, 0xc3, 0x5e, 0x45, 0xff, 0xc7, 0x12, 0x34, - 0x93, 0x79, 0xc4, 0xa7, 0x00, 0xa8, 0x77, 0xe3, 0x53, 0xc7, 0x4b, 0x83, 0x9a, 0x3b, 0xf9, 0x95, - 0x56, 0xf1, 0xc6, 0x3e, 0x43, 0x2a, 0xbb, 0x37, 0x52, 0x53, 0x82, 0x07, 0x07, 0xd0, 0x2d, 0x12, - 0x17, 0x44, 0x77, 0xf7, 0xf3, 0x76, 0xbe, 0xbb, 0xf6, 0x9d, 0xc2, 0xd4, 0x38, 0x92, 0x84, 0x39, - 0x67, 0xf2, 0x1f, 0x40, 0x33, 0x41, 0x8b, 0x16, 0x34, 0x36, 0x87, 0x5b, 0xeb, 0x87, 0x3b, 0x28, - 0x24, 0x00, 0xf5, 0x83, 0xed, 0xdd, 0xa7, 0x3b, 0x43, 0x3e, 0xd6, 0xce, 0xf6, 0xc1, 0xa8, 0x57, - 0xd6, 0xff, 0xa8, 0x04, 0xcd, 0x24, 0x86, 0x10, 0xdf, 0x47, 0xe7, 0x4f, 0xa1, 0x8a, 0xf2, 0x0d, - 0x54, 0x8e, 0xc8, 0x25, 0x53, 0x46, 0x42, 0x47, 0xc5, 0x20, 0x53, 0x97, 0x44, 0x15, 0x04, 0xe4, - 0x53, 0xb9, 0x4a, 0xa1, 0x9a, 0x80, 0x59, 0xa9, 0xef, 0x49, 0x15, 0x24, 0x52, 0x9b, 0x64, 0xd0, - 0xf1, 0x2c, 0xb2, 0x16, 0x35, 0x25, 0x83, 0x08, 0x8f, 0x22, 0xfd, 0xaf, 0xaa, 0xd0, 0x35, 0x64, - 0x14, 0xfb, 0xa1, 0x34, 0xe4, 0xcf, 0xa7, 0x98, 0x6a, 0xbf, 0x46, 0x98, 0xdf, 0x01, 0x08, 0xb9, - 0x73, 0x26, 0xce, 0x9a, 0xc2, 0x70, 0x98, 0xee, 0xfa, 0x16, 0x49, 0x91, 0xf2, 0x1e, 0x29, 0x2c, - 0xee, 0x80, 0x76, 0x64, 0x5a, 0x67, 0x3c, 0x2d, 0xfb, 0x90, 0x26, 0x23, 0x78, 0x5e, 0xd3, 0xb2, - 0x64, 0x14, 0x8d, 0xf1, 0x52, 0xd8, 0x93, 0x68, 0x8c, 0x79, 0x26, 0x2f, 0x90, 0x1c, 0x49, 0x2b, - 0x94, 0x31, 0x91, 0xd9, 0x40, 0x68, 0x8c, 0x41, 0xf2, 0x7b, 0xd0, 0x89, 0x64, 0x84, 0x5e, 0x67, - 0x1c, 0xfb, 0x67, 0xd2, 0x53, 0xd6, 0xa2, 0xad, 0x90, 0x23, 0xc4, 0xa1, 0x1d, 0x37, 0x3d, 0xdf, - 0xbb, 0x98, 0xf8, 0xd3, 0x48, 0x19, 0xe0, 0x0c, 0x21, 0x56, 0xe1, 0xa6, 0xf4, 0xac, 0xf0, 0x22, - 0xc0, 0xbd, 0xe2, 0x2a, 0xe3, 0x63, 0xc7, 0x95, 0x2a, 0x50, 0xbc, 0x91, 0x91, 0x9e, 0xc9, 0x8b, - 0x2d, 0xc7, 0x95, 0xb8, 0xa3, 0x73, 0x73, 0xea, 0xc6, 0x63, 0x4a, 0x24, 0x81, 0x77, 0x44, 0x98, - 0x75, 0xcc, 0x26, 0x3f, 0x84, 0x1b, 0x4c, 0x0e, 0x7d, 0x57, 0x3a, 0x36, 0x4f, 0xd6, 0xa2, 0x5e, - 0xd7, 0x89, 0x60, 0x10, 0x9e, 0xa6, 0x5a, 0x85, 0x9b, 0xdc, 0x97, 0x0f, 0x94, 0xf4, 0x6e, 0xf3, - 0xd2, 0x44, 0x3a, 0x50, 0x94, 0xe2, 0xd2, 0x81, 0x19, 0x9f, 0x52, 0x82, 0x98, 0x2c, 0xbd, 0x6f, - 0xc6, 0xa7, 0xe8, 0x0d, 0x99, 0x7c, 0xec, 0x48, 0x97, 0x13, 0x3f, 0xcd, 0xe0, 0x11, 0x5b, 0x88, - 0x11, 0xef, 0x42, 0x5b, 0x75, 0xf0, 0xc3, 0x89, 0xc9, 0xf5, 0x25, 0xcd, 0xe0, 0x41, 0x5b, 0x84, - 0xc2, 0x25, 0xd4, 0x5d, 0x79, 0xd3, 0x49, 0xbf, 0xc7, 0xd7, 0xcc, 0x98, 0xdd, 0xe9, 0x44, 0xff, - 0x9f, 0x32, 0x34, 0xd3, 0x64, 0xe3, 0x3e, 0x68, 0x93, 0xc4, 0x72, 0xa8, 0x20, 0xa6, 0x53, 0x30, - 0x27, 0x46, 0x46, 0x17, 0xef, 0x40, 0xf9, 0xec, 0x5c, 0x59, 0xb1, 0xce, 0x2a, 0xd7, 0x5b, 0x83, - 0xa3, 0xb5, 0xd5, 0x67, 0x2f, 0x8c, 0xf2, 0xd9, 0x79, 0x16, 0x0c, 0xd5, 0xde, 0x18, 0x0c, 0x7d, - 0x00, 0xd7, 0x2d, 0x57, 0x9a, 0xde, 0x38, 0x73, 0xce, 0x2c, 0x17, 0x5d, 0x42, 0xef, 0xa7, 0x1e, - 0x5a, 0x29, 0x7a, 0x23, 0x53, 0xf4, 0x7b, 0x50, 0xb3, 0xa5, 0x1b, 0x9b, 0xf9, 0x42, 0xe0, 0x5e, - 0x68, 0x5a, 0xae, 0xdc, 0x44, 0xb4, 0xc1, 0x54, 0xb4, 0x6b, 0x49, 0x42, 0x94, 0xb7, 0x6b, 0x89, - 0x0a, 0x1b, 0x29, 0x35, 0xd3, 0x50, 0xc8, 0x6b, 0xe8, 0x7d, 0xb8, 0x21, 0x67, 0x01, 0x19, 0xf3, - 0x71, 0x9a, 0xbc, 0xb6, 0xa8, 0x47, 0x2f, 0x21, 0x3c, 0x51, 0x78, 0xf1, 0x11, 0xaa, 0x33, 0xa9, - 0x11, 0x5d, 0x7c, 0x6b, 0x4d, 0x90, 0x3d, 0x28, 0x28, 0xa6, 0x91, 0x74, 0xd1, 0x3d, 0xa8, 0x3c, - 0x7b, 0x71, 0xa0, 0xb8, 0x59, 0xba, 0x8a, 0x9b, 0x89, 0x25, 0x28, 0xe7, 0x2c, 0xc1, 0x5d, 0x36, - 0xa2, 0xc4, 0x9a, 0xa4, 0x48, 0x95, 0xc3, 0xe0, 0x51, 0xd8, 0x81, 0x54, 0xb9, 0x7e, 0x45, 0x80, - 0xfe, 0x5f, 0x15, 0x68, 0x28, 0xaf, 0x8e, 0xfc, 0x9c, 0xa6, 0xf5, 0x17, 0x6c, 0x16, 0xd3, 0x9e, - 0x34, 0x3c, 0xc8, 0x17, 0xb3, 0x2b, 0x6f, 0x2e, 0x66, 0x8b, 0x4f, 0xa1, 0x1d, 0x30, 0x2d, 0x1f, - 0x50, 0xbc, 0x95, 0x1f, 0xa3, 0xbe, 0x34, 0xae, 0x15, 0x64, 0x00, 0x5a, 0x2c, 0xaa, 0xf4, 0xc5, - 0xe6, 0x09, 0x89, 0x4e, 0xdb, 0x68, 0x20, 0x3c, 0x32, 0x4f, 0xae, 0x08, 0x2b, 0xbe, 0x49, 0x74, - 0xd0, 0xa5, 0x30, 0xa3, 0x4d, 0x06, 0x10, 0x23, 0x8a, 0xbc, 0x23, 0xef, 0x14, 0x1d, 0xf9, 0x1d, - 0xd0, 0x2c, 0x7f, 0x32, 0x71, 0x88, 0xd6, 0x55, 0xf5, 0x09, 0x42, 0x8c, 0x22, 0xfd, 0xf7, 0x4a, - 0xd0, 0x50, 0xa7, 0xbd, 0xe4, 0x26, 0x36, 0xb6, 0x77, 0xd7, 0x8d, 0x9f, 0xf6, 0x4a, 0xe8, 0x06, - 0xb7, 0x77, 0x47, 0xbd, 0xb2, 0xd0, 0xa0, 0xb6, 0xb5, 0xb3, 0xb7, 0x3e, 0xea, 0x55, 0xd0, 0x75, - 0x6c, 0xec, 0xed, 0xed, 0xf4, 0xaa, 0xa2, 0x0d, 0xcd, 0xcd, 0xf5, 0xd1, 0x70, 0xb4, 0xfd, 0x7c, - 0xd8, 0xab, 0x61, 0xdf, 0xa7, 0xc3, 0xbd, 0x5e, 0x1d, 0x1b, 0x87, 0xdb, 0x9b, 0xbd, 0x06, 0xd2, - 0xf7, 0xd7, 0x0f, 0x0e, 0xbe, 0xd8, 0x33, 0x36, 0x7b, 0x4d, 0x72, 0x3f, 0x23, 0x63, 0x7b, 0xf7, - 0x69, 0x4f, 0xc3, 0xf6, 0xde, 0xc6, 0x8f, 0x87, 0x4f, 0x46, 0x3d, 0xd0, 0x1f, 0x43, 0x2b, 0xc7, - 0x41, 0x1c, 0x6d, 0x0c, 0xb7, 0x7a, 0xd7, 0x70, 0xc9, 0x17, 0xeb, 0x3b, 0x87, 0xe8, 0xad, 0xba, - 0x00, 0xd4, 0x1c, 0xef, 0xac, 0xef, 0x3e, 0xed, 0x95, 0xf5, 0xcf, 0xa1, 0x79, 0xe8, 0xd8, 0x1b, - 0xae, 0x6f, 0x9d, 0xa1, 0x38, 0x1d, 0x99, 0x91, 0x54, 0xa9, 0x11, 0xb5, 0x31, 0x8a, 0x24, 0x65, - 0x89, 0xd4, 0xdd, 0x2b, 0x08, 0x79, 0xe5, 0x4d, 0x27, 0x63, 0x7a, 0x00, 0xa9, 0xb0, 0x0b, 0xf1, - 0xa6, 0x93, 0x43, 0xc7, 0x8e, 0xf4, 0x33, 0x68, 0x1c, 0x3a, 0xf6, 0xbe, 0x69, 0x9d, 0x91, 0x99, - 0xc1, 0xa9, 0xc7, 0x91, 0xf3, 0x95, 0x54, 0xae, 0x46, 0x23, 0xcc, 0x81, 0xf3, 0x95, 0x14, 0xef, - 0x43, 0x9d, 0x80, 0x24, 0x0d, 0x26, 0xf5, 0x4b, 0xb6, 0x63, 0x28, 0x1a, 0xbd, 0x3f, 0xb8, 0xae, - 0x6f, 0x8d, 0x43, 0x79, 0xdc, 0x7f, 0x8b, 0x79, 0x4f, 0x08, 0x43, 0x1e, 0xeb, 0xbf, 0x5f, 0x4a, - 0xcf, 0x4c, 0xe5, 0xef, 0x25, 0xa8, 0x06, 0xa6, 0x75, 0xa6, 0x7c, 0x6e, 0x4b, 0x4d, 0x88, 0x9b, - 0x31, 0x88, 0x20, 0x3e, 0x80, 0xa6, 0x12, 0xac, 0x64, 0xd5, 0x56, 0x4e, 0x02, 0x8d, 0x94, 0x58, - 0xbc, 0xf2, 0x4a, 0xf1, 0xca, 0x29, 0x87, 0x0a, 0x5c, 0x27, 0x66, 0x35, 0xaa, 0x1a, 0x0a, 0xd2, - 0x7f, 0x00, 0x90, 0xbd, 0x38, 0x2c, 0x08, 0x41, 0x6e, 0x41, 0xcd, 0x74, 0x1d, 0x33, 0xc9, 0xc9, - 0x18, 0xd0, 0x77, 0xa1, 0x95, 0x7b, 0xa7, 0x40, 0xde, 0x9a, 0xae, 0x8b, 0x3e, 0x2a, 0xa2, 0xb1, - 0x4d, 0xa3, 0x61, 0xba, 0xee, 0x33, 0x79, 0x11, 0x61, 0xf8, 0xc7, 0x4f, 0x1c, 0xe5, 0xb9, 0xea, - 0x38, 0x0d, 0x35, 0x98, 0xa8, 0x7f, 0x04, 0xf5, 0xad, 0x24, 0x00, 0x4e, 0xd4, 0xa0, 0x74, 0x95, - 0x1a, 0xe8, 0x9f, 0xa8, 0x3d, 0x53, 0x81, 0x5d, 0xdc, 0x57, 0x4f, 0x29, 0x11, 0x3f, 0xdc, 0x94, - 0xb2, 0xac, 0x9e, 0x3b, 0xa9, 0x57, 0x14, 0xea, 0xac, 0x6f, 0x42, 0xf3, 0xb5, 0x8f, 0x53, 0x8a, - 0x01, 0xe5, 0x8c, 0x01, 0x0b, 0x9e, 0xab, 0xf4, 0x9f, 0x01, 0x64, 0x4f, 0x2e, 0x4a, 0x2b, 0x79, - 0x16, 0xd4, 0xca, 0x0f, 0xa1, 0x69, 0x9d, 0x3a, 0xae, 0x1d, 0x4a, 0xaf, 0x70, 0xea, 0xec, 0x91, - 0x26, 0xa5, 0x8b, 0x65, 0xa8, 0xd2, 0x4b, 0x52, 0x25, 0xb3, 0xe6, 0xe9, 0x33, 0x12, 0x51, 0xf4, - 0x19, 0x74, 0x38, 0xae, 0xfe, 0x06, 0xb1, 0x50, 0xd1, 0x94, 0x96, 0x2f, 0x99, 0xd2, 0xdb, 0x50, - 0x27, 0x17, 0x9c, 0x9c, 0x46, 0x41, 0x57, 0x98, 0xd8, 0xdf, 0x2d, 0x03, 0xf0, 0xd2, 0xbb, 0xbe, - 0x2d, 0x8b, 0x59, 0x67, 0x69, 0x3e, 0xeb, 0x14, 0x50, 0x4d, 0x1f, 0x09, 0x35, 0x83, 0xda, 0x99, - 0x13, 0x52, 0x99, 0x28, 0x3b, 0xa1, 0xb7, 0x41, 0xa3, 0x90, 0xc8, 0xf9, 0x8a, 0x2a, 0xdb, 0xb8, - 0x60, 0x86, 0xc8, 0x3f, 0x99, 0xd5, 0x8a, 0x4f, 0x66, 0xe9, 0xbb, 0x42, 0x9d, 0x67, 0xe3, 0x77, - 0x85, 0x05, 0x4f, 0x24, 0x9c, 0xe7, 0x47, 0x32, 0x8c, 0x93, 0xac, 0x96, 0xa1, 0x34, 0x73, 0xd3, - 0x54, 0x5f, 0x93, 0x33, 0x75, 0xcf, 0x1f, 0x5b, 0xbe, 0x77, 0xec, 0x3a, 0x56, 0xac, 0x9e, 0xc8, - 0xc0, 0xf3, 0x9f, 0x28, 0x8c, 0xfe, 0x29, 0xb4, 0x13, 0xfe, 0xd3, 0x4b, 0xc4, 0x87, 0x69, 0xe6, - 0x53, 0xca, 0xee, 0x36, 0x63, 0xd3, 0x46, 0xb9, 0x5f, 0x4a, 0x72, 0x1f, 0xfd, 0x3f, 0x2b, 0xc9, - 0x60, 0x55, 0x50, 0x7f, 0x3d, 0x0f, 0x8b, 0xe9, 0x6b, 0xf9, 0x1b, 0xa5, 0xaf, 0x3f, 0x04, 0xcd, - 0xa6, 0xfc, 0xcc, 0x39, 0x4f, 0x9c, 0xda, 0x60, 0x3e, 0x17, 0x53, 0x19, 0x9c, 0x73, 0x2e, 0x8d, - 0xac, 0xf3, 0x1b, 0xee, 0x21, 0xe5, 0x76, 0x6d, 0x11, 0xb7, 0xeb, 0xbf, 0x22, 0xb7, 0xdf, 0x85, - 0xb6, 0xe7, 0x7b, 0x63, 0x6f, 0xea, 0xba, 0xe6, 0x91, 0x2b, 0x15, 0xbb, 0x5b, 0x9e, 0xef, 0xed, - 0x2a, 0x14, 0xc6, 0xa9, 0xf9, 0x2e, 0xac, 0xd4, 0x2d, 0xea, 0x77, 0x3d, 0xd7, 0x8f, 0x54, 0x7f, - 0x05, 0x7a, 0xfe, 0xd1, 0xcf, 0xa4, 0x15, 0x13, 0xc7, 0xc6, 0xa4, 0xcd, 0x1c, 0xa4, 0x76, 0x19, - 0x8f, 0x2c, 0xda, 0x45, 0xbd, 0x9e, 0xbb, 0xe6, 0xce, 0xa5, 0x6b, 0xfe, 0x04, 0xb4, 0x94, 0x4b, - 0xb9, 0x5c, 0x50, 0x83, 0xda, 0xf6, 0xee, 0xe6, 0xf0, 0x27, 0xbd, 0x12, 0x3a, 0x4a, 0x63, 0xf8, - 0x62, 0x68, 0x1c, 0x0c, 0x7b, 0x65, 0x74, 0x62, 0x9b, 0xc3, 0x9d, 0xe1, 0x68, 0xd8, 0xab, 0xfc, - 0xb8, 0xda, 0x6c, 0xf4, 0x9a, 0x54, 0x16, 0x77, 0x1d, 0xcb, 0x89, 0xf5, 0x03, 0x80, 0x2c, 0xc1, - 0x45, 0xab, 0x9c, 0x6d, 0x4e, 0xd5, 0xbc, 0xe2, 0x64, 0x5b, 0x2b, 0xa9, 0x42, 0x96, 0xaf, 0x4a, - 0xa3, 0x99, 0xae, 0xaf, 0x81, 0xf6, 0xdc, 0x0c, 0x3e, 0xe3, 0x17, 0xa0, 0x7b, 0xd0, 0x0d, 0xcc, - 0x30, 0x76, 0x92, 0xcc, 0x80, 0x8d, 0x65, 0xdb, 0xe8, 0xa4, 0x58, 0xb4, 0xbd, 0xfa, 0x5f, 0x97, - 0xe0, 0xd6, 0x73, 0xff, 0x5c, 0xa6, 0x91, 0xe7, 0xbe, 0x79, 0xe1, 0xfa, 0xa6, 0xfd, 0x06, 0x31, - 0xc4, 0xd4, 0xc6, 0x9f, 0xd2, 0x5b, 0x4d, 0xf2, 0x7e, 0x65, 0x68, 0x8c, 0x79, 0xaa, 0x1e, 0xd0, - 0x65, 0x14, 0x13, 0x51, 0x39, 0x52, 0x84, 0x91, 0xf4, 0x1d, 0xa8, 0xc7, 0x33, 0x2f, 0x7b, 0x2e, - 0xab, 0xc5, 0x54, 0x91, 0x5d, 0x18, 0x76, 0xd6, 0x16, 0x87, 0x9d, 0xfa, 0x13, 0xd0, 0x46, 0x33, - 0xaa, 0x56, 0x4e, 0xa3, 0x42, 0x80, 0x53, 0x7a, 0x4d, 0x80, 0x53, 0x9e, 0x0b, 0x70, 0xfe, 0xbd, - 0x04, 0xad, 0x5c, 0xfc, 0x2c, 0xde, 0x85, 0x6a, 0x3c, 0xf3, 0x8a, 0x8f, 0xd2, 0xc9, 0x22, 0x06, - 0x91, 0x50, 0x34, 0x27, 0xe6, 0x6c, 0x6c, 0x46, 0x91, 0x73, 0xe2, 0x49, 0x5b, 0x4d, 0xd9, 0x9a, - 0x98, 0xb3, 0x75, 0x85, 0x12, 0x3b, 0x70, 0x9d, 0x2d, 0x6f, 0x72, 0x88, 0xa4, 0x4c, 0xf2, 0xde, - 0x5c, 0xbc, 0xce, 0x15, 0xdd, 0xe4, 0x48, 0x2a, 0xf7, 0xef, 0x9e, 0x14, 0x90, 0x83, 0x75, 0xb8, - 0xb9, 0xa0, 0xdb, 0xb7, 0xaa, 0xe1, 0x2f, 0x41, 0x67, 0x34, 0xf3, 0x46, 0xce, 0x44, 0x46, 0xb1, - 0x39, 0x09, 0x28, 0x40, 0x54, 0x9e, 0xb3, 0x6a, 0x94, 0xe3, 0x48, 0xff, 0x1e, 0xb4, 0xf7, 0xa5, - 0x0c, 0x0d, 0x19, 0x05, 0xbe, 0xc7, 0xc1, 0x91, 0xaa, 0xa4, 0xb2, 0x9b, 0x56, 0x90, 0xfe, 0x5b, - 0xa0, 0x61, 0xa2, 0xbf, 0x61, 0xc6, 0xd6, 0xe9, 0xb7, 0x29, 0x04, 0x7c, 0x0f, 0x1a, 0x01, 0xcb, - 0x94, 0xca, 0xb3, 0xda, 0xe4, 0xae, 0x95, 0x9c, 0x19, 0x09, 0x51, 0x7f, 0x0c, 0x37, 0x0f, 0xa6, - 0x47, 0x91, 0x15, 0x3a, 0x94, 0xb2, 0x26, 0xae, 0x6c, 0x00, 0xcd, 0x20, 0x94, 0xc7, 0xce, 0x4c, - 0x26, 0x12, 0x9c, 0xc2, 0xfa, 0x8f, 0xe0, 0x56, 0x71, 0x88, 0x3a, 0xc2, 0x7b, 0x50, 0x39, 0x3b, - 0x8f, 0xd4, 0xce, 0x6e, 0x14, 0x52, 0x0c, 0x7a, 0x0b, 0x46, 0xaa, 0x6e, 0x40, 0x65, 0x77, 0x3a, - 0xc9, 0xff, 0xcf, 0x52, 0xe5, 0xff, 0x59, 0xee, 0xe4, 0x0b, 0x9b, 0x9c, 0x85, 0x64, 0x05, 0xcc, - 0xb7, 0x41, 0x3b, 0xf6, 0xc3, 0x5f, 0x98, 0xa1, 0x2d, 0x6d, 0xe5, 0xb3, 0x32, 0x84, 0xfe, 0x25, - 0xb4, 0x12, 0x49, 0xd8, 0xb6, 0xe9, 0xf1, 0x8b, 0x44, 0x71, 0xdb, 0x2e, 0x48, 0x26, 0x97, 0x0d, - 0xa5, 0x67, 0x6f, 0x27, 0x22, 0xc4, 0x40, 0x71, 0x65, 0xf5, 0x66, 0x91, 0xac, 0xac, 0x6f, 0x41, - 0x3b, 0x49, 0xe2, 0x9e, 0xcb, 0xd8, 0x24, 0xe1, 0x76, 0x1d, 0xe9, 0xe5, 0x04, 0xbf, 0xc9, 0x88, - 0x51, 0xb1, 0xb2, 0x57, 0x2e, 0x04, 0x00, 0xfa, 0x2a, 0xd4, 0x95, 0xe6, 0x08, 0xa8, 0x5a, 0xbe, - 0xcd, 0xda, 0x5d, 0x33, 0xa8, 0x8d, 0xec, 0x98, 0x44, 0x27, 0x49, 0x70, 0x33, 0x89, 0x4e, 0xf4, - 0xbf, 0x2d, 0x43, 0x67, 0x83, 0x92, 0xe8, 0xe4, 0x4a, 0x72, 0x45, 0x9c, 0x52, 0xa1, 0x88, 0x93, - 0x2f, 0xd8, 0x94, 0x0b, 0x05, 0x9b, 0xc2, 0x86, 0x2a, 0xc5, 0x88, 0xe4, 0x2d, 0x68, 0x4c, 0x3d, - 0x67, 0x96, 0x98, 0x04, 0xcd, 0xa8, 0x23, 0x38, 0x8a, 0xc4, 0x32, 0xb4, 0xd0, 0x6a, 0x38, 0x1e, - 0x97, 0x66, 0xb8, 0xbe, 0x92, 0x47, 0xcd, 0x15, 0x60, 0xea, 0xaf, 0x2f, 0xc0, 0x34, 0xde, 0x58, - 0x80, 0x69, 0xbe, 0xa9, 0x00, 0xa3, 0xcd, 0x17, 0x60, 0x8a, 0xd1, 0x14, 0xcc, 0x47, 0x53, 0xfa, - 0x0e, 0x74, 0x13, 0xde, 0x29, 0xd9, 0xfc, 0x14, 0xae, 0xab, 0x2a, 0xa6, 0x0c, 0x55, 0xf9, 0x81, - 0x2d, 0xce, 0x0d, 0xaa, 0xa3, 0x52, 0xa1, 0x51, 0x51, 0x8c, 0xae, 0x9d, 0x07, 0x23, 0xfd, 0x0f, - 0x4b, 0xd0, 0x29, 0xf4, 0x10, 0x8f, 0xb3, 0x9a, 0x68, 0x89, 0x1c, 0x7b, 0xff, 0xd2, 0x2c, 0xaf, - 0xaf, 0x8b, 0x96, 0xe7, 0xea, 0xa2, 0xb9, 0x6a, 0xa7, 0xaa, 0x71, 0x5e, 0x4b, 0x6b, 0x9c, 0xa5, - 0xb4, 0xc6, 0x49, 0xd5, 0xce, 0xf5, 0xd1, 0xc8, 0xe8, 0x55, 0xf4, 0x3f, 0x29, 0x43, 0x67, 0x38, - 0x0b, 0xe8, 0x3f, 0x8c, 0x37, 0x46, 0x9f, 0x39, 0xd1, 0x29, 0x17, 0x44, 0x27, 0x27, 0x04, 0x15, - 0xf5, 0xf0, 0xc2, 0x42, 0x80, 0xf1, 0x28, 0x57, 0x7c, 0x94, 0x70, 0x30, 0xf4, 0x7f, 0x40, 0x38, - 0xf0, 0xf2, 0x13, 0xc6, 0xa8, 0xcb, 0xff, 0x46, 0x1a, 0xc7, 0xff, 0x50, 0xb9, 0x69, 0xa1, 0x83, - 0x01, 0xfd, 0x0f, 0xca, 0xa0, 0xb1, 0x2c, 0xe1, 0xf6, 0xbe, 0xaf, 0x62, 0xe9, 0x52, 0x56, 0xf5, - 0x4d, 0x89, 0xab, 0xcf, 0xe4, 0x05, 0xc5, 0x80, 0x1c, 0x62, 0x2f, 0x7a, 0x1b, 0x51, 0xe5, 0x10, - 0xce, 0x00, 0xa9, 0x1c, 0x72, 0x07, 0x34, 0x76, 0xa3, 0x53, 0x27, 0x79, 0x4d, 0x65, 0xbf, 0x7a, - 0xe8, 0xd0, 0xaf, 0x27, 0xb1, 0x0c, 0x27, 0x8a, 0xcb, 0xd4, 0x2e, 0xc6, 0xda, 0x1d, 0x15, 0xfd, - 0xe9, 0xa7, 0xd0, 0x50, 0xab, 0x63, 0x30, 0x74, 0xb8, 0xfb, 0x6c, 0x77, 0xef, 0x8b, 0xdd, 0x82, - 0x0c, 0xa5, 0xe1, 0x52, 0x39, 0x1f, 0x2e, 0x55, 0x10, 0xff, 0x64, 0xef, 0x70, 0x77, 0xd4, 0xab, - 0x8a, 0x0e, 0x68, 0xd4, 0x1c, 0x1b, 0xc3, 0x17, 0xbd, 0x1a, 0x55, 0x06, 0x9e, 0x7c, 0x36, 0x7c, - 0xbe, 0xde, 0xab, 0xa7, 0x12, 0xd8, 0xd0, 0xff, 0xa2, 0x04, 0x37, 0xf8, 0xc8, 0xf9, 0x54, 0x39, - 0xff, 0xff, 0x62, 0x95, 0xff, 0x5f, 0xfc, 0xf5, 0x66, 0xc7, 0x38, 0x68, 0xea, 0xd8, 0xe3, 0xa3, - 0x0b, 0xb4, 0x00, 0x5c, 0xc6, 0x69, 0x4e, 0x1d, 0x7b, 0x03, 0x61, 0xfd, 0xef, 0x4b, 0x30, 0xe0, - 0x28, 0xed, 0x69, 0x68, 0x06, 0xa7, 0x9f, 0xef, 0x5c, 0xca, 0xd3, 0xae, 0x8a, 0x5d, 0xee, 0x41, - 0x97, 0xfe, 0xf0, 0xfc, 0xb9, 0x3b, 0x56, 0xb9, 0x04, 0xdf, 0x5f, 0x47, 0x61, 0x79, 0x22, 0xf1, - 0x31, 0xb4, 0xf9, 0x4f, 0x50, 0xaa, 0x28, 0x16, 0xde, 0x64, 0x0a, 0x31, 0x62, 0x8b, 0x7b, 0xd1, - 0xeb, 0x90, 0x78, 0x9c, 0x0e, 0xca, 0x52, 0xba, 0xcb, 0xcf, 0x2e, 0x6a, 0xc8, 0x88, 0x12, 0xbd, - 0x87, 0x70, 0x67, 0xe1, 0x39, 0x94, 0x60, 0xe7, 0xca, 0x6b, 0x2c, 0x4f, 0x6b, 0x7f, 0x57, 0x82, - 0x2a, 0xc6, 0x03, 0xe2, 0x01, 0x68, 0x9f, 0x49, 0x33, 0x8c, 0x8f, 0xa4, 0x19, 0x8b, 0x82, 0xef, - 0x1f, 0xd0, 0x8a, 0xd9, 0xd3, 0xaf, 0x7e, 0xed, 0x51, 0x49, 0xac, 0xf2, 0xcf, 0x59, 0xc9, 0x3f, - 0x67, 0x9d, 0x24, 0xae, 0xa0, 0xb8, 0x63, 0x50, 0x18, 0xaf, 0x5f, 0x5b, 0xa1, 0xfe, 0x3f, 0xf6, - 0x1d, 0xef, 0x09, 0xff, 0x4b, 0x24, 0xe6, 0xe3, 0x90, 0xf9, 0x11, 0xe2, 0x01, 0xd4, 0xb7, 0x23, - 0x0c, 0x78, 0x2e, 0x77, 0x25, 0xae, 0xe5, 0x63, 0x21, 0xfd, 0xda, 0xda, 0x5f, 0x56, 0xa0, 0xfa, - 0xa5, 0x0c, 0x7d, 0xf1, 0x11, 0x34, 0xd4, 0x43, 0xb9, 0xc8, 0x3d, 0x88, 0x0f, 0x28, 0xf7, 0x9a, - 0x7b, 0x41, 0xa7, 0x55, 0x7a, 0xcc, 0xae, 0xac, 0x0e, 0x2c, 0xb2, 0x77, 0xfc, 0x4b, 0x9b, 0xfa, - 0x04, 0x7a, 0x07, 0x71, 0x28, 0xcd, 0x49, 0xae, 0x7b, 0x91, 0x55, 0x8b, 0x8a, 0xca, 0xc4, 0xaf, - 0xfb, 0x50, 0xe7, 0xa8, 0x72, 0x6e, 0xc0, 0x7c, 0x7d, 0x98, 0x3a, 0x7f, 0x00, 0xad, 0x83, 0x53, - 0x7f, 0xea, 0xda, 0x07, 0x32, 0x3c, 0x97, 0x22, 0xf7, 0xeb, 0xcb, 0x20, 0xd7, 0xd6, 0xaf, 0x89, - 0x15, 0x00, 0x0e, 0x64, 0x0e, 0x51, 0x81, 0x1a, 0x48, 0xdb, 0x9d, 0x4e, 0x78, 0xd2, 0x5c, 0x84, - 0xc3, 0x3d, 0x73, 0xc1, 0xe5, 0xeb, 0x7a, 0x7e, 0x0c, 0x9d, 0x27, 0xa4, 0x4c, 0x7b, 0xe1, 0xfa, - 0x91, 0x1f, 0xc6, 0x62, 0xfe, 0xf7, 0x97, 0xc1, 0x3c, 0x42, 0xbf, 0x26, 0x1e, 0x41, 0x73, 0x14, - 0x5e, 0x70, 0xff, 0x1b, 0x2a, 0x26, 0xcf, 0xd6, 0x5b, 0x70, 0xca, 0xb5, 0xff, 0xae, 0x42, 0xfd, - 0x0b, 0x3f, 0x3c, 0x93, 0x21, 0xe6, 0xe1, 0x54, 0xcf, 0x57, 0x62, 0x94, 0xd6, 0xf6, 0x17, 0x2d, - 0xf4, 0x3e, 0x68, 0xc4, 0x94, 0x91, 0x19, 0x9d, 0xf1, 0x55, 0xd1, 0x2f, 0xc5, 0xcc, 0x17, 0xce, - 0xeb, 0xe9, 0x5e, 0xbb, 0x7c, 0x51, 0xe9, 0x93, 0x58, 0xa1, 0xba, 0x3e, 0xa0, 0xf3, 0x3f, 0x7b, - 0x71, 0x80, 0xa2, 0xf9, 0xa8, 0x84, 0x56, 0xfa, 0x80, 0x4f, 0x8a, 0x9d, 0xb2, 0x5f, 0x29, 0x59, - 0xf2, 0xb3, 0x7f, 0x17, 0xf5, 0x6b, 0xe2, 0x21, 0xd4, 0x95, 0x4a, 0xdf, 0xc8, 0x94, 0x57, 0xd9, - 0x89, 0x41, 0x2f, 0x8f, 0x52, 0x03, 0x1e, 0x43, 0x9d, 0xcd, 0x1f, 0x0f, 0x28, 0x84, 0x68, 0x03, - 0x91, 0x47, 0x25, 0xc2, 0x2c, 0xee, 0x43, 0x43, 0xd5, 0xe6, 0xc5, 0x82, 0x42, 0x3d, 0x1f, 0x95, - 0x63, 0x43, 0x9e, 0x9f, 0xbd, 0x17, 0xcf, 0x5f, 0x70, 0xf1, 0x3c, 0x7f, 0xd1, 0xb9, 0xb1, 0xd4, - 0x1b, 0xd2, 0x92, 0x4e, 0x2e, 0x9d, 0x14, 0x09, 0x47, 0x16, 0xa8, 0xee, 0x27, 0xd0, 0x29, 0xa4, - 0x9e, 0x82, 0x82, 0x97, 0x45, 0xd9, 0xe8, 0x25, 0x85, 0xf9, 0x11, 0x68, 0x2a, 0xf2, 0x3f, 0x92, - 0x82, 0xaa, 0xed, 0x0b, 0x72, 0x87, 0xc1, 0xe5, 0xd0, 0x9f, 0xb4, 0xe0, 0x27, 0x70, 0x73, 0x81, - 0x2d, 0x13, 0xf4, 0xdf, 0xd1, 0xd5, 0xc6, 0x7a, 0xb0, 0x74, 0x25, 0x3d, 0x61, 0xc0, 0x46, 0xef, - 0x1f, 0xbe, 0xbe, 0x5b, 0xfa, 0xe7, 0xaf, 0xef, 0x96, 0xfe, 0xf5, 0xeb, 0xbb, 0xa5, 0x5f, 0xfe, - 0xdb, 0xdd, 0x6b, 0x47, 0x75, 0xfa, 0xbd, 0xfe, 0xe3, 0xff, 0x0d, 0x00, 0x00, 0xff, 0xff, 0x0d, - 0x35, 0xa4, 0x91, 0xd4, 0x2f, 0x00, 0x00, + 0x72, 0xb8, 0xa6, 0xe7, 0xb3, 0x6b, 0x66, 0xa8, 0xd1, 0x93, 0x56, 0x9e, 0xa5, 0x6c, 0x91, 0x6e, + 0x5b, 0x6b, 0xae, 0x65, 0x51, 0x12, 0xbd, 0x3f, 0xfc, 0xd6, 0x5e, 0x04, 0x08, 0x29, 0x0e, 0x65, + 0xae, 0x28, 0x92, 0x6e, 0x0e, 0xe5, 0x5d, 0x1f, 0x32, 0x68, 0x76, 0x3f, 0x92, 0xbd, 0xec, 0xe9, + 0xee, 0xed, 0xee, 0xe1, 0x0e, 0x7d, 0x4a, 0x10, 0x20, 0xc8, 0x21, 0x39, 0x05, 0x41, 0xf6, 0x94, + 0x04, 0xf9, 0x07, 0x82, 0xe4, 0x14, 0xe4, 0x1c, 0x04, 0x41, 0x0e, 0x41, 0xfe, 0x02, 0x25, 0x70, + 0x72, 0x12, 0x90, 0x53, 0x80, 0x00, 0xb9, 0x04, 0x41, 0x55, 0xbd, 0xfe, 0x1a, 0x0e, 0x25, 0x7b, + 0x81, 0x3d, 0xe4, 0x34, 0x5d, 0x55, 0xef, 0xb3, 0xbe, 0xab, 0xde, 0x40, 0x2b, 0x3c, 0x5a, 0x0d, + 0xa3, 0x20, 0x09, 0x84, 0x16, 0x1e, 0x2d, 0xea, 0x56, 0xe8, 0x32, 0xb8, 0xf8, 0xe1, 0x89, 0x9b, + 0x9c, 0x4e, 0x8e, 0x56, 0xed, 0x60, 0xfc, 0xd0, 0x39, 0x89, 0xac, 0xf0, 0xf4, 0x81, 0x1b, 0x3c, + 0x3c, 0xb2, 0x9c, 0x13, 0x19, 0x3d, 0x3c, 0x5f, 0x7b, 0x18, 0x1e, 0x3d, 0x4c, 0xa7, 0x2e, 0x3e, + 0x28, 0x8c, 0x3d, 0x09, 0x4e, 0x82, 0x87, 0x84, 0x3e, 0x9a, 0x1c, 0x13, 0x44, 0x00, 0x7d, 0xf1, + 0x70, 0x63, 0x11, 0x6a, 0x3b, 0x6e, 0x9c, 0x08, 0x01, 0xb5, 0x89, 0xeb, 0xc4, 0xfd, 0xca, 0x72, + 0x75, 0xa5, 0x61, 0xd2, 0xb7, 0xf1, 0x1c, 0xf4, 0xa1, 0x15, 0x9f, 0xbd, 0xb0, 0xbc, 0x89, 0x14, + 0x3d, 0xa8, 0x9e, 0x5b, 0x5e, 0xbf, 0xb2, 0x5c, 0x59, 0xe9, 0x98, 0xf8, 0x29, 0x56, 0xa1, 0x75, + 0x6e, 0x79, 0xa3, 0xe4, 0x22, 0x94, 0x7d, 0x6d, 0xb9, 0xb2, 0xb2, 0xb0, 0x76, 0x73, 0x35, 0x3c, + 0x5a, 0xdd, 0x0f, 0xe2, 0xc4, 0xf5, 0x4f, 0x56, 0x5f, 0x58, 0xde, 0xf0, 0x22, 0x94, 0x66, 0xf3, + 0x9c, 0x3f, 0x8c, 0x3d, 0x68, 0x1f, 0x44, 0xf6, 0xd6, 0xc4, 0xb7, 0x13, 0x37, 0xf0, 0x71, 0x47, + 0xdf, 0x1a, 0x4b, 0x5a, 0x51, 0x37, 0xe9, 0x1b, 0x71, 0x56, 0x74, 0x12, 0xf7, 0xab, 0xcb, 0x55, + 0xc4, 0xe1, 0xb7, 0xe8, 0x43, 0xd3, 0x8d, 0x9f, 0x04, 0x13, 0x3f, 0xe9, 0xd7, 0x96, 0x2b, 0x2b, + 0x2d, 0x33, 0x05, 0x8d, 0x3f, 0xab, 0x42, 0xfd, 0xf3, 0x89, 0x8c, 0x2e, 0x68, 0x5e, 0x92, 0x44, + 0xe9, 0x5a, 0xf8, 0x2d, 0x6e, 0x41, 0xdd, 0xb3, 0xfc, 0x93, 0xb8, 0xaf, 0xd1, 0x62, 0x0c, 0x88, + 0x3b, 0xa0, 0x5b, 0xc7, 0x89, 0x8c, 0x46, 0x13, 0xd7, 0xe9, 0x57, 0x97, 0x2b, 0x2b, 0x0d, 0xb3, + 0x45, 0x88, 0x43, 0xd7, 0x11, 0xdf, 0x85, 0x96, 0x13, 0x8c, 0xec, 0xe2, 0x5e, 0x4e, 0x40, 0x7b, + 0x89, 0xf7, 0xa0, 0x35, 0x71, 0x9d, 0x91, 0xe7, 0xc6, 0x49, 0xbf, 0xbe, 0x5c, 0x59, 0x69, 0xaf, + 0xb5, 0xf0, 0xb2, 0xc8, 0x3b, 0xb3, 0x39, 0x71, 0x1d, 0x62, 0xe2, 0x87, 0xd0, 0x8a, 0x23, 0x7b, + 0x74, 0x3c, 0xf1, 0xed, 0x7e, 0x83, 0x06, 0x5d, 0xc7, 0x41, 0x85, 0x5b, 0x9b, 0xcd, 0x98, 0x01, + 0xbc, 0x56, 0x24, 0xcf, 0x65, 0x14, 0xcb, 0x7e, 0x93, 0xb7, 0x52, 0xa0, 0x78, 0x04, 0xed, 0x63, + 0xcb, 0x96, 0xc9, 0x28, 0xb4, 0x22, 0x6b, 0xdc, 0x6f, 0xe5, 0x0b, 0x6d, 0x21, 0x7a, 0x1f, 0xb1, + 0xb1, 0x09, 0xc7, 0x19, 0x20, 0x3e, 0x86, 0x2e, 0x41, 0xf1, 0xe8, 0xd8, 0xf5, 0x12, 0x19, 0xf5, + 0x75, 0x9a, 0xb3, 0x40, 0x73, 0x08, 0x33, 0x8c, 0xa4, 0x34, 0x3b, 0x3c, 0x88, 0x31, 0xe2, 0x1d, + 0x00, 0x39, 0x0d, 0x2d, 0xdf, 0x19, 0x59, 0x9e, 0xd7, 0x07, 0x3a, 0x83, 0xce, 0x98, 0x75, 0xcf, + 0x13, 0x6f, 0xe1, 0xf9, 0x2c, 0x67, 0x94, 0xc4, 0xfd, 0xee, 0x72, 0x65, 0xa5, 0x66, 0x36, 0x10, + 0x1c, 0xc6, 0xc8, 0x57, 0xdb, 0xb2, 0x4f, 0x65, 0x7f, 0x61, 0xb9, 0xb2, 0x52, 0x37, 0x19, 0x40, + 0xec, 0xb1, 0x1b, 0xc5, 0x49, 0xff, 0x3a, 0x63, 0x09, 0x30, 0xd6, 0x40, 0x27, 0xed, 0x21, 0xee, + 0xdc, 0x83, 0xc6, 0x39, 0x02, 0xac, 0x64, 0xed, 0xb5, 0x2e, 0x1e, 0x2f, 0x53, 0x30, 0x53, 0x11, + 0x8d, 0xbb, 0xd0, 0xda, 0xb1, 0xfc, 0x93, 0x54, 0x2b, 0x51, 0x6c, 0x34, 0x41, 0x37, 0xe9, 0xdb, + 0xf8, 0xa5, 0x06, 0x0d, 0x53, 0xc6, 0x13, 0x2f, 0x11, 0x1f, 0x00, 0xa0, 0x50, 0xc6, 0x56, 0x12, + 0xb9, 0x53, 0xb5, 0x6a, 0x2e, 0x16, 0x7d, 0xe2, 0x3a, 0xcf, 0x89, 0x24, 0x1e, 0x41, 0x87, 0x56, + 0x4f, 0x87, 0x6a, 0xf9, 0x01, 0xb2, 0xf3, 0x99, 0x6d, 0x1a, 0xa2, 0x66, 0xdc, 0x86, 0x06, 0xe9, + 0x01, 0xeb, 0x62, 0xd7, 0x54, 0x90, 0xb8, 0x07, 0x0b, 0xae, 0x9f, 0xa0, 0x9c, 0xec, 0x64, 0xe4, + 0xc8, 0x38, 0x55, 0x94, 0x6e, 0x86, 0xdd, 0x94, 0x71, 0x22, 0x1e, 0x03, 0x33, 0x3b, 0xdd, 0xb0, + 0x4e, 0x1b, 0x2e, 0x64, 0x42, 0x8c, 0x79, 0x47, 0x1a, 0xa3, 0x76, 0x7c, 0x00, 0x6d, 0xbc, 0x5f, + 0x3a, 0xa3, 0x41, 0x33, 0x3a, 0x74, 0x1b, 0xc5, 0x0e, 0x13, 0x70, 0x80, 0x1a, 0x8e, 0xac, 0x41, + 0x65, 0x64, 0xe5, 0xa1, 0x6f, 0x63, 0x00, 0xf5, 0xbd, 0xc8, 0x91, 0xd1, 0x5c, 0x7b, 0x10, 0x50, + 0x73, 0x64, 0x6c, 0x93, 0xa9, 0xb6, 0x4c, 0xfa, 0xce, 0x6d, 0xa4, 0x5a, 0xb0, 0x11, 0xe3, 0x4f, + 0x2b, 0xd0, 0x3e, 0x08, 0xa2, 0xe4, 0xb9, 0x8c, 0x63, 0xeb, 0x44, 0x8a, 0x25, 0xa8, 0x07, 0xb8, + 0xac, 0xe2, 0xb0, 0x8e, 0x67, 0xa2, 0x7d, 0x4c, 0xc6, 0xcf, 0xc8, 0x41, 0xbb, 0x5a, 0x0e, 0xa8, + 0x3b, 0x64, 0x5d, 0x55, 0xa5, 0x3b, 0x64, 0x5b, 0xb7, 0xa1, 0x11, 0x1c, 0x1f, 0xc7, 0x92, 0x79, + 0x59, 0x37, 0x15, 0x74, 0xa5, 0x0a, 0x1a, 0xff, 0x0f, 0x00, 0xcf, 0xf7, 0x2d, 0xb5, 0xc0, 0x38, + 0x85, 0xb6, 0x69, 0x1d, 0x27, 0x4f, 0x02, 0x3f, 0x91, 0xd3, 0x44, 0x2c, 0x80, 0xe6, 0x3a, 0xc4, + 0xa2, 0x86, 0xa9, 0xb9, 0x0e, 0x1e, 0xee, 0x24, 0x0a, 0x26, 0x21, 0x71, 0xa8, 0x6b, 0x32, 0x40, + 0xac, 0x74, 0x9c, 0x88, 0x4e, 0x8c, 0xac, 0x74, 0x9c, 0x48, 0x2c, 0x41, 0x3b, 0xf6, 0xad, 0x30, + 0x3e, 0x0d, 0x12, 0x3c, 0x5c, 0x8d, 0x0e, 0x07, 0x29, 0x6a, 0x18, 0x1b, 0xff, 0xa1, 0x41, 0xe3, + 0xb9, 0x1c, 0x1f, 0xc9, 0xe8, 0xd2, 0x2e, 0x8f, 0xa0, 0x45, 0x0b, 0x8f, 0x5c, 0x87, 0x37, 0xda, + 0xf8, 0xce, 0xab, 0x97, 0x4b, 0x37, 0x08, 0xb7, 0xed, 0x7c, 0x14, 0x8c, 0xdd, 0x44, 0x8e, 0xc3, + 0xe4, 0xc2, 0x6c, 0x2a, 0xd4, 0xdc, 0x13, 0xdc, 0x86, 0x86, 0x27, 0x2d, 0x94, 0x09, 0xab, 0x9f, + 0x82, 0xc4, 0x03, 0x68, 0x5a, 0xe3, 0x91, 0x23, 0x2d, 0x87, 0xbc, 0x54, 0x6b, 0xe3, 0xd6, 0xab, + 0x97, 0x4b, 0x3d, 0x6b, 0xbc, 0x29, 0xad, 0xe2, 0xda, 0x0d, 0xc6, 0x88, 0x4f, 0x50, 0xe7, 0xe2, + 0x64, 0x34, 0x09, 0x1d, 0x2b, 0x91, 0xe4, 0xb3, 0x6a, 0x1b, 0xfd, 0x57, 0x2f, 0x97, 0x6e, 0x21, + 0xfa, 0x90, 0xb0, 0x85, 0x69, 0x90, 0x63, 0xc5, 0x36, 0xdc, 0xb0, 0xbd, 0x49, 0x8c, 0xae, 0xd4, + 0xf5, 0x8f, 0x83, 0x51, 0xe0, 0x7b, 0x17, 0x24, 0xa6, 0xd6, 0xc6, 0x3b, 0xaf, 0x5e, 0x2e, 0x7d, + 0x57, 0x11, 0xb7, 0xfd, 0xe3, 0x60, 0xcf, 0xf7, 0x2e, 0x0a, 0xab, 0x5c, 0x9f, 0x21, 0x89, 0xdf, + 0x84, 0x85, 0xe3, 0x20, 0xb2, 0xe5, 0x28, 0x63, 0xcc, 0x02, 0xad, 0xb3, 0xf8, 0xea, 0xe5, 0xd2, + 0x6d, 0xa2, 0x3c, 0xbd, 0xc4, 0x9d, 0x4e, 0x11, 0x6f, 0xfc, 0x8d, 0x06, 0x75, 0xfa, 0x16, 0x8f, + 0xa0, 0x39, 0x26, 0xc6, 0xa7, 0x5e, 0xe6, 0x36, 0x6a, 0x02, 0xd1, 0x56, 0x59, 0x22, 0xf1, 0xc0, + 0x4f, 0xa2, 0x0b, 0x33, 0x1d, 0x86, 0x33, 0x12, 0xeb, 0xc8, 0x93, 0x49, 0xac, 0x34, 0xb7, 0x30, + 0x63, 0xc8, 0x04, 0x35, 0x43, 0x0d, 0x9b, 0x15, 0x7f, 0x75, 0x56, 0xfc, 0x62, 0x11, 0x5a, 0xf6, + 0xa9, 0xb4, 0xcf, 0xe2, 0xc9, 0x58, 0x29, 0x47, 0x06, 0x2f, 0x6e, 0x41, 0xa7, 0x78, 0x0e, 0x8c, + 0xab, 0x67, 0xf2, 0x82, 0x14, 0xa4, 0x66, 0xe2, 0xa7, 0x58, 0x86, 0x3a, 0x79, 0x22, 0x52, 0x8f, + 0xf6, 0x1a, 0xe0, 0x71, 0x78, 0x8a, 0xc9, 0x84, 0x4f, 0xb5, 0x1f, 0x56, 0x70, 0x9d, 0xe2, 0xe9, + 0x8a, 0xeb, 0xe8, 0x57, 0xaf, 0xc3, 0x53, 0x0a, 0xeb, 0x18, 0x01, 0x34, 0x77, 0x5c, 0x5b, 0xfa, + 0x31, 0x45, 0xdf, 0x49, 0x2c, 0x33, 0xaf, 0x81, 0xdf, 0x78, 0x95, 0xb1, 0x35, 0xdd, 0x0d, 0x1c, + 0x19, 0xd3, 0x3a, 0x35, 0x33, 0x83, 0x91, 0x26, 0xa7, 0xa1, 0x1b, 0x5d, 0x0c, 0x99, 0x09, 0x55, + 0x33, 0x83, 0x31, 0xbc, 0x49, 0x1f, 0x37, 0x73, 0xd2, 0x48, 0xaa, 0x40, 0xe3, 0xcf, 0xab, 0xd0, + 0xf9, 0x52, 0x46, 0xc1, 0x7e, 0x14, 0x84, 0x41, 0x6c, 0x79, 0x62, 0xbd, 0xcc, 0x4e, 0x16, 0xdb, + 0x32, 0x9e, 0xb6, 0x38, 0x6c, 0xf5, 0x20, 0xe3, 0x2f, 0x8b, 0xa3, 0xc8, 0x70, 0x03, 0x1a, 0x2c, + 0xce, 0x39, 0x3c, 0x53, 0x14, 0x1c, 0xc3, 0x02, 0xa4, 0xb3, 0x96, 0xf9, 0xa1, 0x28, 0xe2, 0x2e, + 0xc0, 0xd8, 0x9a, 0xee, 0x48, 0x2b, 0x96, 0xdb, 0x4e, 0x6a, 0xd7, 0x39, 0x46, 0x71, 0x63, 0x38, + 0xf5, 0x87, 0x31, 0xd9, 0x17, 0x73, 0x83, 0x60, 0xf1, 0x36, 0xe8, 0x63, 0x6b, 0x8a, 0x0e, 0x66, + 0xdb, 0x61, 0x4b, 0x32, 0x73, 0x84, 0x78, 0x17, 0xaa, 0xc9, 0xd4, 0x27, 0x6f, 0x8d, 0xc1, 0x1c, + 0x73, 0xbb, 0xe1, 0xd4, 0x57, 0xae, 0xc8, 0x44, 0x5a, 0x2a, 0xc1, 0x56, 0x2e, 0xc1, 0x1e, 0x54, + 0x6d, 0xd7, 0xa1, 0x68, 0xae, 0x9b, 0xf8, 0x29, 0xee, 0x41, 0xd3, 0x63, 0x69, 0x51, 0xc4, 0x6e, + 0xaf, 0xb5, 0xd9, 0xd1, 0x11, 0xca, 0x4c, 0x69, 0x8b, 0xbf, 0x01, 0xd7, 0x67, 0xd8, 0x55, 0xd4, + 0x8f, 0x2e, 0xaf, 0x7e, 0xab, 0xa8, 0x1f, 0xb5, 0xa2, 0x4e, 0xfc, 0x4b, 0x15, 0xae, 0x2b, 0x25, + 0x3d, 0x75, 0xc3, 0x83, 0x04, 0xed, 0xbd, 0x0f, 0x4d, 0xf2, 0xd6, 0x4a, 0x3f, 0x6a, 0x66, 0x0a, + 0x8a, 0xff, 0x0f, 0x0d, 0x32, 0xdc, 0xd4, 0x7e, 0x96, 0x72, 0xe6, 0x67, 0xd3, 0xd9, 0x9e, 0x94, + 0xe4, 0xd4, 0x70, 0xf1, 0x03, 0xa8, 0x7f, 0x25, 0xa3, 0x80, 0xa3, 0x4f, 0x7b, 0xed, 0xee, 0xbc, + 0x79, 0xa8, 0x02, 0x6a, 0x1a, 0x0f, 0xfe, 0x35, 0xca, 0xe8, 0x7d, 0x8c, 0x37, 0xe3, 0xe0, 0x5c, + 0x3a, 0xfd, 0x26, 0x9d, 0xa8, 0xa8, 0x46, 0x29, 0x29, 0x15, 0x4a, 0x6b, 0xae, 0x50, 0xf4, 0xd7, + 0x08, 0x65, 0x13, 0xda, 0x05, 0x2e, 0xcc, 0x11, 0xc8, 0x52, 0xd9, 0x60, 0xf5, 0xcc, 0x0f, 0x15, + 0xed, 0x7e, 0x13, 0x20, 0xe7, 0xc9, 0xaf, 0xea, 0x3d, 0x8c, 0xdf, 0xa9, 0xc0, 0xf5, 0x27, 0x81, + 0xef, 0x4b, 0xca, 0x4a, 0x59, 0xc2, 0xb9, 0x11, 0x55, 0xae, 0x34, 0xa2, 0xef, 0x43, 0x3d, 0xc6, + 0xc1, 0x6a, 0xf5, 0x9b, 0x73, 0x44, 0x66, 0xf2, 0x08, 0xf4, 0x92, 0x63, 0x6b, 0x3a, 0x0a, 0xa5, + 0xef, 0xb8, 0xfe, 0x49, 0xea, 0x25, 0xc7, 0xd6, 0x74, 0x9f, 0x31, 0xc6, 0x1f, 0x6b, 0x00, 0x9f, + 0x49, 0xcb, 0x4b, 0x4e, 0x31, 0x12, 0xa0, 0xdc, 0x5c, 0x3f, 0x4e, 0x2c, 0xdf, 0x4e, 0x6b, 0x82, + 0x0c, 0x46, 0xe5, 0xc3, 0xb0, 0x27, 0x63, 0x76, 0x42, 0xba, 0x99, 0x82, 0x18, 0x08, 0x71, 0xbb, + 0x49, 0xac, 0xc2, 0xa3, 0x82, 0xf2, 0x60, 0x5e, 0x23, 0xb4, 0x0a, 0xe6, 0x7d, 0x68, 0x62, 0x8e, + 0xed, 0x06, 0x3e, 0xa9, 0x86, 0x6e, 0xa6, 0x20, 0xae, 0x33, 0x09, 0x13, 0x77, 0xcc, 0x41, 0xb0, + 0x6a, 0x2a, 0x08, 0x4f, 0x85, 0x41, 0x6f, 0x60, 0x9f, 0x06, 0x64, 0xbc, 0x55, 0x33, 0x83, 0x71, + 0xb5, 0xc0, 0x3f, 0x09, 0xf0, 0x76, 0x2d, 0xca, 0x9f, 0x52, 0x90, 0xef, 0xe2, 0xc8, 0x29, 0x92, + 0x74, 0x22, 0x65, 0x30, 0xf2, 0x45, 0xca, 0xd1, 0xb1, 0xb4, 0x92, 0x49, 0x24, 0xe3, 0x3e, 0x10, + 0x19, 0xa4, 0xdc, 0x52, 0x18, 0xe3, 0xb7, 0x35, 0x68, 0xb0, 0x5f, 0x2a, 0x25, 0x0b, 0x95, 0x6f, + 0x94, 0x2c, 0xbc, 0x0d, 0x7a, 0x18, 0x49, 0xc7, 0xb5, 0x53, 0x21, 0xe9, 0x66, 0x8e, 0xa0, 0x2c, + 0x1d, 0xe3, 0x26, 0x31, 0xab, 0x65, 0x32, 0x80, 0xd8, 0x38, 0xb4, 0x6c, 0xa9, 0x2e, 0xc8, 0x00, + 0x72, 0x84, 0x55, 0x9e, 0x54, 0xbd, 0x65, 0x2a, 0x48, 0x7c, 0x0c, 0x3a, 0x65, 0x65, 0x14, 0xf0, + 0x75, 0x0a, 0xd4, 0xb7, 0x5f, 0xbd, 0x5c, 0x12, 0x88, 0x9c, 0x89, 0xf4, 0xad, 0x14, 0x87, 0x79, + 0x09, 0x4e, 0x46, 0xff, 0x0e, 0x94, 0x64, 0x50, 0x5e, 0x82, 0xa8, 0x61, 0x5c, 0xcc, 0x4b, 0x18, + 0x63, 0xfc, 0x93, 0x06, 0x9d, 0x4d, 0x37, 0x92, 0x76, 0x22, 0x9d, 0x81, 0x73, 0x42, 0x87, 0x91, + 0x7e, 0xe2, 0x26, 0x17, 0x2a, 0x93, 0x52, 0x50, 0x96, 0xe8, 0x6a, 0xe5, 0xc2, 0x8f, 0x2d, 0xa0, + 0x4a, 0xb5, 0x2a, 0x03, 0x62, 0x0d, 0x80, 0x4b, 0x00, 0xaa, 0x57, 0x6b, 0x57, 0xd7, 0xab, 0x3a, + 0x0d, 0xc3, 0x4f, 0xac, 0x07, 0x79, 0x8e, 0xcb, 0xe9, 0x54, 0x83, 0x8a, 0xd9, 0x09, 0x7a, 0x19, + 0xca, 0x9c, 0x8f, 0xa4, 0x47, 0xea, 0x42, 0x99, 0xf3, 0x91, 0xf4, 0xb2, 0x7a, 0xa5, 0xc9, 0xc7, + 0xc1, 0x6f, 0xf1, 0x1e, 0x68, 0x41, 0x48, 0x3c, 0x54, 0x1b, 0x16, 0x2f, 0xb6, 0xba, 0x17, 0x9a, + 0x5a, 0x10, 0xa2, 0xed, 0x71, 0x71, 0x46, 0xea, 0x82, 0xb6, 0x87, 0x11, 0x82, 0x4a, 0x05, 0x53, + 0x51, 0x84, 0x01, 0x1d, 0xcb, 0xf3, 0x82, 0x5f, 0x48, 0x67, 0x3f, 0x92, 0x4e, 0xaa, 0x39, 0x25, + 0x9c, 0x71, 0x1b, 0xb4, 0xbd, 0x50, 0x34, 0xa1, 0x7a, 0x30, 0x18, 0xf6, 0xae, 0xe1, 0xc7, 0xe6, + 0x60, 0xa7, 0x57, 0x31, 0xbe, 0xd6, 0x40, 0x7f, 0x3e, 0x49, 0x2c, 0xb4, 0xf6, 0x18, 0xef, 0x55, + 0x56, 0xab, 0x5c, 0x7f, 0xbe, 0x0b, 0xad, 0x38, 0xb1, 0x22, 0x8a, 0xc4, 0x1c, 0x17, 0x9a, 0x04, + 0x0f, 0x63, 0xf1, 0x3d, 0xa8, 0x4b, 0xe7, 0x44, 0xa6, 0xee, 0xba, 0x37, 0x7b, 0x17, 0x93, 0xc9, + 0x62, 0x05, 0x1a, 0xb1, 0x7d, 0x2a, 0xc7, 0x56, 0xbf, 0x96, 0x0f, 0x3c, 0x20, 0x0c, 0xe7, 0x8e, + 0xa6, 0xa2, 0x8b, 0xf7, 0xa1, 0x8e, 0xd2, 0x88, 0x55, 0xb1, 0x43, 0xe5, 0x11, 0x32, 0x5e, 0x0d, + 0x63, 0x22, 0xea, 0x8e, 0x13, 0x05, 0xe1, 0x28, 0x08, 0x89, 0xaf, 0x0b, 0x6b, 0xb7, 0xc8, 0xeb, + 0xa4, 0xb7, 0x59, 0xdd, 0x8c, 0x82, 0x70, 0x2f, 0x34, 0x1b, 0x0e, 0xfd, 0x62, 0x5d, 0x4b, 0xc3, + 0x59, 0x07, 0xd8, 0x4d, 0xeb, 0x88, 0xe1, 0x3e, 0xc6, 0x0a, 0xb4, 0xc6, 0x32, 0xb1, 0x1c, 0x2b, + 0xb1, 0x94, 0xb7, 0xee, 0xb0, 0x13, 0x63, 0x9c, 0x99, 0x51, 0x8d, 0x87, 0xd0, 0xe0, 0xa5, 0x45, + 0x0b, 0x6a, 0xbb, 0x7b, 0xbb, 0x03, 0x66, 0xe8, 0xfa, 0xce, 0x4e, 0xaf, 0x82, 0xa8, 0xcd, 0xf5, + 0xe1, 0x7a, 0x4f, 0xc3, 0xaf, 0xe1, 0x4f, 0xf7, 0x07, 0xbd, 0xaa, 0xf1, 0x8f, 0x15, 0x68, 0xa5, + 0xeb, 0x88, 0x4f, 0x01, 0xd0, 0xee, 0x46, 0xa7, 0xae, 0x9f, 0x25, 0x35, 0x77, 0x8a, 0x3b, 0xad, + 0xa2, 0xc4, 0x3e, 0x43, 0x2a, 0x87, 0x37, 0x32, 0x53, 0x82, 0x17, 0x0f, 0x60, 0xa1, 0x4c, 0x9c, + 0x93, 0xdd, 0xdd, 0x2f, 0xfa, 0xf9, 0x85, 0xb5, 0xef, 0x94, 0x96, 0xc6, 0x99, 0xa4, 0xcc, 0x05, + 0x97, 0xff, 0x00, 0x5a, 0x29, 0x5a, 0xb4, 0xa1, 0xb9, 0x39, 0xd8, 0x5a, 0x3f, 0xdc, 0x41, 0x25, + 0x01, 0x68, 0x1c, 0x6c, 0xef, 0x3e, 0xdd, 0x19, 0xf0, 0xb5, 0x76, 0xb6, 0x0f, 0x86, 0x3d, 0xcd, + 0xf8, 0xa3, 0x0a, 0xb4, 0xd2, 0x1c, 0x42, 0x7c, 0x1f, 0x83, 0x3f, 0xa5, 0x2a, 0x2a, 0x36, 0x50, + 0x3b, 0xa2, 0x50, 0x4c, 0x99, 0x29, 0x1d, 0x0d, 0x83, 0x5c, 0x5d, 0x9a, 0x55, 0x10, 0x50, 0x2c, + 0xe5, 0xaa, 0xa5, 0x6e, 0x02, 0x56, 0xa5, 0x81, 0x2f, 0x55, 0x92, 0x48, 0xdf, 0xa4, 0x83, 0xae, + 0x6f, 0x93, 0xb7, 0xa8, 0x2b, 0x1d, 0x44, 0x78, 0x18, 0x1b, 0x7f, 0x55, 0x83, 0x05, 0x53, 0xc6, + 0x49, 0x10, 0x49, 0x53, 0xfe, 0x7c, 0x82, 0xa5, 0xf6, 0x6b, 0x94, 0xf9, 0x1d, 0x80, 0x88, 0x07, + 0xe7, 0xea, 0xac, 0x2b, 0x0c, 0xa7, 0xe9, 0x5e, 0x60, 0x93, 0x16, 0xa9, 0xe8, 0x91, 0xc1, 0xe2, + 0x0e, 0xe8, 0x47, 0x96, 0x7d, 0xc6, 0xcb, 0x72, 0x0c, 0x69, 0x31, 0x82, 0xd7, 0xb5, 0x6c, 0x5b, + 0xc6, 0xf1, 0x08, 0x85, 0xc2, 0x91, 0x44, 0x67, 0xcc, 0x33, 0x79, 0x81, 0xe4, 0x58, 0xda, 0x91, + 0x4c, 0x88, 0xcc, 0x0e, 0x42, 0x67, 0x0c, 0x92, 0xdf, 0x83, 0x6e, 0x2c, 0x63, 0x8c, 0x3a, 0xa3, + 0x24, 0x38, 0x93, 0xbe, 0xf2, 0x16, 0x1d, 0x85, 0x1c, 0x22, 0x0e, 0xfd, 0xb8, 0xe5, 0x07, 0xfe, + 0xc5, 0x38, 0x98, 0xc4, 0xca, 0x01, 0xe7, 0x08, 0xb1, 0x0a, 0x37, 0xa5, 0x6f, 0x47, 0x17, 0x21, + 0x9e, 0x15, 0x77, 0x19, 0x1d, 0xbb, 0x9e, 0x54, 0x89, 0xe2, 0x8d, 0x9c, 0xf4, 0x4c, 0x5e, 0x6c, + 0xb9, 0x9e, 0xc4, 0x13, 0x9d, 0x5b, 0x13, 0x2f, 0x19, 0x51, 0x21, 0x09, 0x7c, 0x22, 0xc2, 0xac, + 0x63, 0x35, 0xf9, 0x21, 0xdc, 0x60, 0x72, 0x14, 0x78, 0xd2, 0x75, 0x78, 0xb1, 0x36, 0x8d, 0xba, + 0x4e, 0x04, 0x93, 0xf0, 0xb4, 0xd4, 0x2a, 0xdc, 0xe4, 0xb1, 0x7c, 0xa1, 0x74, 0x74, 0x87, 0xb7, + 0x26, 0xd2, 0x81, 0xa2, 0x94, 0xb7, 0x0e, 0xad, 0xe4, 0x94, 0x0a, 0xc4, 0x74, 0xeb, 0x7d, 0x2b, + 0x39, 0xc5, 0x68, 0xc8, 0xe4, 0x63, 0x57, 0x7a, 0x5c, 0xf8, 0xe9, 0x26, 0xcf, 0xd8, 0x42, 0x8c, + 0x78, 0x17, 0x3a, 0x6a, 0x40, 0x10, 0x8d, 0x2d, 0xee, 0x2f, 0xe9, 0x26, 0x4f, 0xda, 0x22, 0x14, + 0x6e, 0xa1, 0x64, 0xe5, 0x4f, 0xc6, 0xfd, 0x1e, 0x8b, 0x99, 0x31, 0xbb, 0x93, 0xb1, 0xf1, 0x3f, + 0x1a, 0xb4, 0xb2, 0x62, 0xe3, 0x3e, 0xe8, 0xe3, 0xd4, 0x73, 0xa8, 0x24, 0xa6, 0x5b, 0x72, 0x27, + 0x66, 0x4e, 0x17, 0xef, 0x80, 0x76, 0x76, 0xae, 0xbc, 0x58, 0x77, 0x95, 0xfb, 0xad, 0xe1, 0xd1, + 0xda, 0xea, 0xb3, 0x17, 0xa6, 0x76, 0x76, 0x9e, 0x27, 0x43, 0xf5, 0x37, 0x26, 0x43, 0x1f, 0xc0, + 0x75, 0xdb, 0x93, 0x96, 0x3f, 0xca, 0x83, 0x33, 0xeb, 0xc5, 0x02, 0xa1, 0xf7, 0xb3, 0x08, 0xad, + 0x0c, 0xbd, 0x99, 0x1b, 0xfa, 0x3d, 0xa8, 0x3b, 0xd2, 0x4b, 0xac, 0x62, 0x23, 0x70, 0x2f, 0xb2, + 0x6c, 0x4f, 0x6e, 0x22, 0xda, 0x64, 0x2a, 0xfa, 0xb5, 0xb4, 0x20, 0x2a, 0xfa, 0xb5, 0xd4, 0x84, + 0xcd, 0x8c, 0x9a, 0x5b, 0x28, 0x14, 0x2d, 0xf4, 0x3e, 0xdc, 0x90, 0xd3, 0x90, 0x9c, 0xf9, 0x28, + 0x2b, 0x5e, 0xdb, 0x34, 0xa2, 0x97, 0x12, 0x9e, 0x28, 0xbc, 0xf8, 0x08, 0xcd, 0x99, 0xcc, 0x88, + 0x04, 0xdf, 0x5e, 0x13, 0xe4, 0x0f, 0x4a, 0x86, 0x69, 0xa6, 0x43, 0x0c, 0x1f, 0xaa, 0xcf, 0x5e, + 0x1c, 0x28, 0x6e, 0x56, 0xae, 0xe2, 0x66, 0xea, 0x09, 0xb4, 0x82, 0x27, 0xb8, 0xcb, 0x4e, 0x94, + 0x58, 0x93, 0x36, 0xa9, 0x0a, 0x18, 0xbc, 0x0a, 0x07, 0x90, 0x1a, 0xf7, 0xaf, 0x08, 0x30, 0xfe, + 0xab, 0x0a, 0x4d, 0x15, 0xd5, 0x91, 0x9f, 0x93, 0xac, 0xff, 0x82, 0x9f, 0xe5, 0xb2, 0x27, 0x4b, + 0x0f, 0x8a, 0xcd, 0xec, 0xea, 0x9b, 0x9b, 0xd9, 0xe2, 0x53, 0xe8, 0x84, 0x4c, 0x2b, 0x26, 0x14, + 0x6f, 0x15, 0xe7, 0xa8, 0x5f, 0x9a, 0xd7, 0x0e, 0x73, 0x00, 0x3d, 0x16, 0x75, 0xfa, 0x12, 0xeb, + 0x84, 0x54, 0xa7, 0x63, 0x36, 0x11, 0x1e, 0x5a, 0x27, 0x57, 0xa4, 0x15, 0xdf, 0x24, 0x3b, 0x58, + 0xa0, 0x34, 0xa3, 0x43, 0x0e, 0x10, 0x33, 0x8a, 0x62, 0x20, 0xef, 0x96, 0x03, 0xf9, 0x1d, 0xd0, + 0xed, 0x60, 0x3c, 0x76, 0x89, 0xb6, 0xa0, 0xfa, 0x13, 0x84, 0x18, 0xc6, 0xc6, 0xef, 0x55, 0xa0, + 0xa9, 0x6e, 0x7b, 0x29, 0x4c, 0x6c, 0x6c, 0xef, 0xae, 0x9b, 0x3f, 0xed, 0x55, 0x30, 0x0c, 0x6e, + 0xef, 0x0e, 0x7b, 0x9a, 0xd0, 0xa1, 0xbe, 0xb5, 0xb3, 0xb7, 0x3e, 0xec, 0x55, 0x31, 0x74, 0x6c, + 0xec, 0xed, 0xed, 0xf4, 0x6a, 0xa2, 0x03, 0xad, 0xcd, 0xf5, 0xe1, 0x60, 0xb8, 0xfd, 0x7c, 0xd0, + 0xab, 0xe3, 0xd8, 0xa7, 0x83, 0xbd, 0x5e, 0x03, 0x3f, 0x0e, 0xb7, 0x37, 0x7b, 0x4d, 0xa4, 0xef, + 0xaf, 0x1f, 0x1c, 0x7c, 0xb1, 0x67, 0x6e, 0xf6, 0x5a, 0x14, 0x7e, 0x86, 0xe6, 0xf6, 0xee, 0xd3, + 0x9e, 0x8e, 0xdf, 0x7b, 0x1b, 0x3f, 0x1e, 0x3c, 0x19, 0xf6, 0xc0, 0x78, 0x0c, 0xed, 0x02, 0x07, + 0x71, 0xb6, 0x39, 0xd8, 0xea, 0x5d, 0xc3, 0x2d, 0x5f, 0xac, 0xef, 0x1c, 0x62, 0xb4, 0x5a, 0x00, + 0xa0, 0xcf, 0xd1, 0xce, 0xfa, 0xee, 0xd3, 0x9e, 0x66, 0x7c, 0x0e, 0xad, 0x43, 0xd7, 0xd9, 0xf0, + 0x02, 0xfb, 0x0c, 0xd5, 0xe9, 0xc8, 0x8a, 0xa5, 0x2a, 0x8d, 0xe8, 0x1b, 0xb3, 0x48, 0x32, 0x96, + 0x58, 0xc9, 0x5e, 0x41, 0xc8, 0x2b, 0x7f, 0x32, 0x1e, 0xd1, 0x03, 0x48, 0x95, 0x43, 0x88, 0x3f, + 0x19, 0x1f, 0xba, 0x4e, 0x6c, 0x9c, 0x41, 0xf3, 0xd0, 0x75, 0xf6, 0x2d, 0xfb, 0x8c, 0xdc, 0x0c, + 0x2e, 0x3d, 0x8a, 0xdd, 0xaf, 0xa4, 0x0a, 0x35, 0x3a, 0x61, 0x0e, 0xdc, 0xaf, 0xa4, 0x78, 0x1f, + 0x1a, 0x04, 0xa4, 0x65, 0x30, 0x99, 0x5f, 0x7a, 0x1c, 0x53, 0xd1, 0xe8, 0xfd, 0xc1, 0xf3, 0x02, + 0x7b, 0x14, 0xc9, 0xe3, 0xfe, 0x5b, 0xcc, 0x7b, 0x42, 0x98, 0xf2, 0xd8, 0xf8, 0x83, 0x4a, 0x76, + 0x67, 0x6a, 0x7f, 0x2f, 0x41, 0x2d, 0xb4, 0xec, 0x33, 0x15, 0x73, 0xdb, 0x6a, 0x41, 0x3c, 0x8c, + 0x49, 0x04, 0xf1, 0x01, 0xb4, 0x94, 0x62, 0xa5, 0xbb, 0xb6, 0x0b, 0x1a, 0x68, 0x66, 0xc4, 0xb2, + 0xc8, 0xab, 0x65, 0x91, 0x53, 0x0d, 0x15, 0x7a, 0x6e, 0xc2, 0x66, 0x54, 0x33, 0x15, 0x64, 0xfc, + 0x00, 0x20, 0x7f, 0x71, 0x98, 0x93, 0x82, 0xdc, 0x82, 0xba, 0xe5, 0xb9, 0x56, 0x5a, 0x93, 0x31, + 0x60, 0xec, 0x42, 0xbb, 0xf0, 0x4e, 0x81, 0xbc, 0xb5, 0x3c, 0x0f, 0x63, 0x54, 0x4c, 0x73, 0x5b, + 0x66, 0xd3, 0xf2, 0xbc, 0x67, 0xf2, 0x22, 0xc6, 0xf4, 0x8f, 0x9f, 0x38, 0xb4, 0x99, 0xee, 0x38, + 0x4d, 0x35, 0x99, 0x68, 0x7c, 0x04, 0x8d, 0xad, 0x34, 0x01, 0x4e, 0xcd, 0xa0, 0x72, 0x95, 0x19, + 0x18, 0x9f, 0xa8, 0x33, 0x53, 0x83, 0x5d, 0xdc, 0x57, 0x4f, 0x29, 0x31, 0x3f, 0xdc, 0x54, 0xf2, + 0xaa, 0x9e, 0x07, 0xa9, 0x57, 0x14, 0x1a, 0x6c, 0x6c, 0x42, 0xeb, 0xb5, 0x8f, 0x53, 0x8a, 0x01, + 0x5a, 0xce, 0x80, 0x39, 0xcf, 0x55, 0xc6, 0xcf, 0x00, 0xf2, 0x27, 0x17, 0x65, 0x95, 0xbc, 0x0a, + 0x5a, 0xe5, 0x87, 0xd0, 0xb2, 0x4f, 0x5d, 0xcf, 0x89, 0xa4, 0x5f, 0xba, 0x75, 0xfe, 0x48, 0x93, + 0xd1, 0xc5, 0x32, 0xd4, 0xe8, 0x25, 0xa9, 0x9a, 0x7b, 0xf3, 0xec, 0x19, 0x89, 0x28, 0xc6, 0x14, + 0xba, 0x9c, 0x57, 0x7f, 0x83, 0x5c, 0xa8, 0xec, 0x4a, 0xb5, 0x4b, 0xae, 0xf4, 0x36, 0x34, 0x28, + 0x04, 0xa7, 0xb7, 0x51, 0xd0, 0x15, 0x2e, 0xf6, 0x77, 0x35, 0x00, 0xde, 0x7a, 0x37, 0x70, 0x64, + 0xb9, 0xea, 0xac, 0xcc, 0x56, 0x9d, 0x02, 0x6a, 0xd9, 0x23, 0xa1, 0x6e, 0xd2, 0x77, 0x1e, 0x84, + 0x54, 0x25, 0xca, 0x41, 0xe8, 0x6d, 0xd0, 0x29, 0x25, 0x72, 0xbf, 0xa2, 0xce, 0x36, 0x6e, 0x98, + 0x23, 0x8a, 0x4f, 0x66, 0xf5, 0xf2, 0x93, 0x59, 0xf6, 0xae, 0xd0, 0xe0, 0xd5, 0xf8, 0x5d, 0x61, + 0xce, 0x13, 0x09, 0xd7, 0xf9, 0xb1, 0x8c, 0x92, 0xb4, 0xaa, 0x65, 0x28, 0xab, 0xdc, 0x74, 0x35, + 0xd6, 0xe2, 0x4a, 0xdd, 0x0f, 0x46, 0x76, 0xe0, 0x1f, 0x7b, 0xae, 0x9d, 0xa8, 0x27, 0x32, 0xf0, + 0x83, 0x27, 0x0a, 0x63, 0x7c, 0x0a, 0x9d, 0x94, 0xff, 0xf4, 0x12, 0xf1, 0x61, 0x56, 0xf9, 0x54, + 0x72, 0xd9, 0xe6, 0x6c, 0xda, 0xd0, 0xfa, 0x95, 0xb4, 0xf6, 0x31, 0xfe, 0xb3, 0x9a, 0x4e, 0x56, + 0x0d, 0xf5, 0xd7, 0xf3, 0xb0, 0x5c, 0xbe, 0x6a, 0xdf, 0xa8, 0x7c, 0xfd, 0x21, 0xe8, 0x0e, 0xd5, + 0x67, 0xee, 0x79, 0x1a, 0xd4, 0x16, 0x67, 0x6b, 0x31, 0x55, 0xc1, 0xb9, 0xe7, 0xd2, 0xcc, 0x07, + 0xbf, 0x41, 0x0e, 0x19, 0xb7, 0xeb, 0xf3, 0xb8, 0xdd, 0xf8, 0x15, 0xb9, 0xfd, 0x2e, 0x74, 0xfc, + 0xc0, 0x1f, 0xf9, 0x13, 0xcf, 0xb3, 0x8e, 0x3c, 0xa9, 0xd8, 0xdd, 0xf6, 0x03, 0x7f, 0x57, 0xa1, + 0x30, 0x4f, 0x2d, 0x0e, 0x61, 0xa3, 0x6e, 0xd3, 0xb8, 0xeb, 0x85, 0x71, 0x64, 0xfa, 0x2b, 0xd0, + 0x0b, 0x8e, 0x7e, 0x26, 0xed, 0x84, 0x38, 0x36, 0x22, 0x6b, 0xe6, 0x24, 0x75, 0x81, 0xf1, 0xc8, + 0xa2, 0x5d, 0xb4, 0xeb, 0x19, 0x31, 0x77, 0x2f, 0x89, 0xf9, 0x13, 0xd0, 0x33, 0x2e, 0x15, 0x6a, + 0x41, 0x1d, 0xea, 0xdb, 0xbb, 0x9b, 0x83, 0x9f, 0xf4, 0x2a, 0x18, 0x28, 0xcd, 0xc1, 0x8b, 0x81, + 0x79, 0x30, 0xe8, 0x69, 0x18, 0xc4, 0x36, 0x07, 0x3b, 0x83, 0xe1, 0xa0, 0x57, 0xfd, 0x71, 0xad, + 0xd5, 0xec, 0xb5, 0xa8, 0x2d, 0xee, 0xb9, 0xb6, 0x9b, 0x18, 0x07, 0x00, 0x79, 0x81, 0x8b, 0x5e, + 0x39, 0x3f, 0x9c, 0xea, 0x79, 0x25, 0xe9, 0xb1, 0x56, 0x32, 0x83, 0xd4, 0xae, 0x2a, 0xa3, 0x99, + 0x6e, 0xac, 0x81, 0xfe, 0xdc, 0x0a, 0x3f, 0xe3, 0x17, 0xa0, 0x7b, 0xb0, 0x10, 0x5a, 0x51, 0xe2, + 0xa6, 0x95, 0x01, 0x3b, 0xcb, 0x8e, 0xd9, 0xcd, 0xb0, 0xe8, 0x7b, 0x8d, 0xbf, 0xae, 0xc0, 0xad, + 0xe7, 0xc1, 0xb9, 0xcc, 0x32, 0xcf, 0x7d, 0xeb, 0xc2, 0x0b, 0x2c, 0xe7, 0x0d, 0x6a, 0x88, 0xa5, + 0x4d, 0x30, 0xa1, 0xb7, 0x9a, 0xf4, 0xfd, 0xca, 0xd4, 0x19, 0xf3, 0x54, 0x3d, 0xa0, 0xcb, 0x38, + 0x21, 0xa2, 0x0a, 0xa4, 0x08, 0x23, 0xe9, 0x3b, 0xd0, 0x48, 0xa6, 0x7e, 0xfe, 0x5c, 0x56, 0x4f, + 0xa8, 0x23, 0x3b, 0x37, 0xed, 0xac, 0xcf, 0x4f, 0x3b, 0x8d, 0x27, 0xa0, 0x0f, 0xa7, 0xd4, 0xad, + 0x9c, 0xc4, 0xa5, 0x04, 0xa7, 0xf2, 0x9a, 0x04, 0x47, 0x9b, 0x49, 0x70, 0xfe, 0xbd, 0x02, 0xed, + 0x42, 0xfe, 0x2c, 0xde, 0x85, 0x5a, 0x32, 0xf5, 0xcb, 0x8f, 0xd2, 0xe9, 0x26, 0x26, 0x91, 0x50, + 0x35, 0xc7, 0xd6, 0x74, 0x64, 0xc5, 0xb1, 0x7b, 0xe2, 0x4b, 0x47, 0x2d, 0xd9, 0x1e, 0x5b, 0xd3, + 0x75, 0x85, 0x12, 0x3b, 0x70, 0x9d, 0x3d, 0x6f, 0x7a, 0x89, 0xb4, 0x4d, 0xf2, 0xde, 0x4c, 0xbe, + 0xce, 0x1d, 0xdd, 0xf4, 0x4a, 0xaa, 0xf6, 0x5f, 0x38, 0x29, 0x21, 0x17, 0xd7, 0xe1, 0xe6, 0x9c, + 0x61, 0xdf, 0xaa, 0x87, 0xbf, 0x04, 0xdd, 0xe1, 0xd4, 0x1f, 0xba, 0x63, 0x19, 0x27, 0xd6, 0x38, + 0xa4, 0x04, 0x51, 0x45, 0xce, 0x9a, 0xa9, 0x25, 0xb1, 0xf1, 0x3d, 0xe8, 0xec, 0x4b, 0x19, 0x99, + 0x32, 0x0e, 0x03, 0x9f, 0x93, 0x23, 0xd5, 0x49, 0xe5, 0x30, 0xad, 0x20, 0xe3, 0xb7, 0x40, 0xc7, + 0x42, 0x7f, 0xc3, 0x4a, 0xec, 0xd3, 0x6f, 0xd3, 0x08, 0xf8, 0x1e, 0x34, 0x43, 0xd6, 0x29, 0x55, + 0x67, 0x75, 0x28, 0x5c, 0x2b, 0x3d, 0x33, 0x53, 0xa2, 0xf1, 0x18, 0x6e, 0x1e, 0x4c, 0x8e, 0x62, + 0x3b, 0x72, 0xa9, 0x64, 0x4d, 0x43, 0xd9, 0x22, 0xb4, 0xc2, 0x48, 0x1e, 0xbb, 0x53, 0x99, 0x6a, + 0x70, 0x06, 0x1b, 0x3f, 0x82, 0x5b, 0xe5, 0x29, 0xea, 0x0a, 0xef, 0x41, 0xf5, 0xec, 0x3c, 0x56, + 0x27, 0xbb, 0x51, 0x2a, 0x31, 0xe8, 0x2d, 0x18, 0xa9, 0x86, 0x09, 0xd5, 0xdd, 0xc9, 0xb8, 0xf8, + 0x7f, 0x96, 0x1a, 0xff, 0x9f, 0xe5, 0x4e, 0xb1, 0xb1, 0xc9, 0x55, 0x48, 0xde, 0xc0, 0x7c, 0x1b, + 0xf4, 0xe3, 0x20, 0xfa, 0x85, 0x15, 0x39, 0xd2, 0x51, 0x31, 0x2b, 0x47, 0x18, 0x5f, 0x42, 0x3b, + 0xd5, 0x84, 0x6d, 0x87, 0x1e, 0xbf, 0x48, 0x15, 0xb7, 0x9d, 0x92, 0x66, 0x72, 0xdb, 0x50, 0xfa, + 0xce, 0x76, 0xaa, 0x42, 0x0c, 0x94, 0x77, 0x56, 0x6f, 0x16, 0xe9, 0xce, 0xc6, 0x16, 0x74, 0xd2, + 0x22, 0xee, 0xb9, 0x4c, 0x2c, 0x52, 0x6e, 0xcf, 0x95, 0x7e, 0x41, 0xf1, 0x5b, 0x8c, 0x18, 0x96, + 0x3b, 0x7b, 0x5a, 0x29, 0x01, 0x30, 0x56, 0xa1, 0xa1, 0x2c, 0x47, 0x40, 0xcd, 0x0e, 0x1c, 0xb6, + 0xee, 0xba, 0x49, 0xdf, 0xc8, 0x8e, 0x71, 0x7c, 0x92, 0x26, 0x37, 0xe3, 0xf8, 0xc4, 0xf8, 0x5b, + 0x0d, 0xba, 0x1b, 0x54, 0x44, 0xa7, 0x22, 0x29, 0x34, 0x71, 0x2a, 0xa5, 0x26, 0x4e, 0xb1, 0x61, + 0xa3, 0x95, 0x1a, 0x36, 0xa5, 0x03, 0x55, 0xcb, 0x19, 0xc9, 0x5b, 0xd0, 0x9c, 0xf8, 0xee, 0x34, + 0x75, 0x09, 0xba, 0xd9, 0x40, 0x70, 0x18, 0x8b, 0x65, 0x68, 0xa3, 0xd7, 0x70, 0x7d, 0x6e, 0xcd, + 0x70, 0x7f, 0xa5, 0x88, 0x9a, 0x69, 0xc0, 0x34, 0x5e, 0xdf, 0x80, 0x69, 0xbe, 0xb1, 0x01, 0xd3, + 0x7a, 0x53, 0x03, 0x46, 0x9f, 0x6d, 0xc0, 0x94, 0xb3, 0x29, 0x98, 0xcd, 0xa6, 0x8c, 0x1d, 0x58, + 0x48, 0x79, 0xa7, 0x74, 0xf3, 0x53, 0xb8, 0xae, 0xba, 0x98, 0x32, 0x52, 0xed, 0x07, 0xf6, 0x38, + 0x37, 0xa8, 0x8f, 0x4a, 0x8d, 0x46, 0x45, 0x31, 0x17, 0x9c, 0x22, 0x18, 0x1b, 0xbf, 0x5f, 0x81, + 0x6e, 0x69, 0x84, 0x78, 0x9c, 0xf7, 0x44, 0x2b, 0x14, 0xd8, 0xfb, 0x97, 0x56, 0x79, 0x7d, 0x5f, + 0x54, 0x9b, 0xe9, 0x8b, 0x1a, 0xf7, 0xb2, 0x6e, 0xa7, 0xea, 0x71, 0x5e, 0xcb, 0x7a, 0x9c, 0xd4, + 0x16, 0x5c, 0x1f, 0x0e, 0xcd, 0x9e, 0x66, 0xfc, 0x89, 0x06, 0xdd, 0xc1, 0x34, 0xa4, 0x7f, 0x5f, + 0xbc, 0x31, 0xe7, 0x2c, 0x28, 0x8c, 0x56, 0x52, 0x98, 0x82, 0xe8, 0xab, 0xea, 0xb9, 0x85, 0x45, + 0x8f, 0x59, 0x28, 0xf7, 0x79, 0x94, 0x4a, 0x30, 0xf4, 0x7f, 0x40, 0x25, 0x50, 0xe4, 0x29, 0x63, + 0x94, 0xc8, 0xbf, 0x91, 0x9d, 0xf1, 0x3f, 0xa7, 0xbc, 0xac, 0xbd, 0xc1, 0x80, 0xf1, 0x87, 0x1a, + 0xe8, 0xac, 0x41, 0x78, 0xbc, 0xef, 0xab, 0x0c, 0xba, 0x92, 0xf7, 0x7a, 0x33, 0xe2, 0xea, 0x33, + 0x79, 0x41, 0x99, 0x1f, 0x27, 0xd6, 0xf3, 0x5e, 0x44, 0x54, 0x13, 0x84, 0xeb, 0x3e, 0x6a, 0x82, + 0xdc, 0x01, 0x9d, 0x83, 0xe7, 0xc4, 0x4d, 0xdf, 0x50, 0x39, 0x9a, 0x1e, 0xba, 0xf4, 0x87, 0x93, + 0x44, 0x46, 0x63, 0xc5, 0x65, 0xfa, 0x2e, 0x67, 0xd8, 0x5d, 0x95, 0xf3, 0x19, 0xa7, 0xd0, 0x54, + 0xbb, 0x63, 0x0a, 0x74, 0xb8, 0xfb, 0x6c, 0x77, 0xef, 0x8b, 0xdd, 0x92, 0xe6, 0x64, 0x49, 0x92, + 0x56, 0x4c, 0x92, 0xaa, 0x88, 0x7f, 0xb2, 0x77, 0xb8, 0x3b, 0xec, 0xd5, 0x44, 0x17, 0x74, 0xfa, + 0x1c, 0x99, 0x83, 0x17, 0xbd, 0x3a, 0xf5, 0x03, 0x9e, 0x7c, 0x36, 0x78, 0xbe, 0xde, 0x6b, 0x64, + 0xbd, 0xf5, 0xa6, 0xf1, 0x17, 0x15, 0xb8, 0xc1, 0x57, 0x2e, 0x16, 0xc8, 0xc5, 0x7f, 0x2d, 0xd6, + 0xf8, 0x5f, 0x8b, 0xbf, 0xde, 0x9a, 0x18, 0x27, 0x4d, 0x5c, 0x67, 0x74, 0x74, 0x81, 0x76, 0xcf, + 0xcd, 0x9b, 0xd6, 0xc4, 0x75, 0x36, 0x10, 0x36, 0xfe, 0xbe, 0x02, 0x8b, 0x9c, 0x9b, 0x3d, 0x8d, + 0xac, 0xf0, 0xf4, 0xf3, 0x9d, 0x4b, 0xd5, 0xd9, 0x55, 0x19, 0xcb, 0x3d, 0x58, 0xa0, 0xff, 0x75, + 0xfe, 0xdc, 0x1b, 0xa9, 0x0a, 0x82, 0xe5, 0xd7, 0x55, 0x58, 0x5e, 0x48, 0x7c, 0x0c, 0x1d, 0xfe, + 0xff, 0x27, 0xf5, 0x11, 0x4b, 0x2f, 0x31, 0xa5, 0xcc, 0xb0, 0xcd, 0xa3, 0xe8, 0x4d, 0x48, 0x3c, + 0xce, 0x26, 0xe5, 0x85, 0xdc, 0xe5, 0xc7, 0x16, 0x35, 0x65, 0x48, 0xe5, 0xdd, 0x43, 0xb8, 0x33, + 0xf7, 0x1e, 0x4a, 0xb1, 0x0b, 0x4d, 0x35, 0xd6, 0xa7, 0xb5, 0xbf, 0xab, 0x40, 0x0d, 0xb3, 0x00, + 0xf1, 0x00, 0xf4, 0xcf, 0xa4, 0x15, 0x25, 0x47, 0xd2, 0x4a, 0x44, 0x29, 0xe2, 0x2f, 0xd2, 0x8e, + 0xf9, 0x83, 0xaf, 0x71, 0xed, 0x51, 0x45, 0xac, 0xf2, 0x5f, 0xb2, 0xd2, 0x7f, 0x9a, 0x75, 0xd3, + 0x6c, 0x82, 0xb2, 0x8d, 0xc5, 0xd2, 0x7c, 0xe3, 0xda, 0x0a, 0x8d, 0xff, 0x71, 0xe0, 0xfa, 0x4f, + 0xf8, 0x1f, 0x44, 0x62, 0x36, 0xfb, 0x98, 0x9d, 0x21, 0x1e, 0x40, 0x63, 0x3b, 0xc6, 0x34, 0xe7, + 0xf2, 0x50, 0xe2, 0x5a, 0x31, 0x03, 0x32, 0xae, 0xad, 0xfd, 0x65, 0x15, 0x6a, 0x5f, 0xca, 0x28, + 0x10, 0x1f, 0x41, 0x53, 0x3d, 0x8f, 0x8b, 0xc2, 0x33, 0xf8, 0x22, 0x55, 0x5c, 0x33, 0xef, 0xe6, + 0xb4, 0x4b, 0x8f, 0xd9, 0x95, 0x77, 0x7f, 0x45, 0xfe, 0x7a, 0x7f, 0xe9, 0x50, 0x9f, 0x40, 0xef, + 0x20, 0x89, 0xa4, 0x35, 0x2e, 0x0c, 0x2f, 0xb3, 0x6a, 0x5e, 0x2b, 0x99, 0xf8, 0x75, 0x1f, 0x1a, + 0x9c, 0x4b, 0xce, 0x4c, 0x98, 0xed, 0x0a, 0xd3, 0xe0, 0x0f, 0xa0, 0x7d, 0x70, 0x1a, 0x4c, 0x3c, + 0xe7, 0x40, 0x46, 0xe7, 0x52, 0x14, 0xfe, 0xf0, 0xb2, 0x58, 0xf8, 0x36, 0xae, 0x89, 0x15, 0x00, + 0x4e, 0x5f, 0x0e, 0xd1, 0x80, 0x9a, 0x48, 0xdb, 0x9d, 0x8c, 0x79, 0xd1, 0x42, 0x5e, 0xc3, 0x23, + 0x0b, 0x29, 0xe5, 0xeb, 0x46, 0x7e, 0x0c, 0xdd, 0x27, 0x64, 0x4c, 0x7b, 0xd1, 0xfa, 0x51, 0x10, + 0x25, 0x62, 0xf6, 0x4f, 0x2f, 0x8b, 0xb3, 0x08, 0xe3, 0x9a, 0x78, 0x04, 0xad, 0x61, 0x74, 0xc1, + 0xe3, 0x6f, 0xa8, 0x4c, 0x3c, 0xdf, 0x6f, 0xce, 0x2d, 0xd7, 0xfe, 0xbb, 0x06, 0x8d, 0x2f, 0x82, + 0xe8, 0x4c, 0x46, 0x58, 0x7d, 0x53, 0x17, 0x5f, 0xa9, 0x51, 0xd6, 0xd1, 0x9f, 0xb7, 0xd1, 0xfb, + 0xa0, 0x13, 0x53, 0x86, 0x56, 0x7c, 0xc6, 0xa2, 0xa2, 0x3f, 0x12, 0x33, 0x5f, 0xb8, 0x9a, 0x27, + 0xb9, 0x2e, 0xb0, 0xa0, 0xb2, 0x87, 0xb0, 0x52, 0x4f, 0x7d, 0x91, 0xee, 0xff, 0xec, 0xc5, 0x01, + 0xaa, 0xe6, 0xa3, 0x0a, 0x7a, 0xe9, 0x03, 0xbe, 0x29, 0x0e, 0xca, 0xff, 0x40, 0xc9, 0x9a, 0x9f, + 0xff, 0x63, 0xd1, 0xb8, 0x26, 0x1e, 0x42, 0x43, 0x99, 0xf4, 0x8d, 0xdc, 0x78, 0x95, 0x9f, 0x58, + 0xec, 0x15, 0x51, 0x6a, 0xc2, 0x63, 0x68, 0xb0, 0xfb, 0xe3, 0x09, 0xa5, 0xc4, 0x6c, 0x51, 0x14, + 0x51, 0xa9, 0x32, 0x8b, 0xfb, 0xd0, 0x54, 0x1d, 0x79, 0x31, 0xa7, 0x3d, 0xcf, 0x57, 0xe5, 0x8c, + 0x90, 0xd7, 0xe7, 0xe8, 0xc5, 0xeb, 0x97, 0x42, 0x3c, 0xaf, 0x5f, 0x0e, 0x6e, 0xac, 0xf5, 0xa6, + 0xb4, 0xa5, 0x5b, 0x28, 0x22, 0x45, 0xca, 0x91, 0x39, 0xa6, 0xfb, 0x09, 0x74, 0x4b, 0x05, 0xa7, + 0xa0, 0x94, 0x65, 0x5e, 0x0d, 0x7a, 0xc9, 0x60, 0x7e, 0x04, 0xba, 0xca, 0xf7, 0x8f, 0xa4, 0xa0, + 0x1e, 0xfb, 0x9c, 0x8a, 0x61, 0xf1, 0x72, 0xc2, 0x4f, 0x56, 0xf0, 0x13, 0xb8, 0x39, 0xc7, 0x97, + 0x09, 0xfa, 0xb7, 0xd1, 0xd5, 0xce, 0x7a, 0x71, 0xe9, 0x4a, 0x7a, 0xca, 0x80, 0x8d, 0xde, 0x3f, + 0x7c, 0x7d, 0xb7, 0xf2, 0xcf, 0x5f, 0xdf, 0xad, 0xfc, 0xeb, 0xd7, 0x77, 0x2b, 0xbf, 0xfc, 0xb7, + 0xbb, 0xd7, 0x8e, 0x1a, 0xf4, 0xa7, 0xfa, 0x8f, 0xff, 0x37, 0x00, 0x00, 0xff, 0xff, 0xfb, 0xd8, + 0x82, 0x07, 0xca, 0x2f, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. diff --git a/worker/backup_processor.go b/worker/backup_processor.go index e410e56a2fc..8c8542ff8f9 100644 --- a/worker/backup_processor.go +++ b/worker/backup_processor.go @@ -347,7 +347,6 @@ func checkAndGetDropOp(key []byte, l *posting.List, readTs uint64) (*pb.DropOper // A dgraph.drop.op record can have values in only one of following formats: // * DROP_ALL; // * DROP_DATA; - // * DROP_TYPE;typeName // * DROP_ATTR;attrName // So, accordingly construct the *pb.DropOperation. dropOp := &pb.DropOperation{} @@ -360,9 +359,6 @@ func checkAndGetDropOp(key []byte, l *posting.List, readTs uint64) (*pb.DropOper dropOp.DropOp = pb.DropOperation_ALL case "DROP_DATA": dropOp.DropOp = pb.DropOperation_DATA - case "DROP_TYPE": - dropOp.DropOp = pb.DropOperation_TYPE - dropOp.DropValue = dropInfo[1] case "DROP_ATTR": dropOp.DropOp = pb.DropOperation_ATTR dropOp.DropValue = dropInfo[1] diff --git a/worker/restore.go b/worker/restore.go index ae4e7b12f8a..8526f2790e6 100644 --- a/worker/restore.go +++ b/worker/restore.go @@ -235,8 +235,6 @@ func applyDropOperationsBeforeRestore(db *badger.DB, dropOperations []*pb.DropOp return db.DropAll() case pb.DropOperation_DATA: return db.DropPrefix([]byte{x.DefaultPrefix}) - case pb.DropOperation_TYPE: - // TODO: check if there is anything to be done here case pb.DropOperation_ATTR: return db.DropPrefix(x.PredicatePrefix(operation.DropValue)) } From aa809e6dfb201584248780d86352d666aba76d00 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Thu, 5 Nov 2020 10:57:21 +0530 Subject: [PATCH 04/14] fix tests --- ee/acl/acl_test.go | 4 ++++ graphql/e2e/common/admin.go | 4 ++++ graphql/e2e/directives/schema_response.json | 4 ++++ graphql/e2e/normal/schema_response.json | 4 ++++ graphql/e2e/schema/schema_test.go | 4 ++++ systest/backup/encryption/backup_test.go | 2 +- systest/backup/filesystem/backup_test.go | 2 +- systest/backup/minio/backup_test.go | 2 +- systest/export/export_test.go | 1 + systest/queries_test.go | 3 +++ worker/backup_processor.go | 2 +- x/x.go | 1 + 12 files changed, 29 insertions(+), 4 deletions(-) diff --git a/ee/acl/acl_test.go b/ee/acl/acl_test.go index 459c5e915da..016c5ad8aca 100644 --- a/ee/acl/acl_test.go +++ b/ee/acl/acl_test.go @@ -2146,6 +2146,10 @@ func TestSchemaQueryWithACL(t *testing.T) { ], "upsert": true }, + { + "predicate":"dgraph.drop.op", + "type":"string" + }, { "predicate":"dgraph.graphql.p_query", "type":"string" diff --git a/graphql/e2e/common/admin.go b/graphql/e2e/common/admin.go index ceb755d6a27..eea71277d3b 100644 --- a/graphql/e2e/common/admin.go +++ b/graphql/e2e/common/admin.go @@ -53,6 +53,10 @@ const ( ], "upsert": true }, + { + "predicate": "dgraph.drop.op", + "type": "string" + }, { "predicate":"dgraph.graphql.p_query", "type":"string" diff --git a/graphql/e2e/directives/schema_response.json b/graphql/e2e/directives/schema_response.json index 6437ca7e608..50859d71756 100644 --- a/graphql/e2e/directives/schema_response.json +++ b/graphql/e2e/directives/schema_response.json @@ -256,6 +256,10 @@ "list": true, "upsert": true }, + { + "predicate": "dgraph.drop.op", + "type": "string" + }, { "predicate":"dgraph.graphql.p_query", "type":"string" diff --git a/graphql/e2e/normal/schema_response.json b/graphql/e2e/normal/schema_response.json index a6a55754964..2baf3adfa8e 100644 --- a/graphql/e2e/normal/schema_response.json +++ b/graphql/e2e/normal/schema_response.json @@ -420,6 +420,10 @@ "list": true, "upsert": true }, + { + "predicate": "dgraph.drop.op", + "type": "string" + }, { "predicate": "dgraph.graphql.schema", "type": "string" diff --git a/graphql/e2e/schema/schema_test.go b/graphql/e2e/schema/schema_test.go index 01f2c34a1e3..8dd85c22e57 100644 --- a/graphql/e2e/schema/schema_test.go +++ b/graphql/e2e/schema/schema_test.go @@ -219,6 +219,10 @@ func TestConcurrentSchemaUpdates(t *testing.T) { ], "upsert": true }, + { + "predicate":"dgraph.drop.op", + "type":"string" + }, { "predicate":"dgraph.graphql.p_query", "type":"string" diff --git a/systest/backup/encryption/backup_test.go b/systest/backup/encryption/backup_test.go index 920898c4036..a9347c31cbf 100644 --- a/systest/backup/encryption/backup_test.go +++ b/systest/backup/encryption/backup_test.go @@ -296,7 +296,7 @@ func runRestore(t *testing.T, lastDir string, commitTs uint64) map[string]string require.NoError(t, err) require.ElementsMatch(t, []string{"dgraph.graphql.schema", "dgraph.cors", "dgraph.graphql.xid", "dgraph.type", "movie", "dgraph.graphql.schema_history", "dgraph.graphql.schema_created_at", - "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash"}, + "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash", "dgraph.drop.op"}, restoredPreds) restoredTypes, err := testutil.GetTypeNames(pdir) diff --git a/systest/backup/filesystem/backup_test.go b/systest/backup/filesystem/backup_test.go index 688bda325d4..0077895e84c 100644 --- a/systest/backup/filesystem/backup_test.go +++ b/systest/backup/filesystem/backup_test.go @@ -122,7 +122,7 @@ func TestBackupFilesystem(t *testing.T) { // TODO: refactor tests so that minio and filesystem tests share most of their logic. preds := []string{"dgraph.graphql.schema", "dgraph.cors", "name", "dgraph.graphql.xid", "dgraph.type", "movie", "dgraph.graphql.schema_history", "dgraph.graphql.schema_created_at", - "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash"} + "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash", "dgraph.drop.op"} types := []string{"Node", "dgraph.graphql", "dgraph.graphql.history", "dgraph.graphql.persisted_query"} testutil.CheckSchema(t, preds, types) diff --git a/systest/backup/minio/backup_test.go b/systest/backup/minio/backup_test.go index 95a7df97bbb..a256c3dd496 100644 --- a/systest/backup/minio/backup_test.go +++ b/systest/backup/minio/backup_test.go @@ -116,7 +116,7 @@ func TestBackupMinio(t *testing.T) { // TODO: refactor tests so that minio and filesystem tests share most of their logic. preds := []string{"dgraph.graphql.schema", "dgraph.cors", "dgraph.graphql.xid", "dgraph.type", "movie", "dgraph.graphql.schema_history", "dgraph.graphql.schema_created_at", "dgraph.graphql.p_query", - "dgraph.graphql.p_sha256hash"} + "dgraph.graphql.p_sha256hash", "dgraph.drop.op"} types := []string{"Node", "dgraph.graphql", "dgraph.graphql.history", "dgraph.graphql.persisted_query"} testutil.CheckSchema(t, preds, types) diff --git a/systest/export/export_test.go b/systest/export/export_test.go index 0a837d54cd5..14431596133 100644 --- a/systest/export/export_test.go +++ b/systest/export/export_test.go @@ -79,6 +79,7 @@ func TestExportSchemaToMinio(t *testing.T) { var expectedSchema = `:string .` + " " + ` :[string] @index(exact) @upsert .` + " " + ` :[string] @index(exact) .` + " " + ` +:string .` + " " + ` :string @index(exact) @upsert .` + " " + ` :string .` + " " + ` :string .` + " " + ` diff --git a/systest/queries_test.go b/systest/queries_test.go index e1436c16447..cc8d4050353 100644 --- a/systest/queries_test.go +++ b/systest/queries_test.go @@ -389,6 +389,9 @@ func SchemaQueryTestPredicate1(t *testing.T, c *dgo.Dgraph) { js := ` { "schema": [ + { + "predicate": "dgraph.drop.op" + }, { "predicate": "dgraph.cors" }, diff --git a/worker/backup_processor.go b/worker/backup_processor.go index 8c8542ff8f9..03344ce4c16 100644 --- a/worker/backup_processor.go +++ b/worker/backup_processor.go @@ -344,7 +344,7 @@ func checkAndGetDropOp(key []byte, l *posting.List, readTs uint64) (*pb.DropOper if !ok { return nil, errors.Errorf("cannot convert value of dgraph.drop.op to byte array") } - // A dgraph.drop.op record can have values in only one of following formats: + // A dgraph.drop.op record can have values in only one of the following formats: // * DROP_ALL; // * DROP_DATA; // * DROP_ATTR;attrName diff --git a/x/x.go b/x/x.go index 0ab35764674..042ac19d0e7 100644 --- a/x/x.go +++ b/x/x.go @@ -169,6 +169,7 @@ const ( // GraphqlPredicates is the json representation of the predicate reserved for graphql system. GraphqlPredicates = ` +{"predicate":"dgraph.drop.op", "type": "string"}, {"predicate":"dgraph.graphql.schema", "type": "string"}, {"predicate":"dgraph.graphql.schema_history", "type": "string"}, {"predicate":"dgraph.graphql.schema_created_at", "type": "datetime"}, From 8e4597142e0c07728f5a97262eea97465080cd76 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Thu, 5 Nov 2020 11:41:46 +0530 Subject: [PATCH 05/14] fix more tests --- dgraph/cmd/bulk/systest/test-bulk-schema.sh | 1 + edgraph/server.go | 4 ++-- graphql/e2e/common/admin.go | 12 ++++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/dgraph/cmd/bulk/systest/test-bulk-schema.sh b/dgraph/cmd/bulk/systest/test-bulk-schema.sh index d124f04f19f..439320b5069 100755 --- a/dgraph/cmd/bulk/systest/test-bulk-schema.sh +++ b/dgraph/cmd/bulk/systest/test-bulk-schema.sh @@ -201,6 +201,7 @@ EOF diff <(LC_ALL=C sort all_dbs.out | uniq -c) - < Date: Thu, 5 Nov 2020 18:24:14 +0530 Subject: [PATCH 06/14] fix review comments --- worker/backup_ee.go | 22 ++++++++++++++-------- worker/backup_processor.go | 6 ++++-- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/worker/backup_ee.go b/worker/backup_ee.go index 58596022378..e300d204f7c 100644 --- a/worker/backup_ee.go +++ b/worker/backup_ee.go @@ -170,25 +170,31 @@ func ProcessBackupRequest(ctx context.Context, req *pb.BackupRequest, forceFull ctx, cancel := context.WithCancel(ctx) defer cancel() - errCh := make(chan error, len(state.Groups)) - var dropOperations []*pb.DropOperation + resOrErrCh := make(chan interface{}, len(state.Groups)) for _, gid := range groups { br := proto.Clone(req).(*pb.BackupRequest) br.GroupId = gid br.Predicates = predMap[gid] go func(req *pb.BackupRequest) { res, err := BackupGroup(ctx, req) - if res != nil && len(res.DropOperations) > 0 { - dropOperations = append(dropOperations, res.DropOperations...) + if err != nil { + resOrErrCh <- err + } else { + resOrErrCh <- res } - errCh <- err }(br) } + var dropOperations []*pb.DropOperation for range groups { - if err := <-errCh; err != nil { - glog.Errorf("Error received during backup: %v", err) - return err + if resOrErr := <-resOrErrCh; resOrErr != nil { + switch val := resOrErr.(type) { + case error: + glog.Errorf("Error received during backup: %v", val) + return val + case *pb.BackupResponse: + dropOperations = append(dropOperations, val.DropOperations...) + } } } diff --git a/worker/backup_processor.go b/worker/backup_processor.go index 03344ce4c16..0b5b260c107 100644 --- a/worker/backup_processor.go +++ b/worker/backup_processor.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "net/url" + "reflect" "strings" "github.com/dgraph-io/badger/v2" @@ -342,7 +343,8 @@ func checkAndGetDropOp(key []byte, l *posting.List, readTs uint64) (*pb.DropOper case 1: val, ok := vals[0].Value.([]byte) if !ok { - return nil, errors.Errorf("cannot convert value of dgraph.drop.op to byte array") + return nil, errors.Errorf("cannot convert value of dgraph.drop.op to byte array, "+ + "got type: %s", reflect.TypeOf(vals[0].Value)) } // A dgraph.drop.op record can have values in only one of the following formats: // * DROP_ALL; @@ -366,6 +368,6 @@ func checkAndGetDropOp(key []byte, l *posting.List, readTs uint64) (*pb.DropOper return dropOp, nil default: // getting more than one values for a non-list predicate is an error - return nil, errors.Errorf("found multiple values for dgraph.drop.op") + return nil, errors.Errorf("found multiple values for dgraph.drop.op: %v", vals) } } From 1c1d666cb24bb67c8f1c6f464d21587d7564cea0 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Fri, 6 Nov 2020 16:18:54 +0530 Subject: [PATCH 07/14] add test cases --- dgraph/cmd/alpha/run_test.go | 22 +- systest/mutations_test.go | 30 +- systest/online-restore/online_restore_test.go | 279 ++++++++++++++++-- systest/queries_test.go | 46 +-- testutil/client.go | 14 +- testutil/graphql.go | 2 +- testutil/schema.go | 139 +++++++++ x/x.go | 48 --- 8 files changed, 422 insertions(+), 158 deletions(-) create mode 100644 testutil/schema.go diff --git a/dgraph/cmd/alpha/run_test.go b/dgraph/cmd/alpha/run_test.go index 1b41d85ec85..450c8214c1d 100644 --- a/dgraph/cmd/alpha/run_test.go +++ b/dgraph/cmd/alpha/run_test.go @@ -244,12 +244,9 @@ func TestDeletePredicate(t *testing.T) { output, err = runGraphqlQuery(`schema{}`) require.NoError(t, err) - testutil.CompareJSON(t, `{"data":{"schema":[`+ - `{"predicate":"age","type":"default"},`+ - `{"predicate":"name","type":"string","index":true, "tokenizer":["term"]},`+ - x.AclPredicates+","+x.GraphqlPredicates+","+x.CorsPredicate+","+x.PersistedQueryPredicate+","+ - `{"predicate":"dgraph.type","type":"string","index":true, "tokenizer":["exact"], - "list":true}],`+x.InitialTypes+`}}`, output) + testutil.CompareJSON(t, testutil.GetFullSchemaHTTPResponse(testutil.SchemaOptions{UserPreds: `{"predicate":"age","type":"default"},` + + `{"predicate":"name","type":"string","index":true, "tokenizer":["term"]}`}), + output) output, err = runGraphqlQuery(q1) require.NoError(t, err) @@ -1076,11 +1073,8 @@ func TestListTypeSchemaChange(t *testing.T) { q = `schema{}` res, err = runGraphqlQuery(q) require.NoError(t, err) - testutil.CompareJSON(t, `{"data":{"schema":[`+ - x.AclPredicates+","+x.GraphqlPredicates+","+x.CorsPredicate+","+x.PersistedQueryPredicate+","+ - `{"predicate":"occupations","type":"string"},`+ - `{"predicate":"dgraph.type", "type":"string", "index":true, "tokenizer": ["exact"], - "list":true}],`+x.InitialTypes+`}}`, res) + testutil.CompareJSON(t, testutil.GetFullSchemaHTTPResponse(testutil. + SchemaOptions{UserPreds: `{"predicate":"occupations","type":"string"}`}), res) } func TestDeleteAllSP2(t *testing.T) { @@ -1323,11 +1317,7 @@ func TestDropAll(t *testing.T) { q3 := "schema{}" output, err = runGraphqlQuery(q3) require.NoError(t, err) - testutil.CompareJSON(t, - `{"data":{"schema":[`+ - x.AclPredicates+","+x.GraphqlPredicates+","+x.CorsPredicate+","+x.PersistedQueryPredicate+","+ - `{"predicate":"dgraph.type", "type":"string", "index":true, "tokenizer":["exact"], - "list":true}],`+x.InitialTypes+`}}`, output) + testutil.CompareJSON(t, testutil.GetFullSchemaHTTPResponse(testutil.SchemaOptions{}), output) // Reinstate schema so that we can re-run the original query. err = alterSchemaWithRetry(s) diff --git a/systest/mutations_test.go b/systest/mutations_test.go index 278bc2bc989..09368996127 100644 --- a/systest/mutations_test.go +++ b/systest/mutations_test.go @@ -33,7 +33,6 @@ import ( "github.com/dgraph-io/dgo/v200" "github.com/dgraph-io/dgo/v200/protos/api" "github.com/dgraph-io/dgraph/testutil" - "github.com/dgraph-io/dgraph/x" "github.com/stretchr/testify/require" ) @@ -634,16 +633,9 @@ func SchemaAfterDeleteNode(t *testing.T, c *dgo.Dgraph) { require.NoError(t, err) michael := assigned.Uids["michael"] - resp, err := c.NewTxn().Query(ctx, `schema{}`) - require.NoError(t, err) - testutil.CompareJSON(t, asJson(`[`+x.CorsPredicate+","+x.PersistedQueryPredicate+","+ - x.AclPredicates+","+x.GraphqlPredicates+","+ - `{"predicate":"friend","type":"uid","list":true},`+ - `{"predicate":"married","type":"bool"},`+ - `{"predicate":"name","type":"default"},`+ - `{"predicate":"dgraph.type","type":"string","index":true, "tokenizer":["exact"], - "list":true}],`+x.InitialTypes), - string(resp.Json)) + testutil.VerifySchema(t, c, testutil.SchemaOptions{UserPreds: `{"predicate":"friend","type":"uid","list":true},` + + `{"predicate":"married","type":"bool"},` + + `{"predicate":"name","type":"default"}`}) require.NoError(t, c.Alter(ctx, &api.Operation{DropAttr: "married"})) @@ -656,20 +648,8 @@ func SchemaAfterDeleteNode(t *testing.T, c *dgo.Dgraph) { }) require.NoError(t, err) - resp, err = c.NewTxn().Query(ctx, `schema{}`) - require.NoError(t, err) - testutil.CompareJSON(t, asJson(`[`+ - x.AclPredicates+","+x.CorsPredicate+","+x.PersistedQueryPredicate+","+ - x.GraphqlPredicates+","+ - `{"predicate":"friend","type":"uid","list":true},`+ - `{"predicate":"name","type":"default"},`+ - `{"predicate":"dgraph.type","type":"string","index":true, "tokenizer":["exact"], - "list":true}],`+x.InitialTypes), - string(resp.Json)) -} - -func asJson(schema string) string { - return fmt.Sprintf(`{"schema":%v}`, schema) + testutil.VerifySchema(t, c, testutil.SchemaOptions{UserPreds: `{"predicate":"friend","type":"uid","list":true},` + + `{"predicate":"name","type":"default"}`}) } func FullTextEqual(t *testing.T, c *dgo.Dgraph) { diff --git a/systest/online-restore/online_restore_test.go b/systest/online-restore/online_restore_test.go index e507808745c..7d7e509b76b 100644 --- a/systest/online-restore/online_restore_test.go +++ b/systest/online-restore/online_restore_test.go @@ -22,6 +22,7 @@ import ( "fmt" "io/ioutil" "net/http" + "os" "path" "runtime" "strings" @@ -37,34 +38,39 @@ import ( "github.com/dgraph-io/dgraph/testutil" ) -func sendRestoreRequest(t *testing.T, backupId string, backupNum int) int { - restoreRequest := fmt.Sprintf(`mutation restore() { - restore(input: {location: "/data/backup", backupId: "%s", backupNum: %d, - encryptionKeyFile: "/data/keys/enc_key"}) { - code - message - restoreId - } - }`, backupId, backupNum) - - adminUrl := "http://localhost:8180/admin" +func sendRestoreRequest(t *testing.T, location, backupId string, backupNum int) int { + if location == "" { + location = "/data/backup" + } params := testutil.GraphQLParams{ - Query: restoreRequest, + Query: `mutation restore($location: String!, $backupId: String, $backupNum: Int) { + restore(input: {location: $location, backupId: $backupId, backupNum: $backupNum, + encryptionKeyFile: "/data/keys/enc_key"}) { + code + message + restoreId + } + }`, + Variables: map[string]interface{}{ + "location": location, + "backupId": backupId, + "backupNum": backupNum, + }, } - b, err := json.Marshal(params) - require.NoError(t, err) - - resp, err := http.Post(adminUrl, "application/json", bytes.NewBuffer(b)) - require.NoError(t, err) - buf, err := ioutil.ReadAll(resp.Body) - bufString := string(buf) - require.NoError(t, err) - require.Contains(t, bufString, "Success") - jsonMap := make(map[string]map[string]interface{}) - require.NoError(t, json.Unmarshal([]byte(bufString), &jsonMap)) - restoreId := int(jsonMap["data"]["restore"].(map[string]interface{})["restoreId"].(float64)) - require.NotEqual(t, "", restoreId) - return restoreId + resp := testutil.MakeGQLRequest(t, ¶ms) + resp.RequireNoGraphQLErrors(t) + + var restoreResp struct { + Restore struct { + Code string + Message string + RestoreId int + } + } + require.NoError(t, json.Unmarshal(resp.Data, &restoreResp)) + require.Equal(t, restoreResp.Restore.Code, "Success") + require.Greater(t, restoreResp.Restore.RestoreId, 0) + return restoreResp.Restore.RestoreId } func waitForRestore(t *testing.T, restoreId int, dg *dgo.Dgraph) { @@ -229,7 +235,7 @@ func TestBasicRestore(t *testing.T) { ctx := context.Background() require.NoError(t, dg.Alter(ctx, &api.Operation{DropAll: true})) - restoreId := sendRestoreRequest(t, "youthful_rhodes3", 0) + restoreId := sendRestoreRequest(t, "", "youthful_rhodes3", 0) waitForRestore(t, restoreId, dg) runQueries(t, dg, false) runMutations(t, dg) @@ -246,7 +252,7 @@ func TestRestoreBackupNum(t *testing.T) { require.NoError(t, dg.Alter(ctx, &api.Operation{DropAll: true})) runQueries(t, dg, true) - restoreId := sendRestoreRequest(t, "youthful_rhodes3", 1) + restoreId := sendRestoreRequest(t, "", "youthful_rhodes3", 1) waitForRestore(t, restoreId, dg) runQueries(t, dg, true) runMutations(t, dg) @@ -321,13 +327,13 @@ func TestMoveTablets(t *testing.T) { ctx := context.Background() require.NoError(t, dg.Alter(ctx, &api.Operation{DropAll: true})) - restoreId := sendRestoreRequest(t, "youthful_rhodes3", 0) + restoreId := sendRestoreRequest(t, "", "youthful_rhodes3", 0) waitForRestore(t, restoreId, dg) runQueries(t, dg, false) // Send another restore request with a different backup. This backup has some of the // same predicates as the previous one but they are stored in different groups. - restoreId = sendRestoreRequest(t, "blissful_hermann1", 0) + restoreId = sendRestoreRequest(t, "", "blissful_hermann1", 0) waitForRestore(t, restoreId, dg) resp, err := dg.NewTxn().Query(context.Background(), `{ @@ -408,3 +414,216 @@ func TestListBackups(t *testing.T) { require.Contains(t, sbuf, `"backupNum":2`) require.Contains(t, sbuf, "initial_release_date") } + +func TestRestoreWithDropOperations(t *testing.T) { + dg, err := testutil.DgraphClientDropAll(testutil.SockAddr) + require.NoError(t, err) + + // apply initial schema + initialSchema := ` + name: string . + age: int . + type Person { + name + age + }` + require.NoError(t, dg.Alter(context.Background(), &api.Operation{Schema: initialSchema})) + + // add some data + alice := ` + _:alice "Alice" . + _:alice "20" . + _:alice "Person" . + ` + _, err = dg.NewTxn().Mutate(context.Background(), &api.Mutation{SetNquads: []byte(alice), + CommitNow: true}) + require.NoError(t, err) + + // setup backup directories + backupDir := "/data/backup/tmp" + localFsDirs := []string{"./backup/tmp"} + setupDirs(t, localFsDirs) + + // create a full backup in backupDir + backup(t, backupDir) + + // add some more data + bob := ` + _:bob "Bob" . + _:bob "25" . + _:bob "Person" . + ` + _, err = dg.NewTxn().Mutate(context.Background(), &api.Mutation{SetNquads: []byte(bob), + CommitNow: true}) + require.NoError(t, err) + + // create another backup (incremental) in backupDir + backup(t, backupDir) + + // Now start testing + queryPersonCount := ` + { + persons(func: type(Person)) { + count(uid) + } + }` + queryPerson := ` + { + persons(func: type(Person)) { + name + age + } + }` + initialPreds := ` + {"predicate":"name", "type": "string"}, + {"predicate":"age", "type": "int"}` + initialTypes := ` + { + "fields": [{"name": "name"},{"name": "age"}], + "name": "Person" + }` + + /* STEP-1: DROP_ATTR, reapply schema for that attr then add some new values for the same attr. + Then backup and restore. + Verify that dropped ATTR is not there for old nodes and other data is intact. + Also verify that the schema is intact after restore. + */ + require.NoError(t, dg.Alter(context.Background(), &api.Operation{ + DropOp: api.Operation_ATTR, + DropValue: "age", + })) + require.NoError(t, dg.Alter(context.Background(), &api.Operation{Schema: `age: int .`})) + charlie := ` + _:charlie "Charlie" . + _:charlie "30" . + _:charlie "Person" . + ` + _, err = dg.NewTxn().Mutate(context.Background(), &api.Mutation{SetNquads: []byte(charlie), + CommitNow: true}) + require.NoError(t, err) + backupRestoreAndVerify(t, dg, backupDir, + queryPerson, + `{ + "persons": [ + { + "name": "Alice" + }, + { + "name": "Bob" + }, + { + "name": "Charlie", + "age": 30 + } + ] + }`, + testutil.SchemaOptions{ + UserPreds: initialPreds, + UserTypes: initialTypes, + }) + + /* STEP-2: DROP_DATA, then backup and restore. + Verify that there is no user data, and the schema is intact after restore. + */ + require.NoError(t, dg.Alter(context.Background(), &api.Operation{DropOp: api.Operation_DATA})) + backupRestoreAndVerify(t, dg, backupDir, + queryPersonCount, + `{"persons":[{"count":0}]}`, + testutil.SchemaOptions{ + UserPreds: initialPreds, + UserTypes: initialTypes, + }) + + /* STEP-3: DROP_ALL, then backup and restore. + Verify that there is no user data, and no user schema. + */ + require.NoError(t, dg.Alter(context.Background(), &api.Operation{DropOp: api.Operation_ALL})) + backupRestoreAndVerify(t, dg, backupDir, + queryPersonCount, + `{"persons":[{"count":0}]}`, + testutil.SchemaOptions{}) + + /* STEP-4: Apply a schema, and backup to backupDir. Then add some data, and do a DROP_ALL. + Now, add different schema and data, and do a DROP_DATA. + Then, backup and restore using backupDir. + Verify that the schema is latest and there is no data. + */ + require.NoError(t, dg.Alter(context.Background(), &api.Operation{Schema: initialSchema})) + backup(t, backupDir) + _, err = dg.NewTxn().Mutate(context.Background(), &api.Mutation{SetNquads: []byte(alice), + CommitNow: true}) + require.NoError(t, err) + require.NoError(t, dg.Alter(context.Background(), &api.Operation{DropOp: api.Operation_ALL})) + require.NoError(t, dg.Alter(context.Background(), &api.Operation{ + Schema: ` + color: String . + type Flower { + color + }`})) + _, err = dg.NewTxn().Mutate(context.Background(), &api.Mutation{SetNquads: []byte(` + _:flower "yellow" . + `), + CommitNow: true}) + require.NoError(t, err) + require.NoError(t, dg.Alter(context.Background(), &api.Operation{DropOp: api.Operation_DATA})) + backupRestoreAndVerify(t, dg, backupDir, + `{ + flowers(func: has(color)) { + count(uid) + } + }`, + `{"flowers":[{"count":0}]}`, + testutil.SchemaOptions{ + UserPreds: `{"predicate":"color", "type": "string"}`, + UserTypes: ` + { + "fields": [{"name": "color"}], + "name": "Flower" + }`, + }) + + // remove backup directories to make sure this test doesn't leave anything behind + cleanupDirs(t, localFsDirs) +} + +func setupDirs(t *testing.T, dirs []string) { + // first, clean them up + cleanupDirs(t, dirs) + + // then create them + for _, dir := range dirs { + require.NoError(t, os.MkdirAll(dir, os.ModePerm)) + } +} + +func cleanupDirs(t *testing.T, dirs []string) { + for _, dir := range dirs { + require.NoError(t, os.RemoveAll(dir)) + } +} + +func backup(t *testing.T, backupDir string) { + backupParams := &testutil.GraphQLParams{ + Query: `mutation($backupDir: String!) { + backup(input: { + destination: $backupDir + }) { + response { + code + message + } + } + }`, + Variables: map[string]interface{}{"backupDir": backupDir}, + } + testutil.MakeGQLRequest(t, backupParams).RequireNoGraphQLErrors(t) +} + +func backupRestoreAndVerify(t *testing.T, dg *dgo.Dgraph, backupDir, queryToVerify, + expectedResponse string, schemaVerificationOpts testutil.SchemaOptions) { + schemaVerificationOpts.ExcludeAclSchema = true + backup(t, backupDir) + waitForRestore(t, sendRestoreRequest(t, backupDir, "", 0), dg) + testutil.VerifyQueryResponse(t, dg, queryToVerify, expectedResponse) + testutil.VerifySchema(t, dg, schemaVerificationOpts) +} diff --git a/systest/queries_test.go b/systest/queries_test.go index cc8d4050353..70021fdee50 100644 --- a/systest/queries_test.go +++ b/systest/queries_test.go @@ -28,7 +28,6 @@ import ( "github.com/dgraph-io/dgo/v200" "github.com/dgraph-io/dgo/v200/protos/api" "github.com/dgraph-io/dgraph/testutil" - "github.com/dgraph-io/dgraph/x" "github.com/stretchr/testify/require" ) @@ -331,32 +330,15 @@ func SchemaQueryTest(t *testing.T, c *dgo.Dgraph) { require.NoError(t, err) require.NoError(t, txn.Commit(ctx)) - txn = c.NewTxn() - resp, err := txn.Query(ctx, `schema {}`) - require.NoError(t, err) - js := ` - { - "schema": [` + x.CorsPredicate + "," + x.PersistedQueryPredicate + "," + x.AclPredicates + `,` + x.GraphqlPredicates + `, - { - "predicate": "dgraph.type", - "type": "string", - "index": true, - "tokenizer": [ - "exact" - ], - "list": true - }, - { + testutil.VerifySchema(t, c, testutil.SchemaOptions{UserPreds: ` + { "predicate": "name", "type": "string", "index": true, "tokenizer": [ "exact" ] - } - ],` + x.InitialTypes + ` - }` - testutil.CompareJSON(t, js, string(resp.Json)) + }`}) } func SchemaQueryTestPredicate1(t *testing.T, c *dgo.Dgraph) { @@ -443,7 +425,9 @@ func SchemaQueryTestPredicate1(t *testing.T, c *dgo.Dgraph) { { "predicate": "age" } - ],` + x.InitialTypes + ` + ], + "types": [` + testutil.GetInternalTypes(true) + ` + ] }` testutil.CompareJSON(t, js, string(resp.Json)) } @@ -567,27 +551,15 @@ func SchemaQueryTestHTTP(t *testing.T, c *dgo.Dgraph) { require.NoError(t, json.Unmarshal(bb.Bytes(), &m)) require.NotNil(t, m["extensions"]) - js := ` - { - "schema": [` + x.CorsPredicate + `,` + x.PersistedQueryPredicate + `,` + x.AclPredicates + `,` + x.GraphqlPredicates + `, - { - "index": true, - "predicate": "dgraph.type", - "type": "string", - "tokenizer": ["exact"], - "list": true - }, - { + testutil.CompareJSON(t, testutil.GetFullSchemaJSON(testutil.SchemaOptions{UserPreds: ` + { "predicate": "name", "type": "string", "index": true, "tokenizer": [ "exact" ] - } - ],` + x.InitialTypes + ` - }` - testutil.CompareJSON(t, js, string(m["data"])) + }`}), string(m["data"])) } func FuzzyMatch(t *testing.T, c *dgo.Dgraph) { diff --git a/testutil/client.go b/testutil/client.go index c62d48cab79..7539872a34f 100644 --- a/testutil/client.go +++ b/testutil/client.go @@ -81,9 +81,13 @@ func init() { // by all tests, so there is no testing.T instance for it to use. func DgraphClientDropAll(serviceAddr string) (*dgo.Dgraph, error) { dg, err := DgraphClient(serviceAddr) + if err != nil { + return nil, err + } + for { // keep retrying until we succeed or receive a non-retriable error - err := dg.Alter(context.Background(), &api.Operation{DropAll: true}) + err = dg.Alter(context.Background(), &api.Operation{DropAll: true}) if err == nil || !strings.Contains(err.Error(), "Please retry") { break } @@ -160,6 +164,14 @@ func DropAll(t *testing.T, dg *dgo.Dgraph) { require.NoError(t, err) } +// VerifyQueryResponse executes the given query and verifies that the response of the query is +// same as the expected response. +func VerifyQueryResponse(t *testing.T, dg *dgo.Dgraph, query, expectedResponse string) { + resp, err := dg.NewReadOnlyTxn().Query(context.Background(), query) + require.NoError(t, err) + CompareJSON(t, expectedResponse, string(resp.GetJson())) +} + // RetryQuery will retry a query until it succeeds or a non-retryable error is received. func RetryQuery(dg *dgo.Dgraph, q string) (*api.Response, error) { for { diff --git a/testutil/graphql.go b/testutil/graphql.go index 6a207b88e3d..94fa5f837e7 100644 --- a/testutil/graphql.go +++ b/testutil/graphql.go @@ -64,7 +64,7 @@ type GraphQLResponse struct { func (resp *GraphQLResponse) RequireNoGraphQLErrors(t *testing.T) { if resp == nil { - return + require.Fail(t, "got nil response") } require.Nil(t, resp.Errors, "required no GraphQL errors, but received :\n%s", resp.Errors.Error()) diff --git a/testutil/schema.go b/testutil/schema.go new file mode 100644 index 00000000000..6def29cb608 --- /dev/null +++ b/testutil/schema.go @@ -0,0 +1,139 @@ +/* + * Copyright 2020 Dgraph Labs, Inc. and Contributors + * + * 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 testutil + +import ( + "context" + "fmt" + "testing" + + "github.com/dgraph-io/dgo/v200" + "github.com/stretchr/testify/require" +) + +const ( + aclPreds = ` +{"predicate":"dgraph.xid","type":"string", "index":true, "tokenizer":["exact"], "upsert":true}, +{"predicate":"dgraph.password","type":"password"}, +{"predicate":"dgraph.user.group","list":true, "reverse":true, "type":"uid"}, +{"predicate":"dgraph.acl.rule","type":"uid","list":true}, +{"predicate":"dgraph.rule.predicate","type":"string","index":true,"tokenizer":["exact"],"upsert":true}, +{"predicate":"dgraph.rule.permission","type":"int"} +` + otherInternalPreds = ` +{"predicate":"dgraph.type","type":"string","index":true,"tokenizer":["exact"],"list":true}, +{"predicate":"dgraph.cors","type":"string","list":true,"type":"string","index":true,"tokenizer":["exact"],"upsert":true}, +{"predicate":"dgraph.drop.op", "type": "string"}, +{"predicate":"dgraph.graphql.p_query","type":"string"}, +{"predicate":"dgraph.graphql.p_sha256hash","type":"string","index":true,"tokenizer":["exact"]}, +{"predicate":"dgraph.graphql.schema", "type": "string"}, +{"predicate":"dgraph.graphql.schema_history", "type": "string"}, +{"predicate":"dgraph.graphql.schema_created_at", "type": "datetime"}, +{"predicate":"dgraph.graphql.xid","type":"string","index":true,"tokenizer":["exact"],"upsert":true} +` + aclTypes = ` +{ + "fields": [{"name": "dgraph.password"},{"name": "dgraph.xid"},{"name": "dgraph.user.group"}], + "name": "dgraph.type.User" +},{ + "fields": [{"name": "dgraph.acl.rule"},{"name": "dgraph.xid"}], + "name": "dgraph.type.Group" +},{ + "fields": [{"name": "dgraph.rule.predicate"},{"name": "dgraph.rule.permission"}], + "name": "dgraph.type.Rule" +} +` + otherInternalTypes = ` +{ + "fields": [{"name": "dgraph.graphql.schema"},{"name": "dgraph.graphql.xid"}], + "name": "dgraph.graphql" +},{ + "fields": [{"name": "dgraph.graphql.schema_history"},{"name": "dgraph.graphql.schema_created_at"}], + "name": "dgraph.graphql.history" +},{ + "fields": [{"name": "dgraph.graphql.p_query"},{"name": "dgraph.graphql.p_sha256hash"}], + "name": "dgraph.graphql.persisted_query" +} +` +) + +type SchemaOptions struct { + UserPreds string + UserTypes string + ExcludeAclSchema bool +} + +func GetInternalPreds(excludeAclPreds bool) string { + if excludeAclPreds { + return otherInternalPreds + } + return aclPreds + "," + otherInternalPreds +} + +func GetInternalTypes(excludeAclTypes bool) string { + if excludeAclTypes { + return otherInternalTypes + } + return aclTypes + "," + otherInternalTypes +} + +// GetFullSchemaJSON returns a string representation of the JSON object returned by the full +// schema{} query. It uses the user provided predicates and types along with the initial internal +// schema to generate the string. Example response looks like: +// { +// "schema": [ ... ], +// "types": [ ... ] +// } +func GetFullSchemaJSON(opts SchemaOptions) string { + expectedPreds := GetInternalPreds(opts.ExcludeAclSchema) + if len(opts.UserPreds) > 0 { + expectedPreds += "," + opts.UserPreds + } + + expectedTypes := GetInternalTypes(opts.ExcludeAclSchema) + if len(opts.UserTypes) > 0 { + expectedTypes += "," + opts.UserTypes + } + + return fmt.Sprintf(` + { + "schema": [%s], + "types": [%s] + }`, expectedPreds, expectedTypes) +} + +// GetFullSchemaHTTPResponse returns a string representation of the HTTP response returned by the +// full schema{} query. It uses the user provided predicates and types along with the initial +// internal schema to generate the string. Example response looks like: +// { +// "data": { +// "schema": [ ... ], +// "types": [ ... ] +// } +// } +func GetFullSchemaHTTPResponse(opts SchemaOptions) string { + return `{"data":` + GetFullSchemaJSON(opts) + `}` +} + +// VerifySchema verifies that the full schema generated using user provided predicates and types is +// same as the response of the schema{} query. +func VerifySchema(t *testing.T, dg *dgo.Dgraph, opts SchemaOptions) { + resp, err := dg.NewTxn().Query(context.Background(), `schema {}`) + require.NoError(t, err) + + CompareJSON(t, GetFullSchemaJSON(opts), string(resp.GetJson())) +} diff --git a/x/x.go b/x/x.go index 042ac19d0e7..0359814326c 100644 --- a/x/x.go +++ b/x/x.go @@ -116,45 +116,6 @@ const ( GrootId = "groot" // GuardiansId is the ID of the admin group for ACLs. GuardiansId = "guardians" - // AclPredicates is the JSON representation of the predicates reserved for use - // by the ACL system. - AclPredicates = ` -{"predicate":"dgraph.xid","type":"string", "index":true, "tokenizer":["exact"], "upsert":true}, -{"predicate":"dgraph.password","type":"password"}, -{"predicate":"dgraph.user.group","list":true, "reverse":true, "type":"uid"}, -{"predicate":"dgraph.acl.rule","type":"uid","list":true}, -{"predicate":"dgraph.rule.predicate","type":"string","index":true,"tokenizer":["exact"],"upsert":true}, -{"predicate":"dgraph.rule.permission","type":"int"} -` - // CorsPredicate is the json representation of the predicate reserved by dgraph for the use - // of cors - CorsPredicate = `{"predicate":"dgraph.cors","type":"string","list":true,"type":"string","index":true,"tokenizer":["exact"],"upsert":true}` - - // PersistedQueryPredicate is the json representation of the predicate reserved by dgraph for the use of persisted queries - PersistedQueryPredicate = ` - {"predicate":"dgraph.graphql.p_query","type":"string"}, - {"predicate":"dgraph.graphql.p_sha256hash","type":"string","index":true,"tokenizer":["exact"]}` - - InitialTypes = ` -"types": [{ - "fields": [{"name": "dgraph.graphql.schema"},{"name": "dgraph.graphql.xid"}], - "name": "dgraph.graphql" -},{ - "fields": [{"name": "dgraph.password"},{"name": "dgraph.xid"},{"name": "dgraph.user.group"}], - "name": "dgraph.type.User" -},{ - "fields": [{"name": "dgraph.acl.rule"},{"name": "dgraph.xid"}], - "name": "dgraph.type.Group" -},{ - "fields": [{"name": "dgraph.rule.predicate"},{"name": "dgraph.rule.permission"}], - "name": "dgraph.type.Rule" -}, { - "fields": [{"name": "dgraph.graphql.schema_history"},{"name": "dgraph.graphql.schema_created_at"}], - "name": "dgraph.graphql.history" -}, { - "fields": [{"name": "dgraph.graphql.p_query"},{"name": "dgraph.graphql.p_sha256hash"}], - "name": "dgraph.graphql.persisted_query" -}]` // GroupIdFileName is the name of the file storing the ID of the group to which // the data in a postings directory belongs. This ID is used to join the proper @@ -166,15 +127,6 @@ const ( "Content-Type, Content-Length, Accept-Encoding, Cache-Control, " + "X-CSRF-Token, X-Auth-Token, X-Requested-With" DgraphCostHeader = "Dgraph-TouchedUids" - - // GraphqlPredicates is the json representation of the predicate reserved for graphql system. - GraphqlPredicates = ` -{"predicate":"dgraph.drop.op", "type": "string"}, -{"predicate":"dgraph.graphql.schema", "type": "string"}, -{"predicate":"dgraph.graphql.schema_history", "type": "string"}, -{"predicate":"dgraph.graphql.schema_created_at", "type": "datetime"}, -{"predicate":"dgraph.graphql.xid","type":"string","index":true,"tokenizer":["exact"],"upsert":true} -` ) var ( From 250bf587b3ab98a2e09ab8da4c12dcc461b4d322 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Fri, 6 Nov 2020 17:36:06 +0530 Subject: [PATCH 08/14] add filesystem specific tests --- systest/backup/encryption/backup_test.go | 33 +++++++++++++++-- systest/backup/filesystem/backup_test.go | 46 ++++++++++++++++++++---- systest/backup/minio/backup_test.go | 33 +++++++++++++++-- systest/queries_test.go | 2 +- 4 files changed, 103 insertions(+), 11 deletions(-) diff --git a/systest/backup/encryption/backup_test.go b/systest/backup/encryption/backup_test.go index a9347c31cbf..947bffd4f5f 100644 --- a/systest/backup/encryption/backup_test.go +++ b/systest/backup/encryption/backup_test.go @@ -188,7 +188,7 @@ func TestBackupMinio(t *testing.T) { require.NoError(t, err) // Perform second full backup. - dirs := runBackupInternal(t, true, 12, 4) + _ = runBackupInternal(t, true, 12, 4) restored = runRestore(t, "", incr3.Txn.CommitTs) // Check all the values were restored to their most recent value. @@ -205,10 +205,39 @@ func TestBackupMinio(t *testing.T) { require.EqualValues(t, check.expected, restored[original.Uids[check.blank]]) } + // Do a DROP_DATA + require.NoError(t, dg.Alter(ctx, &api.Operation{DropOp: api.Operation_DATA})) + + // add some data + incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ + CommitNow: true, + SetNquads: []byte(fmt.Sprintf(` + "El laberinto del fauno" . + "Black Panther 2" . + `)), + }) + require.NoError(t, err) + + // perform an incremental backup and then restore + dirs := runBackup(t, 15, 5) + restored = runRestore(t, "", incr4.Txn.CommitTs) + + // Check that the newly added data is the only data for the movie predicate + require.Len(t, restored, 2) + checks = []struct { + blank, expected string + }{ + {blank: "x1", expected: "El laberinto del fauno"}, + {blank: "x2", expected: "Black Panther 2"}, + } + for _, check := range checks { + require.EqualValues(t, check.expected, restored[incr4.Uids[check.blank]]) + } + // Remove the full backup dirs and verify restore catches the error. require.NoError(t, os.RemoveAll(dirs[0])) require.NoError(t, os.RemoveAll(dirs[3])) - runFailingRestore(t, backupDir, "", incr3.Txn.CommitTs) + runFailingRestore(t, backupDir, "", incr4.Txn.CommitTs) // Clean up test directories. dirCleanup(t) diff --git a/systest/backup/filesystem/backup_test.go b/systest/backup/filesystem/backup_test.go index 0077895e84c..521f7d832c8 100644 --- a/systest/backup/filesystem/backup_test.go +++ b/systest/backup/filesystem/backup_test.go @@ -126,7 +126,7 @@ func TestBackupFilesystem(t *testing.T) { types := []string{"Node", "dgraph.graphql", "dgraph.graphql.history", "dgraph.graphql.persisted_query"} testutil.CheckSchema(t, preds, types) - verifyUids := func() { + verifyUids := func(count int) { query := ` { me(func: eq(name, "ibrahim")) { @@ -135,9 +135,9 @@ func TestBackupFilesystem(t *testing.T) { }` res, err := dg.NewTxn().Query(context.Background(), query) require.NoError(t, err) - require.JSONEq(t, string(res.GetJson()), `{"me":[{"count":10000}]}`) + require.JSONEq(t, string(res.GetJson()), fmt.Sprintf(`{"me":[{"count":%d}]}`, count)) } - verifyUids() + verifyUids(10000) checks := []struct { blank, expected string @@ -231,7 +231,7 @@ func TestBackupFilesystem(t *testing.T) { require.NoError(t, err) // Perform second full backup. - dirs := runBackupInternal(t, true, 12, 4) + _ = runBackupInternal(t, true, 12, 4) restored = runRestore(t, copyBackupDir, "", incr3.Txn.CommitTs) testutil.CheckSchema(t, preds, types) @@ -249,11 +249,45 @@ func TestBackupFilesystem(t *testing.T) { require.EqualValues(t, check.expected, restored[original.Uids[check.blank]]) } - verifyUids() + verifyUids(10000) + + // Do a DROP_DATA + require.NoError(t, dg.Alter(ctx, &api.Operation{DropOp: api.Operation_DATA})) + + // add some data + incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ + CommitNow: true, + SetNquads: []byte(fmt.Sprintf(` + "El laberinto del fauno" . + "Black Panther 2" . + `)), + }) + require.NoError(t, err) + + // perform an incremental backup and then restore + dirs := runBackup(t, 15, 5) + restored = runRestore(t, copyBackupDir, "", incr4.Txn.CommitTs) + testutil.CheckSchema(t, preds, types) + + // Check that the newly added data is the only data for the movie predicate + require.Len(t, restored, 2) + checks = []struct { + blank, expected string + }{ + {blank: "x1", expected: "El laberinto del fauno"}, + {blank: "x2", expected: "Black Panther 2"}, + } + for _, check := range checks { + require.EqualValues(t, check.expected, restored[incr4.Uids[check.blank]]) + } + + // Verify that there is no data for predicate `name` + verifyUids(0) + // Remove the full backup testDirs and verify restore catches the error. require.NoError(t, os.RemoveAll(dirs[0])) require.NoError(t, os.RemoveAll(dirs[3])) - runFailingRestore(t, copyBackupDir, "", incr3.Txn.CommitTs) + runFailingRestore(t, copyBackupDir, "", incr4.Txn.CommitTs) // Clean up test directories. dirCleanup(t) diff --git a/systest/backup/minio/backup_test.go b/systest/backup/minio/backup_test.go index a256c3dd496..6005626056f 100644 --- a/systest/backup/minio/backup_test.go +++ b/systest/backup/minio/backup_test.go @@ -210,7 +210,7 @@ func TestBackupMinio(t *testing.T) { require.NoError(t, err) // Perform second full backup. - dirs := runBackupInternal(t, true, 12, 4) + _ = runBackupInternal(t, true, 12, 4) restored = runRestore(t, "", incr3.Txn.CommitTs) testutil.CheckSchema(t, preds, types) @@ -228,10 +228,39 @@ func TestBackupMinio(t *testing.T) { require.EqualValues(t, check.expected, restored[original.Uids[check.blank]]) } + // Do a DROP_DATA + require.NoError(t, dg.Alter(ctx, &api.Operation{DropOp: api.Operation_DATA})) + + // add some data + incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ + CommitNow: true, + SetNquads: []byte(fmt.Sprintf(` + "El laberinto del fauno" . + "Black Panther 2" . + `)), + }) + require.NoError(t, err) + + // perform an incremental backup and then restore + dirs := runBackup(t, 15, 5) + restored = runRestore(t, "", incr4.Txn.CommitTs) + + // Check that the newly added data is the only data for the movie predicate + require.Len(t, restored, 2) + checks = []struct { + blank, expected string + }{ + {blank: "x1", expected: "El laberinto del fauno"}, + {blank: "x2", expected: "Black Panther 2"}, + } + for _, check := range checks { + require.EqualValues(t, check.expected, restored[incr4.Uids[check.blank]]) + } + // Remove the full backup dirs and verify restore catches the error. require.NoError(t, os.RemoveAll(dirs[0])) require.NoError(t, os.RemoveAll(dirs[3])) - runFailingRestore(t, backupDir, "", incr3.Txn.CommitTs) + runFailingRestore(t, backupDir, "", incr4.Txn.CommitTs) // Clean up test directories. dirCleanup(t) diff --git a/systest/queries_test.go b/systest/queries_test.go index 70021fdee50..45986a6a3d0 100644 --- a/systest/queries_test.go +++ b/systest/queries_test.go @@ -426,7 +426,7 @@ func SchemaQueryTestPredicate1(t *testing.T, c *dgo.Dgraph) { "predicate": "age" } ], - "types": [` + testutil.GetInternalTypes(true) + ` + "types": [` + testutil.GetInternalTypes(false) + ` ] }` testutil.CompareJSON(t, js, string(resp.Json)) From b54f7f714525fb0cab9fd3883d1211a20d72718a Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Fri, 6 Nov 2020 17:43:29 +0530 Subject: [PATCH 09/14] fix deep-source --- systest/backup/encryption/backup_test.go | 4 ++-- systest/backup/filesystem/backup_test.go | 4 ++-- systest/backup/minio/backup_test.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/systest/backup/encryption/backup_test.go b/systest/backup/encryption/backup_test.go index 947bffd4f5f..b9cac6bfce1 100644 --- a/systest/backup/encryption/backup_test.go +++ b/systest/backup/encryption/backup_test.go @@ -211,10 +211,10 @@ func TestBackupMinio(t *testing.T) { // add some data incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, - SetNquads: []byte(fmt.Sprintf(` + SetNquads: []byte(` "El laberinto del fauno" . "Black Panther 2" . - `)), + `), }) require.NoError(t, err) diff --git a/systest/backup/filesystem/backup_test.go b/systest/backup/filesystem/backup_test.go index 521f7d832c8..af5f1d6b168 100644 --- a/systest/backup/filesystem/backup_test.go +++ b/systest/backup/filesystem/backup_test.go @@ -257,10 +257,10 @@ func TestBackupFilesystem(t *testing.T) { // add some data incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, - SetNquads: []byte(fmt.Sprintf(` + SetNquads: []byte(` "El laberinto del fauno" . "Black Panther 2" . - `)), + `), }) require.NoError(t, err) diff --git a/systest/backup/minio/backup_test.go b/systest/backup/minio/backup_test.go index 6005626056f..fdbf01709a6 100644 --- a/systest/backup/minio/backup_test.go +++ b/systest/backup/minio/backup_test.go @@ -234,10 +234,10 @@ func TestBackupMinio(t *testing.T) { // add some data incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, - SetNquads: []byte(fmt.Sprintf(` + SetNquads: []byte(` "El laberinto del fauno" . "Black Panther 2" . - `)), + `), }) require.NoError(t, err) From adc73ad80dfeab20bb3b9bd2e6ea58e162d3c368 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Fri, 6 Nov 2020 17:53:00 +0530 Subject: [PATCH 10/14] comment cleanup for teamcity --- systest/online-restore/online_restore_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/systest/online-restore/online_restore_test.go b/systest/online-restore/online_restore_test.go index 7d7e509b76b..03912fab8d0 100644 --- a/systest/online-restore/online_restore_test.go +++ b/systest/online-restore/online_restore_test.go @@ -583,7 +583,8 @@ func TestRestoreWithDropOperations(t *testing.T) { }) // remove backup directories to make sure this test doesn't leave anything behind - cleanupDirs(t, localFsDirs) + // TODO: This is having some problem on TeamCity + //cleanupDirs(t, localFsDirs) } func setupDirs(t *testing.T, dirs []string) { From 1b1b59bc0575c6976993d496bc0da008207821ae Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Fri, 6 Nov 2020 17:59:39 +0530 Subject: [PATCH 11/14] fix typo --- systest/backup/encryption/backup_test.go | 4 ++-- systest/backup/filesystem/backup_test.go | 4 ++-- systest/backup/minio/backup_test.go | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/systest/backup/encryption/backup_test.go b/systest/backup/encryption/backup_test.go index b9cac6bfce1..2efe863723e 100644 --- a/systest/backup/encryption/backup_test.go +++ b/systest/backup/encryption/backup_test.go @@ -212,8 +212,8 @@ func TestBackupMinio(t *testing.T) { incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, SetNquads: []byte(` - "El laberinto del fauno" . - "Black Panther 2" . + <_:x1> "El laberinto del fauno" . + <_:x2> "Black Panther 2" . `), }) require.NoError(t, err) diff --git a/systest/backup/filesystem/backup_test.go b/systest/backup/filesystem/backup_test.go index af5f1d6b168..1f48dfede3f 100644 --- a/systest/backup/filesystem/backup_test.go +++ b/systest/backup/filesystem/backup_test.go @@ -258,8 +258,8 @@ func TestBackupFilesystem(t *testing.T) { incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, SetNquads: []byte(` - "El laberinto del fauno" . - "Black Panther 2" . + <_:x1> "El laberinto del fauno" . + <_:x2> "Black Panther 2" . `), }) require.NoError(t, err) diff --git a/systest/backup/minio/backup_test.go b/systest/backup/minio/backup_test.go index fdbf01709a6..d39c041fa96 100644 --- a/systest/backup/minio/backup_test.go +++ b/systest/backup/minio/backup_test.go @@ -235,8 +235,8 @@ func TestBackupMinio(t *testing.T) { incr4, err := dg.NewTxn().Mutate(ctx, &api.Mutation{ CommitNow: true, SetNquads: []byte(` - "El laberinto del fauno" . - "Black Panther 2" . + <_:x1> "El laberinto del fauno" . + <_:x2> "Black Panther 2" . `), }) require.NoError(t, err) From fff52197b1472ce10a464e7571cdd76912d251e9 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Fri, 6 Nov 2020 18:30:14 +0530 Subject: [PATCH 12/14] fix tls tests --- tlstest/mtls_internal/backup/encryption/backup_test.go | 2 +- tlstest/mtls_internal/backup/filesystem/backup_test.go | 2 +- tlstest/mtls_internal/backup/minio/backup_test.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tlstest/mtls_internal/backup/encryption/backup_test.go b/tlstest/mtls_internal/backup/encryption/backup_test.go index e3beff331b6..61b87a0e006 100644 --- a/tlstest/mtls_internal/backup/encryption/backup_test.go +++ b/tlstest/mtls_internal/backup/encryption/backup_test.go @@ -319,7 +319,7 @@ func runRestore(t *testing.T, lastDir string, commitTs uint64) map[string]string require.NoError(t, err) require.ElementsMatch(t, []string{"dgraph.graphql.schema", "dgraph.cors", "dgraph.graphql.xid", "dgraph.type", "movie", "dgraph.graphql.schema_history", "dgraph.graphql.schema_created_at", - "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash"}, + "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash", "dgraph.drop.op"}, restoredPreds) restoredTypes, err := testutil.GetTypeNames(pdir) diff --git a/tlstest/mtls_internal/backup/filesystem/backup_test.go b/tlstest/mtls_internal/backup/filesystem/backup_test.go index 6347f0240df..c8e529d67d3 100644 --- a/tlstest/mtls_internal/backup/filesystem/backup_test.go +++ b/tlstest/mtls_internal/backup/filesystem/backup_test.go @@ -147,7 +147,7 @@ func TestBackupFilesystem(t *testing.T) { // TODO: refactor tests so that minio and filesystem tests share most of their logic. preds := []string{"dgraph.graphql.schema", "dgraph.cors", "name", "dgraph.graphql.xid", "dgraph.type", "movie", "dgraph.graphql.schema_history", "dgraph.graphql.schema_created_at", - "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash"} + "dgraph.graphql.p_query", "dgraph.graphql.p_sha256hash", "dgraph.drop.op"} types := []string{"Node", "dgraph.graphql", "dgraph.graphql.history", "dgraph.graphql.persisted_query"} testutil.CheckSchema(t, preds, types) diff --git a/tlstest/mtls_internal/backup/minio/backup_test.go b/tlstest/mtls_internal/backup/minio/backup_test.go index a4d2d4d1721..5e6455306f2 100644 --- a/tlstest/mtls_internal/backup/minio/backup_test.go +++ b/tlstest/mtls_internal/backup/minio/backup_test.go @@ -141,7 +141,7 @@ func TestBackupMinio(t *testing.T) { // TODO: refactor tests so that minio and filesystem tests share most of their logic. preds := []string{"dgraph.graphql.schema", "dgraph.cors", "dgraph.graphql.xid", "dgraph.type", "movie", "dgraph.graphql.schema_history", "dgraph.graphql.schema_created_at", "dgraph.graphql.p_query", - "dgraph.graphql.p_sha256hash"} + "dgraph.graphql.p_sha256hash", "dgraph.drop.op"} types := []string{"Node", "dgraph.graphql", "dgraph.graphql.history", "dgraph.graphql.persisted_query"} testutil.CheckSchema(t, preds, types) From 72975df64c4602c171d887a0212e77a32744e2f9 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Sun, 8 Nov 2020 23:39:13 +0530 Subject: [PATCH 13/14] fix export test --- worker/export.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/worker/export.go b/worker/export.go index fde3a410fe4..b8fc2ffa789 100644 --- a/worker/export.go +++ b/worker/export.go @@ -659,6 +659,8 @@ func exportInternal(ctx context.Context, in *pb.ExportRequest, db *badger.DB, // Ignore this predicate. case pk.Attr == "dgraph.cors": // Ignore this predicate. + case pk.Attr == "dgraph.drop.op": + // Ignore this predicate. case pk.Attr == "dgraph.graphql.schema_created_at": // Ignore this predicate. case pk.Attr == "dgraph.graphql.schema_history": From 719cac493d61229cce54d416541ad5c74c80cf44 Mon Sep 17 00:00:00 2001 From: Abhimanyu Singh Gaur <12651351+abhimanyusinghgaur@users.noreply.github.com> Date: Mon, 9 Nov 2020 17:39:07 +0530 Subject: [PATCH 14/14] fix review comments --- edgraph/server.go | 7 +++++++ protos/pb.proto | 1 + protos/pb/pb.pb.go | 11 ++++++----- worker/backup_ee.go | 28 ++++++++++++++-------------- worker/backup_processor.go | 9 +++++++-- x/keys.go | 3 +++ 6 files changed, 38 insertions(+), 21 deletions(-) diff --git a/edgraph/server.go b/edgraph/server.go index b9f1c3f482d..f65ca03503d 100644 --- a/edgraph/server.go +++ b/edgraph/server.go @@ -289,6 +289,13 @@ func parseSchemaFromAlterOperation(op *api.Operation) (*schema.ParsedSchema, err return result, nil } +// insertDropRecord is used to insert a helper record when a DROP operation is performed. +// This helper record lets us know during backup that a DROP operation was performed and that we +// need to write this information in backup manifest. So that while restoring from a backup series, +// we can create an exact replica of the system which existed at the time the last backup was taken. +// Note that if the server crashes after the DROP operation & before this helper record is inserted, +// then restoring from the incremental backup of such a DB would restore even the dropped +// data back. func insertDropRecord(ctx context.Context, dropOp string) error { _, err := (&Server{}).doQuery(context.WithValue(ctx, IsGraphql, true), &api.Request{ diff --git a/protos/pb.proto b/protos/pb.proto index 469b38d6eec..cb259d6fa0d 100644 --- a/protos/pb.proto +++ b/protos/pb.proto @@ -610,6 +610,7 @@ message DropOperation { ATTR = 2; } DropOp drop_op = 1; + // When drop_op is ATTR, drop_value will be the name of the ATTR; empty otherwise. string drop_value = 2; } diff --git a/protos/pb/pb.pb.go b/protos/pb/pb.pb.go index 53289ab677a..72cfdbeab1d 100644 --- a/protos/pb/pb.pb.go +++ b/protos/pb/pb.pb.go @@ -4520,11 +4520,12 @@ func (m *BackupResponse) GetDropOperations() []*DropOperation { } type DropOperation struct { - DropOp DropOperation_DropOp `protobuf:"varint,1,opt,name=drop_op,json=dropOp,proto3,enum=pb.DropOperation_DropOp" json:"drop_op,omitempty"` - DropValue string `protobuf:"bytes,2,opt,name=drop_value,json=dropValue,proto3" json:"drop_value,omitempty"` - XXX_NoUnkeyedLiteral struct{} `json:"-"` - XXX_unrecognized []byte `json:"-"` - XXX_sizecache int32 `json:"-"` + DropOp DropOperation_DropOp `protobuf:"varint,1,opt,name=drop_op,json=dropOp,proto3,enum=pb.DropOperation_DropOp" json:"drop_op,omitempty"` + // When drop_op is ATTR, drop_value will be the name of the ATTR; empty otherwise. + DropValue string `protobuf:"bytes,2,opt,name=drop_value,json=dropValue,proto3" json:"drop_value,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` } func (m *DropOperation) Reset() { *m = DropOperation{} } diff --git a/worker/backup_ee.go b/worker/backup_ee.go index e300d204f7c..c1e095bd185 100644 --- a/worker/backup_ee.go +++ b/worker/backup_ee.go @@ -86,6 +86,13 @@ func BackupGroup(ctx context.Context, in *pb.BackupRequest) (*pb.BackupResponse, // backups with the same backupNum in their manifest. var backupLock sync.Mutex +// BackupRes is used to represent the response and error of the Backup gRPC call together to be +// transported via a channel. +type BackupRes struct { + res *pb.BackupResponse + err error +} + func ProcessBackupRequest(ctx context.Context, req *pb.BackupRequest, forceFull bool) error { if !EnterpriseEnabled() { return errors.New("you must enable enterprise features first. " + @@ -170,31 +177,24 @@ func ProcessBackupRequest(ctx context.Context, req *pb.BackupRequest, forceFull ctx, cancel := context.WithCancel(ctx) defer cancel() - resOrErrCh := make(chan interface{}, len(state.Groups)) + resCh := make(chan BackupRes, len(state.Groups)) for _, gid := range groups { br := proto.Clone(req).(*pb.BackupRequest) br.GroupId = gid br.Predicates = predMap[gid] go func(req *pb.BackupRequest) { res, err := BackupGroup(ctx, req) - if err != nil { - resOrErrCh <- err - } else { - resOrErrCh <- res - } + resCh <- BackupRes{res: res, err: err} }(br) } var dropOperations []*pb.DropOperation for range groups { - if resOrErr := <-resOrErrCh; resOrErr != nil { - switch val := resOrErr.(type) { - case error: - glog.Errorf("Error received during backup: %v", val) - return val - case *pb.BackupResponse: - dropOperations = append(dropOperations, val.DropOperations...) - } + if backupRes := <-resCh; backupRes.err != nil { + glog.Errorf("Error received during backup: %v", backupRes.err) + return backupRes.err + } else { + dropOperations = append(dropOperations, backupRes.res.GetDropOperations()...) } } diff --git a/worker/backup_processor.go b/worker/backup_processor.go index 0b5b260c107..780dfa4642f 100644 --- a/worker/backup_processor.go +++ b/worker/backup_processor.go @@ -134,10 +134,14 @@ func (pr *BackupProcessor) WriteBackup(ctx context.Context) (*pb.BackupResponse, tl := pr.threads[itr.ThreadId] tl.alloc = stream.Allocator(itr.ThreadId) kvList, dropOp, err := tl.toBackupList(key, itr) + if err != nil { + return nil, err + } + // we don't want to append a nil value to the slice, so need to check. if dropOp != nil { response.DropOperations = append(response.DropOperations, dropOp) } - return kvList, err + return kvList, nil } stream.ChooseKey = func(item *badger.Item) bool { @@ -344,7 +348,8 @@ func checkAndGetDropOp(key []byte, l *posting.List, readTs uint64) (*pb.DropOper val, ok := vals[0].Value.([]byte) if !ok { return nil, errors.Errorf("cannot convert value of dgraph.drop.op to byte array, "+ - "got type: %s", reflect.TypeOf(vals[0].Value)) + "got type: %s, value: %v, tid: %v", reflect.TypeOf(vals[0].Value), vals[0].Value, + vals[0].Tid) } // A dgraph.drop.op record can have values in only one of the following formats: // * DROP_ALL; diff --git a/x/keys.go b/x/keys.go index 460829a812c..8316290ed56 100644 --- a/x/keys.go +++ b/x/keys.go @@ -553,6 +553,9 @@ var aclPredicateMap = map[string]struct{}{ "dgraph.acl.rule": {}, } +// TODO: rename this map to a better suited name as per its properties. It is not just for GraphQL +// predicates, but for all those which are PreDefined and whose value is not allowed to be mutated +// by users. When renaming this also rename the IsGraphql context key in edgraph/server.go. var graphqlReservedPredicate = map[string]struct{}{ "dgraph.graphql.xid": {}, "dgraph.graphql.schema": {},