diff --git a/.gitignore b/.gitignore index 5ddd14bd2..98a401933 100644 --- a/.gitignore +++ b/.gitignore @@ -77,4 +77,5 @@ crashlytics-build.properties test_data build +target *.class diff --git a/other/java/client/pom.xml b/other/java/client/pom.xml new file mode 100644 index 000000000..07015145e --- /dev/null +++ b/other/java/client/pom.xml @@ -0,0 +1,70 @@ + + + 4.0.0 + + seaweedfs + client + 1.0-SNAPSHOT + + + 3.5.1 + 1.16.1 + + + + + + com.google.protobuf + protobuf-java + ${protobuf.version} + + + io.grpc + grpc-netty-shaded + ${grpc.version} + + + io.grpc + grpc-protobuf + ${grpc.version} + + + io.grpc + grpc-stub + ${grpc.version} + + + + + + + kr.motd.maven + os-maven-plugin + 1.5.0.Final + + + + + org.xolstice.maven.plugins + protobuf-maven-plugin + 0.5.1 + + com.google.protobuf:protoc:${protobuf.version}-1:exe:${os.detected.classifier} + grpc-java + io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier} + + + + + compile + compile-custom + + + + + + + + diff --git a/other/java/client/src/main/java/seaweedfs/client/FilerGrpcClient.java b/other/java/client/src/main/java/seaweedfs/client/FilerGrpcClient.java new file mode 100644 index 000000000..47712bc37 --- /dev/null +++ b/other/java/client/src/main/java/seaweedfs/client/FilerGrpcClient.java @@ -0,0 +1,45 @@ +package seaweedfs.client; + +import io.grpc.ManagedChannel; +import io.grpc.ManagedChannelBuilder; + +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; + +public class FilerGrpcClient { + + private static final Logger logger = Logger.getLogger(FilerGrpcClient.class.getName()); + + private final ManagedChannel channel; + private final SeaweedFilerGrpc.SeaweedFilerBlockingStub blockingStub; + private final SeaweedFilerGrpc.SeaweedFilerStub asyncStub; + private final SeaweedFilerGrpc.SeaweedFilerFutureStub futureStub; + + + public FilerGrpcClient(String host, int port) { + this(ManagedChannelBuilder.forAddress(host, port).usePlaintext()); + } + + public FilerGrpcClient(ManagedChannelBuilder channelBuilder) { + channel = channelBuilder.build(); + blockingStub = SeaweedFilerGrpc.newBlockingStub(channel); + asyncStub = SeaweedFilerGrpc.newStub(channel); + futureStub = SeaweedFilerGrpc.newFutureStub(channel); + } + + public void shutdown() throws InterruptedException { + channel.shutdown().awaitTermination(5, TimeUnit.SECONDS); + } + + public SeaweedFilerGrpc.SeaweedFilerBlockingStub getBlockingStub() { + return blockingStub; + } + + public SeaweedFilerGrpc.SeaweedFilerStub getAsyncStub() { + return asyncStub; + } + + public SeaweedFilerGrpc.SeaweedFilerFutureStub getFutureStub() { + return futureStub; + } +} diff --git a/other/java/client/src/main/proto/filer.proto b/other/java/client/src/main/proto/filer.proto new file mode 100644 index 000000000..124eabcd2 --- /dev/null +++ b/other/java/client/src/main/proto/filer.proto @@ -0,0 +1,178 @@ +syntax = "proto3"; + +package filer_pb; + +option java_package = "seaweedfs.client"; +option java_outer_classname = "FilerProto"; + +////////////////////////////////////////////////// + +service SeaweedFiler { + + rpc LookupDirectoryEntry (LookupDirectoryEntryRequest) returns (LookupDirectoryEntryResponse) { + } + + rpc ListEntries (ListEntriesRequest) returns (ListEntriesResponse) { + } + + rpc CreateEntry (CreateEntryRequest) returns (CreateEntryResponse) { + } + + rpc UpdateEntry (UpdateEntryRequest) returns (UpdateEntryResponse) { + } + + rpc DeleteEntry (DeleteEntryRequest) returns (DeleteEntryResponse) { + } + + rpc AssignVolume (AssignVolumeRequest) returns (AssignVolumeResponse) { + } + + rpc LookupVolume (LookupVolumeRequest) returns (LookupVolumeResponse) { + } + + rpc DeleteCollection (DeleteCollectionRequest) returns (DeleteCollectionResponse) { + } + + rpc Statistics (StatisticsRequest) returns (StatisticsResponse) { + } + +} + +////////////////////////////////////////////////// + +message LookupDirectoryEntryRequest { + string directory = 1; + string name = 2; +} + +message LookupDirectoryEntryResponse { + Entry entry = 1; +} + +message ListEntriesRequest { + string directory = 1; + string prefix = 2; + string startFromFileName = 3; + bool inclusiveStartFrom = 4; + uint32 limit = 5; +} + +message ListEntriesResponse { + repeated Entry entries = 1; +} + +message Entry { + string name = 1; + bool is_directory = 2; + repeated FileChunk chunks = 3; + FuseAttributes attributes = 4; + map extended = 5; +} + +message EventNotification { + Entry old_entry = 1; + Entry new_entry = 2; + bool delete_chunks = 3; +} + +message FileChunk { + string file_id = 1; + int64 offset = 2; + uint64 size = 3; + int64 mtime = 4; + string e_tag = 5; + string source_file_id = 6; +} + +message FuseAttributes { + uint64 file_size = 1; + int64 mtime = 2; // unix time in seconds + uint32 file_mode = 3; + uint32 uid = 4; + uint32 gid = 5; + int64 crtime = 6; // unix time in seconds + string mime = 7; + string replication = 8; + string collection = 9; + int32 ttl_sec = 10; + string user_name = 11; // for hdfs + repeated string group_name = 12; // for hdfs +} + +message CreateEntryRequest { + string directory = 1; + Entry entry = 2; +} + +message CreateEntryResponse { +} + +message UpdateEntryRequest { + string directory = 1; + Entry entry = 2; +} +message UpdateEntryResponse { +} + +message DeleteEntryRequest { + string directory = 1; + string name = 2; + bool is_directory = 3; + bool is_delete_data = 4; + bool is_recursive = 5; +} + +message DeleteEntryResponse { +} + +message AssignVolumeRequest { + int32 count = 1; + string collection = 2; + string replication = 3; + int32 ttl_sec = 4; + string data_center = 5; +} + +message AssignVolumeResponse { + string file_id = 1; + string url = 2; + string public_url = 3; + int32 count = 4; +} + +message LookupVolumeRequest { + repeated string volume_ids = 1; +} + +message Locations { + repeated Location locations = 1; +} + +message Location { + string url = 1; + string public_url = 2; +} +message LookupVolumeResponse { + map locations_map = 1; +} + +message DeleteCollectionRequest { + string collection = 1; +} + +message DeleteCollectionResponse { +} + +message StatisticsRequest { + string replication = 1; + string collection = 2; + string ttl = 3; +} +message StatisticsResponse { + string replication = 1; + string collection = 2; + string ttl = 3; + uint64 total_size = 4; + uint64 used_size = 5; + uint64 file_count = 6; +} diff --git a/other/java/hdfs/pom.xml b/other/java/hdfs/pom.xml index 0892c85e8..1fb554a19 100644 --- a/other/java/hdfs/pom.xml +++ b/other/java/hdfs/pom.xml @@ -4,8 +4,8 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - seaweed.hadoop - seaweedfs + seaweedfs + hadoop-client 1.0-SNAPSHOT @@ -18,6 +18,11 @@ hadoop-client ${hadoop.version} + + seaweedfs + client + 1.0-SNAPSHOT + diff --git a/other/java/hdfs/src/main/java/seaweed/hdfs/SeaweedFileSystem.java b/other/java/hdfs/src/main/java/seaweed/hdfs/SeaweedFileSystem.java index 9b1a842c8..217f4a10e 100644 --- a/other/java/hdfs/src/main/java/seaweed/hdfs/SeaweedFileSystem.java +++ b/other/java/hdfs/src/main/java/seaweed/hdfs/SeaweedFileSystem.java @@ -3,9 +3,11 @@ package seaweed.hdfs; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; +import org.apache.hadoop.fs.FileAlreadyExistsException; import org.apache.hadoop.fs.FileStatus; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.permission.FsPermission; +import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.util.Progressable; import java.io.FileNotFoundException; @@ -20,6 +22,7 @@ public class SeaweedFileSystem extends org.apache.hadoop.fs.FileSystem { private URI uri; private Path workingDirectory = new Path("/"); + private SeaweedFileSystemStore seaweedFileSystemStore; public URI getUri() { return uri; @@ -48,6 +51,8 @@ public class SeaweedFileSystem extends org.apache.hadoop.fs.FileSystem { setConf(conf); this.uri = uri; + + seaweedFileSystemStore = new SeaweedFileSystemStore(host, port); } public FSDataInputStream open(Path path, int i) throws IOException { @@ -66,12 +71,24 @@ public class SeaweedFileSystem extends org.apache.hadoop.fs.FileSystem { return false; } - public boolean delete(Path path, boolean b) throws IOException { - return false; + public boolean delete(Path path, boolean recursive) throws IOException { + + path = qualify(path); + + FileStatus fileStatus = getFileStatus(path); + if (fileStatus == null) { + return true; + } + + return seaweedFileSystemStore.deleteEntries(path, fileStatus.isDirectory(), recursive); + } public FileStatus[] listStatus(Path path) throws FileNotFoundException, IOException { - return new FileStatus[0]; + + path = qualify(path); + + return seaweedFileSystemStore.listEntries(path); } public Path getWorkingDirectory() { @@ -87,10 +104,34 @@ public class SeaweedFileSystem extends org.apache.hadoop.fs.FileSystem { } public boolean mkdirs(Path path, FsPermission fsPermission) throws IOException { - return false; + + path = qualify(path); + + try { + FileStatus fileStatus = getFileStatus(path); + + if (fileStatus.isDirectory()) { + return true; + } else { + throw new FileAlreadyExistsException("Path is a file: " + path); + } + } catch (FileNotFoundException e) { + UserGroupInformation currentUser = UserGroupInformation.getCurrentUser(); + return seaweedFileSystemStore.createDirectory(path, currentUser, + fsPermission == null ? FsPermission.getDirDefault() : fsPermission, + FsPermission.getUMask(getConf())); + } } public FileStatus getFileStatus(Path path) throws IOException { - return null; + + path = qualify(path); + + return seaweedFileSystemStore.getFileStatus(path); } + + Path qualify(Path path) { + return path.makeQualified(uri, workingDirectory); + } + } diff --git a/other/java/hdfs/src/main/java/seaweed/hdfs/SeaweedFileSystemStore.java b/other/java/hdfs/src/main/java/seaweed/hdfs/SeaweedFileSystemStore.java new file mode 100644 index 000000000..085d5d217 --- /dev/null +++ b/other/java/hdfs/src/main/java/seaweed/hdfs/SeaweedFileSystemStore.java @@ -0,0 +1,120 @@ +package seaweed.hdfs; + +import org.apache.hadoop.fs.FileStatus; +import org.apache.hadoop.fs.Path; +import org.apache.hadoop.fs.permission.FsPermission; +import org.apache.hadoop.security.UserGroupInformation; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import seaweedfs.client.FilerGrpcClient; +import seaweedfs.client.FilerProto; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SeaweedFileSystemStore { + + private static final Logger LOG = LoggerFactory.getLogger(SeaweedFileSystemStore.class); + + private FilerGrpcClient filerGrpcClient; + + public SeaweedFileSystemStore(String host, int port) { + filerGrpcClient = new FilerGrpcClient(host, port); + } + + public boolean createDirectory(final Path path, UserGroupInformation currentUser, + final FsPermission permission, final FsPermission umask) { + + LOG.debug("createDirectory path: {} permission: {} umask: {}", + path, + permission, + umask); + + long now = System.currentTimeMillis() / 1000L; + + FilerProto.CreateEntryRequest.Builder request = FilerProto.CreateEntryRequest.newBuilder() + .setDirectory(path.getParent().toUri().getPath()) + .setEntry(FilerProto.Entry.newBuilder() + .setName(path.getName()) + .setIsDirectory(true) + .setAttributes(FilerProto.FuseAttributes.newBuilder() + .setMtime(now) + .setCrtime(now) + .setFileMode(permission.toShort()) + .setUserName(currentUser.getUserName()) + .addAllGroupName(Arrays.asList(currentUser.getGroupNames()))) + ); + + FilerProto.CreateEntryResponse response = filerGrpcClient.getBlockingStub().createEntry(request.build()); + return true; + } + + public FileStatus[] listEntries(final Path path) { + LOG.debug("listEntries path: {}", path); + + List fileStatuses = new ArrayList(); + + FilerProto.ListEntriesResponse response = + filerGrpcClient.getBlockingStub().listEntries(FilerProto.ListEntriesRequest.newBuilder() + .setDirectory(path.toUri().getPath()) + .setLimit(100000) + .build()); + + for (FilerProto.Entry entry : response.getEntriesList()) { + + FileStatus fileStatus = getFileStatus(new Path(path, entry.getName()), entry); + + fileStatuses.add(fileStatus); + } + return fileStatuses.toArray(new FileStatus[0]); + } + + public FileStatus getFileStatus(final Path path) { + LOG.debug("getFileStatus path: {}", path); + + FilerProto.LookupDirectoryEntryResponse response = + filerGrpcClient.getBlockingStub().lookupDirectoryEntry(FilerProto.LookupDirectoryEntryRequest.newBuilder() + .setDirectory(path.getParent().toUri().getPath()) + .setName(path.getName()) + .build()); + + FilerProto.Entry entry = response.getEntry(); + FileStatus fileStatus = getFileStatus(path, entry); + return fileStatus; + } + + public boolean deleteEntries(final Path path, boolean isDirectroy, boolean recursive) { + LOG.debug("deleteEntries path: {} isDirectory {} recursive: {}", + path, + String.valueOf(isDirectroy), + String.valueOf(recursive)); + + FilerProto.DeleteEntryResponse response = + filerGrpcClient.getBlockingStub().deleteEntry(FilerProto.DeleteEntryRequest.newBuilder() + .setDirectory(path.getParent().toUri().getPath()) + .setName(path.getName()) + .setIsDirectory(isDirectroy) + .setIsDeleteData(true) + .build()); + + return true; + } + + + private FileStatus getFileStatus(Path path, FilerProto.Entry entry) { + FilerProto.FuseAttributes attributes = entry.getAttributes(); + long length = attributes.getFileSize(); + boolean isDir = entry.getIsDirectory(); + int block_replication = 1; + int blocksize = 512; + long modification_time = attributes.getMtime(); + long access_time = 0; + FsPermission permission = FsPermission.createImmutable((short) attributes.getFileMode()); + String owner = attributes.getUserName(); + String group = attributes.getGroupNameCount() > 0 ? attributes.getGroupName(0) : ""; + return new FileStatus(length, isDir, block_replication, blocksize, + modification_time, access_time, permission, owner, group, null, path); + } + +} diff --git a/weed/command/filer.go b/weed/command/filer.go index a65139b15..c7cfd6cdc 100644 --- a/weed/command/filer.go +++ b/weed/command/filer.go @@ -47,7 +47,7 @@ func init() { f.disableDirListing = cmdFiler.Flag.Bool("disableDirListing", false, "turn off directory listing") f.maxMB = cmdFiler.Flag.Int("maxMB", 32, "split files larger than the limit") f.secretKey = cmdFiler.Flag.String("secure.secret", "", "secret to encrypt Json Web Token(JWT)") - f.dirListingLimit = cmdFiler.Flag.Int("dirListLimit", 1000, "limit sub dir listing size") + f.dirListingLimit = cmdFiler.Flag.Int("dirListLimit", 100000, "limit sub dir listing size") f.dataCenter = cmdFiler.Flag.String("dataCenter", "", "prefer to write to volumes in this data center") } diff --git a/weed/pb/Makefile b/weed/pb/Makefile index 2e4d33718..c50410574 100644 --- a/weed/pb/Makefile +++ b/weed/pb/Makefile @@ -6,3 +6,5 @@ gen: protoc master.proto --go_out=plugins=grpc:./master_pb protoc volume_server.proto --go_out=plugins=grpc:./volume_server_pb protoc filer.proto --go_out=plugins=grpc:./filer_pb + # protoc filer.proto --java_out=../../other/java/client/src/main/java + cp filer.proto ../../other/java/client/src/main/proto diff --git a/weed/pb/filer.proto b/weed/pb/filer.proto index a19aa7dbc..124eabcd2 100644 --- a/weed/pb/filer.proto +++ b/weed/pb/filer.proto @@ -2,6 +2,9 @@ syntax = "proto3"; package filer_pb; +option java_package = "seaweedfs.client"; +option java_outer_classname = "FilerProto"; + ////////////////////////////////////////////////// service SeaweedFiler { @@ -83,15 +86,17 @@ message FileChunk { message FuseAttributes { uint64 file_size = 1; - int64 mtime = 2; + int64 mtime = 2; // unix time in seconds uint32 file_mode = 3; uint32 uid = 4; uint32 gid = 5; - int64 crtime = 6; + int64 crtime = 6; // unix time in seconds string mime = 7; string replication = 8; string collection = 9; int32 ttl_sec = 10; + string user_name = 11; // for hdfs + repeated string group_name = 12; // for hdfs } message CreateEntryRequest { diff --git a/weed/pb/filer_pb/filer.pb.go b/weed/pb/filer_pb/filer.pb.go index f9e4d9858..10528fe17 100644 --- a/weed/pb/filer_pb/filer.pb.go +++ b/weed/pb/filer_pb/filer.pb.go @@ -297,16 +297,18 @@ func (m *FileChunk) GetSourceFileId() string { } type FuseAttributes struct { - FileSize uint64 `protobuf:"varint,1,opt,name=file_size,json=fileSize" json:"file_size,omitempty"` - Mtime int64 `protobuf:"varint,2,opt,name=mtime" json:"mtime,omitempty"` - FileMode uint32 `protobuf:"varint,3,opt,name=file_mode,json=fileMode" json:"file_mode,omitempty"` - Uid uint32 `protobuf:"varint,4,opt,name=uid" json:"uid,omitempty"` - Gid uint32 `protobuf:"varint,5,opt,name=gid" json:"gid,omitempty"` - Crtime int64 `protobuf:"varint,6,opt,name=crtime" json:"crtime,omitempty"` - Mime string `protobuf:"bytes,7,opt,name=mime" json:"mime,omitempty"` - Replication string `protobuf:"bytes,8,opt,name=replication" json:"replication,omitempty"` - Collection string `protobuf:"bytes,9,opt,name=collection" json:"collection,omitempty"` - TtlSec int32 `protobuf:"varint,10,opt,name=ttl_sec,json=ttlSec" json:"ttl_sec,omitempty"` + FileSize uint64 `protobuf:"varint,1,opt,name=file_size,json=fileSize" json:"file_size,omitempty"` + Mtime int64 `protobuf:"varint,2,opt,name=mtime" json:"mtime,omitempty"` + FileMode uint32 `protobuf:"varint,3,opt,name=file_mode,json=fileMode" json:"file_mode,omitempty"` + Uid uint32 `protobuf:"varint,4,opt,name=uid" json:"uid,omitempty"` + Gid uint32 `protobuf:"varint,5,opt,name=gid" json:"gid,omitempty"` + Crtime int64 `protobuf:"varint,6,opt,name=crtime" json:"crtime,omitempty"` + Mime string `protobuf:"bytes,7,opt,name=mime" json:"mime,omitempty"` + Replication string `protobuf:"bytes,8,opt,name=replication" json:"replication,omitempty"` + Collection string `protobuf:"bytes,9,opt,name=collection" json:"collection,omitempty"` + TtlSec int32 `protobuf:"varint,10,opt,name=ttl_sec,json=ttlSec" json:"ttl_sec,omitempty"` + UserName string `protobuf:"bytes,11,opt,name=user_name,json=userName" json:"user_name,omitempty"` + GroupName []string `protobuf:"bytes,12,rep,name=group_name,json=groupName" json:"group_name,omitempty"` } func (m *FuseAttributes) Reset() { *m = FuseAttributes{} } @@ -384,6 +386,20 @@ func (m *FuseAttributes) GetTtlSec() int32 { return 0 } +func (m *FuseAttributes) GetUserName() string { + if m != nil { + return m.UserName + } + return "" +} + +func (m *FuseAttributes) GetGroupName() []string { + if m != nil { + return m.GroupName + } + return nil +} + type CreateEntryRequest struct { Directory string `protobuf:"bytes,1,opt,name=directory" json:"directory,omitempty"` Entry *Entry `protobuf:"bytes,2,opt,name=entry" json:"entry,omitempty"` @@ -1142,82 +1158,85 @@ var _SeaweedFiler_serviceDesc = grpc.ServiceDesc{ func init() { proto.RegisterFile("filer.proto", fileDescriptor0) } var fileDescriptor0 = []byte{ - // 1225 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0x4b, 0x6f, 0xdb, 0xc6, - 0x13, 0x0f, 0xf5, 0x8a, 0x38, 0x92, 0xfc, 0xb7, 0x57, 0xfe, 0x37, 0x82, 0x6c, 0xa7, 0x0a, 0x9b, - 0x14, 0x0e, 0x6a, 0x18, 0x81, 0xdb, 0x43, 0xd2, 0xa0, 0x40, 0x03, 0x3f, 0x00, 0x03, 0x4e, 0x02, - 0xd0, 0x71, 0x81, 0xa2, 0x07, 0x82, 0x26, 0xc7, 0xea, 0xc2, 0x14, 0xa9, 0x72, 0x97, 0x76, 0xd2, - 0xaf, 0xd0, 0x6b, 0xaf, 0x3d, 0xf4, 0xd4, 0x7b, 0x3f, 0x40, 0x2f, 0xfd, 0x54, 0xbd, 0x15, 0xfb, - 0x20, 0xb5, 0x14, 0x69, 0xa7, 0x45, 0x91, 0xdb, 0xee, 0x6f, 0x66, 0xe7, 0xb5, 0xbf, 0x9d, 0x21, - 0xa1, 0x77, 0x41, 0x23, 0x4c, 0x77, 0xe7, 0x69, 0xc2, 0x13, 0xd2, 0x95, 0x1b, 0x6f, 0x7e, 0xee, - 0xbc, 0x86, 0x8d, 0x93, 0x24, 0xb9, 0xcc, 0xe6, 0x07, 0x34, 0xc5, 0x80, 0x27, 0xe9, 0xbb, 0xc3, - 0x98, 0xa7, 0xef, 0x5c, 0xfc, 0x21, 0x43, 0xc6, 0xc9, 0x26, 0xd8, 0x61, 0x2e, 0x18, 0x59, 0x13, - 0x6b, 0xdb, 0x76, 0x17, 0x00, 0x21, 0xd0, 0x8a, 0xfd, 0x19, 0x8e, 0x1a, 0x52, 0x20, 0xd7, 0xce, - 0x21, 0x6c, 0xd6, 0x1b, 0x64, 0xf3, 0x24, 0x66, 0x48, 0x1e, 0x41, 0x1b, 0x05, 0x20, 0xad, 0xf5, - 0xf6, 0xfe, 0xb7, 0x9b, 0x87, 0xb2, 0xab, 0xf4, 0x94, 0xd4, 0xf9, 0xc3, 0x02, 0x72, 0x42, 0x19, - 0x17, 0x20, 0x45, 0xf6, 0xcf, 0xe2, 0xf9, 0x08, 0x3a, 0xf3, 0x14, 0x2f, 0xe8, 0x5b, 0x1d, 0x91, - 0xde, 0x91, 0x1d, 0x58, 0x63, 0xdc, 0x4f, 0xf9, 0x51, 0x9a, 0xcc, 0x8e, 0x68, 0x84, 0xaf, 0x44, - 0xd0, 0x4d, 0xa9, 0x52, 0x15, 0x90, 0x5d, 0x20, 0x34, 0x0e, 0xa2, 0x8c, 0xd1, 0x2b, 0x3c, 0xcd, - 0xa5, 0xa3, 0xd6, 0xc4, 0xda, 0xee, 0xba, 0x35, 0x12, 0xb2, 0x0e, 0xed, 0x88, 0xce, 0x28, 0x1f, - 0xb5, 0x27, 0xd6, 0xf6, 0xc0, 0x55, 0x1b, 0xe7, 0x6b, 0x18, 0x96, 0xe2, 0xd7, 0xe9, 0x3f, 0x86, - 0xbb, 0xa8, 0xa0, 0x91, 0x35, 0x69, 0xd6, 0x15, 0x20, 0x97, 0x3b, 0xbf, 0x34, 0xa0, 0x2d, 0xa1, - 0xa2, 0xce, 0xd6, 0xa2, 0xce, 0xe4, 0x01, 0xf4, 0x29, 0xf3, 0x16, 0xc5, 0x68, 0xc8, 0xf8, 0x7a, - 0x94, 0x15, 0x75, 0x27, 0x9f, 0x41, 0x27, 0xf8, 0x3e, 0x8b, 0x2f, 0xd9, 0xa8, 0x29, 0x5d, 0x0d, - 0x17, 0xae, 0x44, 0xb2, 0xfb, 0x42, 0xe6, 0x6a, 0x15, 0xf2, 0x14, 0xc0, 0xe7, 0x3c, 0xa5, 0xe7, - 0x19, 0x47, 0x26, 0xb3, 0xed, 0xed, 0x8d, 0x8c, 0x03, 0x19, 0xc3, 0x17, 0x85, 0xdc, 0x35, 0x74, - 0xc9, 0x33, 0xe8, 0xe2, 0x5b, 0x8e, 0x71, 0x88, 0xe1, 0xa8, 0x2d, 0x1d, 0x6d, 0x2d, 0xe5, 0xb4, - 0x7b, 0xa8, 0xe5, 0x2a, 0xc3, 0x42, 0x7d, 0xfc, 0x1c, 0x06, 0x25, 0x11, 0x59, 0x85, 0xe6, 0x25, - 0xe6, 0x37, 0x2b, 0x96, 0xa2, 0xba, 0x57, 0x7e, 0x94, 0x29, 0x92, 0xf5, 0x5d, 0xb5, 0xf9, 0xb2, - 0xf1, 0xd4, 0x72, 0x7e, 0xb6, 0x60, 0xed, 0xf0, 0x0a, 0x63, 0xfe, 0x2a, 0xe1, 0xf4, 0x82, 0x06, - 0x3e, 0xa7, 0x49, 0x4c, 0x76, 0xc0, 0x4e, 0xa2, 0xd0, 0xbb, 0x95, 0x63, 0xdd, 0x24, 0xd2, 0xfe, - 0x76, 0xc0, 0x8e, 0xf1, 0x5a, 0x6b, 0x37, 0x6e, 0xd0, 0x8e, 0xf1, 0x5a, 0x69, 0x7f, 0x02, 0x83, - 0x10, 0x23, 0xe4, 0xe8, 0x15, 0x75, 0x15, 0x45, 0xef, 0x2b, 0x50, 0xd6, 0x93, 0x39, 0xbf, 0x5a, - 0x60, 0x17, 0xe5, 0x25, 0xf7, 0xe0, 0xae, 0x30, 0xe7, 0xd1, 0x50, 0x27, 0xd5, 0x11, 0xdb, 0xe3, - 0x50, 0x70, 0x35, 0xb9, 0xb8, 0x60, 0xc8, 0xa5, 0xdb, 0xa6, 0xab, 0x77, 0xe2, 0xae, 0x19, 0xfd, - 0x51, 0xd1, 0xb3, 0xe5, 0xca, 0xb5, 0xa8, 0xc1, 0x8c, 0xd3, 0x19, 0xca, 0x6b, 0x69, 0xba, 0x6a, - 0x43, 0x86, 0xd0, 0x46, 0x8f, 0xfb, 0x53, 0xc9, 0x3b, 0xdb, 0x6d, 0xe1, 0x1b, 0x7f, 0x4a, 0x1e, - 0xc2, 0x0a, 0x4b, 0xb2, 0x34, 0x40, 0x2f, 0x77, 0xdb, 0x91, 0xd2, 0xbe, 0x42, 0x8f, 0xa4, 0x73, - 0xe7, 0xa7, 0x06, 0xac, 0x94, 0x6f, 0x94, 0x6c, 0x80, 0x2d, 0x4f, 0x48, 0xe7, 0x96, 0x74, 0x2e, - 0xbb, 0xc4, 0x69, 0x29, 0x80, 0x86, 0x19, 0x40, 0x7e, 0x64, 0x96, 0x84, 0x2a, 0xde, 0x81, 0x3a, - 0xf2, 0x32, 0x09, 0x51, 0xdc, 0x64, 0x46, 0x43, 0x19, 0xf1, 0xc0, 0x15, 0x4b, 0x81, 0x4c, 0x69, - 0xa8, 0x5f, 0x89, 0x58, 0x8a, 0x1a, 0x04, 0xa9, 0xb4, 0xdb, 0x51, 0x35, 0x50, 0x3b, 0x51, 0x83, - 0x99, 0x40, 0xef, 0xaa, 0xc4, 0xc4, 0x9a, 0x4c, 0xa0, 0x97, 0xe2, 0x3c, 0xd2, 0xd7, 0x3c, 0xea, - 0x4a, 0x91, 0x09, 0x91, 0xfb, 0x00, 0x41, 0x12, 0x45, 0x18, 0x48, 0x05, 0x5b, 0x2a, 0x18, 0x88, - 0xb8, 0x0a, 0xce, 0x23, 0x8f, 0x61, 0x30, 0x82, 0x89, 0xb5, 0xdd, 0x76, 0x3b, 0x9c, 0x47, 0xa7, - 0x18, 0x38, 0xdf, 0x02, 0xd9, 0x4f, 0xd1, 0xe7, 0xf8, 0x2f, 0x5a, 0x5f, 0xd1, 0xc6, 0x1a, 0xb7, - 0xb6, 0xb1, 0xff, 0xc3, 0xb0, 0x64, 0x5a, 0x75, 0x01, 0xe1, 0xf1, 0x6c, 0x1e, 0x7e, 0x28, 0x8f, - 0x25, 0xd3, 0xda, 0xe3, 0xef, 0x16, 0x90, 0x03, 0x49, 0xd3, 0xff, 0xd6, 0xdf, 0x2b, 0x7d, 0xa7, - 0x59, 0xed, 0x3b, 0x0f, 0x61, 0x45, 0xa8, 0xa8, 0x97, 0x12, 0xfa, 0xdc, 0xd7, 0xcd, 0xb3, 0x4f, - 0x99, 0x0a, 0xe1, 0xc0, 0xe7, 0xbe, 0x36, 0x94, 0x62, 0x90, 0xa5, 0xa2, 0x9f, 0x4a, 0x5e, 0x48, - 0x43, 0x6e, 0x0e, 0x89, 0x5c, 0x4a, 0x31, 0xeb, 0x5c, 0x7e, 0xb3, 0x60, 0xf8, 0x82, 0x31, 0x3a, - 0x8d, 0xbf, 0x49, 0xa2, 0x6c, 0x86, 0x79, 0x32, 0xeb, 0xd0, 0x0e, 0x92, 0x2c, 0xe6, 0x32, 0x91, - 0xb6, 0xab, 0x36, 0x4b, 0xb4, 0x68, 0x54, 0x68, 0xb1, 0x44, 0xac, 0x66, 0x95, 0x58, 0x06, 0x71, - 0x5a, 0x26, 0x71, 0xc8, 0xc7, 0xd0, 0x13, 0xe9, 0x79, 0x01, 0xc6, 0x1c, 0x53, 0xfd, 0x0e, 0x41, - 0x40, 0xfb, 0x12, 0x71, 0xae, 0x60, 0xbd, 0x1c, 0xa8, 0x9e, 0x02, 0x37, 0x76, 0x05, 0xf1, 0x6a, - 0xd2, 0x48, 0x47, 0x29, 0x96, 0x64, 0x0b, 0x60, 0x9e, 0x9d, 0x47, 0x34, 0xf0, 0x84, 0x40, 0x45, - 0x67, 0x2b, 0xe4, 0x2c, 0x8d, 0x16, 0x39, 0xb7, 0x8c, 0x9c, 0x9d, 0x2f, 0x60, 0xa8, 0x86, 0x70, - 0xb9, 0x40, 0x5b, 0x00, 0x57, 0x12, 0xf0, 0x68, 0xa8, 0xe6, 0x8f, 0xed, 0xda, 0x0a, 0x39, 0x0e, - 0x99, 0xf3, 0x15, 0xd8, 0x27, 0x89, 0xca, 0x99, 0x91, 0x27, 0x60, 0x47, 0xf9, 0x46, 0x8f, 0x2a, - 0xb2, 0xa0, 0x5c, 0xae, 0xe7, 0x2e, 0x94, 0x9c, 0xe7, 0xd0, 0xcd, 0xe1, 0x3c, 0x0f, 0xeb, 0xa6, - 0x3c, 0x1a, 0x4b, 0x79, 0x38, 0x7f, 0x5a, 0xb0, 0x5e, 0x0e, 0x59, 0x97, 0xea, 0x0c, 0x06, 0x85, - 0x0b, 0x6f, 0xe6, 0xcf, 0x75, 0x2c, 0x4f, 0xcc, 0x58, 0xaa, 0xc7, 0x8a, 0x00, 0xd9, 0x4b, 0x7f, - 0xae, 0xd8, 0xd3, 0x8f, 0x0c, 0x68, 0xfc, 0x06, 0xd6, 0x2a, 0x2a, 0x35, 0xd3, 0xe7, 0xb1, 0x39, - 0x7d, 0x4a, 0x13, 0xb4, 0x38, 0x6d, 0x8e, 0xa4, 0x67, 0x70, 0x4f, 0x11, 0x76, 0xbf, 0xe0, 0x57, - 0x5e, 0xfb, 0x32, 0x0d, 0xad, 0x65, 0x1a, 0x3a, 0x63, 0x18, 0x55, 0x8f, 0x6a, 0xc2, 0x4f, 0x61, - 0xed, 0x94, 0xfb, 0x9c, 0x32, 0x4e, 0x83, 0xe2, 0x53, 0x68, 0x89, 0xb7, 0xd6, 0xfb, 0x1a, 0x62, - 0x95, 0xf9, 0xab, 0xd0, 0xe4, 0x3c, 0xe7, 0x94, 0x58, 0x8a, 0x5b, 0x20, 0xa6, 0x27, 0x7d, 0x07, - 0x1f, 0xc0, 0x95, 0xe0, 0x03, 0x4f, 0xb8, 0x1f, 0xa9, 0x81, 0xd3, 0x92, 0x03, 0xc7, 0x96, 0x88, - 0x9c, 0x38, 0x1b, 0x60, 0x67, 0x0c, 0x43, 0x25, 0x6d, 0xab, 0x71, 0x24, 0x00, 0x29, 0xdc, 0x02, - 0x90, 0xcf, 0x47, 0x31, 0xbf, 0xa3, 0xce, 0x0a, 0x64, 0x5f, 0x00, 0x7b, 0x7f, 0xb5, 0xa1, 0x7f, - 0x8a, 0xfe, 0x35, 0x62, 0x28, 0xe6, 0x5d, 0x4a, 0xa6, 0x39, 0xb7, 0xca, 0xdf, 0xa4, 0xe4, 0xd1, - 0x32, 0x89, 0x6a, 0x3f, 0x82, 0xc7, 0x9f, 0xbe, 0x4f, 0x4d, 0x5f, 0xd3, 0x1d, 0x72, 0x02, 0x3d, - 0xe3, 0xa3, 0x8f, 0x6c, 0x1a, 0x07, 0x2b, 0xdf, 0xb2, 0xe3, 0xad, 0x1b, 0xa4, 0xa6, 0x35, 0x63, - 0x78, 0x98, 0xd6, 0xaa, 0xe3, 0xca, 0xb4, 0x56, 0x37, 0x71, 0xa4, 0x35, 0x63, 0x30, 0x98, 0xd6, - 0xaa, 0xa3, 0xc8, 0xb4, 0x56, 0x37, 0x4d, 0xa4, 0x35, 0xa3, 0x35, 0x9b, 0xd6, 0xaa, 0x53, 0xc6, - 0xb4, 0x56, 0xd7, 0xcf, 0xef, 0x90, 0xd7, 0xd0, 0x37, 0xfb, 0x24, 0x31, 0x0e, 0xd4, 0x34, 0xfa, - 0xf1, 0xfd, 0x9b, 0xc4, 0xa6, 0x41, 0xb3, 0x2d, 0x98, 0x06, 0x6b, 0x1a, 0xa3, 0x69, 0xb0, 0xae, - 0x9b, 0x38, 0x77, 0xc8, 0x77, 0xb0, 0xba, 0xfc, 0x3c, 0xc9, 0x83, 0xe5, 0xb4, 0x2a, 0xaf, 0x7e, - 0xec, 0xdc, 0xa6, 0x52, 0x18, 0x3f, 0x06, 0x58, 0xbc, 0x3a, 0xb2, 0xb1, 0x38, 0x53, 0x79, 0xf5, - 0xe3, 0xcd, 0x7a, 0x61, 0x6e, 0xea, 0xbc, 0x23, 0x7f, 0xf0, 0x3e, 0xff, 0x3b, 0x00, 0x00, 0xff, - 0xff, 0xd6, 0x35, 0x68, 0xc8, 0xef, 0x0d, 0x00, 0x00, + // 1272 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xb4, 0x57, 0xcd, 0x6f, 0xdc, 0x44, + 0x14, 0xaf, 0xf7, 0x2b, 0xeb, 0xb7, 0xbb, 0x21, 0x99, 0x0d, 0xd4, 0xda, 0x7c, 0xb0, 0x35, 0x2d, + 0x4a, 0x45, 0xb4, 0xaa, 0x02, 0x87, 0x96, 0x0a, 0x89, 0x36, 0x1f, 0x52, 0xa4, 0xb4, 0x45, 0x4e, + 0x83, 0x84, 0x38, 0x58, 0x8e, 0x3d, 0xbb, 0x8c, 0xe2, 0xb5, 0x8d, 0x67, 0x9c, 0xb4, 0xfc, 0x1d, + 0x5c, 0x39, 0x70, 0xe2, 0xce, 0x1f, 0xc0, 0x85, 0x03, 0x7f, 0x13, 0x37, 0x34, 0x1f, 0xf6, 0x8e, + 0xd7, 0x4e, 0x0a, 0x42, 0xbd, 0xcd, 0xfc, 0xde, 0x9b, 0xf7, 0x35, 0xbf, 0x79, 0xcf, 0x86, 0xde, + 0x94, 0x84, 0x38, 0x9d, 0x24, 0x69, 0xcc, 0x62, 0xd4, 0x15, 0x1b, 0x37, 0xb9, 0xb0, 0x5f, 0xc1, + 0xe6, 0x69, 0x1c, 0x5f, 0x66, 0xc9, 0x21, 0x49, 0xb1, 0xcf, 0xe2, 0xf4, 0xed, 0x51, 0xc4, 0xd2, + 0xb7, 0x0e, 0xfe, 0x31, 0xc3, 0x94, 0xa1, 0x2d, 0x30, 0x83, 0x5c, 0x60, 0x19, 0x63, 0x63, 0xd7, + 0x74, 0x16, 0x00, 0x42, 0xd0, 0x8a, 0xbc, 0x39, 0xb6, 0x1a, 0x42, 0x20, 0xd6, 0xf6, 0x11, 0x6c, + 0xd5, 0x1b, 0xa4, 0x49, 0x1c, 0x51, 0x8c, 0x1e, 0x40, 0x1b, 0x73, 0x40, 0x58, 0xeb, 0xed, 0x7f, + 0x30, 0xc9, 0x43, 0x99, 0x48, 0x3d, 0x29, 0xb5, 0xff, 0x30, 0x00, 0x9d, 0x12, 0xca, 0x38, 0x48, + 0x30, 0xfd, 0x77, 0xf1, 0x7c, 0x04, 0x9d, 0x24, 0xc5, 0x53, 0xf2, 0x46, 0x45, 0xa4, 0x76, 0x68, + 0x0f, 0xd6, 0x29, 0xf3, 0x52, 0x76, 0x9c, 0xc6, 0xf3, 0x63, 0x12, 0xe2, 0x97, 0x3c, 0xe8, 0xa6, + 0x50, 0xa9, 0x0a, 0xd0, 0x04, 0x10, 0x89, 0xfc, 0x30, 0xa3, 0xe4, 0x0a, 0x9f, 0xe5, 0x52, 0xab, + 0x35, 0x36, 0x76, 0xbb, 0x4e, 0x8d, 0x04, 0x6d, 0x40, 0x3b, 0x24, 0x73, 0xc2, 0xac, 0xf6, 0xd8, + 0xd8, 0x1d, 0x38, 0x72, 0x63, 0x7f, 0x0d, 0xc3, 0x52, 0xfc, 0x2a, 0xfd, 0x87, 0xb0, 0x82, 0x25, + 0x64, 0x19, 0xe3, 0x66, 0x5d, 0x01, 0x72, 0xb9, 0xfd, 0x4b, 0x03, 0xda, 0x02, 0x2a, 0xea, 0x6c, + 0x2c, 0xea, 0x8c, 0xee, 0x41, 0x9f, 0x50, 0x77, 0x51, 0x8c, 0x86, 0x88, 0xaf, 0x47, 0x68, 0x51, + 0x77, 0xf4, 0x19, 0x74, 0xfc, 0x1f, 0xb2, 0xe8, 0x92, 0x5a, 0x4d, 0xe1, 0x6a, 0xb8, 0x70, 0xc5, + 0x93, 0x3d, 0xe0, 0x32, 0x47, 0xa9, 0xa0, 0xc7, 0x00, 0x1e, 0x63, 0x29, 0xb9, 0xc8, 0x18, 0xa6, + 0x22, 0xdb, 0xde, 0xbe, 0xa5, 0x1d, 0xc8, 0x28, 0x7e, 0x56, 0xc8, 0x1d, 0x4d, 0x17, 0x3d, 0x81, + 0x2e, 0x7e, 0xc3, 0x70, 0x14, 0xe0, 0xc0, 0x6a, 0x0b, 0x47, 0xdb, 0x4b, 0x39, 0x4d, 0x8e, 0x94, + 0x5c, 0x66, 0x58, 0xa8, 0x8f, 0x9e, 0xc2, 0xa0, 0x24, 0x42, 0x6b, 0xd0, 0xbc, 0xc4, 0xf9, 0xcd, + 0xf2, 0x25, 0xaf, 0xee, 0x95, 0x17, 0x66, 0x92, 0x64, 0x7d, 0x47, 0x6e, 0xbe, 0x6c, 0x3c, 0x36, + 0xec, 0x9f, 0x0d, 0x58, 0x3f, 0xba, 0xc2, 0x11, 0x7b, 0x19, 0x33, 0x32, 0x25, 0xbe, 0xc7, 0x48, + 0x1c, 0xa1, 0x3d, 0x30, 0xe3, 0x30, 0x70, 0x6f, 0xe5, 0x58, 0x37, 0x0e, 0x95, 0xbf, 0x3d, 0x30, + 0x23, 0x7c, 0xad, 0xb4, 0x1b, 0x37, 0x68, 0x47, 0xf8, 0x5a, 0x6a, 0x7f, 0x02, 0x83, 0x00, 0x87, + 0x98, 0x61, 0xb7, 0xa8, 0x2b, 0x2f, 0x7a, 0x5f, 0x82, 0xa2, 0x9e, 0xd4, 0xfe, 0xd5, 0x00, 0xb3, + 0x28, 0x2f, 0xba, 0x0b, 0x2b, 0xdc, 0x9c, 0x4b, 0x02, 0x95, 0x54, 0x87, 0x6f, 0x4f, 0x02, 0xce, + 0xd5, 0x78, 0x3a, 0xa5, 0x98, 0x09, 0xb7, 0x4d, 0x47, 0xed, 0xf8, 0x5d, 0x53, 0xf2, 0x93, 0xa4, + 0x67, 0xcb, 0x11, 0x6b, 0x5e, 0x83, 0x39, 0x23, 0x73, 0x2c, 0xae, 0xa5, 0xe9, 0xc8, 0x0d, 0x1a, + 0x42, 0x1b, 0xbb, 0xcc, 0x9b, 0x09, 0xde, 0x99, 0x4e, 0x0b, 0xbf, 0xf6, 0x66, 0xe8, 0x3e, 0xac, + 0xd2, 0x38, 0x4b, 0x7d, 0xec, 0xe6, 0x6e, 0x3b, 0x42, 0xda, 0x97, 0xe8, 0xb1, 0x70, 0x6e, 0xff, + 0xd5, 0x80, 0xd5, 0xf2, 0x8d, 0xa2, 0x4d, 0x30, 0xc5, 0x09, 0xe1, 0xdc, 0x10, 0xce, 0x45, 0x97, + 0x38, 0x2b, 0x05, 0xd0, 0xd0, 0x03, 0xc8, 0x8f, 0xcc, 0xe3, 0x40, 0xc6, 0x3b, 0x90, 0x47, 0x5e, + 0xc4, 0x01, 0xe6, 0x37, 0x99, 0x91, 0x40, 0x44, 0x3c, 0x70, 0xf8, 0x92, 0x23, 0x33, 0x12, 0xa8, + 0x57, 0xc2, 0x97, 0xbc, 0x06, 0x7e, 0x2a, 0xec, 0x76, 0x64, 0x0d, 0xe4, 0x8e, 0xd7, 0x60, 0xce, + 0xd1, 0x15, 0x99, 0x18, 0x5f, 0xa3, 0x31, 0xf4, 0x52, 0x9c, 0x84, 0xea, 0x9a, 0xad, 0xae, 0x10, + 0xe9, 0x10, 0xda, 0x01, 0xf0, 0xe3, 0x30, 0xc4, 0xbe, 0x50, 0x30, 0x85, 0x82, 0x86, 0xf0, 0xab, + 0x60, 0x2c, 0x74, 0x29, 0xf6, 0x2d, 0x18, 0x1b, 0xbb, 0x6d, 0xa7, 0xc3, 0x58, 0x78, 0x86, 0x7d, + 0x9e, 0x47, 0x46, 0x71, 0xea, 0x8a, 0x37, 0xd6, 0x13, 0xe7, 0xba, 0x1c, 0x10, 0xdd, 0x60, 0x1b, + 0x60, 0x96, 0xc6, 0x59, 0x22, 0xa5, 0xfd, 0x71, 0x93, 0xb7, 0x1c, 0x81, 0x70, 0xb1, 0xfd, 0x1d, + 0xa0, 0x83, 0x14, 0x7b, 0x0c, 0xff, 0x87, 0xb6, 0x59, 0xb4, 0xc0, 0xc6, 0xad, 0x2d, 0xf0, 0x43, + 0x18, 0x96, 0x4c, 0xcb, 0x0e, 0xc2, 0x3d, 0x9e, 0x27, 0xc1, 0xfb, 0xf2, 0x58, 0x32, 0xad, 0x3c, + 0xfe, 0x6e, 0x00, 0x3a, 0x14, 0x14, 0xff, 0x7f, 0xb3, 0xa1, 0xd2, 0xb3, 0x9a, 0xd5, 0x9e, 0x75, + 0x1f, 0x56, 0xb9, 0x8a, 0x7c, 0x65, 0x81, 0xc7, 0x3c, 0xd5, 0x78, 0xfb, 0x84, 0xca, 0x10, 0x0e, + 0x3d, 0xe6, 0x29, 0x43, 0x29, 0xf6, 0xb3, 0x94, 0xf7, 0x62, 0xc1, 0x29, 0x61, 0xc8, 0xc9, 0x21, + 0x9e, 0x4b, 0x29, 0x66, 0x95, 0xcb, 0x6f, 0x06, 0x0c, 0x9f, 0x51, 0x4a, 0x66, 0xd1, 0xb7, 0x71, + 0x98, 0xcd, 0x71, 0x9e, 0xcc, 0x06, 0xb4, 0xfd, 0x38, 0x8b, 0x98, 0x48, 0xa4, 0xed, 0xc8, 0xcd, + 0x12, 0xa5, 0x1a, 0x15, 0x4a, 0x2d, 0x91, 0xb2, 0x59, 0x25, 0xa5, 0x46, 0xba, 0x56, 0x89, 0x74, + 0x1f, 0x43, 0x8f, 0xa7, 0xe7, 0xfa, 0x38, 0x62, 0x38, 0x55, 0x6f, 0x18, 0x38, 0x74, 0x20, 0x10, + 0xfb, 0x0a, 0x36, 0xca, 0x81, 0xaa, 0x09, 0x72, 0x63, 0x47, 0xe1, 0x2f, 0x2e, 0x0d, 0x55, 0x94, + 0x7c, 0xc9, 0xb9, 0x9b, 0x64, 0x17, 0x21, 0xf1, 0x5d, 0x2e, 0x90, 0xd1, 0x99, 0x12, 0x39, 0x4f, + 0xc3, 0x45, 0xce, 0x2d, 0x2d, 0x67, 0xfb, 0x0b, 0x18, 0xca, 0x01, 0x5e, 0x2e, 0xd0, 0x36, 0xc0, + 0x95, 0x00, 0x5c, 0x12, 0xc8, 0xd9, 0x65, 0x3a, 0xa6, 0x44, 0x4e, 0x02, 0x6a, 0x7f, 0x05, 0xe6, + 0x69, 0x2c, 0x73, 0xa6, 0xe8, 0x11, 0x98, 0x61, 0xbe, 0x51, 0x63, 0x0e, 0x2d, 0x28, 0x97, 0xeb, + 0x39, 0x0b, 0x25, 0xfb, 0x29, 0x74, 0x73, 0x38, 0xcf, 0xc3, 0xb8, 0x29, 0x8f, 0xc6, 0x52, 0x1e, + 0xf6, 0x9f, 0x06, 0x6c, 0x94, 0x43, 0x56, 0xa5, 0x3a, 0x87, 0x41, 0xe1, 0xc2, 0x9d, 0x7b, 0x89, + 0x8a, 0xe5, 0x91, 0x1e, 0x4b, 0xf5, 0x58, 0x11, 0x20, 0x7d, 0xe1, 0x25, 0x92, 0x3d, 0xfd, 0x50, + 0x83, 0x46, 0xaf, 0x61, 0xbd, 0xa2, 0x52, 0x33, 0xb9, 0x1e, 0xea, 0x93, 0xab, 0x34, 0x7d, 0x8b, + 0xd3, 0xfa, 0x38, 0x7b, 0x02, 0x77, 0x25, 0x61, 0x0f, 0x0a, 0x7e, 0xe5, 0xb5, 0x2f, 0xd3, 0xd0, + 0x58, 0xa6, 0xa1, 0x3d, 0x02, 0xab, 0x7a, 0x54, 0x11, 0x7e, 0x06, 0xeb, 0x67, 0xcc, 0x63, 0x84, + 0x32, 0xe2, 0x17, 0x9f, 0x51, 0x4b, 0xbc, 0x35, 0xde, 0xd5, 0x4c, 0xab, 0xcc, 0x5f, 0x83, 0x26, + 0x63, 0x39, 0xa7, 0xf8, 0x92, 0xdf, 0x02, 0xd2, 0x3d, 0xa9, 0x3b, 0x78, 0x0f, 0xae, 0x38, 0x1f, + 0x58, 0xcc, 0xbc, 0x50, 0x0e, 0xab, 0x96, 0x18, 0x56, 0xa6, 0x40, 0xc4, 0xb4, 0x92, 0xfd, 0x3c, + 0x90, 0xd2, 0xb6, 0x1c, 0x65, 0x1c, 0x10, 0xc2, 0x6d, 0x00, 0xf1, 0x7c, 0x24, 0xf3, 0x3b, 0xf2, + 0x2c, 0x47, 0x0e, 0x38, 0xb0, 0xff, 0x77, 0x1b, 0xfa, 0x67, 0xd8, 0xbb, 0xc6, 0x38, 0xe0, 0xb3, + 0x32, 0x45, 0xb3, 0x9c, 0x5b, 0xe5, 0xef, 0x59, 0xf4, 0x60, 0x99, 0x44, 0xb5, 0x1f, 0xd0, 0xa3, + 0x4f, 0xdf, 0xa5, 0xa6, 0xae, 0xe9, 0x0e, 0x3a, 0x85, 0x9e, 0xf6, 0xc1, 0x88, 0xb6, 0xb4, 0x83, + 0x95, 0xef, 0xe0, 0xd1, 0xf6, 0x0d, 0x52, 0xdd, 0x9a, 0x36, 0x3c, 0x74, 0x6b, 0xd5, 0x71, 0xa5, + 0x5b, 0xab, 0x9b, 0x38, 0xc2, 0x9a, 0x36, 0x18, 0x74, 0x6b, 0xd5, 0x51, 0xa4, 0x5b, 0xab, 0x9b, + 0x26, 0xc2, 0x9a, 0xd6, 0x9a, 0x75, 0x6b, 0xd5, 0x29, 0xa3, 0x5b, 0xab, 0xeb, 0xe7, 0x77, 0xd0, + 0x2b, 0xe8, 0xeb, 0x7d, 0x12, 0x69, 0x07, 0x6a, 0x1a, 0xfd, 0x68, 0xe7, 0x26, 0xb1, 0x6e, 0x50, + 0x6f, 0x0b, 0xba, 0xc1, 0x9a, 0xc6, 0xa8, 0x1b, 0xac, 0xeb, 0x26, 0xf6, 0x1d, 0xf4, 0x3d, 0xac, + 0x2d, 0x3f, 0x4f, 0x74, 0x6f, 0x39, 0xad, 0xca, 0xab, 0x1f, 0xd9, 0xb7, 0xa9, 0x14, 0xc6, 0x4f, + 0x00, 0x16, 0xaf, 0x0e, 0x6d, 0x2e, 0xce, 0x54, 0x5e, 0xfd, 0x68, 0xab, 0x5e, 0x98, 0x9b, 0x7a, + 0xbe, 0x03, 0x6b, 0x54, 0x52, 0x7f, 0x4a, 0x27, 0x7e, 0x48, 0x70, 0xc4, 0x9e, 0x83, 0x78, 0x05, + 0xdf, 0xf0, 0xbf, 0xc6, 0x8b, 0x8e, 0xf8, 0x79, 0xfc, 0xfc, 0x9f, 0x00, 0x00, 0x00, 0xff, 0xff, + 0x58, 0x55, 0x30, 0x36, 0x4b, 0x0e, 0x00, 0x00, }