diff --git a/Makefile b/Makefile index f59816e96a43..7c1a8010be50 100644 --- a/Makefile +++ b/Makefile @@ -1017,7 +1017,7 @@ CPP_PROTOS := $(filter %/roachpb/metadata.proto %/roachpb/data.proto %/roachpb/i CPP_HEADERS := $(subst $(PKG_ROOT),$(CPP_PROTO_ROOT),$(CPP_PROTOS:%.proto=%.pb.h)) CPP_SOURCES := $(subst $(PKG_ROOT),$(CPP_PROTO_ROOT),$(CPP_PROTOS:%.proto=%.pb.cc)) -CPP_PROTOS_CCL := $(filter %/ccl/baseccl/encryption_options.proto %/ccl/storageccl/engineccl/enginepbccl/key_registry.proto,$(GO_PROTOS)) +CPP_PROTOS_CCL := $(filter %/ccl/baseccl/encryption_options.proto %/ccl/storageccl/engineccl/enginepbccl/key_registry.proto %/ccl/storageccl/engineccl/enginepbccl/stats.proto,$(GO_PROTOS)) CPP_HEADERS_CCL := $(subst $(PKG_ROOT),$(CPP_PROTO_CCL_ROOT),$(CPP_PROTOS_CCL:%.proto=%.pb.h)) CPP_SOURCES_CCL := $(subst $(PKG_ROOT),$(CPP_PROTO_CCL_ROOT),$(CPP_PROTOS_CCL:%.proto=%.pb.cc)) diff --git a/c-deps/libroach/CMakeLists.txt b/c-deps/libroach/CMakeLists.txt index e39fda611d41..0c5e0c5694e5 100644 --- a/c-deps/libroach/CMakeLists.txt +++ b/c-deps/libroach/CMakeLists.txt @@ -65,6 +65,7 @@ add_library(roachccl ccl/key_manager.cc protosccl/ccl/baseccl/encryption_options.pb.cc protosccl/ccl/storageccl/engineccl/enginepbccl/key_registry.pb.cc + protosccl/ccl/storageccl/engineccl/enginepbccl/stats.pb.cc ) target_include_directories(roachccl PRIVATE .. # CryptoPP headers are directly in the directory. Include .. to be able to include diff --git a/c-deps/libroach/batch.cc b/c-deps/libroach/batch.cc index e7aa3fe76038..5f32196f31d3 100644 --- a/c-deps/libroach/batch.cc +++ b/c-deps/libroach/batch.cc @@ -513,6 +513,8 @@ DBStatus DBBatch::GetStats(DBStatsResult* stats) { return FmtStatus("unsupported DBString DBBatch::GetCompactionStats() { return ToDBString("unsupported"); } +DBStatus DBBatch::GetEnvStats(DBEnvStatsResult* stats) { return FmtStatus("unsupported"); } + DBStatus DBBatch::EnvWriteFile(DBSlice path, DBSlice contents) { return FmtStatus("unsupported"); } DBStatus DBBatch::EnvOpenFile(DBSlice path, rocksdb::WritableFile** file) { @@ -590,6 +592,8 @@ DBStatus DBWriteOnlyBatch::GetStats(DBStatsResult* stats) { return FmtStatus("un DBString DBWriteOnlyBatch::GetCompactionStats() { return ToDBString("unsupported"); } +DBStatus DBWriteOnlyBatch::GetEnvStats(DBEnvStatsResult* stats) { return FmtStatus("unsupported"); } + DBStatus DBWriteOnlyBatch::EnvWriteFile(DBSlice path, DBSlice contents) { return FmtStatus("unsupported"); } diff --git a/c-deps/libroach/batch.h b/c-deps/libroach/batch.h index 9700e8107fa0..7365fe327cef 100644 --- a/c-deps/libroach/batch.h +++ b/c-deps/libroach/batch.h @@ -40,6 +40,7 @@ struct DBBatch : public DBEngine { virtual DBIterator* NewIter(rocksdb::ReadOptions*); virtual DBStatus GetStats(DBStatsResult* stats); virtual DBString GetCompactionStats(); + virtual DBStatus GetEnvStats(DBEnvStatsResult* stats); virtual DBStatus EnvWriteFile(DBSlice path, DBSlice contents); virtual DBStatus EnvOpenFile(DBSlice path, rocksdb::WritableFile** file); virtual DBStatus EnvAppendFile(rocksdb::WritableFile* file, DBSlice contents); @@ -65,6 +66,7 @@ struct DBWriteOnlyBatch : public DBEngine { virtual DBIterator* NewIter(rocksdb::ReadOptions*); virtual DBStatus GetStats(DBStatsResult* stats); virtual DBString GetCompactionStats(); + virtual DBString GetEnvStats(DBEnvStatsResult* stats); virtual DBStatus EnvWriteFile(DBSlice path, DBSlice contents); virtual DBStatus EnvOpenFile(DBSlice path, rocksdb::WritableFile** file); virtual DBStatus EnvAppendFile(rocksdb::WritableFile* file, DBSlice contents); diff --git a/c-deps/libroach/ccl/db.cc b/c-deps/libroach/ccl/db.cc index 708160daedd5..d093f0178049 100644 --- a/c-deps/libroach/ccl/db.cc +++ b/c-deps/libroach/ccl/db.cc @@ -21,6 +21,7 @@ #include "../rocksdbutils/env_encryption.h" #include "../status.h" #include "ccl/baseccl/encryption_options.pb.h" +#include "ccl/storageccl/engineccl/enginepbccl/stats.pb.h" #include "ctr_stream.h" #include "key_manager.h" @@ -28,6 +29,44 @@ using namespace cockroach; namespace cockroach { +class CCLEnvStatsHandler : public EnvStatsHandler { + public: + explicit CCLEnvStatsHandler(KeyManager* store_key_manager, KeyManager* data_key_manager) + : store_key_manager_(store_key_manager), data_key_manager_(data_key_manager) {} + virtual ~CCLEnvStatsHandler() {} + + virtual rocksdb::Status GetEncryptionStats(std::string* serialized_stats) override { + enginepbccl::EncryptionStatus enc_status; + + bool has_stats = false; + if (this->store_key_manager_ != nullptr) { + has_stats = true; + // Transfer ownership of new key info to status proto, this frees any previous value. + enc_status.set_allocated_active_store_key(store_key_manager_->CurrentKeyInfo().release()); + } + + if (this->data_key_manager_ != nullptr) { + has_stats = true; + // Transfer ownership of new key info to status proto, this frees any previous value. + enc_status.set_allocated_active_data_key(data_key_manager_->CurrentKeyInfo().release()); + } + + if (!has_stats) { + return rocksdb::Status::OK(); + } + + if (!enc_status.SerializeToString(serialized_stats)) { + return rocksdb::Status::InvalidArgument("failed to serialize encryption status"); + } + return rocksdb::Status::OK(); + } + + private: + // KeyManagers are needed to get key information but are not owned by the StatsHandler. + KeyManager* store_key_manager_; + KeyManager* data_key_manager_; +}; + // DBOpenHook parses the extra_options field of DBOptions and initializes encryption objects if // needed. rocksdb::Status DBOpenHook(const std::string& db_dir, const DBOptions db_opts, @@ -98,12 +137,16 @@ rocksdb::Status DBOpenHook(const std::string& db_dir, const DBOptions db_opts, std::unique_ptr store_key = store_key_manager->CurrentKeyInfo(); assert(store_key != nullptr); - // Generate a new data key if needed by giving the active store key info to the data key manager. + // Generate a new data key if needed by giving the active store key info to the data key + // manager. status = data_key_manager->SetActiveStoreKey(std::move(store_key)); if (!status.ok()) { return status; } + // Everything's ok: initialize a stats handler. + env_mgr->SetStatsHandler(new CCLEnvStatsHandler(store_key_manager, data_key_manager)); + return rocksdb::Status::OK(); } diff --git a/c-deps/libroach/ccl/db_test.cc b/c-deps/libroach/ccl/db_test.cc index 0e2a3e086925..3c272b1f3dcb 100644 --- a/c-deps/libroach/ccl/db_test.cc +++ b/c-deps/libroach/ccl/db_test.cc @@ -8,6 +8,8 @@ #include "../db.h" #include "../testutils.h" +#include "ccl/baseccl/encryption_options.pb.h" +#include "ccl/storageccl/engineccl/enginepbccl/stats.pb.h" using namespace cockroach; @@ -30,3 +32,49 @@ TEST(LibroachCCL, DBOpenHook) { db_opts.extra_options = ToDBSlice("blah"); EXPECT_ERR(DBOpenHook("", db_opts, nullptr), "failed to parse extra options"); } + +TEST(Libroach, DBOpen) { + { + // Empty options: no encryption. + DBOptions db_opts = defaultDBOptions(); + DBEngine* db; + db_opts.use_file_registry = true; + + EXPECT_STREQ(DBOpen(&db, DBSlice(), db_opts).data, NULL); + DBEnvStatsResult stats; + EXPECT_STREQ(DBGetEnvStats(db, &stats).data, NULL); + EXPECT_STREQ(stats.encryption_status.data, NULL); + + DBClose(db); + } + { + // Encryption enabled. + DBOptions db_opts = defaultDBOptions(); + DBEngine* db; + db_opts.use_file_registry = true; + + // Enable encryption, but plaintext only, that's enough to get stats going. + cockroach::ccl::baseccl::EncryptionOptions enc_opts; + enc_opts.set_key_source(cockroach::ccl::baseccl::KeyFiles); + enc_opts.mutable_key_files()->set_current_key("plain"); + enc_opts.mutable_key_files()->set_old_key("plain"); + + std::string tmpstr; + ASSERT_TRUE(enc_opts.SerializeToString(&tmpstr)); + db_opts.extra_options = ToDBSlice(tmpstr); + + EXPECT_STREQ(DBOpen(&db, DBSlice(), db_opts).data, NULL); + DBEnvStatsResult stats; + EXPECT_STREQ(DBGetEnvStats(db, &stats).data, NULL); + EXPECT_STRNE(stats.encryption_status.data, NULL); + + // Now parse the status protobuf. + cockroach::ccl::storageccl::engineccl::enginepbccl::EncryptionStatus enc_status; + ASSERT_TRUE( + enc_status.ParseFromArray(stats.encryption_status.data, stats.encryption_status.len)); + EXPECT_STREQ(enc_status.active_store_key().key_id().c_str(), "plain"); + EXPECT_STREQ(enc_status.active_data_key().key_id().c_str(), "plain"); + + DBClose(db); + } +} diff --git a/c-deps/libroach/db.cc b/c-deps/libroach/db.cc index 28a63fa61823..ae050face905 100644 --- a/c-deps/libroach/db.cc +++ b/c-deps/libroach/db.cc @@ -628,6 +628,8 @@ DBStatus DBGetStats(DBEngine* db, DBStatsResult* stats) { return db->GetStats(st DBString DBGetCompactionStats(DBEngine* db) { return db->GetCompactionStats(); } +DBStatus DBGetEnvStats(DBEngine* db, DBEnvStatsResult* stats) { return db->GetEnvStats(stats); } + DBSSTable* DBGetSSTables(DBEngine* db, int* n) { return db->GetSSTables(n); } DBString DBGetUserProperties(DBEngine* db) { return db->GetUserProperties(); } diff --git a/c-deps/libroach/db_test.cc b/c-deps/libroach/db_test.cc index 01a69de29f30..f5f86ff0c560 100644 --- a/c-deps/libroach/db_test.cc +++ b/c-deps/libroach/db_test.cc @@ -14,6 +14,7 @@ #include "db.h" #include "include/libroach.h" +#include "status.h" #include "testutils.h" using namespace cockroach; @@ -30,3 +31,15 @@ TEST(Libroach, DBOpenHook) { EXPECT_ERR(DBOpenHook("", db_opts, nullptr), "DBOptions has extra_options, but OSS code cannot handle them"); } + +TEST(Libroach, DBOpen) { + DBOptions db_opts = defaultDBOptions(); + DBEngine* db; + + EXPECT_STREQ(DBOpen(&db, DBSlice(), db_opts).data, NULL); + DBEnvStatsResult stats; + EXPECT_STREQ(DBGetEnvStats(db, &stats).data, NULL); + EXPECT_STREQ(stats.encryption_status.data, NULL); + + DBClose(db); +} diff --git a/c-deps/libroach/engine.cc b/c-deps/libroach/engine.cc index bbd373d0044d..f48d89ec973b 100644 --- a/c-deps/libroach/engine.cc +++ b/c-deps/libroach/engine.cc @@ -204,6 +204,24 @@ DBString DBImpl::GetCompactionStats() { return ToDBString(tmp); } +DBStatus DBImpl::GetEnvStats(DBEnvStatsResult* stats) { + // Always initialize the field to the empty string. + stats->encryption_status = DBString(); + + if (this->env_mgr->env_stats_handler == nullptr) { + return kSuccess; + } + + std::string encryption_status; + auto status = this->env_mgr->env_stats_handler->GetEncryptionStats(&encryption_status); + if (!status.ok()) { + return ToDBStatus(status); + } + + stats->encryption_status = ToDBString(encryption_status); + return kSuccess; +} + // EnvWriteFile writes the given data as a new "file" in the given engine. DBStatus DBImpl::EnvWriteFile(DBSlice path, DBSlice contents) { rocksdb::Status s; diff --git a/c-deps/libroach/engine.h b/c-deps/libroach/engine.h index 63c2d28ce4d0..991726628783 100644 --- a/c-deps/libroach/engine.h +++ b/c-deps/libroach/engine.h @@ -41,6 +41,7 @@ struct DBEngine { virtual DBIterator* NewIter(rocksdb::ReadOptions*) = 0; virtual DBStatus GetStats(DBStatsResult* stats) = 0; virtual DBString GetCompactionStats() = 0; + virtual DBString GetEnvStats(DBEnvStatsResult* stats) = 0; virtual DBStatus EnvWriteFile(DBSlice path, DBSlice contents) = 0; virtual DBStatus EnvOpenFile(DBSlice path, rocksdb::WritableFile** file) = 0; virtual DBStatus EnvAppendFile(rocksdb::WritableFile* file, DBSlice contents) = 0; @@ -81,6 +82,7 @@ struct DBImpl : public DBEngine { virtual DBIterator* NewIter(rocksdb::ReadOptions*); virtual DBStatus GetStats(DBStatsResult* stats); virtual DBString GetCompactionStats(); + virtual DBStatus GetEnvStats(DBEnvStatsResult* stats); virtual DBStatus EnvWriteFile(DBSlice path, DBSlice contents); virtual DBStatus EnvOpenFile(DBSlice path, rocksdb::WritableFile** file); virtual DBStatus EnvAppendFile(rocksdb::WritableFile* file, DBSlice contents); diff --git a/c-deps/libroach/env_manager.h b/c-deps/libroach/env_manager.h index dbb75de2d1c2..6b1018753812 100644 --- a/c-deps/libroach/env_manager.h +++ b/c-deps/libroach/env_manager.h @@ -20,6 +20,14 @@ namespace cockroach { +// EnvStatsHandler provides an interface to generate Env-specific stats. +class EnvStatsHandler { + public: + virtual ~EnvStatsHandler() {} + + virtual rocksdb::Status GetEncryptionStats(std::string* stats) = 0; +}; + // EnvManager manages all created Envs, as well as the file registry. // Rocksdb owns Env::Default (global static). All other envs are owned by EnvManager. // @@ -30,10 +38,14 @@ struct EnvManager { EnvManager(rocksdb::Env* env) : base_env(env), db_env(env) {} ~EnvManager() {} + // Set the stats handler implementing GetEncryptionStats to fill in env-related stats. + // It does not have called, leaving env_stats_handler nil. + void SetStatsHandler(EnvStatsHandler* stats_handler) { env_stats_handler.reset(stats_handler); } void TakeEnvOwnership(rocksdb::Env* env) { envs.push_back(std::unique_ptr(env)); } rocksdb::Env* base_env; rocksdb::Env* db_env; + std::unique_ptr env_stats_handler; std::unique_ptr file_registry; std::vector> envs; }; diff --git a/c-deps/libroach/include/libroach.h b/c-deps/libroach/include/libroach.h index fc94f5e1706d..a49377225c45 100644 --- a/c-deps/libroach/include/libroach.h +++ b/c-deps/libroach/include/libroach.h @@ -304,8 +304,16 @@ typedef struct { int64_t pending_compaction_bytes_estimate; } DBStatsResult; +// DBEnvStatsResult contains Env stats (filesystem layer). +typedef struct { + // encryption status (CCL only). + // This is a serialized enginepbccl/stats.proto:EncryptionStatus + DBString encryption_status; +} DBEnvStatsResult; + DBStatus DBGetStats(DBEngine* db, DBStatsResult* stats); DBString DBGetCompactionStats(DBEngine* db); +DBStatus DBGetEnvStats(DBEngine* db, DBEnvStatsResult* stats); typedef struct { int level; diff --git a/c-deps/libroach/protosccl/ccl/storageccl/engineccl/enginepbccl/stats.pb.cc b/c-deps/libroach/protosccl/ccl/storageccl/engineccl/enginepbccl/stats.pb.cc new file mode 100644 index 000000000000..b2b84054ca1b --- /dev/null +++ b/c-deps/libroach/protosccl/ccl/storageccl/engineccl/enginepbccl/stats.pb.cc @@ -0,0 +1,332 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ccl/storageccl/engineccl/enginepbccl/stats.proto + +#include "ccl/storageccl/engineccl/enginepbccl/stats.pb.h" + +#include + +#include +#include +#include +#include +#include +#include +// This is a temporary google only hack +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS +#include "third_party/protobuf/version.h" +#endif +// @@protoc_insertion_point(includes) +namespace cockroach { +namespace ccl { +namespace storageccl { +namespace engineccl { +namespace enginepbccl { +class EncryptionStatusDefaultTypeInternal { + public: + ::google::protobuf::internal::ExplicitlyConstructed + _instance; +} _EncryptionStatus_default_instance_; +} // namespace enginepbccl +} // namespace engineccl +} // namespace storageccl +} // namespace ccl +} // namespace cockroach +namespace protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto { +void InitDefaultsEncryptionStatusImpl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + +#ifdef GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + ::google::protobuf::internal::InitProtobufDefaultsForceUnique(); +#else + ::google::protobuf::internal::InitProtobufDefaults(); +#endif // GOOGLE_PROTOBUF_ENFORCE_UNIQUENESS + protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fkey_5fregistry_2eproto::InitDefaultsKeyInfo(); + { + void* ptr = &::cockroach::ccl::storageccl::engineccl::enginepbccl::_EncryptionStatus_default_instance_; + new (ptr) ::cockroach::ccl::storageccl::engineccl::enginepbccl::EncryptionStatus(); + ::google::protobuf::internal::OnShutdownDestroyMessage(ptr); + } + ::cockroach::ccl::storageccl::engineccl::enginepbccl::EncryptionStatus::InitAsDefaultInstance(); +} + +void InitDefaultsEncryptionStatus() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &InitDefaultsEncryptionStatusImpl); +} + +} // namespace protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto +namespace cockroach { +namespace ccl { +namespace storageccl { +namespace engineccl { +namespace enginepbccl { + +// =================================================================== + +void EncryptionStatus::InitAsDefaultInstance() { + ::cockroach::ccl::storageccl::engineccl::enginepbccl::_EncryptionStatus_default_instance_._instance.get_mutable()->active_store_key_ = const_cast< ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo*>( + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo::internal_default_instance()); + ::cockroach::ccl::storageccl::engineccl::enginepbccl::_EncryptionStatus_default_instance_._instance.get_mutable()->active_data_key_ = const_cast< ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo*>( + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo::internal_default_instance()); +} +void EncryptionStatus::clear_active_store_key() { + if (GetArenaNoVirtual() == NULL && active_store_key_ != NULL) { + delete active_store_key_; + } + active_store_key_ = NULL; +} +void EncryptionStatus::clear_active_data_key() { + if (GetArenaNoVirtual() == NULL && active_data_key_ != NULL) { + delete active_data_key_; + } + active_data_key_ = NULL; +} +#if !defined(_MSC_VER) || _MSC_VER >= 1900 +const int EncryptionStatus::kActiveStoreKeyFieldNumber; +const int EncryptionStatus::kActiveDataKeyFieldNumber; +#endif // !defined(_MSC_VER) || _MSC_VER >= 1900 + +EncryptionStatus::EncryptionStatus() + : ::google::protobuf::MessageLite(), _internal_metadata_(NULL) { + if (GOOGLE_PREDICT_TRUE(this != internal_default_instance())) { + ::protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto::InitDefaultsEncryptionStatus(); + } + SharedCtor(); + // @@protoc_insertion_point(constructor:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) +} +EncryptionStatus::EncryptionStatus(const EncryptionStatus& from) + : ::google::protobuf::MessageLite(), + _internal_metadata_(NULL), + _cached_size_(0) { + _internal_metadata_.MergeFrom(from._internal_metadata_); + if (from.has_active_store_key()) { + active_store_key_ = new ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo(*from.active_store_key_); + } else { + active_store_key_ = NULL; + } + if (from.has_active_data_key()) { + active_data_key_ = new ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo(*from.active_data_key_); + } else { + active_data_key_ = NULL; + } + // @@protoc_insertion_point(copy_constructor:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) +} + +void EncryptionStatus::SharedCtor() { + ::memset(&active_store_key_, 0, static_cast( + reinterpret_cast(&active_data_key_) - + reinterpret_cast(&active_store_key_)) + sizeof(active_data_key_)); + _cached_size_ = 0; +} + +EncryptionStatus::~EncryptionStatus() { + // @@protoc_insertion_point(destructor:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + SharedDtor(); +} + +void EncryptionStatus::SharedDtor() { + if (this != internal_default_instance()) delete active_store_key_; + if (this != internal_default_instance()) delete active_data_key_; +} + +void EncryptionStatus::SetCachedSize(int size) const { + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); +} +const EncryptionStatus& EncryptionStatus::default_instance() { + ::protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto::InitDefaultsEncryptionStatus(); + return *internal_default_instance(); +} + +EncryptionStatus* EncryptionStatus::New(::google::protobuf::Arena* arena) const { + EncryptionStatus* n = new EncryptionStatus; + if (arena != NULL) { + arena->Own(n); + } + return n; +} + +void EncryptionStatus::Clear() { +// @@protoc_insertion_point(message_clear_start:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + ::google::protobuf::uint32 cached_has_bits = 0; + // Prevent compiler warnings about cached_has_bits being unused + (void) cached_has_bits; + + if (GetArenaNoVirtual() == NULL && active_store_key_ != NULL) { + delete active_store_key_; + } + active_store_key_ = NULL; + if (GetArenaNoVirtual() == NULL && active_data_key_ != NULL) { + delete active_data_key_; + } + active_data_key_ = NULL; + _internal_metadata_.Clear(); +} + +bool EncryptionStatus::MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) { +#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure + ::google::protobuf::uint32 tag; + ::google::protobuf::internal::LiteUnknownFieldSetter unknown_fields_setter( + &_internal_metadata_); + ::google::protobuf::io::StringOutputStream unknown_fields_output( + unknown_fields_setter.buffer()); + ::google::protobuf::io::CodedOutputStream unknown_fields_stream( + &unknown_fields_output, false); + // @@protoc_insertion_point(parse_start:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + for (;;) { + ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoffNoLastTag(127u); + tag = p.first; + if (!p.second) goto handle_unusual; + switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) { + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_store_key = 1; + case 1: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(10u /* 10 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessage( + input, mutable_active_store_key())); + } else { + goto handle_unusual; + } + break; + } + + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_data_key = 2; + case 2: { + if (static_cast< ::google::protobuf::uint8>(tag) == + static_cast< ::google::protobuf::uint8>(18u /* 18 & 0xFF */)) { + DO_(::google::protobuf::internal::WireFormatLite::ReadMessage( + input, mutable_active_data_key())); + } else { + goto handle_unusual; + } + break; + } + + default: { + handle_unusual: + if (tag == 0) { + goto success; + } + DO_(::google::protobuf::internal::WireFormatLite::SkipField( + input, tag, &unknown_fields_stream)); + break; + } + } + } +success: + // @@protoc_insertion_point(parse_success:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + return true; +failure: + // @@protoc_insertion_point(parse_failure:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + return false; +#undef DO_ +} + +void EncryptionStatus::SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const { + // @@protoc_insertion_point(serialize_start:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_store_key = 1; + if (this->has_active_store_key()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 1, *this->active_store_key_, output); + } + + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_data_key = 2; + if (this->has_active_data_key()) { + ::google::protobuf::internal::WireFormatLite::WriteMessage( + 2, *this->active_data_key_, output); + } + + output->WriteRaw((::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()).data(), + static_cast((::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()).size())); + // @@protoc_insertion_point(serialize_end:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) +} + +size_t EncryptionStatus::ByteSizeLong() const { +// @@protoc_insertion_point(message_byte_size_start:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + size_t total_size = 0; + + total_size += (::google::protobuf::internal::GetProto3PreserveUnknownsDefault() ? _internal_metadata_.unknown_fields() : _internal_metadata_.default_instance()).size(); + + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_store_key = 1; + if (this->has_active_store_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSize( + *this->active_store_key_); + } + + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_data_key = 2; + if (this->has_active_data_key()) { + total_size += 1 + + ::google::protobuf::internal::WireFormatLite::MessageSize( + *this->active_data_key_); + } + + int cached_size = ::google::protobuf::internal::ToCachedSize(total_size); + GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN(); + _cached_size_ = cached_size; + GOOGLE_SAFE_CONCURRENT_WRITES_END(); + return total_size; +} + +void EncryptionStatus::CheckTypeAndMergeFrom( + const ::google::protobuf::MessageLite& from) { + MergeFrom(*::google::protobuf::down_cast(&from)); +} + +void EncryptionStatus::MergeFrom(const EncryptionStatus& from) { +// @@protoc_insertion_point(class_specific_merge_from_start:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + GOOGLE_DCHECK_NE(&from, this); + _internal_metadata_.MergeFrom(from._internal_metadata_); + ::google::protobuf::uint32 cached_has_bits = 0; + (void) cached_has_bits; + + if (from.has_active_store_key()) { + mutable_active_store_key()->::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo::MergeFrom(from.active_store_key()); + } + if (from.has_active_data_key()) { + mutable_active_data_key()->::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo::MergeFrom(from.active_data_key()); + } +} + +void EncryptionStatus::CopyFrom(const EncryptionStatus& from) { +// @@protoc_insertion_point(class_specific_copy_from_start:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + if (&from == this) return; + Clear(); + MergeFrom(from); +} + +bool EncryptionStatus::IsInitialized() const { + return true; +} + +void EncryptionStatus::Swap(EncryptionStatus* other) { + if (other == this) return; + InternalSwap(other); +} +void EncryptionStatus::InternalSwap(EncryptionStatus* other) { + using std::swap; + swap(active_store_key_, other->active_store_key_); + swap(active_data_key_, other->active_data_key_); + _internal_metadata_.Swap(&other->_internal_metadata_); + swap(_cached_size_, other->_cached_size_); +} + +::std::string EncryptionStatus::GetTypeName() const { + return "cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus"; +} + + +// @@protoc_insertion_point(namespace_scope) +} // namespace enginepbccl +} // namespace engineccl +} // namespace storageccl +} // namespace ccl +} // namespace cockroach + +// @@protoc_insertion_point(global_scope) diff --git a/c-deps/libroach/protosccl/ccl/storageccl/engineccl/enginepbccl/stats.pb.h b/c-deps/libroach/protosccl/ccl/storageccl/engineccl/enginepbccl/stats.pb.h new file mode 100644 index 000000000000..0471b8f91fb6 --- /dev/null +++ b/c-deps/libroach/protosccl/ccl/storageccl/engineccl/enginepbccl/stats.pb.h @@ -0,0 +1,292 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: ccl/storageccl/engineccl/enginepbccl/stats.proto + +#ifndef PROTOBUF_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto__INCLUDED +#define PROTOBUF_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto__INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3005000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3005001 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +#include "ccl/storageccl/engineccl/enginepbccl/key_registry.pb.h" +// @@protoc_insertion_point(includes) + +namespace protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto { +// Internal implementation detail -- do not use these members. +struct TableStruct { + static const ::google::protobuf::internal::ParseTableField entries[]; + static const ::google::protobuf::internal::AuxillaryParseTableField aux[]; + static const ::google::protobuf::internal::ParseTable schema[1]; + static const ::google::protobuf::internal::FieldMetadata field_metadata[]; + static const ::google::protobuf::internal::SerializationTable serialization_table[]; + static const ::google::protobuf::uint32 offsets[]; +}; +void InitDefaultsEncryptionStatusImpl(); +void InitDefaultsEncryptionStatus(); +inline void InitDefaults() { + InitDefaultsEncryptionStatus(); +} +} // namespace protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto +namespace cockroach { +namespace ccl { +namespace storageccl { +namespace engineccl { +namespace enginepbccl { +class EncryptionStatus; +class EncryptionStatusDefaultTypeInternal; +extern EncryptionStatusDefaultTypeInternal _EncryptionStatus_default_instance_; +} // namespace enginepbccl +} // namespace engineccl +} // namespace storageccl +} // namespace ccl +} // namespace cockroach +namespace cockroach { +namespace ccl { +namespace storageccl { +namespace engineccl { +namespace enginepbccl { + +// =================================================================== + +class EncryptionStatus : public ::google::protobuf::MessageLite /* @@protoc_insertion_point(class_definition:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) */ { + public: + EncryptionStatus(); + virtual ~EncryptionStatus(); + + EncryptionStatus(const EncryptionStatus& from); + + inline EncryptionStatus& operator=(const EncryptionStatus& from) { + CopyFrom(from); + return *this; + } + #if LANG_CXX11 + EncryptionStatus(EncryptionStatus&& from) noexcept + : EncryptionStatus() { + *this = ::std::move(from); + } + + inline EncryptionStatus& operator=(EncryptionStatus&& from) noexcept { + if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) { + if (this != &from) InternalSwap(&from); + } else { + CopyFrom(from); + } + return *this; + } + #endif + static const EncryptionStatus& default_instance(); + + static void InitAsDefaultInstance(); // FOR INTERNAL USE ONLY + static inline const EncryptionStatus* internal_default_instance() { + return reinterpret_cast( + &_EncryptionStatus_default_instance_); + } + static PROTOBUF_CONSTEXPR int const kIndexInFileMessages = + 0; + + void Swap(EncryptionStatus* other); + friend void swap(EncryptionStatus& a, EncryptionStatus& b) { + a.Swap(&b); + } + + // implements Message ---------------------------------------------- + + inline EncryptionStatus* New() const PROTOBUF_FINAL { return New(NULL); } + + EncryptionStatus* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL; + void CheckTypeAndMergeFrom(const ::google::protobuf::MessageLite& from) + PROTOBUF_FINAL; + void CopyFrom(const EncryptionStatus& from); + void MergeFrom(const EncryptionStatus& from); + void Clear() PROTOBUF_FINAL; + bool IsInitialized() const PROTOBUF_FINAL; + + size_t ByteSizeLong() const PROTOBUF_FINAL; + bool MergePartialFromCodedStream( + ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL; + void SerializeWithCachedSizes( + ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL; + void DiscardUnknownFields(); + int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; } + private: + void SharedCtor(); + void SharedDtor(); + void SetCachedSize(int size) const; + void InternalSwap(EncryptionStatus* other); + private: + inline ::google::protobuf::Arena* GetArenaNoVirtual() const { + return NULL; + } + inline void* MaybeArenaPtr() const { + return NULL; + } + public: + + ::std::string GetTypeName() const PROTOBUF_FINAL; + + // nested types ---------------------------------------------------- + + // accessors ------------------------------------------------------- + + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_store_key = 1; + bool has_active_store_key() const; + void clear_active_store_key(); + static const int kActiveStoreKeyFieldNumber = 1; + const ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo& active_store_key() const; + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* release_active_store_key(); + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* mutable_active_store_key(); + void set_allocated_active_store_key(::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* active_store_key); + + // .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_data_key = 2; + bool has_active_data_key() const; + void clear_active_data_key(); + static const int kActiveDataKeyFieldNumber = 2; + const ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo& active_data_key() const; + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* release_active_data_key(); + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* mutable_active_data_key(); + void set_allocated_active_data_key(::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* active_data_key); + + // @@protoc_insertion_point(class_scope:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus) + private: + + ::google::protobuf::internal::InternalMetadataWithArenaLite _internal_metadata_; + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* active_store_key_; + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* active_data_key_; + mutable int _cached_size_; + friend struct ::protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto::TableStruct; + friend void ::protobuf_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto::InitDefaultsEncryptionStatusImpl(); +}; +// =================================================================== + + +// =================================================================== + +#ifdef __GNUC__ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wstrict-aliasing" +#endif // __GNUC__ +// EncryptionStatus + +// .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_store_key = 1; +inline bool EncryptionStatus::has_active_store_key() const { + return this != internal_default_instance() && active_store_key_ != NULL; +} +inline const ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo& EncryptionStatus::active_store_key() const { + const ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* p = active_store_key_; + // @@protoc_insertion_point(field_get:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_store_key) + return p != NULL ? *p : *reinterpret_cast( + &::cockroach::ccl::storageccl::engineccl::enginepbccl::_KeyInfo_default_instance_); +} +inline ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* EncryptionStatus::release_active_store_key() { + // @@protoc_insertion_point(field_release:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_store_key) + + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* temp = active_store_key_; + active_store_key_ = NULL; + return temp; +} +inline ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* EncryptionStatus::mutable_active_store_key() { + + if (active_store_key_ == NULL) { + active_store_key_ = new ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo; + } + // @@protoc_insertion_point(field_mutable:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_store_key) + return active_store_key_; +} +inline void EncryptionStatus::set_allocated_active_store_key(::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* active_store_key) { + ::google::protobuf::Arena* message_arena = GetArenaNoVirtual(); + if (message_arena == NULL) { + delete reinterpret_cast< ::google::protobuf::MessageLite*>(active_store_key_); + } + if (active_store_key) { + ::google::protobuf::Arena* submessage_arena = NULL; + if (message_arena != submessage_arena) { + active_store_key = ::google::protobuf::internal::GetOwnedMessage( + message_arena, active_store_key, submessage_arena); + } + + } else { + + } + active_store_key_ = active_store_key; + // @@protoc_insertion_point(field_set_allocated:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_store_key) +} + +// .cockroach.ccl.storageccl.engineccl.enginepbccl.KeyInfo active_data_key = 2; +inline bool EncryptionStatus::has_active_data_key() const { + return this != internal_default_instance() && active_data_key_ != NULL; +} +inline const ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo& EncryptionStatus::active_data_key() const { + const ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* p = active_data_key_; + // @@protoc_insertion_point(field_get:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_data_key) + return p != NULL ? *p : *reinterpret_cast( + &::cockroach::ccl::storageccl::engineccl::enginepbccl::_KeyInfo_default_instance_); +} +inline ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* EncryptionStatus::release_active_data_key() { + // @@protoc_insertion_point(field_release:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_data_key) + + ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* temp = active_data_key_; + active_data_key_ = NULL; + return temp; +} +inline ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* EncryptionStatus::mutable_active_data_key() { + + if (active_data_key_ == NULL) { + active_data_key_ = new ::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo; + } + // @@protoc_insertion_point(field_mutable:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_data_key) + return active_data_key_; +} +inline void EncryptionStatus::set_allocated_active_data_key(::cockroach::ccl::storageccl::engineccl::enginepbccl::KeyInfo* active_data_key) { + ::google::protobuf::Arena* message_arena = GetArenaNoVirtual(); + if (message_arena == NULL) { + delete reinterpret_cast< ::google::protobuf::MessageLite*>(active_data_key_); + } + if (active_data_key) { + ::google::protobuf::Arena* submessage_arena = NULL; + if (message_arena != submessage_arena) { + active_data_key = ::google::protobuf::internal::GetOwnedMessage( + message_arena, active_data_key, submessage_arena); + } + + } else { + + } + active_data_key_ = active_data_key; + // @@protoc_insertion_point(field_set_allocated:cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus.active_data_key) +} + +#ifdef __GNUC__ + #pragma GCC diagnostic pop +#endif // __GNUC__ + +// @@protoc_insertion_point(namespace_scope) + +} // namespace enginepbccl +} // namespace engineccl +} // namespace storageccl +} // namespace ccl +} // namespace cockroach + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF_ccl_2fstorageccl_2fengineccl_2fenginepbccl_2fstats_2eproto__INCLUDED diff --git a/c-deps/libroach/snapshot.cc b/c-deps/libroach/snapshot.cc index 916f048ecd8b..647c1817f6a7 100644 --- a/c-deps/libroach/snapshot.cc +++ b/c-deps/libroach/snapshot.cc @@ -53,6 +53,8 @@ DBStatus DBSnapshot::GetStats(DBStatsResult* stats) { return FmtStatus("unsuppor DBString DBSnapshot::GetCompactionStats() { return ToDBString("unsupported"); } +DBStatus DBSnapshot::GetEnvStats(DBEnvStatsResult* stats) { return FmtStatus("unsupported"); } + DBStatus DBSnapshot::EnvWriteFile(DBSlice path, DBSlice contents) { return FmtStatus("unsupported"); } diff --git a/c-deps/libroach/snapshot.h b/c-deps/libroach/snapshot.h index 1cc5600e6493..a87c7d3e7473 100644 --- a/c-deps/libroach/snapshot.h +++ b/c-deps/libroach/snapshot.h @@ -37,6 +37,7 @@ struct DBSnapshot : public DBEngine { virtual DBIterator* NewIter(rocksdb::ReadOptions*); virtual DBStatus GetStats(DBStatsResult* stats); virtual DBString GetCompactionStats(); + virtual DBStatus GetEnvStats(DBEnvStatsResult* stats); virtual DBStatus EnvWriteFile(DBSlice path, DBSlice contents); virtual DBStatus EnvOpenFile(DBSlice path, rocksdb::WritableFile** file); virtual DBStatus EnvAppendFile(rocksdb::WritableFile* file, DBSlice contents); diff --git a/c-deps/libroach/testutils.cc b/c-deps/libroach/testutils.cc index 7c944cf22b3c..13e3f2412efb 100644 --- a/c-deps/libroach/testutils.cc +++ b/c-deps/libroach/testutils.cc @@ -19,6 +19,12 @@ #include #include "fmt.h" +extern "C" { +// Tests are run in plain C++, we need a symbol for rocksDBLog, normally +// implemented on the Go side. +void __attribute__((weak)) rocksDBLog(char*, int) {} +} // extern "C" + namespace testutils { rocksdb::Status compareErrorMessage(rocksdb::Status status, const char* err_msg) { diff --git a/c-deps/libroach/testutils.h b/c-deps/libroach/testutils.h index 3b96761b33e2..3c61782e1363 100644 --- a/c-deps/libroach/testutils.h +++ b/c-deps/libroach/testutils.h @@ -18,6 +18,21 @@ #include #include #include +#include "include/libroach.h" + +// Returns initialized DBOptions with reasonable values for unittests. +inline DBOptions defaultDBOptions() { + return DBOptions{ + nullptr, // cache + 2, // num_cpu + 1024, // max_open_files + false, // use_file_registry + false, // must_exist + false, // read_only + DBSlice(), // rocksdb_options + DBSlice(), // extra_options + }; +} namespace testutils { diff --git a/pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.pb.go b/pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.pb.go index 8134a3292f8d..aa56e856d995 100644 --- a/pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.pb.go +++ b/pkg/ccl/storageccl/engineccl/enginepbccl/key_registry.pb.go @@ -6,12 +6,14 @@ It is generated from these files: ccl/storageccl/engineccl/enginepbccl/key_registry.proto + ccl/storageccl/engineccl/enginepbccl/stats.proto It has these top-level messages: DataKeysRegistry KeyInfo SecretKey EncryptionSettings + EncryptionStatus */ package enginepbccl diff --git a/pkg/ccl/storageccl/engineccl/enginepbccl/stats.pb.go b/pkg/ccl/storageccl/engineccl/enginepbccl/stats.pb.go new file mode 100644 index 000000000000..0ee99e3002a4 --- /dev/null +++ b/pkg/ccl/storageccl/engineccl/enginepbccl/stats.pb.go @@ -0,0 +1,350 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: ccl/storageccl/engineccl/enginepbccl/stats.proto + +package enginepbccl + +import proto "github.com/gogo/protobuf/proto" +import fmt "fmt" +import math "math" + +import io "io" + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// EncryptionStatus contains encryption-related information. +type EncryptionStatus struct { + // Information about the active store key, if any. + ActiveStoreKey *KeyInfo `protobuf:"bytes,1,opt,name=active_store_key,json=activeStoreKey" json:"active_store_key,omitempty"` + // Information about the active data key, if any. + ActiveDataKey *KeyInfo `protobuf:"bytes,2,opt,name=active_data_key,json=activeDataKey" json:"active_data_key,omitempty"` +} + +func (m *EncryptionStatus) Reset() { *m = EncryptionStatus{} } +func (m *EncryptionStatus) String() string { return proto.CompactTextString(m) } +func (*EncryptionStatus) ProtoMessage() {} +func (*EncryptionStatus) Descriptor() ([]byte, []int) { return fileDescriptorStats, []int{0} } + +func init() { + proto.RegisterType((*EncryptionStatus)(nil), "cockroach.ccl.storageccl.engineccl.enginepbccl.EncryptionStatus") +} +func (m *EncryptionStatus) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *EncryptionStatus) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.ActiveStoreKey != nil { + dAtA[i] = 0xa + i++ + i = encodeVarintStats(dAtA, i, uint64(m.ActiveStoreKey.Size())) + n1, err := m.ActiveStoreKey.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n1 + } + if m.ActiveDataKey != nil { + dAtA[i] = 0x12 + i++ + i = encodeVarintStats(dAtA, i, uint64(m.ActiveDataKey.Size())) + n2, err := m.ActiveDataKey.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n2 + } + return i, nil +} + +func encodeVarintStats(dAtA []byte, offset int, v uint64) int { + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return offset + 1 +} +func (m *EncryptionStatus) Size() (n int) { + var l int + _ = l + if m.ActiveStoreKey != nil { + l = m.ActiveStoreKey.Size() + n += 1 + l + sovStats(uint64(l)) + } + if m.ActiveDataKey != nil { + l = m.ActiveDataKey.Size() + n += 1 + l + sovStats(uint64(l)) + } + return n +} + +func sovStats(x uint64) (n int) { + for { + n++ + x >>= 7 + if x == 0 { + break + } + } + return n +} +func sozStats(x uint64) (n int) { + return sovStats(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *EncryptionStatus) 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 ErrIntOverflowStats + } + 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: EncryptionStatus: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: EncryptionStatus: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ActiveStoreKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStats + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ActiveStoreKey == nil { + m.ActiveStoreKey = &KeyInfo{} + } + if err := m.ActiveStoreKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ActiveDataKey", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStats + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStats + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.ActiveDataKey == nil { + m.ActiveDataKey = &KeyInfo{} + } + if err := m.ActiveDataKey.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStats(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStats + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipStats(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStats + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStats + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + return iNdEx, nil + case 1: + iNdEx += 8 + return iNdEx, nil + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStats + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + iNdEx += length + if length < 0 { + return 0, ErrInvalidLengthStats + } + return iNdEx, nil + case 3: + for { + var innerWire uint64 + var start int = iNdEx + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowStats + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + innerWire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + innerWireType := int(innerWire & 0x7) + if innerWireType == 4 { + break + } + next, err := skipStats(dAtA[start:]) + if err != nil { + return 0, err + } + iNdEx = start + next + } + return iNdEx, nil + case 4: + return iNdEx, nil + case 5: + iNdEx += 4 + return iNdEx, nil + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + } + panic("unreachable") +} + +var ( + ErrInvalidLengthStats = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowStats = fmt.Errorf("proto: integer overflow") +) + +func init() { + proto.RegisterFile("ccl/storageccl/engineccl/enginepbccl/stats.proto", fileDescriptorStats) +} + +var fileDescriptorStats = []byte{ + // 245 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0x32, 0x48, 0x4e, 0xce, 0xd1, + 0x2f, 0x2e, 0xc9, 0x2f, 0x4a, 0x4c, 0x4f, 0x05, 0x31, 0x53, 0xf3, 0xd2, 0x33, 0xf3, 0x90, 0x58, + 0x05, 0x49, 0x10, 0x05, 0x89, 0x25, 0xc5, 0x7a, 0x05, 0x45, 0xf9, 0x25, 0xf9, 0x42, 0x7a, 0xc9, + 0xf9, 0xc9, 0xd9, 0x45, 0xf9, 0x89, 0xc9, 0x19, 0x7a, 0xc9, 0xc9, 0x39, 0x7a, 0x08, 0xbd, 0x7a, + 0x70, 0xbd, 0x7a, 0x48, 0x7a, 0xa5, 0x44, 0xd2, 0xf3, 0xd3, 0xf3, 0xc1, 0x5a, 0xf5, 0x41, 0x2c, + 0x88, 0x29, 0x52, 0xe6, 0x44, 0xd9, 0x9b, 0x9d, 0x5a, 0x19, 0x5f, 0x94, 0x9a, 0x9e, 0x59, 0x5c, + 0x52, 0x54, 0x09, 0xd1, 0xa8, 0x74, 0x8d, 0x91, 0x4b, 0xc0, 0x35, 0x2f, 0xb9, 0xa8, 0xb2, 0xa0, + 0x24, 0x33, 0x3f, 0x2f, 0xb8, 0x24, 0xb1, 0xa4, 0xb4, 0x58, 0x28, 0x91, 0x4b, 0x20, 0x31, 0xb9, + 0x24, 0xb3, 0x2c, 0x35, 0x1e, 0x64, 0x64, 0x6a, 0x7c, 0x76, 0x6a, 0xa5, 0x04, 0xa3, 0x02, 0xa3, + 0x06, 0xb7, 0x91, 0x39, 0x89, 0xce, 0xd5, 0xf3, 0x4e, 0xad, 0xf4, 0xcc, 0x4b, 0xcb, 0x0f, 0xe2, + 0x83, 0x18, 0x18, 0x0c, 0x32, 0xcf, 0x3b, 0xb5, 0x52, 0x28, 0x9e, 0x8b, 0x1f, 0x6a, 0x45, 0x4a, + 0x62, 0x49, 0x22, 0xd8, 0x06, 0x26, 0xca, 0x6c, 0xe0, 0x85, 0x98, 0xe7, 0x92, 0x58, 0x92, 0xe8, + 0x9d, 0x5a, 0xe9, 0xa4, 0x7a, 0xe2, 0xa1, 0x1c, 0xc3, 0x89, 0x47, 0x72, 0x8c, 0x17, 0x1e, 0xc9, + 0x31, 0xde, 0x78, 0x24, 0xc7, 0xf8, 0xe0, 0x91, 0x1c, 0xe3, 0x84, 0xc7, 0x72, 0x0c, 0x51, 0xdc, + 0x48, 0xba, 0x93, 0xd8, 0xc0, 0xc1, 0x60, 0x0c, 0x08, 0x00, 0x00, 0xff, 0xff, 0x73, 0xf5, 0x75, + 0x36, 0xb9, 0x01, 0x00, 0x00, +} diff --git a/pkg/ccl/storageccl/engineccl/enginepbccl/stats.proto b/pkg/ccl/storageccl/engineccl/enginepbccl/stats.proto new file mode 100644 index 000000000000..f171882b80ea --- /dev/null +++ b/pkg/ccl/storageccl/engineccl/enginepbccl/stats.proto @@ -0,0 +1,22 @@ +// Copyright 2018 The Cockroach Authors. +// +// Licensed as a CockroachDB Enterprise file under the Cockroach Community +// License (the "License"); you may not use this file except in compliance with +// the License. You may obtain a copy of the License at +// +// https://github.com/cockroachdb/cockroach/blob/master/licenses/CCL.txt + +syntax = "proto3"; +package cockroach.ccl.storageccl.engineccl.enginepbccl; +option go_package = "enginepbccl"; + +import "gogoproto/gogo.proto"; +import "ccl/storageccl/engineccl/enginepbccl/key_registry.proto"; + +// EncryptionStatus contains encryption-related information. +message EncryptionStatus { + // Information about the active store key, if any. + KeyInfo active_store_key = 1; + // Information about the active data key, if any. + KeyInfo active_data_key = 2; +} diff --git a/pkg/server/serverpb/admin.pb.go b/pkg/server/serverpb/admin.pb.go index 8a1e90c25c6f..62d027a2313b 100644 --- a/pkg/server/serverpb/admin.pb.go +++ b/pkg/server/serverpb/admin.pb.go @@ -113,6 +113,9 @@ CommandQueueRequest CommandQueueResponse DiagnosticsRequest + StoresRequest + StoreDetails + StoresResponse */ package serverpb diff --git a/pkg/server/serverpb/status.pb.go b/pkg/server/serverpb/status.pb.go index 72c3796e3cbe..a56a7ab66ec2 100644 --- a/pkg/server/serverpb/status.pb.go +++ b/pkg/server/serverpb/status.pb.go @@ -37,7 +37,8 @@ var _ = fmt.Errorf var _ = math.Inf var _ = time.Kitchen -// We use an enum to allow reporting of client certs and potential others (eg: UI). +// We use an enum to allow reporting of client certs and potential others (eg: +// UI). type CertificateDetails_CertificateType int32 const ( @@ -102,9 +103,6 @@ func (x ActiveQuery_Phase) String() string { func (ActiveQuery_Phase) EnumDescriptor() ([]byte, []int) { return fileDescriptorStatus, []int{36, 0} } type CertificatesRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -119,7 +117,8 @@ type CertificateDetails struct { Type CertificateDetails_CertificateType `protobuf:"varint,1,opt,name=type,proto3,enum=cockroach.server.serverpb.CertificateDetails_CertificateType" json:"type,omitempty"` // "error_message" and "data" are mutually exclusive. ErrorMessage string `protobuf:"bytes,2,opt,name=error_message,json=errorMessage,proto3" json:"error_message,omitempty"` - // data is the raw file contents of the certificate. This means PEM-encoded DER data. + // data is the raw file contents of the certificate. This means PEM-encoded + // DER data. Data []byte `protobuf:"bytes,3,opt,name=data,proto3" json:"data,omitempty"` Fields []CertificateDetails_Fields `protobuf:"bytes,4,rep,name=fields" json:"fields"` } @@ -159,9 +158,6 @@ func (*CertificatesResponse) Descriptor() ([]byte, []int) { return fileDescripto // DetailsRequest requests a nodes details. type DetailsRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -204,9 +200,6 @@ func (*NodesResponse) ProtoMessage() {} func (*NodesResponse) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{6} } type NodeRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -320,9 +313,6 @@ func (*RangeInfo) ProtoMessage() {} func (*RangeInfo) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{13} } type RangesRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -344,9 +334,6 @@ func (*RangesResponse) ProtoMessage() {} func (*RangesResponse) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{15} } type GossipRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -378,8 +365,6 @@ func (*AllocatorDryRun_Event) ProtoMessage() {} func (*AllocatorDryRun_Event) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{17, 0} } type AllocatorRangeRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "RangeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. RangeId int64 `protobuf:"varint,1,opt,name=range_id,json=rangeId,proto3" json:"range_id,omitempty"` } @@ -401,8 +386,6 @@ func (*AllocatorRangeResponse) ProtoMessage() {} func (*AllocatorRangeResponse) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{19} } type AllocatorRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` RangeIDs []github_com_cockroachdb_cockroach_pkg_roachpb.RangeID `protobuf:"varint,2,rep,packed,name=range_ids,json=rangeIds,casttype=github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" json:"range_ids,omitempty"` } @@ -431,9 +414,6 @@ func (*JSONResponse) ProtoMessage() {} func (*JSONResponse) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{22} } type LogsRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -459,9 +439,6 @@ func (*LogEntriesResponse) ProtoMessage() {} func (*LogEntriesResponse) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{24} } type LogFilesListRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -482,9 +459,6 @@ func (*LogFilesListResponse) ProtoMessage() {} func (*LogFilesListResponse) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{26} } type LogFileRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -497,9 +471,6 @@ func (*LogFileRequest) ProtoMessage() {} func (*LogFileRequest) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{27} } type StacksRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -511,9 +482,6 @@ func (*StacksRequest) ProtoMessage() {} func (*StacksRequest) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{28} } type ProfileRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -527,9 +495,6 @@ func (*ProfileRequest) ProtoMessage() {} func (*ProfileRequest) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{29} } type MetricsRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -792,8 +757,6 @@ func (*ProblemRangesResponse_NodeProblems) Descriptor() ([]byte, []int) { } type RangeRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "RangeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. RangeId int64 `protobuf:"varint,1,opt,name=range_id,json=rangeId,proto3" json:"range_id,omitempty"` } @@ -847,9 +810,6 @@ func (*CommandQueueResponse) Descriptor() ([]byte, []int) { return fileDescripto // DiagnosticsRequest requests a diagnostics report. type DiagnosticsRequest struct { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` @@ -860,6 +820,38 @@ func (m *DiagnosticsRequest) String() string { return proto.CompactTe func (*DiagnosticsRequest) ProtoMessage() {} func (*DiagnosticsRequest) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{53} } +type StoresRequest struct { + // node_id is a string so that "local" can be used to specify that no + // forwarding is necessary. + NodeId string `protobuf:"bytes,1,opt,name=node_id,json=nodeId,proto3" json:"node_id,omitempty"` +} + +func (m *StoresRequest) Reset() { *m = StoresRequest{} } +func (m *StoresRequest) String() string { return proto.CompactTextString(m) } +func (*StoresRequest) ProtoMessage() {} +func (*StoresRequest) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{54} } + +type StoreDetails struct { + StoreID github_com_cockroachdb_cockroach_pkg_roachpb.StoreID `protobuf:"varint,1,opt,name=store_id,json=storeId,proto3,casttype=github.com/cockroachdb/cockroach/pkg/roachpb.StoreID" json:"store_id,omitempty"` + // encryption_status is a serialized + // ccl/storageccl/engineccl/enginepbccl/stats.go::EncryptionStatus protobuf. + EncryptionStatus []byte `protobuf:"bytes,2,opt,name=encryption_status,json=encryptionStatus,proto3" json:"encryption_status,omitempty"` +} + +func (m *StoreDetails) Reset() { *m = StoreDetails{} } +func (m *StoreDetails) String() string { return proto.CompactTextString(m) } +func (*StoreDetails) ProtoMessage() {} +func (*StoreDetails) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{55} } + +type StoresResponse struct { + Stores []StoreDetails `protobuf:"bytes,1,rep,name=stores" json:"stores"` +} + +func (m *StoresResponse) Reset() { *m = StoresResponse{} } +func (m *StoresResponse) String() string { return proto.CompactTextString(m) } +func (*StoresResponse) ProtoMessage() {} +func (*StoresResponse) Descriptor() ([]byte, []int) { return fileDescriptorStatus, []int{56} } + func init() { proto.RegisterType((*CertificatesRequest)(nil), "cockroach.server.serverpb.CertificatesRequest") proto.RegisterType((*CertificateDetails)(nil), "cockroach.server.serverpb.CertificateDetails") @@ -920,6 +912,9 @@ func init() { proto.RegisterType((*CommandQueueRequest)(nil), "cockroach.server.serverpb.CommandQueueRequest") proto.RegisterType((*CommandQueueResponse)(nil), "cockroach.server.serverpb.CommandQueueResponse") proto.RegisterType((*DiagnosticsRequest)(nil), "cockroach.server.serverpb.DiagnosticsRequest") + proto.RegisterType((*StoresRequest)(nil), "cockroach.server.serverpb.StoresRequest") + proto.RegisterType((*StoreDetails)(nil), "cockroach.server.serverpb.StoreDetails") + proto.RegisterType((*StoresResponse)(nil), "cockroach.server.serverpb.StoresResponse") proto.RegisterEnum("cockroach.server.serverpb.CertificateDetails_CertificateType", CertificateDetails_CertificateType_name, CertificateDetails_CertificateType_value) proto.RegisterEnum("cockroach.server.serverpb.ProfileRequest_Type", ProfileRequest_Type_name, ProfileRequest_Type_value) proto.RegisterEnum("cockroach.server.serverpb.ActiveQuery_Phase", ActiveQuery_Phase_name, ActiveQuery_Phase_value) @@ -992,6 +987,7 @@ type StatusClient interface { Range(ctx context.Context, in *RangeRequest, opts ...grpc.CallOption) (*RangeResponse, error) CommandQueue(ctx context.Context, in *CommandQueueRequest, opts ...grpc.CallOption) (*CommandQueueResponse, error) Diagnostics(ctx context.Context, in *DiagnosticsRequest, opts ...grpc.CallOption) (*cockroach_server_diagnosticspb.DiagnosticReport, error) + Stores(ctx context.Context, in *StoresRequest, opts ...grpc.CallOption) (*StoresResponse, error) } type statusClient struct { @@ -1218,6 +1214,15 @@ func (c *statusClient) Diagnostics(ctx context.Context, in *DiagnosticsRequest, return out, nil } +func (c *statusClient) Stores(ctx context.Context, in *StoresRequest, opts ...grpc.CallOption) (*StoresResponse, error) { + out := new(StoresResponse) + err := grpc.Invoke(ctx, "/cockroach.server.serverpb.Status/Stores", in, out, c.cc, opts...) + if err != nil { + return nil, err + } + return out, nil +} + // Server API for Status service type StatusServer interface { @@ -1250,6 +1255,7 @@ type StatusServer interface { Range(context.Context, *RangeRequest) (*RangeResponse, error) CommandQueue(context.Context, *CommandQueueRequest) (*CommandQueueResponse, error) Diagnostics(context.Context, *DiagnosticsRequest) (*cockroach_server_diagnosticspb.DiagnosticReport, error) + Stores(context.Context, *StoresRequest) (*StoresResponse, error) } func RegisterStatusServer(s *grpc.Server, srv StatusServer) { @@ -1688,6 +1694,24 @@ func _Status_Diagnostics_Handler(srv interface{}, ctx context.Context, dec func( return interceptor(ctx, in, info, handler) } +func _Status_Stores_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(StoresRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(StatusServer).Stores(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/cockroach.server.serverpb.Status/Stores", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(StatusServer).Stores(ctx, req.(*StoresRequest)) + } + return interceptor(ctx, in, info, handler) +} + var _Status_serviceDesc = grpc.ServiceDesc{ ServiceName: "cockroach.server.serverpb.Status", HandlerType: (*StatusServer)(nil), @@ -1788,6 +1812,10 @@ var _Status_serviceDesc = grpc.ServiceDesc{ MethodName: "Diagnostics", Handler: _Status_Diagnostics_Handler, }, + { + MethodName: "Stores", + Handler: _Status_Stores_Handler, + }, }, Streams: []grpc.StreamDesc{}, Metadata: "server/serverpb/status.proto", @@ -4145,6 +4173,89 @@ func (m *DiagnosticsRequest) MarshalTo(dAtA []byte) (int, error) { return i, nil } +func (m *StoresRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StoresRequest) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.NodeId) > 0 { + dAtA[i] = 0xa + i++ + i = encodeVarintStatus(dAtA, i, uint64(len(m.NodeId))) + i += copy(dAtA[i:], m.NodeId) + } + return i, nil +} + +func (m *StoreDetails) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StoreDetails) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.StoreID != 0 { + dAtA[i] = 0x8 + i++ + i = encodeVarintStatus(dAtA, i, uint64(m.StoreID)) + } + if len(m.EncryptionStatus) > 0 { + dAtA[i] = 0x12 + i++ + i = encodeVarintStatus(dAtA, i, uint64(len(m.EncryptionStatus))) + i += copy(dAtA[i:], m.EncryptionStatus) + } + return i, nil +} + +func (m *StoresResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalTo(dAtA) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *StoresResponse) MarshalTo(dAtA []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if len(m.Stores) > 0 { + for _, msg := range m.Stores { + dAtA[i] = 0xa + i++ + i = encodeVarintStatus(dAtA, i, uint64(msg.Size())) + n, err := msg.MarshalTo(dAtA[i:]) + if err != nil { + return 0, err + } + i += n + } + } + return i, nil +} + func encodeVarintStatus(dAtA []byte, offset int, v uint64) int { for v >= 1<<7 { dAtA[offset] = uint8(v&0x7f | 0x80) @@ -5121,6 +5232,41 @@ func (m *DiagnosticsRequest) Size() (n int) { return n } +func (m *StoresRequest) Size() (n int) { + var l int + _ = l + l = len(m.NodeId) + if l > 0 { + n += 1 + l + sovStatus(uint64(l)) + } + return n +} + +func (m *StoreDetails) Size() (n int) { + var l int + _ = l + if m.StoreID != 0 { + n += 1 + sovStatus(uint64(m.StoreID)) + } + l = len(m.EncryptionStatus) + if l > 0 { + n += 1 + l + sovStatus(uint64(l)) + } + return n +} + +func (m *StoresResponse) Size() (n int) { + var l int + _ = l + if len(m.Stores) > 0 { + for _, e := range m.Stores { + l = e.Size() + n += 1 + l + sovStatus(uint64(l)) + } + } + return n +} + func sovStatus(x uint64) (n int) { for { n++ @@ -12711,6 +12857,266 @@ func (m *DiagnosticsRequest) Unmarshal(dAtA []byte) error { } return nil } +func (m *StoresRequest) 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 ErrIntOverflowStatus + } + 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: StoresRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StoresRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeId", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + 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 ErrInvalidLengthStatus + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeId = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStatus(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStatus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StoreDetails) 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 ErrIntOverflowStatus + } + 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: StoreDetails: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StoreDetails: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field StoreID", wireType) + } + m.StoreID = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.StoreID |= (github_com_cockroachdb_cockroach_pkg_roachpb.StoreID(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field EncryptionStatus", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthStatus + } + postIndex := iNdEx + byteLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.EncryptionStatus = append(m.EncryptionStatus[:0], dAtA[iNdEx:postIndex]...) + if m.EncryptionStatus == nil { + m.EncryptionStatus = []byte{} + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStatus(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStatus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *StoresResponse) 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 ErrIntOverflowStatus + } + 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: StoresResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: StoresResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Stores", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowStatus + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthStatus + } + postIndex := iNdEx + msglen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Stores = append(m.Stores, StoreDetails{}) + if err := m.Stores[len(m.Stores)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipStatus(dAtA[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthStatus + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func skipStatus(dAtA []byte) (n int, err error) { l := len(dAtA) iNdEx := 0 @@ -12819,260 +13225,266 @@ var ( func init() { proto.RegisterFile("server/serverpb/status.proto", fileDescriptorStatus) } var fileDescriptorStatus = []byte{ - // 4065 bytes of a gzipped FileDescriptorProto + // 4161 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x5b, 0xdd, 0x6f, 0x1b, 0x49, - 0x72, 0xf7, 0x48, 0x24, 0x45, 0x16, 0xf5, 0x41, 0xb5, 0x64, 0x9b, 0xe6, 0xee, 0x99, 0xde, 0xf1, - 0xae, 0x2d, 0xeb, 0x6c, 0x72, 0x57, 0xb7, 0x1b, 0x6c, 0x9c, 0x6c, 0x76, 0xf5, 0x65, 0x5b, 0x6b, - 0xaf, 0xac, 0x1d, 0xd9, 0x9b, 0x60, 0x13, 0xdc, 0x60, 0xc8, 0x69, 0x51, 0x73, 0x1a, 0xce, 0xd0, - 0xd3, 0x43, 0x45, 0xbc, 0x85, 0x2f, 0x7b, 0x1b, 0x04, 0xb8, 0x24, 0xc8, 0xe5, 0x2e, 0x5f, 0x38, - 0x20, 0x08, 0x10, 0xdc, 0x4b, 0x82, 0x20, 0x09, 0x02, 0xe4, 0x29, 0x4f, 0x01, 0xf2, 0x10, 0x2c, - 0x90, 0x87, 0x04, 0xb9, 0x3c, 0x04, 0x09, 0xa0, 0x4d, 0x94, 0x3c, 0x24, 0xff, 0xc2, 0x3d, 0x05, - 0x5d, 0xdd, 0x33, 0xec, 0x21, 0x69, 0x92, 0xb2, 0xd6, 0x87, 0x3c, 0xd8, 0x9c, 0xae, 0xee, 0xaa, - 0xfe, 0x75, 0x75, 0x77, 0x75, 0x75, 0x55, 0x0b, 0x5e, 0x66, 0x34, 0x38, 0xa4, 0x41, 0x55, 0xfc, - 0xb4, 0x6a, 0x55, 0x16, 0x5a, 0x61, 0x9b, 0x55, 0x5a, 0x81, 0x1f, 0xfa, 0xe4, 0x52, 0xdd, 0xaf, - 0x1f, 0x04, 0xbe, 0x55, 0xdf, 0xaf, 0x88, 0x06, 0x95, 0xa8, 0x5d, 0xa9, 0x50, 0x6b, 0x3b, 0xae, - 0x5d, 0x75, 0xbc, 0x3d, 0x5f, 0x34, 0x2e, 0x2d, 0x34, 0x7c, 0xc6, 0x9c, 0x56, 0x55, 0xfc, 0x48, - 0x22, 0x41, 0xee, 0x56, 0xad, 0x6a, 0x5b, 0xa1, 0x25, 0x69, 0xd7, 0x64, 0x9f, 0xb6, 0x63, 0x35, - 0x3c, 0x9f, 0x85, 0x4e, 0x9d, 0xf1, 0x06, 0xdd, 0x92, 0x6c, 0x57, 0x8a, 0xb0, 0x21, 0xa4, 0x04, - 0xb2, 0x92, 0xce, 0x42, 0x3f, 0xb0, 0x1a, 0xb4, 0x4a, 0xbd, 0x86, 0xe3, 0x45, 0x3f, 0xad, 0x5a, - 0xb5, 0x79, 0x58, 0xaf, 0xc7, 0xfc, 0xb2, 0x8d, 0x4b, 0x2d, 0x46, 0xcd, 0x04, 0x7f, 0x39, 0xaa, - 0x93, 0xbf, 0x35, 0x8b, 0x51, 0xec, 0x81, 0x46, 0xc0, 0xdb, 0xa1, 0xe3, 0x56, 0x5d, 0xbf, 0xc1, - 0xff, 0x45, 0x02, 0x91, 0xd6, 0xf6, 0x02, 0xca, 0x7c, 0xf7, 0x90, 0xda, 0xa6, 0x65, 0xdb, 0x81, - 0xac, 0x7b, 0x89, 0x86, 0x75, 0xbb, 0x1a, 0x58, 0x7b, 0x21, 0xfe, 0xd7, 0xaa, 0xe1, 0x8f, 0xac, - 0x5c, 0x6c, 0xf8, 0x0d, 0x1f, 0x3f, 0xab, 0xfc, 0x4b, 0x52, 0x5f, 0x6e, 0xf8, 0x7e, 0xc3, 0xa5, - 0x55, 0xab, 0xe5, 0x54, 0x2d, 0xcf, 0xf3, 0x43, 0x2b, 0x74, 0x7c, 0x2f, 0x46, 0x28, 0x6b, 0xb1, - 0x54, 0x6b, 0xef, 0x55, 0x43, 0xa7, 0x49, 0x59, 0x68, 0x35, 0xa5, 0x6a, 0xf5, 0x0a, 0x2c, 0xac, - 0xd3, 0x20, 0x74, 0xf6, 0x9c, 0xba, 0x15, 0x52, 0x66, 0xd0, 0x27, 0x6d, 0xca, 0x42, 0x72, 0x11, - 0xa6, 0x3c, 0xdf, 0xa6, 0xa6, 0x63, 0x17, 0xb5, 0x2b, 0xda, 0x52, 0xce, 0xc8, 0xf0, 0xe2, 0x96, - 0xad, 0xff, 0x63, 0x0a, 0x88, 0xc2, 0xb0, 0x41, 0x43, 0xcb, 0x71, 0x19, 0xf9, 0x10, 0x52, 0x61, - 0xa7, 0x45, 0xb1, 0xf1, 0xec, 0xca, 0x3b, 0x95, 0x67, 0x4e, 0x79, 0xa5, 0x9f, 0x59, 0x25, 0x3d, - 0xea, 0xb4, 0xa8, 0x81, 0xa2, 0xc8, 0x55, 0x98, 0xa1, 0x41, 0xe0, 0x07, 0x66, 0x93, 0x32, 0x66, - 0x35, 0x68, 0x71, 0x02, 0x81, 0x4c, 0x23, 0xf1, 0x03, 0x41, 0x23, 0x04, 0x52, 0x7c, 0x4d, 0x14, - 0x27, 0xaf, 0x68, 0x4b, 0xd3, 0x06, 0x7e, 0x13, 0x03, 0x32, 0x7b, 0x0e, 0x75, 0x6d, 0x56, 0x4c, - 0x5d, 0x99, 0x5c, 0xca, 0xaf, 0xbc, 0x79, 0x3a, 0x34, 0x77, 0x90, 0x77, 0x2d, 0xf5, 0xf9, 0x71, - 0xf9, 0x9c, 0x21, 0x25, 0x95, 0xfe, 0x7a, 0x02, 0x32, 0xa2, 0x82, 0x5c, 0x80, 0x8c, 0xc3, 0x58, - 0x9b, 0x06, 0x91, 0x66, 0x44, 0x89, 0x14, 0x61, 0x8a, 0xb5, 0x6b, 0xdf, 0xa0, 0xf5, 0x50, 0x22, - 0x8d, 0x8a, 0xe4, 0x2b, 0x00, 0x87, 0x96, 0xeb, 0xd8, 0xe6, 0x5e, 0xe0, 0x37, 0x11, 0xea, 0xa4, - 0x91, 0x43, 0xca, 0x9d, 0xc0, 0x6f, 0x92, 0x32, 0xe4, 0x45, 0x75, 0xdb, 0x0b, 0x1d, 0xb7, 0x98, - 0xc2, 0x7a, 0xc1, 0xf1, 0x98, 0x53, 0xc8, 0xcb, 0x90, 0xe3, 0x6b, 0x84, 0x32, 0x46, 0x59, 0x31, - 0x7d, 0x65, 0x72, 0x29, 0x67, 0x74, 0x09, 0xa4, 0x0a, 0x0b, 0xcc, 0x69, 0x78, 0x56, 0xd8, 0x0e, - 0xa8, 0x69, 0xb9, 0x0d, 0x3f, 0x70, 0xc2, 0xfd, 0x66, 0x31, 0x83, 0x18, 0x48, 0x5c, 0xb5, 0x1a, - 0xd5, 0x70, 0x38, 0xad, 0x76, 0xcd, 0x75, 0xea, 0xe6, 0x01, 0xed, 0x14, 0xa7, 0xb0, 0x5d, 0x4e, - 0x50, 0xee, 0xd3, 0x0e, 0x79, 0x09, 0x72, 0x07, 0xb4, 0x63, 0xb6, 0x51, 0xe7, 0x59, 0xec, 0x2d, - 0x7b, 0x40, 0x3b, 0x8f, 0x51, 0xdf, 0x37, 0x81, 0xd0, 0xa3, 0x90, 0x7a, 0x36, 0xb5, 0xcd, 0x6e, - 0xab, 0x1c, 0xb6, 0x2a, 0x44, 0x35, 0xf7, 0x65, 0x6b, 0xfd, 0x2a, 0xcc, 0xf5, 0xcc, 0x2d, 0xc9, - 0xc0, 0xc4, 0xfa, 0x6a, 0xe1, 0x1c, 0xc9, 0x42, 0x6a, 0xfb, 0xe1, 0xc6, 0x66, 0x41, 0xd3, 0x7d, - 0x58, 0x4c, 0xae, 0x40, 0xd6, 0xf2, 0x3d, 0x46, 0xc9, 0xcf, 0xc3, 0x74, 0x5d, 0xa1, 0x17, 0x35, - 0x9c, 0xcc, 0x5b, 0xa7, 0x9a, 0x4c, 0x39, 0x8b, 0x09, 0x41, 0xfa, 0xbb, 0x30, 0x2b, 0xab, 0x47, - 0xad, 0x76, 0xb2, 0x08, 0xe9, 0x80, 0x5a, 0x76, 0x07, 0x67, 0x34, 0x6b, 0x88, 0x82, 0xfe, 0xbf, - 0x1a, 0xcc, 0xc5, 0x12, 0x24, 0xda, 0x8f, 0x93, 0x22, 0xd2, 0x6b, 0xab, 0x27, 0xc7, 0xe5, 0xcc, - 0x36, 0x17, 0xb3, 0xf1, 0xe3, 0xe3, 0xf2, 0xd7, 0x1a, 0x4e, 0xb8, 0xdf, 0xae, 0x55, 0xea, 0x7e, - 0xb3, 0x1a, 0x0f, 0xc0, 0xae, 0x75, 0xbf, 0xab, 0xad, 0x83, 0x46, 0x55, 0x9a, 0xb9, 0x8a, 0x60, - 0x8b, 0x51, 0xfc, 0x1c, 0x4c, 0xc9, 0xe9, 0x46, 0x1c, 0xf9, 0x95, 0xcb, 0x8a, 0x12, 0xb8, 0x35, - 0xa9, 0x3c, 0x8e, 0xad, 0xc9, 0xaa, 0x6d, 0x07, 0x72, 0xd4, 0x11, 0x13, 0xb9, 0x0d, 0x80, 0x76, - 0xd6, 0xe4, 0x76, 0x16, 0xd7, 0x5f, 0x7e, 0xe5, 0xbc, 0x22, 0x02, 0x2b, 0x2b, 0x5b, 0xde, 0x9e, - 0x2f, 0x39, 0x73, 0x48, 0xe1, 0x04, 0x7d, 0x16, 0xa6, 0x39, 0x9a, 0x48, 0x55, 0xfa, 0x0e, 0xcc, - 0xc8, 0xb2, 0x1c, 0xf8, 0xbb, 0x90, 0xe6, 0x30, 0xa3, 0xf9, 0xb9, 0x3a, 0x60, 0x7e, 0x84, 0xc9, - 0xe4, 0x6c, 0xbb, 0xf8, 0x29, 0x7b, 0x11, 0x7c, 0xfa, 0x35, 0xc8, 0xf3, 0xaa, 0x91, 0x96, 0xe7, - 0xaf, 0x52, 0x90, 0x33, 0xac, 0xbd, 0x90, 0xcb, 0xe0, 0x0b, 0x11, 0x02, 0xda, 0x72, 0x9d, 0xba, - 0x15, 0xb5, 0x4c, 0xad, 0xcd, 0x9c, 0x1c, 0x97, 0x73, 0x86, 0xa0, 0x6e, 0x6d, 0x18, 0x39, 0xd9, - 0x60, 0xcb, 0x26, 0x3f, 0x05, 0xb0, 0x6f, 0x05, 0x36, 0x5a, 0x6f, 0x2a, 0x95, 0x38, 0x5f, 0x11, - 0x26, 0xb6, 0x72, 0xcf, 0x0a, 0x6c, 0x14, 0x1a, 0x8d, 0x7e, 0x3f, 0x22, 0x70, 0xf3, 0xe2, 0x52, + 0x72, 0xf7, 0x48, 0x24, 0x45, 0x16, 0x29, 0x89, 0x6a, 0xc9, 0x36, 0x4d, 0xfb, 0x4c, 0xef, 0x78, + 0xd7, 0x96, 0xbd, 0x36, 0xb9, 0xab, 0xdb, 0x0d, 0x36, 0x4e, 0x36, 0xbb, 0x96, 0xe4, 0x0f, 0xad, + 0xbd, 0xb6, 0x76, 0x64, 0xef, 0x05, 0x9b, 0x60, 0x07, 0x43, 0x4e, 0x8b, 0x9a, 0xd3, 0x70, 0x86, + 0x9e, 0x1e, 0x2a, 0xe2, 0x2d, 0x7c, 0xd9, 0xdb, 0x20, 0xc0, 0x25, 0x41, 0x2e, 0x77, 0xf9, 0xc2, + 0x01, 0x41, 0x80, 0xe0, 0x5e, 0x12, 0x04, 0xc8, 0x07, 0x90, 0xa7, 0x3c, 0x05, 0xc8, 0x43, 0xb0, + 0x40, 0x1e, 0x12, 0xe4, 0xf2, 0x10, 0x24, 0x80, 0x36, 0x51, 0xf2, 0x90, 0xfc, 0x0b, 0xf7, 0x14, + 0x74, 0x75, 0xcf, 0xb0, 0x87, 0xa4, 0x49, 0xca, 0x5a, 0x2f, 0xee, 0xc1, 0xe6, 0x74, 0x75, 0x57, + 0xf5, 0xaf, 0xab, 0xbb, 0xab, 0xab, 0xaa, 0x5b, 0x70, 0x8e, 0xd1, 0x60, 0x8f, 0x06, 0x35, 0xf1, + 0xd3, 0xae, 0xd7, 0x58, 0x68, 0x85, 0x1d, 0x56, 0x6d, 0x07, 0x7e, 0xe8, 0x93, 0x33, 0x0d, 0xbf, + 0xb1, 0x1b, 0xf8, 0x56, 0x63, 0xa7, 0x2a, 0x1a, 0x54, 0xa3, 0x76, 0xe5, 0x62, 0xbd, 0xe3, 0xb8, + 0x76, 0xcd, 0xf1, 0xb6, 0x7d, 0xd1, 0xb8, 0xbc, 0xd8, 0xf4, 0x19, 0x73, 0xda, 0x35, 0xf1, 0x23, + 0x89, 0x04, 0xb9, 0xdb, 0xf5, 0x9a, 0x6d, 0x85, 0x96, 0xa4, 0x5d, 0x92, 0x7d, 0xda, 0x8e, 0xd5, + 0xf4, 0x7c, 0x16, 0x3a, 0x0d, 0xc6, 0x1b, 0xf4, 0x4a, 0xb2, 0x5d, 0x39, 0xc2, 0x86, 0x90, 0x12, + 0xc8, 0xca, 0x3a, 0x0b, 0xfd, 0xc0, 0x6a, 0xd2, 0x1a, 0xf5, 0x9a, 0x8e, 0x17, 0xfd, 0xb4, 0xeb, + 0xb5, 0xd6, 0x5e, 0xa3, 0x11, 0xf3, 0xcb, 0x36, 0x2e, 0xb5, 0x18, 0x35, 0x13, 0xfc, 0x95, 0xa8, + 0x4e, 0xfe, 0xd6, 0x2d, 0x46, 0xb1, 0x07, 0x1a, 0x01, 0xef, 0x84, 0x8e, 0x5b, 0x73, 0xfd, 0x26, + 0xff, 0x17, 0x09, 0x44, 0x5a, 0xc7, 0x0b, 0x28, 0xf3, 0xdd, 0x3d, 0x6a, 0x9b, 0x96, 0x6d, 0x07, + 0xb2, 0xee, 0x2c, 0x0d, 0x1b, 0x76, 0x2d, 0xb0, 0xb6, 0x43, 0xfc, 0xaf, 0x5d, 0xc7, 0x1f, 0x59, + 0xb9, 0xd4, 0xf4, 0x9b, 0x3e, 0x7e, 0xd6, 0xf8, 0x97, 0xa4, 0x9e, 0x6b, 0xfa, 0x7e, 0xd3, 0xa5, + 0x35, 0xab, 0xed, 0xd4, 0x2c, 0xcf, 0xf3, 0x43, 0x2b, 0x74, 0x7c, 0x2f, 0x46, 0x28, 0x6b, 0xb1, + 0x54, 0xef, 0x6c, 0xd7, 0x42, 0xa7, 0x45, 0x59, 0x68, 0xb5, 0xa4, 0x6a, 0xf5, 0x2a, 0x2c, 0xae, + 0xd1, 0x20, 0x74, 0xb6, 0x9d, 0x86, 0x15, 0x52, 0x66, 0xd0, 0x27, 0x1d, 0xca, 0x42, 0x72, 0x1a, + 0x66, 0x3c, 0xdf, 0xa6, 0xa6, 0x63, 0x97, 0xb4, 0x0b, 0xda, 0x72, 0xce, 0xc8, 0xf0, 0xe2, 0x86, + 0xad, 0xff, 0x53, 0x0a, 0x88, 0xc2, 0xb0, 0x4e, 0x43, 0xcb, 0x71, 0x19, 0xf9, 0x00, 0x52, 0x61, + 0xb7, 0x4d, 0xb1, 0xf1, 0xdc, 0xca, 0xdb, 0xd5, 0x67, 0x4e, 0x79, 0x75, 0x90, 0x59, 0x25, 0x3d, + 0xea, 0xb6, 0xa9, 0x81, 0xa2, 0xc8, 0x45, 0x98, 0xa5, 0x41, 0xe0, 0x07, 0x66, 0x8b, 0x32, 0x66, + 0x35, 0x69, 0x69, 0x0a, 0x81, 0x14, 0x90, 0xf8, 0xbe, 0xa0, 0x11, 0x02, 0x29, 0xbe, 0x26, 0x4a, + 0xd3, 0x17, 0xb4, 0xe5, 0x82, 0x81, 0xdf, 0xc4, 0x80, 0xcc, 0xb6, 0x43, 0x5d, 0x9b, 0x95, 0x52, + 0x17, 0xa6, 0x97, 0xf3, 0x2b, 0x6f, 0x1c, 0x0d, 0xcd, 0x6d, 0xe4, 0x5d, 0x4d, 0x7d, 0x7e, 0x50, + 0x39, 0x61, 0x48, 0x49, 0xe5, 0xbf, 0x99, 0x82, 0x8c, 0xa8, 0x20, 0xa7, 0x20, 0xe3, 0x30, 0xd6, + 0xa1, 0x41, 0xa4, 0x19, 0x51, 0x22, 0x25, 0x98, 0x61, 0x9d, 0xfa, 0x37, 0x69, 0x23, 0x94, 0x48, + 0xa3, 0x22, 0xf9, 0x1a, 0xc0, 0x9e, 0xe5, 0x3a, 0xb6, 0xb9, 0x1d, 0xf8, 0x2d, 0x84, 0x3a, 0x6d, + 0xe4, 0x90, 0x72, 0x3b, 0xf0, 0x5b, 0xa4, 0x02, 0x79, 0x51, 0xdd, 0xf1, 0x42, 0xc7, 0x2d, 0xa5, + 0xb0, 0x5e, 0x70, 0x3c, 0xe6, 0x14, 0x72, 0x0e, 0x72, 0x7c, 0x8d, 0x50, 0xc6, 0x28, 0x2b, 0xa5, + 0x2f, 0x4c, 0x2f, 0xe7, 0x8c, 0x1e, 0x81, 0xd4, 0x60, 0x91, 0x39, 0x4d, 0xcf, 0x0a, 0x3b, 0x01, + 0x35, 0x2d, 0xb7, 0xe9, 0x07, 0x4e, 0xb8, 0xd3, 0x2a, 0x65, 0x10, 0x03, 0x89, 0xab, 0x6e, 0x46, + 0x35, 0x1c, 0x4e, 0xbb, 0x53, 0x77, 0x9d, 0x86, 0xb9, 0x4b, 0xbb, 0xa5, 0x19, 0x6c, 0x97, 0x13, + 0x94, 0x7b, 0xb4, 0x4b, 0xce, 0x42, 0x6e, 0x97, 0x76, 0xcd, 0x0e, 0xea, 0x3c, 0x8b, 0xbd, 0x65, + 0x77, 0x69, 0xf7, 0x31, 0xea, 0xfb, 0x1a, 0x10, 0xba, 0x1f, 0x52, 0xcf, 0xa6, 0xb6, 0xd9, 0x6b, + 0x95, 0xc3, 0x56, 0xc5, 0xa8, 0xe6, 0x9e, 0x6c, 0xad, 0x5f, 0x84, 0xf9, 0xbe, 0xb9, 0x25, 0x19, + 0x98, 0x5a, 0xbb, 0x59, 0x3c, 0x41, 0xb2, 0x90, 0x7a, 0xf0, 0x70, 0xfd, 0x56, 0x51, 0xd3, 0x7d, + 0x58, 0x4a, 0xae, 0x40, 0xd6, 0xf6, 0x3d, 0x46, 0xc9, 0x37, 0xa0, 0xd0, 0x50, 0xe8, 0x25, 0x0d, + 0x27, 0xf3, 0xfa, 0x91, 0x26, 0x53, 0xce, 0x62, 0x42, 0x90, 0xfe, 0x0e, 0xcc, 0xc9, 0xea, 0x71, + 0xab, 0x9d, 0x2c, 0x41, 0x3a, 0xa0, 0x96, 0xdd, 0xc5, 0x19, 0xcd, 0x1a, 0xa2, 0xa0, 0xff, 0x9f, + 0x06, 0xf3, 0xb1, 0x04, 0x89, 0xf6, 0xa3, 0xa4, 0x88, 0xf4, 0xea, 0xcd, 0xc3, 0x83, 0x4a, 0xe6, + 0x01, 0x17, 0xb3, 0xfe, 0x93, 0x83, 0xca, 0xd7, 0x9b, 0x4e, 0xb8, 0xd3, 0xa9, 0x57, 0x1b, 0x7e, + 0xab, 0x16, 0x0f, 0xc0, 0xae, 0xf7, 0xbe, 0x6b, 0xed, 0xdd, 0x66, 0x4d, 0x9a, 0xb9, 0xaa, 0x60, + 0x8b, 0x51, 0xfc, 0x02, 0xcc, 0xc8, 0xe9, 0x46, 0x1c, 0xf9, 0x95, 0xf3, 0x8a, 0x12, 0xb8, 0x35, + 0xa9, 0x3e, 0x8e, 0xad, 0xc9, 0x4d, 0xdb, 0x0e, 0xe4, 0xa8, 0x23, 0x26, 0x72, 0x03, 0x00, 0xed, + 0xac, 0xc9, 0xed, 0x2c, 0xae, 0xbf, 0xfc, 0xca, 0x49, 0x45, 0x04, 0x56, 0x56, 0x37, 0xbc, 0x6d, + 0x5f, 0x72, 0xe6, 0x90, 0xc2, 0x09, 0xfa, 0x1c, 0x14, 0x38, 0x9a, 0x48, 0x55, 0xfa, 0x26, 0xcc, + 0xca, 0xb2, 0x1c, 0xf8, 0x3b, 0x90, 0xe6, 0x30, 0xa3, 0xf9, 0xb9, 0x38, 0x64, 0x7e, 0x84, 0xc9, + 0xe4, 0x6c, 0x5b, 0xf8, 0x29, 0x7b, 0x11, 0x7c, 0xfa, 0x25, 0xc8, 0xf3, 0xaa, 0xb1, 0x96, 0xe7, + 0xaf, 0x53, 0x90, 0x33, 0xac, 0xed, 0x90, 0xcb, 0xe0, 0x0b, 0x11, 0x02, 0xda, 0x76, 0x9d, 0x86, + 0x15, 0xb5, 0x4c, 0xad, 0xce, 0x1e, 0x1e, 0x54, 0x72, 0x86, 0xa0, 0x6e, 0xac, 0x1b, 0x39, 0xd9, + 0x60, 0xc3, 0x26, 0x3f, 0x03, 0xb0, 0x63, 0x05, 0x36, 0x5a, 0x6f, 0x2a, 0x95, 0xb8, 0x50, 0x15, + 0x26, 0xb6, 0x7a, 0xd7, 0x0a, 0x6c, 0x14, 0x1a, 0x8d, 0x7e, 0x27, 0x22, 0x70, 0xf3, 0xe2, 0x52, 0xcb, 0x46, 0x9d, 0xa5, 0x0c, 0xfc, 0xe6, 0x6b, 0x42, 0x88, 0x49, 0x21, 0x3c, 0x51, 0xe0, 0xbb, - 0xdf, 0x6a, 0xb5, 0x5c, 0x87, 0xda, 0xc5, 0x34, 0x36, 0x8e, 0x8a, 0xe4, 0x11, 0x64, 0x5b, 0x81, - 0xdf, 0xc0, 0xe9, 0xcb, 0xa0, 0x8e, 0x56, 0x86, 0xac, 0xe1, 0x78, 0x84, 0x95, 0x1d, 0xc9, 0xb4, - 0xe9, 0x85, 0x41, 0x47, 0x42, 0x8b, 0x25, 0x91, 0xeb, 0x30, 0xc7, 0xd1, 0x98, 0x61, 0x60, 0x79, - 0x6c, 0x8f, 0x06, 0x94, 0xe2, 0x4e, 0x4e, 0x19, 0xb3, 0x9c, 0xfc, 0x28, 0xa6, 0x96, 0x7e, 0x4b, - 0x83, 0x6c, 0x24, 0x8a, 0x63, 0x6f, 0x5a, 0x61, 0x7d, 0x5f, 0x28, 0xcc, 0x10, 0x05, 0x3e, 0x4a, - 0x8f, 0x1e, 0x09, 0xb3, 0x95, 0x32, 0xf0, 0xbb, 0x3b, 0xca, 0x49, 0x75, 0x94, 0x17, 0x20, 0xd3, - 0xb2, 0xda, 0x8c, 0xda, 0x38, 0xf8, 0xac, 0x21, 0x4b, 0xe4, 0x06, 0x14, 0x5a, 0xd4, 0xb3, 0x1d, - 0xaf, 0x61, 0x32, 0xcf, 0x6a, 0xb1, 0x7d, 0x3f, 0x94, 0x6a, 0x98, 0x93, 0xf4, 0x5d, 0x49, 0x2e, - 0x7d, 0x03, 0x66, 0x12, 0x23, 0x23, 0x05, 0x98, 0xe4, 0x76, 0x48, 0x20, 0xe2, 0x9f, 0x64, 0x1d, - 0xd2, 0x87, 0x96, 0xdb, 0x8e, 0x26, 0xea, 0xd6, 0xa9, 0xd4, 0x65, 0x08, 0xde, 0xdb, 0x13, 0x6f, - 0x6b, 0xfa, 0x8f, 0x34, 0x98, 0x31, 0x2c, 0xaf, 0x41, 0x77, 0x02, 0xbf, 0xe6, 0xd2, 0x26, 0x23, - 0x57, 0x20, 0xdf, 0xf6, 0xac, 0x43, 0xcb, 0x71, 0xad, 0x9a, 0x2b, 0x8e, 0xab, 0xac, 0xa1, 0x92, - 0xc8, 0x5b, 0x70, 0x91, 0x6b, 0x90, 0x06, 0xa6, 0xe7, 0x87, 0xa6, 0x38, 0xf4, 0xf7, 0x7d, 0xd7, - 0xa6, 0x81, 0x34, 0x02, 0x8b, 0xa2, 0x7a, 0xdb, 0x0f, 0x1f, 0xf0, 0xca, 0x7b, 0x58, 0x47, 0x5e, - 0x85, 0x59, 0xcf, 0x37, 0xf9, 0x8a, 0x32, 0x45, 0x3d, 0x2a, 0x2e, 0x6b, 0x4c, 0x7b, 0x3e, 0xc7, - 0xf8, 0x00, 0x69, 0x64, 0x09, 0xe6, 0xda, 0x9e, 0x4d, 0x03, 0xb9, 0x32, 0xc3, 0x58, 0x91, 0xbd, - 0x64, 0x72, 0x09, 0xb2, 0x9e, 0x2f, 0xba, 0x47, 0x4d, 0x66, 0x8d, 0x29, 0xcf, 0xc7, 0x0e, 0xf5, - 0x03, 0x98, 0xc3, 0x41, 0xf1, 0x71, 0x3b, 0xe8, 0xea, 0x70, 0xb3, 0xfc, 0xa4, 0x4d, 0x03, 0x87, - 0x32, 0xb3, 0x45, 0x03, 0x93, 0xd1, 0xba, 0xef, 0x89, 0x5d, 0xa1, 0x19, 0x05, 0x59, 0xb3, 0x43, - 0x83, 0x5d, 0xa4, 0x93, 0x65, 0x98, 0xff, 0xe5, 0xc0, 0x09, 0x93, 0x8d, 0x27, 0xb0, 0xf1, 0x9c, - 0xa8, 0x88, 0xdb, 0xea, 0xf7, 0x00, 0x76, 0x02, 0x1a, 0x86, 0x9d, 0xdd, 0x96, 0xe5, 0xf1, 0xb3, - 0x81, 0x85, 0x56, 0x10, 0x9a, 0xd1, 0x8c, 0xe5, 0x8c, 0x2c, 0x12, 0xf8, 0xc1, 0x71, 0x11, 0xa6, - 0xa8, 0x87, 0xc7, 0x82, 0x3c, 0x00, 0x33, 0xd4, 0xe3, 0x67, 0xc1, 0xed, 0xd4, 0xff, 0xfc, 0x71, - 0x59, 0xd3, 0xff, 0x4c, 0x83, 0x85, 0x75, 0xbf, 0xd9, 0xb4, 0x3c, 0xfb, 0xc3, 0x36, 0x6d, 0xd3, - 0x0f, 0x68, 0x18, 0x70, 0xec, 0xaf, 0xc1, 0x2c, 0x76, 0x6a, 0xd6, 0x45, 0x25, 0x43, 0xc1, 0x93, - 0xc6, 0x0c, 0x52, 0x25, 0x07, 0xe3, 0xee, 0x00, 0xb7, 0xbe, 0xdd, 0x56, 0x13, 0xd8, 0x6a, 0x9a, - 0x13, 0xe3, 0x46, 0xcb, 0x30, 0xdf, 0xb4, 0x8e, 0x4c, 0xff, 0x90, 0x06, 0xae, 0xd5, 0x62, 0x26, - 0xa3, 0xd4, 0x93, 0x07, 0xee, 0x5c, 0xd3, 0x3a, 0x7a, 0x28, 0xe9, 0xbb, 0x94, 0xe2, 0x58, 0xc2, - 0x80, 0x52, 0x93, 0x39, 0xdf, 0x14, 0x7b, 0x39, 0x6d, 0x64, 0x39, 0x61, 0xd7, 0xf9, 0x26, 0xd5, - 0xff, 0x79, 0x8a, 0x1b, 0x1b, 0xaf, 0x41, 0xb9, 0x11, 0x24, 0xef, 0x42, 0x8a, 0xb5, 0x2c, 0x0f, - 0x81, 0xe5, 0x57, 0x5e, 0x1b, 0xb2, 0x1e, 0xbb, 0xba, 0x92, 0x3b, 0x16, 0x19, 0xc9, 0x16, 0x00, - 0x2e, 0x0d, 0xd5, 0xfe, 0xbc, 0x3a, 0xce, 0xb2, 0x8e, 0x4c, 0x52, 0x10, 0x1b, 0xbe, 0x0d, 0xd5, - 0xfc, 0xe4, 0x57, 0x96, 0x54, 0x29, 0xc2, 0x0b, 0xad, 0x28, 0xde, 0x68, 0x25, 0x1e, 0x44, 0x64, - 0x74, 0xc5, 0x46, 0x6e, 0xc2, 0x2c, 0xf3, 0xdb, 0x41, 0x9d, 0x9a, 0x91, 0xb1, 0x4d, 0xe3, 0xa9, - 0x75, 0xf7, 0xe4, 0xb8, 0x3c, 0xbd, 0x8b, 0x35, 0x67, 0x3b, 0xbb, 0xa6, 0x59, 0x57, 0x88, 0x4d, - 0x9e, 0xc0, 0x9c, 0xec, 0x8e, 0x63, 0xc3, 0xfe, 0x32, 0xd8, 0xdf, 0xd6, 0xc9, 0x71, 0x79, 0x46, - 0xf4, 0xb7, 0xcb, 0x6b, 0xb0, 0xc3, 0x37, 0x4f, 0xd5, 0xa1, 0xe4, 0x33, 0x66, 0x98, 0x22, 0xc6, - 0xee, 0x77, 0x1f, 0xa7, 0x06, 0xb8, 0x8f, 0xeb, 0x30, 0x23, 0x77, 0xb8, 0xc3, 0x81, 0x75, 0xd0, - 0xdf, 0xc9, 0xaf, 0x14, 0x15, 0xa5, 0x46, 0xdd, 0xe0, 0xde, 0x8b, 0xfc, 0x09, 0x64, 0xba, 0x27, - 0x78, 0xc8, 0xfb, 0x68, 0xe0, 0xd1, 0xbe, 0x14, 0x73, 0xfd, 0x93, 0xd2, 0x37, 0xb5, 0x8a, 0x3d, - 0x52, 0xcc, 0xba, 0xb0, 0x4f, 0x77, 0xc4, 0xec, 0xb2, 0x22, 0xa0, 0xa0, 0xe5, 0x51, 0x82, 0xba, - 0x36, 0x40, 0x9d, 0x5f, 0x46, 0x1e, 0x41, 0xbe, 0xde, 0xb4, 0xcd, 0x27, 0xa6, 0xeb, 0xd7, 0x2d, - 0xb7, 0x98, 0x47, 0x69, 0x95, 0x61, 0xbe, 0x53, 0xff, 0xce, 0x8c, 0xd6, 0x5e, 0xbd, 0x69, 0x7f, - 0xf8, 0x80, 0x8b, 0x21, 0x1f, 0xc1, 0xb4, 0x90, 0xda, 0x70, 0xfd, 0x9a, 0xe5, 0x16, 0xa7, 0xcf, - 0x20, 0x16, 0xb8, 0xd8, 0xbb, 0x28, 0x87, 0xdc, 0x85, 0x69, 0xf5, 0x76, 0x55, 0x9c, 0xe9, 0xf3, - 0x72, 0xa2, 0xa5, 0x8d, 0xb3, 0x90, 0xf0, 0x22, 0xf2, 0x6e, 0x97, 0xc4, 0x3d, 0xe5, 0x27, 0x6d, - 0x87, 0xb2, 0x3a, 0xf5, 0xc2, 0xe2, 0x2c, 0x9a, 0xcd, 0x2e, 0x41, 0xff, 0xcd, 0xe8, 0x38, 0x18, - 0xed, 0xf8, 0x59, 0x90, 0x0b, 0x78, 0x4b, 0xd3, 0x41, 0x4b, 0x33, 0xb9, 0x34, 0xb9, 0xb6, 0x71, - 0x72, 0x5c, 0xce, 0x8a, 0xed, 0xb4, 0xc1, 0x4e, 0xbd, 0x4a, 0x25, 0xa3, 0x91, 0x45, 0xb1, 0x5b, - 0x36, 0xd3, 0x1f, 0xc1, 0x6c, 0x04, 0x46, 0xba, 0x52, 0x6b, 0x90, 0xc1, 0xda, 0xc8, 0x97, 0x7a, - 0x75, 0xd4, 0xec, 0x2b, 0xfb, 0x5a, 0x72, 0xea, 0x4b, 0x30, 0x73, 0x17, 0xaf, 0xce, 0x23, 0xfd, - 0xa9, 0x1f, 0x4c, 0xc0, 0xdc, 0xaa, 0xcb, 0xd7, 0x47, 0xe8, 0x07, 0x1b, 0x41, 0xc7, 0x68, 0x7b, - 0xe4, 0xeb, 0x90, 0x8d, 0x86, 0x2d, 0xac, 0xf0, 0xda, 0xfa, 0xc9, 0x71, 0x79, 0x4a, 0x82, 0x7f, - 0xee, 0x41, 0x4f, 0xc9, 0x41, 0x93, 0x7b, 0x90, 0xa1, 0x87, 0xd4, 0x0b, 0x85, 0x4e, 0xf3, 0x2b, - 0xaf, 0x0f, 0x19, 0x61, 0x0f, 0xb6, 0xca, 0x26, 0x67, 0x34, 0x24, 0x7f, 0xe9, 0x17, 0x21, 0x8d, - 0x04, 0xf2, 0x36, 0xa4, 0xf8, 0x9d, 0x56, 0xda, 0xe6, 0x52, 0x45, 0x5c, 0x78, 0x2b, 0xd1, 0x85, - 0xb7, 0xf2, 0x28, 0xba, 0xf0, 0xae, 0x65, 0xb9, 0xa2, 0xbe, 0xf7, 0x45, 0x59, 0x33, 0x90, 0x83, - 0xbb, 0x6c, 0xc9, 0xab, 0x65, 0x54, 0xd4, 0x57, 0xe0, 0x7c, 0xdc, 0x3b, 0x8e, 0x21, 0x52, 0xe6, - 0xa5, 0x5e, 0xfd, 0xc4, 0x43, 0xd3, 0xff, 0x46, 0x83, 0x0b, 0xbd, 0x4c, 0x83, 0xef, 0x06, 0x93, - 0x5f, 0xe6, 0xdd, 0x60, 0x1d, 0xa6, 0xec, 0xa0, 0x63, 0x06, 0x6d, 0x4f, 0x1e, 0x2b, 0xcb, 0xe3, - 0xab, 0xd4, 0xc8, 0xd8, 0xf8, 0xab, 0x7f, 0x57, 0x83, 0x42, 0x17, 0xfb, 0xff, 0x83, 0xbd, 0xf1, - 0x31, 0xcc, 0x2b, 0x78, 0xa4, 0x1a, 0x37, 0x21, 0x2b, 0x87, 0x1a, 0x6d, 0x90, 0xd3, 0x8c, 0x75, - 0x4a, 0x8c, 0x95, 0xe9, 0x3a, 0x4c, 0xbf, 0xbf, 0xfb, 0x70, 0x3b, 0x16, 0x1b, 0x85, 0x10, 0xb4, - 0x6e, 0x08, 0x41, 0xff, 0xa1, 0x06, 0xf9, 0x07, 0x7e, 0x63, 0xac, 0x0b, 0xa2, 0x4b, 0x0f, 0xa9, - 0x2b, 0x57, 0x90, 0x28, 0xf0, 0x1b, 0xb6, 0x70, 0x93, 0x70, 0x65, 0x0a, 0x0f, 0x5a, 0x38, 0x4e, - 0x7c, 0x35, 0xf2, 0x55, 0xc4, 0x1d, 0x25, 0xac, 0x14, 0x97, 0x08, 0xee, 0x38, 0x61, 0x55, 0x01, - 0x26, 0x9b, 0xd6, 0x11, 0x1e, 0xc6, 0x39, 0x83, 0x7f, 0xf2, 0x55, 0xda, 0xb2, 0xc2, 0x90, 0x06, - 0x9e, 0xbc, 0xd2, 0x47, 0x45, 0xfd, 0x21, 0x90, 0x07, 0x7e, 0x83, 0x3b, 0xd1, 0x8e, 0x62, 0x44, - 0x7e, 0x9a, 0x7b, 0x61, 0x48, 0x92, 0x4a, 0xba, 0xd4, 0x7b, 0x59, 0x74, 0xfd, 0x46, 0x45, 0xbd, - 0x54, 0x44, 0xed, 0xf5, 0x0a, 0x2c, 0x3c, 0xf0, 0x1b, 0x77, 0x1c, 0x97, 0xb2, 0x07, 0x0e, 0x0b, - 0x47, 0x5a, 0x90, 0x1d, 0x58, 0x4c, 0xb6, 0x97, 0x10, 0xde, 0x86, 0xf4, 0x1e, 0x27, 0x4a, 0x00, - 0x2f, 0x0f, 0x02, 0xc0, 0xb9, 0x54, 0xb7, 0x04, 0x19, 0xf4, 0x77, 0x60, 0x56, 0x4a, 0x1c, 0xa9, - 0x79, 0x02, 0x29, 0xce, 0x23, 0x15, 0x8f, 0xdf, 0xdc, 0xf8, 0xed, 0x86, 0x56, 0xfd, 0x60, 0x74, - 0x18, 0xeb, 0x57, 0x60, 0x76, 0x27, 0xf0, 0xf7, 0xc6, 0xe9, 0x68, 0x4d, 0x86, 0xb6, 0xd2, 0x18, - 0xda, 0xaa, 0x0c, 0x75, 0xfe, 0x54, 0x89, 0x95, 0x6e, 0x2c, 0x4b, 0x2f, 0x40, 0x0a, 0xa3, 0x1f, - 0x59, 0x48, 0xdd, 0xdb, 0x5c, 0xdd, 0x29, 0x9c, 0xd3, 0x6f, 0xc0, 0xac, 0x3c, 0x0f, 0x47, 0x62, - 0xfd, 0x0b, 0x3c, 0xb6, 0xf6, 0x42, 0xdc, 0x26, 0x7c, 0xfb, 0xbf, 0xd0, 0x60, 0xc3, 0x7b, 0x90, - 0xc6, 0x6d, 0x38, 0x96, 0x97, 0xda, 0xe3, 0x5b, 0x22, 0xa3, 0xbe, 0xcc, 0x0f, 0x36, 0x09, 0x77, - 0x93, 0x7b, 0x5b, 0xaa, 0xa5, 0xd5, 0x92, 0x96, 0xf6, 0xd3, 0x09, 0x7e, 0x99, 0x91, 0x8d, 0xe5, - 0x21, 0xfe, 0xa2, 0x0f, 0xa1, 0xbb, 0x90, 0x41, 0x27, 0x30, 0x3a, 0x84, 0x6e, 0x8c, 0x70, 0xc4, - 0xbb, 0x03, 0x89, 0xce, 0x5a, 0xc1, 0xce, 0x5d, 0x71, 0x11, 0xfa, 0x98, 0x44, 0x39, 0x4b, 0xe3, - 0xc8, 0xe1, 0xda, 0x4e, 0xc6, 0x3f, 0xda, 0x50, 0xe0, 0xb5, 0x1b, 0xb4, 0xd6, 0x6e, 0x44, 0x6b, - 0x21, 0x61, 0x62, 0xb5, 0x17, 0x62, 0x62, 0xff, 0x65, 0x02, 0xe6, 0x95, 0x7e, 0xe5, 0xd6, 0xfd, - 0xae, 0xd6, 0xe3, 0x83, 0xbc, 0x3d, 0x62, 0x50, 0x09, 0x76, 0xd1, 0x8d, 0x8c, 0x58, 0xfc, 0x2c, - 0x1f, 0xe4, 0x67, 0x5f, 0x3c, 0x27, 0x50, 0x89, 0xe2, 0x4b, 0x9b, 0xac, 0x12, 0x85, 0xbc, 0x82, - 0x4e, 0x8d, 0x3a, 0x4c, 0x8a, 0xa8, 0xc3, 0x7b, 0xc9, 0xa8, 0xc3, 0xf2, 0x38, 0x1d, 0x89, 0x15, - 0xab, 0x86, 0x1c, 0x7e, 0x6d, 0x02, 0xf2, 0xab, 0xf5, 0xd0, 0x39, 0xa4, 0x1f, 0xb6, 0x69, 0xd0, - 0x21, 0x17, 0x60, 0x22, 0xda, 0xd0, 0x6b, 0x99, 0x93, 0xe3, 0xf2, 0xc4, 0xd6, 0x86, 0x31, 0xe1, - 0xd8, 0xbc, 0x7f, 0xf6, 0x24, 0x3a, 0x36, 0xf8, 0x27, 0xb9, 0x8d, 0xae, 0x7f, 0x10, 0xca, 0x00, - 0xdd, 0x78, 0x9e, 0x8c, 0x60, 0xe1, 0x77, 0x68, 0x87, 0x99, 0xb6, 0xc3, 0xc2, 0xc0, 0xa9, 0xb5, - 0xbb, 0x61, 0x85, 0x19, 0x87, 0x6d, 0x74, 0x89, 0x64, 0x0d, 0xd2, 0xad, 0xfd, 0x28, 0xa2, 0x30, - 0xbb, 0x72, 0x73, 0xd8, 0xf1, 0xd9, 0x1d, 0x43, 0x65, 0x87, 0xf3, 0x18, 0x82, 0x55, 0x7f, 0x0d, - 0xd2, 0x58, 0x26, 0x33, 0x90, 0xdb, 0x31, 0x36, 0x77, 0x56, 0x8d, 0xad, 0xed, 0xbb, 0x85, 0x73, - 0xbc, 0xb8, 0xf9, 0x0b, 0x9b, 0xeb, 0x8f, 0x1f, 0xf1, 0xa2, 0xa6, 0xbf, 0x01, 0x0b, 0xfc, 0x4c, - 0xd8, 0xa5, 0x8c, 0x39, 0xbe, 0x17, 0x1b, 0xb9, 0x12, 0x64, 0xdb, 0x8c, 0x06, 0x9e, 0xd5, 0x8c, - 0x4c, 0x41, 0x5c, 0xd6, 0xbf, 0x93, 0x82, 0x29, 0xd9, 0xfe, 0x85, 0x5a, 0x38, 0x15, 0xc3, 0x44, - 0x12, 0x03, 0x57, 0x64, 0xdd, 0x75, 0xa8, 0x17, 0x9a, 0x51, 0xc4, 0x55, 0x9c, 0xde, 0x33, 0x82, - 0xba, 0x2a, 0x23, 0xaa, 0x37, 0xa0, 0x80, 0xe1, 0xbd, 0x3a, 0x26, 0x5b, 0x4c, 0x14, 0x25, 0x4e, - 0xf2, 0x39, 0x85, 0xbe, 0xcd, 0x25, 0xee, 0xc2, 0xac, 0x85, 0xba, 0x34, 0x65, 0x1c, 0x06, 0x23, - 0xf8, 0xf9, 0x95, 0x6b, 0xe3, 0x29, 0x5f, 0xae, 0xe2, 0x19, 0x2b, 0x26, 0x39, 0x94, 0x75, 0xd7, - 0x4a, 0xe6, 0xf4, 0x6b, 0xe5, 0xeb, 0x90, 0x3b, 0x38, 0x34, 0xc3, 0x23, 0x8f, 0x2b, 0x97, 0x5f, - 0x8a, 0xa7, 0xd7, 0xd6, 0xfe, 0x6d, 0x5c, 0x95, 0x8a, 0xdc, 0x55, 0xdb, 0xb1, 0x2b, 0x8f, 0x1f, - 0x6f, 0x71, 0x93, 0x34, 0x75, 0xff, 0xf0, 0xd1, 0x91, 0xc7, 0xcd, 0xeb, 0x01, 0x7e, 0x60, 0x74, - 0xc9, 0xb5, 0x58, 0x68, 0x2a, 0xa3, 0xe6, 0xf7, 0x6a, 0x54, 0x0e, 0xaf, 0xe8, 0xdf, 0x1d, 0x39, - 0x04, 0xa1, 0xec, 0x0e, 0xfd, 0xd7, 0x35, 0x98, 0x57, 0x97, 0x8f, 0x38, 0x46, 0x5e, 0xe4, 0xa2, - 0x78, 0xf6, 0x65, 0xe0, 0x4f, 0x35, 0x58, 0x4c, 0x2e, 0x65, 0x69, 0x2b, 0x37, 0x20, 0xcb, 0x24, - 0x4d, 0x1a, 0x4b, 0x7d, 0xc8, 0x9c, 0x4a, 0xf6, 0xe8, 0xc6, 0x1f, 0x71, 0x92, 0xf7, 0x7b, 0x0c, - 0xdc, 0xb0, 0x4d, 0xd9, 0xa7, 0x92, 0xa4, 0x8d, 0xd3, 0x9f, 0x00, 0x59, 0xb7, 0xbc, 0x3a, 0x75, - 0x51, 0xbb, 0x23, 0x3d, 0x9b, 0x6b, 0x90, 0xc5, 0xd9, 0xe1, 0x35, 0x38, 0xe8, 0xb5, 0x3c, 0x9f, - 0x51, 0x64, 0xe6, 0x33, 0x8a, 0x95, 0x3d, 0x1b, 0x66, 0xb2, 0x67, 0xd3, 0xde, 0x85, 0x85, 0x44, - 0x97, 0x52, 0x37, 0x25, 0xc8, 0xd6, 0x91, 0x4c, 0x6d, 0x19, 0x64, 0x8d, 0xcb, 0xdc, 0x67, 0x46, - 0xbc, 0x91, 0xcf, 0x8c, 0x05, 0xbd, 0x03, 0x8b, 0x42, 0x90, 0x1c, 0xe0, 0x48, 0xf4, 0x37, 0x01, - 0xa4, 0x12, 0x23, 0xfc, 0xd3, 0x22, 0x03, 0x20, 0x05, 0x6c, 0x6d, 0x18, 0x39, 0xd9, 0x60, 0xc4, - 0x18, 0xb6, 0xe0, 0x7c, 0x4f, 0xd7, 0xcf, 0x3d, 0x8a, 0x7f, 0xd7, 0xa0, 0xb0, 0xdb, 0xb2, 0x3c, - 0x7e, 0x30, 0xc4, 0x46, 0xef, 0x6a, 0xcf, 0x10, 0xd6, 0xa0, 0xbb, 0x6e, 0xe3, 0xe1, 0x18, 0x6a, - 0x68, 0x55, 0x8c, 0xe6, 0xad, 0x1f, 0x1f, 0x97, 0xdf, 0x38, 0xdd, 0xe9, 0x79, 0x9f, 0x76, 0x94, - 0x88, 0xec, 0x76, 0x37, 0x22, 0x3b, 0x79, 0x16, 0x89, 0x32, 0x90, 0xab, 0xff, 0xad, 0x06, 0xf3, - 0xca, 0xe8, 0xa4, 0x96, 0x76, 0x21, 0x1f, 0xfa, 0xa1, 0xe5, 0x9a, 0x22, 0x72, 0x25, 0x2e, 0xe2, - 0x37, 0x07, 0x04, 0x6f, 0x44, 0x7a, 0xbd, 0x12, 0x65, 0xd9, 0x2b, 0x1f, 0x7c, 0xb4, 0xbe, 0x8e, - 0xa2, 0xa2, 0x90, 0x10, 0x8a, 0x41, 0x0a, 0x29, 0x43, 0x5e, 0x78, 0x40, 0x75, 0xbf, 0xed, 0x89, - 0xd4, 0x44, 0xda, 0x00, 0x24, 0xad, 0x73, 0x0a, 0x79, 0x13, 0x2e, 0x58, 0xad, 0x56, 0xe0, 0x1f, - 0x39, 0x4d, 0x2b, 0xa4, 0xfc, 0xec, 0x3b, 0x30, 0x6b, 0x9d, 0x90, 0x32, 0x99, 0xac, 0x59, 0x54, - 0x6a, 0x37, 0x1c, 0x76, 0xb0, 0xc6, 0xeb, 0xf4, 0x9f, 0x81, 0x45, 0x19, 0x7b, 0x4b, 0x06, 0x82, - 0xc6, 0x99, 0x22, 0xfd, 0x1f, 0x72, 0x70, 0xbe, 0x87, 0xbb, 0xff, 0x86, 0x9f, 0xfd, 0xb2, 0x2d, - 0xd3, 0xdf, 0x6b, 0xb0, 0x10, 0xc5, 0x07, 0xcd, 0x5a, 0x27, 0x0e, 0xd8, 0xe6, 0xd0, 0x5c, 0xdc, - 0x19, 0x7e, 0x1f, 0xe9, 0xc7, 0x5a, 0x89, 0x63, 0x8f, 0x1d, 0x11, 0x9c, 0x15, 0xde, 0xda, 0x43, - 0x3e, 0x03, 0x27, 0xc7, 0xe5, 0x42, 0x4f, 0xf5, 0xc6, 0x67, 0x5f, 0x3c, 0x1f, 0xfc, 0x42, 0xab, - 0xa7, 0x9f, 0xd2, 0xb7, 0x33, 0x22, 0x97, 0x18, 0x27, 0x63, 0xfa, 0x42, 0xb4, 0xda, 0x80, 0x10, - 0xed, 0xaf, 0x6a, 0x70, 0x5e, 0xc9, 0xcf, 0x98, 0xbd, 0xa1, 0x87, 0x87, 0x27, 0xc7, 0xe5, 0x85, - 0xc7, 0xdd, 0x06, 0x67, 0x76, 0x91, 0x17, 0xda, 0xbd, 0xc2, 0x6c, 0x46, 0xfe, 0x52, 0x83, 0x6b, - 0x4a, 0x72, 0xa7, 0x2f, 0x37, 0xa4, 0xc0, 0x9a, 0x44, 0x58, 0xbf, 0x74, 0x72, 0x5c, 0xbe, 0xd2, - 0xcd, 0xfc, 0x24, 0xb3, 0x45, 0x67, 0xc6, 0x78, 0x25, 0x18, 0x2a, 0xd9, 0x66, 0xe4, 0x3b, 0x1a, - 0x14, 0x93, 0x09, 0x29, 0x05, 0x62, 0x0a, 0x21, 0xee, 0x9c, 0x1c, 0x97, 0x17, 0xb7, 0x95, 0xf4, - 0xd4, 0x99, 0x61, 0x2d, 0x7a, 0x7d, 0xd2, 0x6c, 0x46, 0x8e, 0x80, 0x44, 0xa9, 0x2c, 0x05, 0x43, - 0x1a, 0x31, 0xdc, 0x3f, 0x39, 0x2e, 0xcf, 0x6d, 0x8b, 0xc4, 0xd6, 0x99, 0xbb, 0x9f, 0xf3, 0x54, - 0x41, 0x36, 0x23, 0xbf, 0xad, 0xc1, 0xa5, 0x9e, 0xc4, 0x9a, 0x82, 0x20, 0x83, 0x08, 0x76, 0x4f, - 0x8e, 0xcb, 0x17, 0x1f, 0x27, 0x1b, 0x9d, 0x19, 0xc9, 0xc5, 0xf6, 0x20, 0x81, 0x36, 0x2b, 0x7d, - 0xa6, 0xc5, 0x26, 0x24, 0xb9, 0x01, 0xd5, 0x0b, 0x49, 0x5a, 0x5c, 0x48, 0x76, 0x93, 0x17, 0x92, - 0x77, 0x4e, 0xbd, 0xd3, 0xd5, 0xcd, 0xa6, 0xdc, 0x51, 0xde, 0x4f, 0x65, 0xb5, 0x42, 0x56, 0xbf, - 0x01, 0xd3, 0xe3, 0xc6, 0x36, 0xff, 0x24, 0x2d, 0x03, 0xe7, 0x3f, 0x91, 0xe7, 0x0e, 0xea, 0xfd, - 0x7f, 0xe2, 0x05, 0xdc, 0xff, 0xff, 0x4e, 0x83, 0xc5, 0x40, 0x0e, 0x24, 0x61, 0x51, 0xc5, 0x35, - 0xfe, 0xdd, 0x51, 0x11, 0x8f, 0xee, 0x6d, 0x37, 0x12, 0x92, 0x34, 0xa5, 0x3b, 0xd2, 0x94, 0xce, - 0xf7, 0xd6, 0x3f, 0xb7, 0x2d, 0x9d, 0x0f, 0x7a, 0x7b, 0x2a, 0x7d, 0x5f, 0x13, 0xc6, 0x54, 0xf5, - 0x55, 0xa2, 0x56, 0x91, 0xaf, 0x12, 0x95, 0xc7, 0x7b, 0x4a, 0xf5, 0x1e, 0xa4, 0x1d, 0x6f, 0xcf, - 0x8f, 0xa2, 0x19, 0xa7, 0x0a, 0xfc, 0x20, 0x63, 0xe9, 0x13, 0xb8, 0x30, 0x58, 0x25, 0x03, 0x16, - 0xf7, 0xfd, 0xe4, 0xe2, 0x7e, 0x6b, 0x6c, 0xa5, 0xab, 0x83, 0x4e, 0x2e, 0xea, 0x54, 0x21, 0xad, - 0xbf, 0x9e, 0xcc, 0x31, 0x8f, 0xb1, 0xb6, 0x3d, 0x58, 0x4c, 0x72, 0x48, 0x9d, 0x7d, 0x04, 0xd9, - 0xf8, 0x29, 0x83, 0x70, 0x69, 0xde, 0x1c, 0x91, 0x6a, 0x55, 0xc5, 0xb0, 0xe8, 0xbd, 0x43, 0xec, - 0xef, 0xcb, 0xb2, 0x7e, 0x0b, 0xc8, 0x46, 0xf7, 0x91, 0xe2, 0x28, 0x2f, 0x77, 0xe5, 0xcf, 0x4b, - 0x90, 0x91, 0x71, 0xb1, 0x1f, 0x68, 0x30, 0xad, 0xbe, 0x94, 0x22, 0x95, 0xf1, 0xde, 0x42, 0x45, - 0x9d, 0x94, 0xaa, 0x63, 0xb7, 0x17, 0x3a, 0xd0, 0xaf, 0x7f, 0xf6, 0xa3, 0xff, 0xfe, 0xdd, 0x89, - 0x57, 0x48, 0xb9, 0x2a, 0x33, 0x73, 0x55, 0xf5, 0x21, 0x55, 0xf5, 0x13, 0x09, 0xf9, 0x29, 0x37, - 0xb4, 0x53, 0xd1, 0x53, 0xc0, 0x61, 0x11, 0x9a, 0xe4, 0xbb, 0xab, 0xd2, 0xf2, 0x38, 0x4d, 0x25, - 0x96, 0x5b, 0x88, 0xe5, 0x3a, 0x29, 0xc5, 0x58, 0x6c, 0xd1, 0xa2, 0x0b, 0xe3, 0xe3, 0x1c, 0x99, - 0xaa, 0xee, 0x53, 0xcb, 0x0d, 0xf7, 0x49, 0x00, 0x69, 0x7c, 0xa7, 0x44, 0xae, 0x0f, 0xe9, 0x43, - 0x7d, 0xd9, 0x54, 0x5a, 0x1a, 0xdd, 0x50, 0x42, 0xb9, 0x80, 0x50, 0x0a, 0x64, 0x36, 0x86, 0x82, - 0x91, 0x3c, 0xd2, 0x86, 0x14, 0x86, 0x67, 0xaf, 0x8d, 0x90, 0x14, 0xf5, 0x38, 0xce, 0x5b, 0x29, - 0xfd, 0x0a, 0x76, 0x56, 0x22, 0xc5, 0x64, 0x67, 0x8a, 0xf2, 0x9f, 0x8a, 0x77, 0x51, 0x18, 0x89, - 0x23, 0x5f, 0x1d, 0x2f, 0x5e, 0x27, 0x00, 0xdc, 0x3c, 0x4d, 0x70, 0x4f, 0x3f, 0x8f, 0x48, 0xe6, - 0xc8, 0x4c, 0x8c, 0x84, 0x7b, 0x17, 0xe4, 0x53, 0x0d, 0x32, 0xe2, 0xe0, 0x21, 0x23, 0xf3, 0xde, - 0xb1, 0xb2, 0x6f, 0x8c, 0xd1, 0x52, 0x76, 0xfb, 0x0a, 0x76, 0xfb, 0x12, 0xb9, 0xa4, 0x74, 0xcb, - 0x1b, 0x28, 0x1a, 0x60, 0x90, 0x11, 0x49, 0xcf, 0xa1, 0x08, 0x12, 0x79, 0xd1, 0x92, 0x9a, 0x95, - 0x90, 0x8f, 0x8d, 0xb9, 0x45, 0x93, 0x5a, 0xef, 0xef, 0x54, 0xbe, 0x4b, 0xee, 0x76, 0xfa, 0x7d, - 0x0d, 0x72, 0x71, 0x92, 0x69, 0xa8, 0xde, 0x7b, 0x53, 0x6b, 0x43, 0xf5, 0xde, 0x97, 0xf7, 0xd2, - 0x6f, 0x20, 0x96, 0xab, 0xe4, 0x95, 0x18, 0x8b, 0x15, 0xb5, 0xc1, 0xb5, 0xa0, 0x60, 0xfa, 0xa1, - 0x06, 0xb3, 0xc9, 0x24, 0x24, 0x19, 0x2b, 0xc5, 0xaa, 0x3a, 0x02, 0xa5, 0x37, 0x4e, 0xc1, 0x21, - 0x21, 0x7e, 0x15, 0x21, 0xbe, 0x46, 0xae, 0x0e, 0x80, 0x88, 0xb3, 0x55, 0xfd, 0x24, 0xb2, 0xbf, - 0x4f, 0xc9, 0x6f, 0x68, 0x30, 0xad, 0x46, 0x32, 0x86, 0xda, 0xb1, 0x01, 0x41, 0xc4, 0xa1, 0x76, - 0x6c, 0x50, 0xa4, 0x46, 0xbf, 0x84, 0xf0, 0x16, 0xc8, 0x7c, 0x0c, 0x2f, 0x0e, 0xbf, 0xfc, 0xbe, - 0x8c, 0x34, 0xe1, 0x03, 0x87, 0x9f, 0x1c, 0xa2, 0x32, 0x22, 0xba, 0x44, 0x2e, 0xc6, 0x88, 0xf0, - 0xa1, 0x86, 0xa9, 0xe2, 0xca, 0x2b, 0x81, 0x15, 0x32, 0xf4, 0xdd, 0x6b, 0x5f, 0xcc, 0xa7, 0x54, - 0x19, 0xb7, 0xf9, 0xb3, 0x2d, 0x3d, 0xb6, 0x12, 0xe1, 0x3b, 0x65, 0x85, 0xfd, 0x91, 0x06, 0x33, - 0x89, 0x60, 0x09, 0xa9, 0x8e, 0xec, 0x2a, 0x19, 0xd1, 0x29, 0xbd, 0x3e, 0x3e, 0xc3, 0x33, 0x77, - 0x80, 0x44, 0x27, 0xd5, 0xa5, 0xe0, 0xfb, 0x54, 0x83, 0x5c, 0x1c, 0xa2, 0x18, 0xba, 0x2b, 0x7b, - 0xc3, 0x34, 0x43, 0x77, 0x65, 0x5f, 0xd4, 0x43, 0x2f, 0x22, 0x26, 0xa2, 0x77, 0xad, 0x21, 0x6b, - 0x59, 0xde, 0x6d, 0x6d, 0x99, 0x7c, 0x0b, 0x4f, 0xec, 0xfa, 0xc1, 0x70, 0x7b, 0x98, 0x48, 0x54, - 0x96, 0x86, 0x9d, 0x52, 0x6a, 0xb6, 0x7a, 0x80, 0x61, 0x62, 0x28, 0x48, 0x51, 0xc1, 0xb7, 0x35, - 0x98, 0x92, 0xa9, 0xc8, 0xa1, 0x87, 0x71, 0x32, 0x5d, 0x39, 0x3e, 0x04, 0x1d, 0x21, 0xbc, 0xac, - 0x9c, 0xc4, 0x2d, 0x21, 0xa9, 0x07, 0x43, 0xf4, 0xc0, 0x6f, 0x18, 0x86, 0x64, 0x0e, 0xf4, 0x2c, - 0x18, 0x9a, 0x42, 0x92, 0x82, 0xe1, 0xf7, 0xb8, 0x9d, 0x51, 0xf2, 0xd3, 0xc3, 0x77, 0x75, 0x7f, - 0xe2, 0x7b, 0xf8, 0xae, 0x1e, 0x90, 0xf8, 0xd6, 0xaf, 0x22, 0xaa, 0xaf, 0x90, 0x97, 0x94, 0x5d, - 0xdd, 0xc0, 0xcc, 0x76, 0x8f, 0xaf, 0x24, 0xb9, 0x87, 0xaa, 0x26, 0x99, 0x08, 0x2f, 0xdd, 0x1a, - 0xde, 0xb4, 0xe7, 0x19, 0x80, 0xbe, 0x8c, 0x50, 0x5e, 0x25, 0xfa, 0x10, 0x28, 0xd5, 0x4f, 0x38, - 0xe1, 0x29, 0xf9, 0x16, 0xa4, 0x1e, 0xf8, 0x0d, 0x36, 0xd4, 0x6f, 0x51, 0x5e, 0x43, 0x9c, 0x16, - 0xca, 0x20, 0x5b, 0xd7, 0x50, 0x35, 0xf2, 0x3b, 0x1a, 0xbe, 0x09, 0xee, 0xde, 0x60, 0x87, 0xda, - 0x94, 0x41, 0xf1, 0xbb, 0xa1, 0x36, 0x65, 0xe0, 0xe5, 0x58, 0xbf, 0x8c, 0xa8, 0x8a, 0xe4, 0x82, - 0xba, 0x8a, 0x79, 0x3b, 0x99, 0x78, 0x7c, 0x0a, 0x69, 0x71, 0x80, 0x5e, 0x1f, 0x7d, 0x35, 0x19, - 0xed, 0x40, 0x26, 0x8f, 0xcb, 0x67, 0xb8, 0x34, 0xea, 0x21, 0xf9, 0x87, 0xdc, 0xd9, 0x57, 0x2e, - 0x14, 0x64, 0xdc, 0x57, 0x76, 0x63, 0x39, 0xfb, 0x03, 0x2e, 0x3c, 0x03, 0x56, 0x4c, 0x2f, 0xa8, - 0x6a, 0xbd, 0x69, 0x3f, 0x41, 0x30, 0x7f, 0xa0, 0x41, 0x5e, 0xb9, 0xc5, 0x0c, 0x3d, 0x9d, 0xfa, - 0x6f, 0x3b, 0x83, 0x66, 0x2b, 0xf1, 0x67, 0x5c, 0x0a, 0x8f, 0x41, 0x5b, 0x7e, 0x10, 0xea, 0xd7, - 0x10, 0xdc, 0x15, 0x72, 0xb9, 0xeb, 0xfd, 0x77, 0x19, 0xba, 0x4b, 0x69, 0x4d, 0xff, 0xfc, 0x3f, - 0x2f, 0x9f, 0xfb, 0xfc, 0xe4, 0xb2, 0xf6, 0x4f, 0x27, 0x97, 0xb5, 0x7f, 0x3d, 0xb9, 0xac, 0xfd, - 0xc7, 0xc9, 0x65, 0xed, 0x7b, 0xff, 0x75, 0xf9, 0xdc, 0xc7, 0xd9, 0x08, 0x50, 0x2d, 0x83, 0x59, - 0xb2, 0xaf, 0xfd, 0x5f, 0x00, 0x00, 0x00, 0xff, 0xff, 0x2b, 0xaf, 0xa4, 0xf2, 0xb6, 0x36, 0x00, + 0xdf, 0x6a, 0xb7, 0x5d, 0x87, 0xda, 0xa5, 0x34, 0x36, 0x8e, 0x8a, 0xe4, 0x11, 0x64, 0xdb, 0x81, + 0xdf, 0xc4, 0xe9, 0xcb, 0xa0, 0x8e, 0x56, 0x46, 0xac, 0xe1, 0x78, 0x84, 0xd5, 0x4d, 0xc9, 0x74, + 0xcb, 0x0b, 0x83, 0xae, 0x84, 0x16, 0x4b, 0x22, 0x97, 0x61, 0x9e, 0xa3, 0x31, 0xc3, 0xc0, 0xf2, + 0xd8, 0x36, 0x0d, 0x28, 0xc5, 0x9d, 0x9c, 0x32, 0xe6, 0x38, 0xf9, 0x51, 0x4c, 0x2d, 0xff, 0xb6, + 0x06, 0xd9, 0x48, 0x14, 0xc7, 0xde, 0xb2, 0xc2, 0xc6, 0x8e, 0x50, 0x98, 0x21, 0x0a, 0x7c, 0x94, + 0x1e, 0xdd, 0x17, 0x66, 0x2b, 0x65, 0xe0, 0x77, 0x6f, 0x94, 0xd3, 0xea, 0x28, 0x4f, 0x41, 0xa6, + 0x6d, 0x75, 0x18, 0xb5, 0x71, 0xf0, 0x59, 0x43, 0x96, 0xc8, 0x15, 0x28, 0xb6, 0xa9, 0x67, 0x3b, + 0x5e, 0xd3, 0x64, 0x9e, 0xd5, 0x66, 0x3b, 0x7e, 0x28, 0xd5, 0x30, 0x2f, 0xe9, 0x5b, 0x92, 0x5c, + 0xfe, 0x26, 0xcc, 0x26, 0x46, 0x46, 0x8a, 0x30, 0xcd, 0xed, 0x90, 0x40, 0xc4, 0x3f, 0xc9, 0x1a, + 0xa4, 0xf7, 0x2c, 0xb7, 0x13, 0x4d, 0xd4, 0xf5, 0x23, 0xa9, 0xcb, 0x10, 0xbc, 0x37, 0xa6, 0xde, + 0xd2, 0xf4, 0x1f, 0x6b, 0x30, 0x6b, 0x58, 0x5e, 0x93, 0x6e, 0x06, 0x7e, 0xdd, 0xa5, 0x2d, 0x46, + 0x2e, 0x40, 0xbe, 0xe3, 0x59, 0x7b, 0x96, 0xe3, 0x5a, 0x75, 0x57, 0x1c, 0x57, 0x59, 0x43, 0x25, + 0x91, 0x37, 0xe1, 0x34, 0xd7, 0x20, 0x0d, 0x4c, 0xcf, 0x0f, 0x4d, 0x71, 0xe8, 0xef, 0xf8, 0xae, + 0x4d, 0x03, 0x69, 0x04, 0x96, 0x44, 0xf5, 0x03, 0x3f, 0xbc, 0xcf, 0x2b, 0xef, 0x62, 0x1d, 0x79, + 0x19, 0xe6, 0x3c, 0xdf, 0xe4, 0x2b, 0xca, 0x14, 0xf5, 0xa8, 0xb8, 0xac, 0x51, 0xf0, 0x7c, 0x8e, + 0xf1, 0x3e, 0xd2, 0xc8, 0x32, 0xcc, 0x77, 0x3c, 0x9b, 0x06, 0x72, 0x65, 0x86, 0xb1, 0x22, 0xfb, + 0xc9, 0xe4, 0x0c, 0x64, 0x3d, 0x5f, 0x74, 0x8f, 0x9a, 0xcc, 0x1a, 0x33, 0x9e, 0x8f, 0x1d, 0xea, + 0xbb, 0x30, 0x8f, 0x83, 0xe2, 0xe3, 0x76, 0xd0, 0xd5, 0xe1, 0x66, 0xf9, 0x49, 0x87, 0x06, 0x0e, + 0x65, 0x66, 0x9b, 0x06, 0x26, 0xa3, 0x0d, 0xdf, 0x13, 0xbb, 0x42, 0x33, 0x8a, 0xb2, 0x66, 0x93, + 0x06, 0x5b, 0x48, 0x27, 0x57, 0x61, 0xe1, 0x57, 0x02, 0x27, 0x4c, 0x36, 0x9e, 0xc2, 0xc6, 0xf3, + 0xa2, 0x22, 0x6e, 0xab, 0xdf, 0x05, 0xd8, 0x0c, 0x68, 0x18, 0x76, 0xb7, 0xda, 0x96, 0xc7, 0xcf, + 0x06, 0x16, 0x5a, 0x41, 0x68, 0x46, 0x33, 0x96, 0x33, 0xb2, 0x48, 0xe0, 0x07, 0xc7, 0x69, 0x98, + 0xa1, 0x1e, 0x1e, 0x0b, 0xf2, 0x00, 0xcc, 0x50, 0x8f, 0x9f, 0x05, 0x37, 0x52, 0xff, 0xfb, 0x27, + 0x15, 0x4d, 0xff, 0x73, 0x0d, 0x16, 0xd7, 0xfc, 0x56, 0xcb, 0xf2, 0xec, 0x0f, 0x3a, 0xb4, 0x43, + 0xdf, 0xa7, 0x61, 0xc0, 0xb1, 0xbf, 0x02, 0x73, 0xd8, 0xa9, 0xd9, 0x10, 0x95, 0x0c, 0x05, 0x4f, + 0x1b, 0xb3, 0x48, 0x95, 0x1c, 0x8c, 0xbb, 0x03, 0xdc, 0xfa, 0xf6, 0x5a, 0x4d, 0x61, 0xab, 0x02, + 0x27, 0xc6, 0x8d, 0xae, 0xc2, 0x42, 0xcb, 0xda, 0x37, 0xfd, 0x3d, 0x1a, 0xb8, 0x56, 0x9b, 0x99, + 0x8c, 0x52, 0x4f, 0x1e, 0xb8, 0xf3, 0x2d, 0x6b, 0xff, 0xa1, 0xa4, 0x6f, 0x51, 0x8a, 0x63, 0x09, + 0x03, 0x4a, 0x4d, 0xe6, 0x7c, 0x4b, 0xec, 0xe5, 0xb4, 0x91, 0xe5, 0x84, 0x2d, 0xe7, 0x5b, 0x54, + 0xff, 0x97, 0x19, 0x6e, 0x6c, 0xbc, 0x26, 0xe5, 0x46, 0x90, 0xbc, 0x03, 0x29, 0xd6, 0xb6, 0x3c, + 0x04, 0x96, 0x5f, 0x79, 0x65, 0xc4, 0x7a, 0xec, 0xe9, 0x4a, 0xee, 0x58, 0x64, 0x24, 0x1b, 0x00, + 0xb8, 0x34, 0x54, 0xfb, 0xf3, 0xf2, 0x24, 0xcb, 0x3a, 0x32, 0x49, 0x41, 0x6c, 0xf8, 0xd6, 0x55, + 0xf3, 0x93, 0x5f, 0x59, 0x56, 0xa5, 0x08, 0x2f, 0xb4, 0xaa, 0x78, 0xa3, 0xd5, 0x78, 0x10, 0x91, + 0xd1, 0x15, 0x1b, 0xb9, 0x05, 0x73, 0xcc, 0xef, 0x04, 0x0d, 0x6a, 0x46, 0xc6, 0x36, 0x8d, 0xa7, + 0xd6, 0x9d, 0xc3, 0x83, 0x4a, 0x61, 0x0b, 0x6b, 0x8e, 0x77, 0x76, 0x15, 0x58, 0x4f, 0x88, 0x4d, + 0x9e, 0xc0, 0xbc, 0xec, 0x8e, 0x63, 0xc3, 0xfe, 0x32, 0xd8, 0xdf, 0xc6, 0xe1, 0x41, 0x65, 0x56, + 0xf4, 0xb7, 0xc5, 0x6b, 0xb0, 0xc3, 0x37, 0x8e, 0xd4, 0xa1, 0xe4, 0x33, 0x66, 0x99, 0x22, 0xc6, + 0x1e, 0x74, 0x1f, 0x67, 0x86, 0xb8, 0x8f, 0x6b, 0x30, 0x2b, 0x77, 0xb8, 0xc3, 0x81, 0x75, 0xd1, + 0xdf, 0xc9, 0xaf, 0x94, 0x14, 0xa5, 0x46, 0xdd, 0xe0, 0xde, 0x8b, 0xfc, 0x09, 0x64, 0xba, 0x2b, + 0x78, 0xc8, 0x7b, 0x68, 0xe0, 0xd1, 0xbe, 0x94, 0x72, 0x83, 0x93, 0x32, 0x30, 0xb5, 0x8a, 0x3d, + 0x52, 0xcc, 0xba, 0xb0, 0x4f, 0xb7, 0xc5, 0xec, 0xb2, 0x12, 0xa0, 0xa0, 0xab, 0xe3, 0x04, 0xf5, + 0x6c, 0x80, 0x3a, 0xbf, 0x8c, 0x3c, 0x82, 0x7c, 0xa3, 0x65, 0x9b, 0x4f, 0x4c, 0xd7, 0x6f, 0x58, + 0x6e, 0x29, 0x8f, 0xd2, 0xaa, 0xa3, 0x7c, 0xa7, 0xc1, 0x9d, 0x19, 0xad, 0xbd, 0x46, 0xcb, 0xfe, + 0xe0, 0x3e, 0x17, 0x43, 0x3e, 0x84, 0x82, 0x90, 0xda, 0x74, 0xfd, 0xba, 0xe5, 0x96, 0x0a, 0xc7, + 0x10, 0x0b, 0x5c, 0xec, 0x1d, 0x94, 0x43, 0xee, 0x40, 0x41, 0x8d, 0xae, 0x4a, 0xb3, 0x03, 0x5e, + 0x4e, 0xb4, 0xb4, 0x71, 0x16, 0x12, 0x5e, 0x44, 0xde, 0xed, 0x91, 0xb8, 0xa7, 0xfc, 0xa4, 0xe3, + 0x50, 0xd6, 0xa0, 0x5e, 0x58, 0x9a, 0x43, 0xb3, 0xd9, 0x23, 0xe8, 0xbf, 0x15, 0x1d, 0x07, 0xe3, + 0x1d, 0x3f, 0x0b, 0x72, 0x01, 0x6f, 0x69, 0x3a, 0x68, 0x69, 0xa6, 0x97, 0xa7, 0x57, 0xd7, 0x0f, + 0x0f, 0x2a, 0x59, 0xb1, 0x9d, 0xd6, 0xd9, 0x91, 0x57, 0xa9, 0x64, 0x34, 0xb2, 0x28, 0x76, 0xc3, + 0x66, 0xfa, 0x23, 0x98, 0x8b, 0xc0, 0x48, 0x57, 0x6a, 0x15, 0x32, 0x58, 0x1b, 0xf9, 0x52, 0x2f, + 0x8f, 0x9b, 0x7d, 0x65, 0x5f, 0x4b, 0x4e, 0x7d, 0x19, 0x66, 0xef, 0x60, 0xe8, 0x3c, 0xd6, 0x9f, + 0xfa, 0xe1, 0x14, 0xcc, 0xdf, 0x74, 0xf9, 0xfa, 0x08, 0xfd, 0x60, 0x3d, 0xe8, 0x1a, 0x1d, 0x8f, + 0x7c, 0x0c, 0xd9, 0x68, 0xd8, 0xc2, 0x0a, 0xaf, 0xae, 0x1d, 0x1e, 0x54, 0x66, 0x24, 0xf8, 0xe7, + 0x1e, 0xf4, 0x8c, 0x1c, 0x34, 0xb9, 0x0b, 0x19, 0xba, 0x47, 0xbd, 0x50, 0xe8, 0x34, 0xbf, 0xf2, + 0xda, 0x88, 0x11, 0xf6, 0x61, 0xab, 0xde, 0xe2, 0x8c, 0x86, 0xe4, 0x2f, 0xff, 0x12, 0xa4, 0x91, + 0x40, 0xde, 0x82, 0x14, 0x8f, 0x69, 0xa5, 0x6d, 0x2e, 0x57, 0x45, 0xc0, 0x5b, 0x8d, 0x02, 0xde, + 0xea, 0xa3, 0x28, 0xe0, 0x5d, 0xcd, 0x72, 0x45, 0x7d, 0xff, 0x8b, 0x8a, 0x66, 0x20, 0x07, 0x77, + 0xd9, 0x92, 0xa1, 0x65, 0x54, 0xd4, 0x57, 0xe0, 0x64, 0xdc, 0x3b, 0x8e, 0x21, 0x52, 0xe6, 0x99, + 0x7e, 0xfd, 0xc4, 0x43, 0xd3, 0xff, 0x56, 0x83, 0x53, 0xfd, 0x4c, 0xc3, 0x63, 0x83, 0xe9, 0x2f, + 0x33, 0x36, 0x58, 0x83, 0x19, 0x3b, 0xe8, 0x9a, 0x41, 0xc7, 0x93, 0xc7, 0xca, 0xd5, 0xc9, 0x55, + 0x6a, 0x64, 0x6c, 0xfc, 0xd5, 0xbf, 0xa7, 0x41, 0xb1, 0x87, 0xfd, 0xa7, 0x60, 0x6f, 0x7c, 0x04, + 0x0b, 0x0a, 0x1e, 0xa9, 0xc6, 0x5b, 0x90, 0x95, 0x43, 0x8d, 0x36, 0xc8, 0x51, 0xc6, 0x3a, 0x23, + 0xc6, 0xca, 0x74, 0x1d, 0x0a, 0xef, 0x6d, 0x3d, 0x7c, 0x10, 0x8b, 0x8d, 0x52, 0x08, 0x5a, 0x2f, + 0x85, 0xa0, 0xff, 0x48, 0x83, 0xfc, 0x7d, 0xbf, 0x39, 0x51, 0x80, 0xe8, 0xd2, 0x3d, 0xea, 0xca, + 0x15, 0x24, 0x0a, 0x3c, 0xc2, 0x16, 0x6e, 0x12, 0xae, 0x4c, 0xe1, 0x41, 0x0b, 0xc7, 0x89, 0xaf, + 0x46, 0xbe, 0x8a, 0xb8, 0xa3, 0x84, 0x95, 0x22, 0x88, 0xe0, 0x8e, 0x13, 0x56, 0x15, 0x61, 0xba, + 0x65, 0xed, 0xe3, 0x61, 0x9c, 0x33, 0xf8, 0x27, 0x5f, 0xa5, 0x6d, 0x2b, 0x0c, 0x69, 0xe0, 0xc9, + 0x90, 0x3e, 0x2a, 0xea, 0x0f, 0x81, 0xdc, 0xf7, 0x9b, 0xdc, 0x89, 0x76, 0x14, 0x23, 0xf2, 0xb3, + 0xdc, 0x0b, 0x43, 0x92, 0x54, 0xd2, 0x99, 0xfe, 0x60, 0xd1, 0xf5, 0x9b, 0x55, 0x35, 0xa8, 0x88, + 0xda, 0xeb, 0x55, 0x58, 0xbc, 0xef, 0x37, 0x6f, 0x3b, 0x2e, 0x65, 0xf7, 0x1d, 0x16, 0x8e, 0xb5, + 0x20, 0x9b, 0xb0, 0x94, 0x6c, 0x2f, 0x21, 0xbc, 0x05, 0xe9, 0x6d, 0x4e, 0x94, 0x00, 0xce, 0x0d, + 0x03, 0xc0, 0xb9, 0x54, 0xb7, 0x04, 0x19, 0xf4, 0xb7, 0x61, 0x4e, 0x4a, 0x1c, 0xab, 0x79, 0x02, + 0x29, 0xce, 0x23, 0x15, 0x8f, 0xdf, 0xdc, 0xf8, 0x6d, 0x85, 0x56, 0x63, 0x77, 0x7c, 0x1a, 0xeb, + 0x57, 0x61, 0x6e, 0x33, 0xf0, 0xb7, 0x27, 0xe9, 0x68, 0x55, 0xa6, 0xb6, 0xd2, 0x98, 0xda, 0xaa, + 0x8e, 0x74, 0xfe, 0x54, 0x89, 0xd5, 0x5e, 0x2e, 0x4b, 0x2f, 0x42, 0x0a, 0xb3, 0x1f, 0x59, 0x48, + 0xdd, 0xbd, 0x75, 0x73, 0xb3, 0x78, 0x42, 0xbf, 0x02, 0x73, 0xf2, 0x3c, 0x1c, 0x8b, 0xf5, 0x2f, + 0xf0, 0xd8, 0xda, 0x0e, 0x71, 0x9b, 0xf0, 0xed, 0xff, 0x42, 0x93, 0x0d, 0xef, 0x42, 0x1a, 0xb7, + 0xe1, 0x44, 0x5e, 0x6a, 0x9f, 0x6f, 0x89, 0x8c, 0xfa, 0x55, 0x7e, 0xb0, 0x49, 0xb8, 0xb7, 0xb8, + 0xb7, 0xa5, 0x5a, 0x5a, 0x2d, 0x69, 0x69, 0x3f, 0x9d, 0xe2, 0xc1, 0x8c, 0x6c, 0x2c, 0x0f, 0xf1, + 0x17, 0x7d, 0x08, 0xdd, 0x81, 0x0c, 0x3a, 0x81, 0xd1, 0x21, 0x74, 0x65, 0x8c, 0x23, 0xde, 0x1b, + 0x48, 0x74, 0xd6, 0x0a, 0x76, 0xee, 0x8a, 0x8b, 0xd4, 0xc7, 0x34, 0xca, 0x59, 0x9e, 0x44, 0x0e, + 0xd7, 0x76, 0x32, 0xff, 0xd1, 0x81, 0x22, 0xaf, 0x5d, 0xa7, 0xf5, 0x4e, 0x33, 0x5a, 0x0b, 0x09, + 0x13, 0xab, 0xbd, 0x10, 0x13, 0xfb, 0xaf, 0x53, 0xb0, 0xa0, 0xf4, 0x2b, 0xb7, 0xee, 0xf7, 0xb4, + 0x3e, 0x1f, 0xe4, 0xad, 0x31, 0x83, 0x4a, 0xb0, 0x8b, 0x6e, 0x64, 0xc6, 0xe2, 0xe7, 0xf9, 0x20, + 0x3f, 0xfb, 0xe2, 0x39, 0x81, 0x4a, 0x14, 0x5f, 0xda, 0x64, 0x95, 0x29, 0xe4, 0x15, 0x74, 0x6a, + 0xd6, 0x61, 0x5a, 0x64, 0x1d, 0xde, 0x4d, 0x66, 0x1d, 0xae, 0x4e, 0xd2, 0x91, 0x58, 0xb1, 0x6a, + 0xca, 0xe1, 0xd7, 0xa7, 0x20, 0x7f, 0xb3, 0x11, 0x3a, 0x7b, 0xf4, 0x83, 0x0e, 0x0d, 0xba, 0xe4, + 0x14, 0x4c, 0x45, 0x1b, 0x7a, 0x35, 0x73, 0x78, 0x50, 0x99, 0xda, 0x58, 0x37, 0xa6, 0x1c, 0x9b, + 0xf7, 0xcf, 0x9e, 0x44, 0xc7, 0x06, 0xff, 0x24, 0x37, 0xd0, 0xf5, 0x0f, 0x42, 0x99, 0xa0, 0x9b, + 0xcc, 0x93, 0x11, 0x2c, 0x3c, 0x86, 0x76, 0x98, 0x69, 0x3b, 0x2c, 0x0c, 0x9c, 0x7a, 0xa7, 0x97, + 0x56, 0x98, 0x75, 0xd8, 0x7a, 0x8f, 0x48, 0x56, 0x21, 0xdd, 0xde, 0x89, 0x32, 0x0a, 0x73, 0x2b, + 0xd7, 0x46, 0x1d, 0x9f, 0xbd, 0x31, 0x54, 0x37, 0x39, 0x8f, 0x21, 0x58, 0xf5, 0x57, 0x20, 0x8d, + 0x65, 0x32, 0x0b, 0xb9, 0x4d, 0xe3, 0xd6, 0xe6, 0x4d, 0x63, 0xe3, 0xc1, 0x9d, 0xe2, 0x09, 0x5e, + 0xbc, 0xf5, 0x8b, 0xb7, 0xd6, 0x1e, 0x3f, 0xe2, 0x45, 0x4d, 0x7f, 0x1d, 0x16, 0xf9, 0x99, 0xb0, + 0x45, 0x19, 0x73, 0x7c, 0x2f, 0x36, 0x72, 0x65, 0xc8, 0x76, 0x18, 0x0d, 0x3c, 0xab, 0x15, 0x99, + 0x82, 0xb8, 0xac, 0x7f, 0x37, 0x05, 0x33, 0xb2, 0xfd, 0x0b, 0xb5, 0x70, 0x2a, 0x86, 0xa9, 0x24, + 0x06, 0xae, 0xc8, 0x86, 0xeb, 0x50, 0x2f, 0x34, 0xa3, 0x8c, 0xab, 0x38, 0xbd, 0x67, 0x05, 0xf5, + 0xa6, 0xcc, 0xa8, 0x5e, 0x81, 0x22, 0xa6, 0xf7, 0x1a, 0x78, 0xd9, 0x62, 0xa2, 0x28, 0x71, 0x92, + 0xcf, 0x2b, 0xf4, 0x07, 0x5c, 0xe2, 0x16, 0xcc, 0x59, 0xa8, 0x4b, 0x53, 0xe6, 0x61, 0x30, 0x83, + 0x9f, 0x5f, 0xb9, 0x34, 0x99, 0xf2, 0xe5, 0x2a, 0x9e, 0xb5, 0x62, 0x92, 0x43, 0x59, 0x6f, 0xad, + 0x64, 0x8e, 0xbe, 0x56, 0x3e, 0x86, 0xdc, 0xee, 0x9e, 0x19, 0xee, 0x7b, 0x5c, 0xb9, 0x3c, 0x28, + 0x2e, 0xac, 0xae, 0xfe, 0xfb, 0xa4, 0x2a, 0x15, 0x77, 0x57, 0x1d, 0xc7, 0xae, 0x3e, 0x7e, 0xbc, + 0xc1, 0x4d, 0xd2, 0xcc, 0xbd, 0xbd, 0x47, 0xfb, 0x1e, 0x37, 0xaf, 0xbb, 0xf8, 0x81, 0xd9, 0x25, + 0xd7, 0x62, 0xa1, 0xa9, 0x8c, 0x9a, 0xc7, 0xd5, 0xa8, 0x1c, 0x5e, 0x31, 0xb8, 0x3b, 0x72, 0x08, + 0x42, 0xd9, 0x1d, 0xfa, 0x6f, 0x68, 0xb0, 0xa0, 0x2e, 0x1f, 0x71, 0x8c, 0xbc, 0xc8, 0x45, 0xf1, + 0xec, 0x60, 0xe0, 0xcf, 0x34, 0x58, 0x4a, 0x2e, 0x65, 0x69, 0x2b, 0xd7, 0x21, 0xcb, 0x24, 0x4d, + 0x1a, 0x4b, 0x7d, 0xc4, 0x9c, 0x4a, 0xf6, 0x28, 0xe2, 0x8f, 0x38, 0xc9, 0x7b, 0x7d, 0x06, 0x6e, + 0xd4, 0xa6, 0x1c, 0x50, 0x49, 0xd2, 0xc6, 0xe9, 0x4f, 0x80, 0xac, 0x59, 0x5e, 0x83, 0xba, 0xa8, + 0xdd, 0xb1, 0x9e, 0xcd, 0x25, 0xc8, 0xe2, 0xec, 0xf0, 0x1a, 0x1c, 0xf4, 0x6a, 0x9e, 0xcf, 0x28, + 0x32, 0xf3, 0x19, 0xc5, 0xca, 0xbe, 0x0d, 0x33, 0xdd, 0xb7, 0x69, 0xef, 0xc0, 0x62, 0xa2, 0x4b, + 0xa9, 0x9b, 0x32, 0x64, 0x1b, 0x48, 0xa6, 0xb6, 0x4c, 0xb2, 0xc6, 0x65, 0xee, 0x33, 0x23, 0xde, + 0xc8, 0x67, 0xc6, 0x82, 0xde, 0x85, 0x25, 0x21, 0x48, 0x0e, 0x70, 0x2c, 0xfa, 0x6b, 0x00, 0x52, + 0x89, 0x11, 0xfe, 0x82, 0xb8, 0x01, 0x90, 0x02, 0x36, 0xd6, 0x8d, 0x9c, 0x6c, 0x30, 0x66, 0x0c, + 0x1b, 0x70, 0xb2, 0xaf, 0xeb, 0xe7, 0x1e, 0xc5, 0x7f, 0x68, 0x50, 0xdc, 0x6a, 0x5b, 0x1e, 0x3f, + 0x18, 0x62, 0xa3, 0x77, 0xb1, 0x6f, 0x08, 0xab, 0xd0, 0x5b, 0xb7, 0xf1, 0x70, 0x0c, 0x35, 0xb5, + 0x2a, 0x46, 0xf3, 0xe6, 0x4f, 0x0e, 0x2a, 0xaf, 0x1f, 0xed, 0xf4, 0xbc, 0x47, 0xbb, 0x4a, 0x46, + 0xf6, 0x41, 0x2f, 0x23, 0x3b, 0x7d, 0x1c, 0x89, 0x32, 0x91, 0xab, 0xff, 0x9d, 0x06, 0x0b, 0xca, + 0xe8, 0xa4, 0x96, 0xb6, 0x20, 0x1f, 0xfa, 0xa1, 0xe5, 0x9a, 0x22, 0x73, 0x25, 0x02, 0xf1, 0x6b, + 0x43, 0x92, 0x37, 0xe2, 0x7a, 0xbd, 0x1a, 0xdd, 0xb2, 0x57, 0xdf, 0xff, 0x70, 0x6d, 0x0d, 0x45, + 0x45, 0x29, 0x21, 0x14, 0x83, 0x14, 0x52, 0x81, 0xbc, 0xf0, 0x80, 0x1a, 0x7e, 0xc7, 0x13, 0x57, + 0x13, 0x69, 0x03, 0x90, 0xb4, 0xc6, 0x29, 0xe4, 0x0d, 0x38, 0x65, 0xb5, 0xdb, 0x81, 0xbf, 0xef, + 0xb4, 0xac, 0x90, 0xf2, 0xb3, 0x6f, 0xd7, 0xac, 0x77, 0x43, 0xca, 0xe4, 0x65, 0xcd, 0x92, 0x52, + 0xbb, 0xee, 0xb0, 0xdd, 0x55, 0x5e, 0xa7, 0xff, 0x1c, 0x2c, 0xc9, 0xdc, 0x5b, 0x32, 0x11, 0x34, + 0xc9, 0x14, 0xe9, 0xff, 0x98, 0x83, 0x93, 0x7d, 0xdc, 0x83, 0x11, 0x7e, 0xf6, 0xcb, 0xb6, 0x4c, + 0xff, 0xa0, 0xc1, 0x62, 0x94, 0x1f, 0x34, 0xeb, 0xdd, 0x38, 0x61, 0x9b, 0x43, 0x73, 0x71, 0x7b, + 0x74, 0x3c, 0x32, 0x88, 0xb5, 0x1a, 0xe7, 0x1e, 0xbb, 0x22, 0x39, 0x2b, 0xbc, 0xb5, 0x87, 0x7c, + 0x06, 0x0e, 0x0f, 0x2a, 0xc5, 0xbe, 0xea, 0xf5, 0xcf, 0xbe, 0x78, 0x3e, 0xf8, 0xc5, 0x76, 0x5f, + 0x3f, 0xe5, 0xef, 0x64, 0xc4, 0x5d, 0x62, 0x7c, 0x19, 0x33, 0x90, 0xa2, 0xd5, 0x86, 0xa4, 0x68, + 0x7f, 0x4d, 0x83, 0x93, 0xca, 0xfd, 0x8c, 0xd9, 0x9f, 0x7a, 0x78, 0x78, 0x78, 0x50, 0x59, 0x7c, + 0xdc, 0x6b, 0x70, 0x6c, 0x17, 0x79, 0xb1, 0xd3, 0x2f, 0xcc, 0x66, 0xe4, 0x2f, 0x35, 0xb8, 0xa4, + 0x5c, 0xee, 0x0c, 0xdc, 0x0d, 0x29, 0xb0, 0xa6, 0x11, 0xd6, 0x2f, 0x1f, 0x1e, 0x54, 0x2e, 0xf4, + 0x6e, 0x7e, 0x92, 0xb7, 0x45, 0xc7, 0xc6, 0x78, 0x21, 0x18, 0x29, 0xd9, 0x66, 0xe4, 0xbb, 0x1a, + 0x94, 0x92, 0x17, 0x52, 0x0a, 0xc4, 0x14, 0x42, 0xdc, 0x3c, 0x3c, 0xa8, 0x2c, 0x3d, 0x50, 0xae, + 0xa7, 0x8e, 0x0d, 0x6b, 0xc9, 0x1b, 0x90, 0x66, 0x33, 0xb2, 0x0f, 0x24, 0xba, 0xca, 0x52, 0x30, + 0xa4, 0x11, 0xc3, 0xbd, 0xc3, 0x83, 0xca, 0xfc, 0x03, 0x71, 0xb1, 0x75, 0xec, 0xee, 0xe7, 0x3d, + 0x55, 0x90, 0xcd, 0xc8, 0xef, 0x68, 0x70, 0xa6, 0xef, 0x62, 0x4d, 0x41, 0x90, 0x41, 0x04, 0x5b, + 0x87, 0x07, 0x95, 0xd3, 0x8f, 0x93, 0x8d, 0x8e, 0x8d, 0xe4, 0x74, 0x67, 0x98, 0x40, 0x9b, 0x95, + 0x3f, 0xd3, 0x62, 0x13, 0x92, 0xdc, 0x80, 0x6a, 0x40, 0x92, 0x16, 0x01, 0xc9, 0x56, 0x32, 0x20, + 0x79, 0xfb, 0xc8, 0x3b, 0x5d, 0xdd, 0x6c, 0x4a, 0x8c, 0xf2, 0x5e, 0x2a, 0xab, 0x15, 0xb3, 0xfa, + 0x15, 0x28, 0x4c, 0x9a, 0xdb, 0xfc, 0xd3, 0xb4, 0x4c, 0x9c, 0x7f, 0x25, 0xcf, 0x1d, 0xd4, 0xf8, + 0x7f, 0xea, 0x05, 0xc4, 0xff, 0x7f, 0xaf, 0xc1, 0x52, 0x20, 0x07, 0x92, 0xb0, 0xa8, 0x22, 0x8c, + 0x7f, 0x67, 0x5c, 0xc6, 0xa3, 0x17, 0xed, 0x46, 0x42, 0x92, 0xa6, 0x74, 0x53, 0x9a, 0xd2, 0x85, + 0xfe, 0xfa, 0xe7, 0xb6, 0xa5, 0x0b, 0x41, 0x7f, 0x4f, 0xe5, 0x1f, 0x68, 0xc2, 0x98, 0xaa, 0xbe, + 0x4a, 0xd4, 0x2a, 0xf2, 0x55, 0xa2, 0xf2, 0x64, 0x4f, 0xa9, 0xde, 0x85, 0xb4, 0xe3, 0x6d, 0xfb, + 0x51, 0x36, 0xe3, 0x48, 0x89, 0x1f, 0x64, 0x2c, 0x7f, 0x02, 0xa7, 0x86, 0xab, 0x64, 0xc8, 0xe2, + 0xbe, 0x97, 0x5c, 0xdc, 0x6f, 0x4e, 0xac, 0x74, 0x75, 0xd0, 0xc9, 0x45, 0x9d, 0x2a, 0xa6, 0xf5, + 0xd7, 0x92, 0x77, 0xcc, 0x13, 0xac, 0x6d, 0x0f, 0x96, 0x92, 0x1c, 0x52, 0x67, 0x1f, 0x42, 0x36, + 0x7e, 0xca, 0x20, 0x5c, 0x9a, 0x37, 0xc6, 0x5c, 0xb5, 0xaa, 0x62, 0x58, 0xf4, 0xde, 0x21, 0xf6, + 0xf7, 0x65, 0x59, 0xbf, 0x0e, 0x64, 0xbd, 0xf7, 0x48, 0x71, 0x6c, 0xf2, 0x0f, 0x53, 0x9a, 0x7e, + 0x30, 0xc1, 0xcb, 0xbc, 0x3f, 0xd2, 0xa0, 0x80, 0x4d, 0xa3, 0x37, 0x79, 0x1f, 0x43, 0x36, 0xbe, + 0x6d, 0x15, 0x9b, 0x14, 0xf7, 0xd1, 0x71, 0xef, 0x59, 0x67, 0x98, 0xbc, 0x61, 0x7d, 0x15, 0x16, + 0xa8, 0xd7, 0x08, 0xba, 0x6d, 0x8c, 0x81, 0xe5, 0xd5, 0x1d, 0x7a, 0xae, 0x46, 0xb1, 0x57, 0x21, + 0x52, 0x24, 0xfa, 0x37, 0x60, 0x2e, 0x1a, 0x47, 0x9c, 0xce, 0xcf, 0xa0, 0xa4, 0x28, 0x78, 0xba, + 0x3c, 0x2a, 0x78, 0x52, 0xc6, 0x15, 0xc5, 0x3c, 0x82, 0x79, 0xe5, 0xaf, 0xce, 0x42, 0x46, 0x26, + 0x0e, 0x7f, 0xa8, 0x41, 0x41, 0x7d, 0x4a, 0x46, 0xaa, 0x93, 0x3d, 0x16, 0x8b, 0x74, 0x5b, 0xae, + 0x4d, 0xdc, 0x5e, 0x8c, 0x41, 0xbf, 0xfc, 0xd9, 0x8f, 0xff, 0xe7, 0xf7, 0xa6, 0x5e, 0x22, 0x95, + 0x9a, 0x1c, 0x7f, 0x4d, 0x7d, 0x69, 0x56, 0xfb, 0x44, 0xce, 0xd4, 0x53, 0x7e, 0x12, 0xcd, 0x44, + 0xf3, 0x32, 0x2a, 0x85, 0x95, 0x7c, 0x98, 0x56, 0xbe, 0x3a, 0x49, 0x53, 0x89, 0xe5, 0x3a, 0x62, + 0xb9, 0x4c, 0xca, 0x31, 0x16, 0x5b, 0xb4, 0xe8, 0xc1, 0xf8, 0x28, 0x47, 0x66, 0x6a, 0x3b, 0xd4, + 0x72, 0xc3, 0x1d, 0x12, 0x40, 0x1a, 0x1f, 0x72, 0x91, 0x51, 0x7a, 0x57, 0x9f, 0x7e, 0x95, 0x97, + 0xc7, 0x37, 0x94, 0x50, 0x4e, 0x21, 0x94, 0x22, 0x99, 0x8b, 0xa1, 0x60, 0xaa, 0x93, 0x74, 0x20, + 0x85, 0xf9, 0xeb, 0x4b, 0x63, 0x24, 0x45, 0x3d, 0x4e, 0xf2, 0x98, 0x4c, 0xbf, 0x80, 0x9d, 0x95, + 0x49, 0x29, 0xd9, 0x99, 0xa2, 0xfc, 0xa7, 0xe2, 0xe1, 0x18, 0xa6, 0x2a, 0xc9, 0xab, 0x93, 0x25, + 0x34, 0x05, 0x80, 0x6b, 0x47, 0xc9, 0x7e, 0xea, 0x27, 0x11, 0xc9, 0x3c, 0x99, 0x8d, 0x91, 0x70, + 0xf7, 0x8b, 0x7c, 0xaa, 0x41, 0x46, 0x9c, 0xcc, 0x64, 0xec, 0xc3, 0x80, 0x58, 0xd9, 0x57, 0x26, + 0x68, 0x29, 0xbb, 0x7d, 0x09, 0xbb, 0x3d, 0x4b, 0xce, 0x28, 0xdd, 0xf2, 0x06, 0x8a, 0x06, 0x18, + 0x64, 0xc4, 0xad, 0xf0, 0x48, 0x04, 0x89, 0x8b, 0xe3, 0xb2, 0x7a, 0x6d, 0x23, 0x5f, 0x63, 0x73, + 0x93, 0x2f, 0xb5, 0x3e, 0xd8, 0xa9, 0x7c, 0xb8, 0xdd, 0xeb, 0xf4, 0x07, 0x1a, 0xe4, 0xe2, 0x5b, + 0xb8, 0x91, 0x7a, 0xef, 0xbf, 0x7b, 0x1c, 0xa9, 0xf7, 0x81, 0x8b, 0x41, 0xfd, 0x0a, 0x62, 0xb9, + 0x48, 0x5e, 0x8a, 0xb1, 0x58, 0x51, 0x1b, 0x5c, 0x0b, 0x0a, 0xa6, 0x1f, 0x69, 0x30, 0x97, 0xbc, + 0xa5, 0x25, 0x13, 0xdd, 0x41, 0xab, 0x9e, 0x52, 0xf9, 0xf5, 0x23, 0x70, 0x48, 0x88, 0xaf, 0x22, + 0xc4, 0x57, 0xc8, 0xc5, 0x21, 0x10, 0x71, 0xb6, 0x6a, 0x9f, 0x44, 0x07, 0xd4, 0x53, 0xf2, 0x9b, + 0x1a, 0x14, 0xd4, 0x54, 0xcf, 0x48, 0x3b, 0x36, 0x24, 0xcb, 0x3a, 0xd2, 0x8e, 0x0d, 0x4b, 0x65, + 0xe9, 0x67, 0x10, 0xde, 0x22, 0x59, 0x88, 0xe1, 0xc5, 0xf9, 0xa9, 0x3f, 0x90, 0xa9, 0x38, 0x7c, + 0x01, 0xf2, 0xd5, 0x21, 0xaa, 0x20, 0xa2, 0x33, 0xe4, 0x74, 0x8c, 0x08, 0x5f, 0xb2, 0x98, 0x2a, + 0xae, 0xbc, 0x92, 0x79, 0x22, 0x23, 0x1f, 0x06, 0x0f, 0x24, 0xc5, 0xca, 0xd5, 0x49, 0x9b, 0x3f, + 0xdb, 0xd2, 0x63, 0x2b, 0x91, 0xdf, 0x54, 0x56, 0xd8, 0x1f, 0x6b, 0x30, 0x9b, 0xc8, 0x26, 0x91, + 0xda, 0xd8, 0xae, 0x92, 0x29, 0xaf, 0xf2, 0x6b, 0x93, 0x33, 0x3c, 0x73, 0x07, 0x48, 0x74, 0x52, + 0x5d, 0x0a, 0xbe, 0x4f, 0x35, 0xc8, 0xc5, 0x39, 0x9c, 0x91, 0xbb, 0xb2, 0x3f, 0x8f, 0x35, 0x72, + 0x57, 0x0e, 0xa4, 0x85, 0xf4, 0x12, 0x62, 0x22, 0x7a, 0xcf, 0x1a, 0xb2, 0xb6, 0xe5, 0xdd, 0xd0, + 0xae, 0x92, 0x6f, 0xe3, 0x89, 0xdd, 0xd8, 0x1d, 0x6d, 0x0f, 0x13, 0x37, 0xb9, 0xe5, 0x51, 0xa7, + 0x94, 0x7a, 0x9d, 0x3f, 0xc4, 0x30, 0x31, 0x14, 0xa4, 0xa8, 0xe0, 0x3b, 0x1a, 0xcc, 0xc8, 0xbb, + 0xda, 0x91, 0x87, 0x71, 0xf2, 0x3e, 0x77, 0x72, 0x08, 0x3a, 0x42, 0x38, 0xa7, 0x9c, 0xc4, 0x6d, + 0x21, 0xa9, 0x0f, 0x43, 0xf4, 0x02, 0x72, 0x14, 0x86, 0xe4, 0x25, 0xf1, 0x71, 0x30, 0xb4, 0x84, + 0x24, 0x05, 0xc3, 0xef, 0x73, 0x3b, 0xa3, 0x5c, 0xe0, 0x8f, 0xde, 0xd5, 0x83, 0x2f, 0x03, 0x46, + 0xef, 0xea, 0x21, 0x2f, 0x03, 0xf4, 0x8b, 0x88, 0xea, 0x6b, 0xe4, 0xac, 0xb2, 0xab, 0x9b, 0x78, + 0xf5, 0xdf, 0xe7, 0x2b, 0x49, 0xee, 0x91, 0xaa, 0x49, 0xbe, 0x14, 0x28, 0x5f, 0x1f, 0xdd, 0xb4, + 0xef, 0x9d, 0x84, 0x7e, 0x15, 0xa1, 0xbc, 0x4c, 0xf4, 0x11, 0x50, 0x6a, 0x9f, 0x70, 0xc2, 0x53, + 0xf2, 0x6d, 0x48, 0xdd, 0xf7, 0x9b, 0x6c, 0xa4, 0xdf, 0xa2, 0x3c, 0x17, 0x39, 0x2a, 0x94, 0x61, + 0xb6, 0xae, 0xa9, 0x6a, 0xe4, 0x77, 0x35, 0x7c, 0x34, 0xdd, 0x0b, 0xf1, 0x47, 0xda, 0x94, 0x61, + 0x09, 0xce, 0x91, 0x36, 0x65, 0x68, 0xf6, 0x40, 0x3f, 0x8f, 0xa8, 0x4a, 0xe4, 0x94, 0xba, 0x8a, + 0x79, 0x3b, 0x79, 0x33, 0xfb, 0x14, 0xd2, 0xe2, 0x00, 0xbd, 0x3c, 0x3e, 0x76, 0x1b, 0xef, 0x40, + 0x26, 0x8f, 0xcb, 0x67, 0xb8, 0x34, 0xea, 0x21, 0xc9, 0xc3, 0x1d, 0x35, 0xe2, 0x22, 0x93, 0x3e, + 0x43, 0x9c, 0xc8, 0xd9, 0x1f, 0x12, 0x11, 0x0e, 0x59, 0x31, 0xfd, 0xa0, 0x6a, 0x8d, 0x96, 0xfd, + 0x04, 0xc1, 0xfc, 0xa1, 0x06, 0x79, 0x25, 0xcc, 0x1b, 0x79, 0x3a, 0x0d, 0x86, 0x83, 0xc3, 0x66, + 0x2b, 0xf1, 0x77, 0x6e, 0x0a, 0x8f, 0x41, 0xdb, 0x7e, 0x10, 0xea, 0x97, 0x10, 0xdc, 0x05, 0x72, + 0xbe, 0xe7, 0xfd, 0xf7, 0x18, 0x92, 0xe6, 0x3f, 0x23, 0x02, 0xb1, 0x31, 0xc6, 0x57, 0x89, 0x39, + 0x47, 0x3a, 0xa3, 0xc9, 0xa8, 0x6e, 0xa8, 0xf9, 0xe5, 0x0d, 0x7a, 0x10, 0x56, 0xf5, 0xcf, 0xff, + 0xeb, 0xfc, 0x89, 0xcf, 0x0f, 0xcf, 0x6b, 0xff, 0x7c, 0x78, 0x5e, 0xfb, 0xb7, 0xc3, 0xf3, 0xda, + 0x7f, 0x1e, 0x9e, 0xd7, 0xbe, 0xff, 0xdf, 0xe7, 0x4f, 0x7c, 0x94, 0x8d, 0xa4, 0xd6, 0x33, 0x78, + 0x93, 0xf9, 0xf5, 0xff, 0x0f, 0x00, 0x00, 0xff, 0xff, 0xcf, 0x9f, 0x48, 0xb4, 0x5a, 0x38, 0x00, 0x00, } diff --git a/pkg/server/serverpb/status.pb.gw.go b/pkg/server/serverpb/status.pb.gw.go index a6f9204972a8..dece4a492d10 100644 --- a/pkg/server/serverpb/status.pb.gw.go +++ b/pkg/server/serverpb/status.pb.gw.go @@ -689,6 +689,33 @@ func request_Status_Diagnostics_0(ctx context.Context, marshaler runtime.Marshal } +func request_Status_Stores_0(ctx context.Context, marshaler runtime.Marshaler, client StatusClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq StoresRequest + var metadata runtime.ServerMetadata + + var ( + val string + ok bool + err error + _ = err + ) + + val, ok = pathParams["node_id"] + if !ok { + return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "node_id") + } + + protoReq.NodeId, err = runtime.String(val) + + if err != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "node_id", err) + } + + msg, err := client.Stores(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + // RegisterStatusHandlerFromEndpoint is same as RegisterStatusHandler but // automatically dials to "endpoint" and closes the connection when "ctx" gets done. func RegisterStatusHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { @@ -1452,6 +1479,35 @@ func RegisterStatusHandlerClient(ctx context.Context, mux *runtime.ServeMux, cli }) + mux.Handle("GET", pattern_Status_Stores_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + if cn, ok := w.(http.CloseNotifier); ok { + go func(done <-chan struct{}, closed <-chan bool) { + select { + case <-done: + case <-closed: + cancel() + } + }(ctx.Done(), cn.CloseNotify()) + } + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_Status_Stores_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_Status_Stores_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + return nil } @@ -1505,6 +1561,8 @@ var ( pattern_Status_CommandQueue_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2, 2, 3}, []string{"_status", "range", "range_id", "cmdqueue"}, "")) pattern_Status_Diagnostics_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"_status", "diagnostics", "node_id"}, "")) + + pattern_Status_Stores_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"_status", "stores", "node_id"}, "")) ) var ( @@ -1557,4 +1615,6 @@ var ( forward_Status_CommandQueue_0 = runtime.ForwardResponseMessage forward_Status_Diagnostics_0 = runtime.ForwardResponseMessage + + forward_Status_Stores_0 = runtime.ForwardResponseMessage ) diff --git a/pkg/server/serverpb/status.proto b/pkg/server/serverpb/status.proto index 38d8eade7b82..947332e433ea 100644 --- a/pkg/server/serverpb/status.proto +++ b/pkg/server/serverpb/status.proto @@ -34,16 +34,14 @@ import "google/api/annotations.proto"; import "google/protobuf/timestamp.proto"; message CertificatesRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; } message CertificateDetails { - // We use an enum to allow reporting of client certs and potential others (eg: UI). + // We use an enum to allow reporting of client certs and potential others (eg: + // UI). enum CertificateType { CA = 0; NODE = 1; @@ -64,20 +62,18 @@ message CertificateDetails { CertificateType type = 1; // "error_message" and "data" are mutually exclusive. string error_message = 2; - // data is the raw file contents of the certificate. This means PEM-encoded DER data. + // data is the raw file contents of the certificate. This means PEM-encoded + // DER data. bytes data = 3; - repeated Fields fields = 4 [(gogoproto.nullable) = false]; + repeated Fields fields = 4 [ (gogoproto.nullable) = false ]; } message CertificatesResponse { - repeated CertificateDetails certificates = 1 [(gogoproto.nullable) = false]; + repeated CertificateDetails certificates = 1 [ (gogoproto.nullable) = false ]; } // DetailsRequest requests a nodes details. message DetailsRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; @@ -87,23 +83,22 @@ message DetailsRequest { } message DetailsResponse { - int32 node_id = 1 [(gogoproto.customname) = "NodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID"]; - util.UnresolvedAddr address = 2 [(gogoproto.nullable) = false]; - build.Info build_info = 3 [(gogoproto.nullable) = false]; + int32 node_id = 1 [ + (gogoproto.customname) = "NodeID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + ]; + util.UnresolvedAddr address = 2 [ (gogoproto.nullable) = false ]; + build.Info build_info = 3 [ (gogoproto.nullable) = false ]; } -message NodesRequest { -} +message NodesRequest {} message NodesResponse { - repeated status.NodeStatus nodes = 1 [(gogoproto.nullable) = false]; + repeated status.NodeStatus nodes = 1 [ (gogoproto.nullable) = false ]; } message NodeRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; @@ -120,8 +115,8 @@ message RaftState { uint64 pending_snapshot = 5; } - uint64 replica_id = 1 [(gogoproto.customname) = "ReplicaID"]; - raftpb.HardState hard_state = 2 [(gogoproto.nullable) = false]; + uint64 replica_id = 1 [ (gogoproto.customname) = "ReplicaID" ]; + raftpb.HardState hard_state = 2 [ (gogoproto.nullable) = false ]; // Lead is part of Raft's SoftState. uint64 lead = 3; // State is part of Raft's SoftState. @@ -129,16 +124,16 @@ message RaftState { // are issues associated with them. string state = 4; uint64 applied = 5; - map progress = 6 [(gogoproto.nullable) = false]; + map progress = 6 [ (gogoproto.nullable) = false ]; uint64 lead_transferee = 7; } message RangeProblems { - bool unavailable = 1; - bool leader_not_lease_holder = 2; - bool no_raft_leader = 3; - bool underreplicated = 4; - bool no_lease = 5; + bool unavailable = 1; + bool leader_not_lease_holder = 2; + bool no_raft_leader = 3; + bool underreplicated = 4; + bool no_lease = 5; } message RangeStatistics { @@ -163,46 +158,45 @@ message CommandQueueMetrics { } message RangeInfo { - PrettySpan span = 1 [(gogoproto.nullable) = false]; - RaftState raft_state = 2 [(gogoproto.nullable) = false]; - storage.storagebase.RangeInfo state = 4 [(gogoproto.nullable) = false]; + PrettySpan span = 1 [ (gogoproto.nullable) = false ]; + RaftState raft_state = 2 [ (gogoproto.nullable) = false ]; + storage.storagebase.RangeInfo state = 4 [ (gogoproto.nullable) = false ]; int32 source_node_id = 5 [ (gogoproto.customname) = "SourceNodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" ]; int32 source_store_id = 6 [ - (gogoproto.customname) = "SourceStoreID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.StoreID" + (gogoproto.customname) = "SourceStoreID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.StoreID" ]; string error_message = 7; - repeated roachpb.Lease lease_history = 8 [(gogoproto.nullable) = false]; - RangeProblems problems = 9 [(gogoproto.nullable) = false]; - RangeStatistics stats = 10 [(gogoproto.nullable) = false]; - CommandQueueMetrics cmd_q_local = 11 [(gogoproto.nullable) = false]; - CommandQueueMetrics cmd_q_global = 12 [(gogoproto.nullable) = false]; - storage.LeaseStatus lease_status = 13 [(gogoproto.nullable) = false]; + repeated roachpb.Lease lease_history = 8 [ (gogoproto.nullable) = false ]; + RangeProblems problems = 9 [ (gogoproto.nullable) = false ]; + RangeStatistics stats = 10 [ (gogoproto.nullable) = false ]; + CommandQueueMetrics cmd_q_local = 11 [ (gogoproto.nullable) = false ]; + CommandQueueMetrics cmd_q_global = 12 [ (gogoproto.nullable) = false ]; + storage.LeaseStatus lease_status = 13 [ (gogoproto.nullable) = false ]; bool quiescent = 14; } message RangesRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; - repeated int64 range_ids = 2 [(gogoproto.customname) = "RangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID"]; + repeated int64 range_ids = 2 [ + (gogoproto.customname) = "RangeIDs", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + ]; } message RangesResponse { - repeated RangeInfo ranges = 1 [(gogoproto.nullable) = false]; + repeated RangeInfo ranges = 1 [ (gogoproto.nullable) = false ]; } message GossipRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; @@ -210,48 +204,47 @@ message GossipRequest { message AllocatorDryRun { message Event { - google.protobuf.Timestamp time = 1 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + google.protobuf.Timestamp time = 1 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; string message = 2; } - int64 range_id = 1 [(gogoproto.customname) = "RangeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID"]; + int64 range_id = 1 [ + (gogoproto.customname) = "RangeID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + ]; repeated Event events = 2; } message AllocatorRangeRequest { - // TODO(tamird): use [(gogoproto.customname) = "RangeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. int64 range_id = 1; } message AllocatorRangeResponse { // The NodeID of the store whose dry run is returned. Only the leaseholder // for a given range will do an allocator dry run for it. - int64 node_id = 1 [(gogoproto.customname) = "NodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID"]; + int64 node_id = 1 [ + (gogoproto.customname) = "NodeID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + ]; AllocatorDryRun dry_run = 2; } message AllocatorRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. string node_id = 1; - repeated int64 range_ids = 2 [(gogoproto.customname) = "RangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID"]; + repeated int64 range_ids = 2 [ + (gogoproto.customname) = "RangeIDs", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + ]; } -message AllocatorResponse { - repeated AllocatorDryRun dry_runs = 1; -} +message AllocatorResponse { repeated AllocatorDryRun dry_runs = 1; } -message JSONResponse { - bytes data = 1; -} +message JSONResponse { bytes data = 1; } message LogsRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; @@ -263,26 +256,22 @@ message LogsRequest { } message LogEntriesResponse { - repeated cockroach.util.log.Entry entries = 1 [(gogoproto.nullable) = false]; + repeated cockroach.util.log.Entry entries = 1 + [ (gogoproto.nullable) = false ]; } message LogFilesListRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; } message LogFilesListResponse { - repeated cockroach.util.log.FileInfo files = 1 [(gogoproto.nullable) = false]; + repeated cockroach.util.log.FileInfo files = 1 + [ (gogoproto.nullable) = false ]; } message LogFileRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; @@ -290,74 +279,74 @@ message LogFileRequest { } message StacksRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; } message ProfileRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; - enum Type { - HEAP = 0; - } + enum Type { HEAP = 0; } // The type of profile to retrieve. Type type = 5; } message MetricsRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; } message RaftRangeNode { - int32 node_id = 1 [(gogoproto.customname) = "NodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID"]; - RangeInfo range = 2 [(gogoproto.nullable) = false]; + int32 node_id = 1 [ + (gogoproto.customname) = "NodeID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + ]; + RangeInfo range = 2 [ (gogoproto.nullable) = false ]; } -message RaftRangeError { - string message = 1; -} +message RaftRangeError { string message = 1; } message RaftRangeStatus { - int64 range_id = 1 [(gogoproto.customname) = "RangeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID"]; - repeated RaftRangeError errors = 2 [(gogoproto.nullable) = false]; - repeated RaftRangeNode nodes = 3 [(gogoproto.nullable) = false]; + int64 range_id = 1 [ + (gogoproto.customname) = "RangeID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + ]; + repeated RaftRangeError errors = 2 [ (gogoproto.nullable) = false ]; + repeated RaftRangeNode nodes = 3 [ (gogoproto.nullable) = false ]; } message RaftDebugRequest { - repeated int64 range_ids = 1 [(gogoproto.customname) = "RangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID"]; + repeated int64 range_ids = 1 [ + (gogoproto.customname) = "RangeIDs", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + ]; } message RaftDebugResponse { - map ranges = 1 [(gogoproto.nullable) = false, - (gogoproto.castkey) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID"]; - repeated RaftRangeError errors = 2 [(gogoproto.nullable) = false]; + map ranges = 1 [ + (gogoproto.nullable) = false, + (gogoproto.castkey) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + ]; + repeated RaftRangeError errors = 2 [ (gogoproto.nullable) = false ]; } // ActiveQuery represents a query in flight on some Session. message ActiveQuery { // ID of the query (uint128 presented as a hexadecimal string). - string id = 1 [(gogoproto.customname) = "ID"]; + string id = 1 [ (gogoproto.customname) = "ID" ]; // SQL query string specified by the user. string sql = 2; // Start timestamp of this query. - google.protobuf.Timestamp start = 3 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + google.protobuf.Timestamp start = 3 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; // True if this query is distributed. bool is_distributed = 4; @@ -379,8 +368,11 @@ message ListSessionsRequest { // Session represents one SQL session. message Session { // ID of node where this session exists. - int32 node_id = 1 [(gogoproto.customname) = "NodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID"]; + int32 node_id = 1 [ + (gogoproto.customname) = "NodeID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + ]; // Username of the user for this session. string username = 2; // Connected client's IP address and port. @@ -388,24 +380,31 @@ message Session { // Application name specified by the client. string application_name = 4; // Queries in progress on this session. - repeated ActiveQuery active_queries = 5 [(gogoproto.nullable) = false]; + repeated ActiveQuery active_queries = 5 [ (gogoproto.nullable) = false ]; // Timestamp of session's start. - google.protobuf.Timestamp start = 6 [(gogoproto.nullable) = false, (gogoproto.stdtime) = true]; + google.protobuf.Timestamp start = 6 + [ (gogoproto.nullable) = false, (gogoproto.stdtime) = true ]; // ID of the current KV transaction for this session. Nil if the session // doesn't currently have a transaction. - bytes kv_txn_id = 7 [(gogoproto.customname) = "KvTxnID", - (gogoproto.customtype) = "github.com/cockroachdb/cockroach/pkg/util/uuid.UUID"]; + bytes kv_txn_id = 7 [ + (gogoproto.customname) = "KvTxnID", + (gogoproto.customtype) = + "github.com/cockroachdb/cockroach/pkg/util/uuid.UUID" + ]; // SQL string of the last query executed on this session. string last_active_query = 8; // ID of the session (uint128 represented as raw bytes). - bytes id = 9 [(gogoproto.customname) = "ID"]; + bytes id = 9 [ (gogoproto.customname) = "ID" ]; } // An error wrapper object for ListSessionsResponse. message ListSessionsError { // ID of node that was being contacted when this error occurred - int32 node_id = 1 [(gogoproto.customname) = "NodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID"]; + int32 node_id = 1 [ + (gogoproto.customname) = "NodeID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + ]; // Error message. string message = 2; } @@ -413,9 +412,9 @@ message ListSessionsError { // Response object for ListSessions and ListLocalSessions. message ListSessionsResponse { // A list of sessions on this node or cluster. - repeated Session sessions = 1 [(gogoproto.nullable) = false]; + repeated Session sessions = 1 [ (gogoproto.nullable) = false ]; // Any errors that occurred during fan-out calls to other nodes. - repeated ListSessionsError errors = 2 [(gogoproto.nullable) = false]; + repeated ListSessionsError errors = 2 [ (gogoproto.nullable) = false ]; } // Request object for issing a query cancel request. @@ -429,7 +428,7 @@ message CancelQueryRequest { // forwarding is necessary. string node_id = 1; // ID of query to be canceled (converted to string). - string query_id = 2 [(gogoproto.customname) = "QueryID"]; + string query_id = 2 [ (gogoproto.customname) = "QueryID" ]; // Username of the user making this cancellation request. string username = 3; } @@ -449,7 +448,7 @@ message CancelSessionRequest { // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; - bytes session_id = 2 [(gogoproto.customname) = "SessionID"]; + bytes session_id = 2 [ (gogoproto.customname) = "SessionID" ]; string username = 3; } @@ -459,19 +458,23 @@ message CancelSessionResponse { } message SpanStatsRequest { - string node_id = 1 [(gogoproto.customname) = "NodeID"]; - bytes start_key = 2 [(gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RKey"]; - bytes end_key = 3 [(gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RKey"]; + string node_id = 1 [ (gogoproto.customname) = "NodeID" ]; + bytes start_key = 2 + [ (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RKey" ]; + bytes end_key = 3 [ (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RKey" ]; } message SpanStatsResponse { int32 range_count = 2; uint64 approximate_disk_bytes = 3; - cockroach.storage.engine.enginepb.MVCCStats total_stats = 1 [(gogoproto.nullable) = false]; + cockroach.storage.engine.enginepb.MVCCStats total_stats = 1 + [ (gogoproto.nullable) = false ]; } message ProblemRangesRequest { - string node_id = 1 [(gogoproto.customname) = "NodeID"]; + string node_id = 1 [ (gogoproto.customname) = "NodeID" ]; } message ProblemRangesResponse { @@ -479,30 +482,36 @@ message ProblemRangesResponse { string error_message = 1; repeated int64 unavailable_range_ids = 2 [ (gogoproto.customname) = "UnavailableRangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" ]; repeated int64 raft_leader_not_lease_holder_range_ids = 3 [ (gogoproto.customname) = "RaftLeaderNotLeaseHolderRangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" ]; repeated int64 no_raft_leader_range_ids = 4 [ (gogoproto.customname) = "NoRaftLeaderRangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" ]; repeated int64 no_lease_range_ids = 5 [ (gogoproto.customname) = "NoLeaseRangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" ]; repeated int64 underreplicated_range_ids = 6 [ (gogoproto.customname) = "UnderreplicatedRangeIDs", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" ]; } reserved 1 to 7; // NodeID is the node that submitted all the requests. int32 node_id = 8 [ (gogoproto.customname) = "NodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" ]; map problems_by_node_id = 9 [ (gogoproto.castkey) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID", @@ -512,8 +521,6 @@ message ProblemRangesResponse { } message RangeRequest { - // TODO(tamird): use [(gogoproto.customname) = "RangeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. int64 range_id = 1; } @@ -521,16 +528,18 @@ message RangeResponse { message NodeResponse { bool response = 1; string error_message = 2; - repeated RangeInfo infos = 3 [(gogoproto.nullable) = false]; + repeated RangeInfo infos = 3 [ (gogoproto.nullable) = false ]; } // NodeID is the node that submitted all the requests. int32 node_id = 1 [ (gogoproto.customname) = "NodeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID" ]; int64 range_id = 2 [ (gogoproto.customname) = "RangeID", - (gogoproto.casttype) = "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.RangeID" ]; map responses_by_node_id = 3 [ (gogoproto.castkey) = "github.com/cockroachdb/cockroach/pkg/roachpb.NodeID", @@ -540,91 +549,112 @@ message RangeResponse { reserved 4; // Previously used. } -message CommandQueueRequest { - int64 range_id = 1; -} +message CommandQueueRequest { int64 range_id = 1; } message CommandQueueResponse { - storage.storagebase.CommandQueuesSnapshot snapshot = 1 [(gogoproto.nullable) = false]; + storage.storagebase.CommandQueuesSnapshot snapshot = 1 + [ (gogoproto.nullable) = false ]; } // DiagnosticsRequest requests a diagnostics report. message DiagnosticsRequest { - // TODO(tamird): use [(gogoproto.customname) = "NodeID"] below. Need to - // figure out how to teach grpc-gateway about custom names. - // // node_id is a string so that "local" can be used to specify that no // forwarding is necessary. string node_id = 1; } +message StoresRequest { + // node_id is a string so that "local" can be used to specify that no + // forwarding is necessary. + string node_id = 1; +} + +message StoreDetails { + int32 store_id = 1 [ + (gogoproto.customname) = "StoreID", + (gogoproto.casttype) = + "github.com/cockroachdb/cockroach/pkg/roachpb.StoreID" + ]; + + // TODO(mberhault): add a lot more information about stores. eg: + // - path + // - settings + // - encryption settings + + // encryption_status is a serialized + // ccl/storageccl/engineccl/enginepbccl/stats.go::EncryptionStatus protobuf. + bytes encryption_status = 2; +} + +message StoresResponse { + repeated StoreDetails stores = 1 [ (gogoproto.nullable) = false ]; +} + service Status { rpc Certificates(CertificatesRequest) returns (CertificatesResponse) { option (google.api.http) = { - get: "/_status/certificates/{node_id}" + get : "/_status/certificates/{node_id}" }; } rpc Details(DetailsRequest) returns (DetailsResponse) { option (google.api.http) = { - get: "/_status/details/{node_id}" - additional_bindings { - get: "/health" - } + get : "/_status/details/{node_id}" + additional_bindings {get : "/health"} }; } rpc Nodes(NodesRequest) returns (NodesResponse) { option (google.api.http) = { - get: "/_status/nodes" + get : "/_status/nodes" }; } rpc Node(NodeRequest) returns (status.NodeStatus) { option (google.api.http) = { - get: "/_status/nodes/{node_id}" + get : "/_status/nodes/{node_id}" }; } rpc RaftDebug(RaftDebugRequest) returns (RaftDebugResponse) { option (google.api.http) = { - get: "/_status/raft" + get : "/_status/raft" }; } rpc Ranges(RangesRequest) returns (RangesResponse) { option (google.api.http) = { - get: "/_status/ranges/{node_id}" + get : "/_status/ranges/{node_id}" }; } rpc Gossip(GossipRequest) returns (gossip.InfoStatus) { option (google.api.http) = { - get: "/_status/gossip/{node_id}" + get : "/_status/gossip/{node_id}" }; } rpc Allocator(AllocatorRequest) returns (AllocatorResponse) { option (google.api.http) = { - get: "/_status/allocator/node/{node_id}" + get : "/_status/allocator/node/{node_id}" }; } rpc AllocatorRange(AllocatorRangeRequest) returns (AllocatorRangeResponse) { option (google.api.http) = { - get: "/_status/allocator/range/{range_id}" + get : "/_status/allocator/range/{range_id}" }; } rpc ListSessions(ListSessionsRequest) returns (ListSessionsResponse) { option (google.api.http) = { - get: "/_status/sessions" + get : "/_status/sessions" }; } rpc ListLocalSessions(ListSessionsRequest) returns (ListSessionsResponse) { option (google.api.http) = { - get: "/_status/local_sessions" + get : "/_status/local_sessions" }; } rpc CancelQuery(CancelQueryRequest) returns (CancelQueryResponse) { option (google.api.http) = { - get: "/_status/cancel_query/{node_id}" + get : "/_status/cancel_query/{node_id}" }; } rpc CancelSession(CancelSessionRequest) returns (CancelSessionResponse) { option (google.api.http) = { - get: "/_status/cancel_session/{node_id}" + get : "/_status/cancel_session/{node_id}" }; } @@ -635,58 +665,64 @@ service Status { // information about the resources on a node used by that table. rpc SpanStats(SpanStatsRequest) returns (SpanStatsResponse) { option (google.api.http) = { - post: "/_status/span" - body: "*" + post : "/_status/span" + body : "*" }; } rpc Stacks(StacksRequest) returns (JSONResponse) { option (google.api.http) = { - get: "/_status/stacks/{node_id}" + get : "/_status/stacks/{node_id}" }; } rpc Profile(ProfileRequest) returns (JSONResponse) { option (google.api.http) = { - get: "/_status/profile/{node_id}" + get : "/_status/profile/{node_id}" }; } rpc Metrics(MetricsRequest) returns (JSONResponse) { option (google.api.http) = { - get: "/_status/metrics/{node_id}" + get : "/_status/metrics/{node_id}" }; } rpc LogFilesList(LogFilesListRequest) returns (LogFilesListResponse) { option (google.api.http) = { - get: "/_status/logfiles/{node_id}" + get : "/_status/logfiles/{node_id}" }; } rpc LogFile(LogFileRequest) returns (LogEntriesResponse) { option (google.api.http) = { - get: "/_status/logfiles/{node_id}/{file}" + get : "/_status/logfiles/{node_id}/{file}" }; } rpc Logs(LogsRequest) returns (LogEntriesResponse) { option (google.api.http) = { - get: "/_status/logs/{node_id}" + get : "/_status/logs/{node_id}" }; } rpc ProblemRanges(ProblemRangesRequest) returns (ProblemRangesResponse) { option (google.api.http) = { - get: "/_status/problemranges" + get : "/_status/problemranges" }; } rpc Range(RangeRequest) returns (RangeResponse) { option (google.api.http) = { - get: "/_status/range/{range_id}" + get : "/_status/range/{range_id}" }; } rpc CommandQueue(CommandQueueRequest) returns (CommandQueueResponse) { option (google.api.http) = { - get: "/_status/range/{range_id}/cmdqueue" + get : "/_status/range/{range_id}/cmdqueue" + }; + } + rpc Diagnostics(DiagnosticsRequest) + returns (cockroach.server.diagnosticspb.DiagnosticReport) { + option (google.api.http) = { + get : "/_status/diagnostics/{node_id}" }; } - rpc Diagnostics(DiagnosticsRequest) returns (cockroach.server.diagnosticspb.DiagnosticReport) { + rpc Stores(StoresRequest) returns (StoresResponse) { option (google.api.http) = { - get: "/_status/diagnostics/{node_id}" + get : "/_status/stores/{node_id}" }; } } diff --git a/pkg/server/status.go b/pkg/server/status.go index 1cd3f9654066..aed80ff8b535 100644 --- a/pkg/server/status.go +++ b/pkg/server/status.go @@ -32,6 +32,7 @@ import ( "strings" "sync" + "github.com/cockroachdb/cockroach/pkg/storage/engine" "github.com/coreos/etcd/raft" gwruntime "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/pkg/errors" @@ -1496,6 +1497,53 @@ func (s *statusServer) Diagnostics( return s.admin.server.getReportingInfo(ctx), nil } +// Stores returns details for each store. +func (s *statusServer) Stores( + ctx context.Context, req *serverpb.StoresRequest, +) (*serverpb.StoresResponse, error) { + ctx = propagateGatewayMetadata(ctx) + ctx = s.AnnotateCtx(ctx) + nodeID, local, err := s.parseNodeID(req.NodeId) + if err != nil { + return nil, grpcstatus.Errorf(codes.InvalidArgument, err.Error()) + } + + if !local { + status, err := s.dialNode(ctx, nodeID) + if err != nil { + return nil, err + } + return status.Stores(ctx, req) + } + + resp := &serverpb.StoresResponse{} + err = s.stores.VisitStores(func(store *storage.Store) error { + storeDetails := serverpb.StoreDetails{ + StoreID: store.Ident.StoreID, + } + + // Encryption Status only exists for rocksdb engines. + if rocksdb, ok := store.Engine().(*engine.RocksDB); ok { + envStats, err := rocksdb.GetEnvStats() + if err != nil { + return err + } + + if len(envStats.EncryptionStatus) > 0 { + storeDetails.EncryptionStatus = envStats.EncryptionStatus + } + } + + resp.Stores = append(resp.Stores, storeDetails) + + return nil + }) + if err != nil { + return nil, err + } + return resp, nil +} + // jsonWrapper provides a wrapper on any slice data type being // marshaled to JSON. This prevents a security vulnerability // where a phishing attack can trick a user's browser into diff --git a/pkg/storage/engine/engine.go b/pkg/storage/engine/engine.go index cd4af68039c4..7ef89dd13e5b 100644 --- a/pkg/storage/engine/engine.go +++ b/pkg/storage/engine/engine.go @@ -342,6 +342,12 @@ type Stats struct { PendingCompactionBytesEstimate int64 } +// EnvStats is a set of RocksDB env stats, including encryption status. +type EnvStats struct { + // EncryptionStatus is a serialized enginepbccl/stats.proto::EncryptionStatus protobuf. + EncryptionStatus []byte +} + // PutProto sets the given key to the protobuf-serialized byte string // of msg and the provided timestamp. Returns the length in bytes of // key and the value. diff --git a/pkg/storage/engine/rocksdb.go b/pkg/storage/engine/rocksdb.go index 8b8d8242f513..70287948bc2e 100644 --- a/pkg/storage/engine/rocksdb.go +++ b/pkg/storage/engine/rocksdb.go @@ -1137,6 +1137,18 @@ func (r *RocksDB) GetCompactionStats() string { return cStringToGoString(C.DBGetCompactionStats(r.rdb)) } +// GetEnvStats returns stats for the RocksDB env. This may include encryption stats. +func (r *RocksDB) GetEnvStats() (*EnvStats, error) { + var s C.DBEnvStatsResult + if err := statusToError(C.DBGetEnvStats(r.rdb, &s)); err != nil { + return nil, err + } + + return &EnvStats{ + EncryptionStatus: cStringToGoBytes(s.encryption_status), + }, nil +} + type rocksDBSnapshot struct { parent *RocksDB handle *C.DBEngine