[hal,wpilib] Switch to new game data (#8584)

Game data is now limited to 8 bytes, and comes through the UDP packets.
This commit is contained in:
Thad House
2026-02-06 21:38:15 -08:00
committed by GitHub
parent ac45c694f3
commit 85adbf990e
45 changed files with 820 additions and 695 deletions

View File

@@ -81,12 +81,12 @@ void wpi::glass::DisplayFMS(FMSModel* model, bool editableDsAttached) {
}
}
// Game Specific Message
if (auto data = model->GetGameSpecificMessageData()) {
std::string gameSpecificMessage = data->GetValue();
// Game Data
if (auto data = model->GetGameData()) {
std::string gameData = data->GetValue();
ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
if (ImGui::InputText("Game Specific", &gameSpecificMessage)) {
model->SetGameSpecificMessage(gameSpecificMessage);
if (ImGui::InputText("Game Data", &gameData)) {
model->SetGameData(gameData);
}
}
}
@@ -145,14 +145,13 @@ void wpi::glass::DisplayFMSReadOnly(FMSModel* model) {
ImGui::TextUnformatted("?");
}
}
if (auto data = model->GetGameSpecificMessageData()) {
if (auto data = model->GetGameData()) {
if (exists) {
wpi::util::SmallString<64> gsmBuf;
std::string_view gsm = data->GetValue(gsmBuf);
ImGui::Text("Game Specific: %.*s", static_cast<int>(gsm.size()),
gsm.data());
ImGui::Text("Game Data: %.*s", static_cast<int>(gsm.size()), gsm.data());
} else {
ImGui::TextUnformatted("Game Specific: ?");
ImGui::TextUnformatted("Game Data: ?");
}
}

View File

@@ -36,7 +36,7 @@ class FMSModel : public Model {
virtual BooleanSource* GetEStopData() = 0;
virtual BooleanSource* GetEnabledData() = 0;
virtual IntegerSource* GetRobotModeData() = 0;
virtual StringSource* GetGameSpecificMessageData() = 0;
virtual StringSource* GetGameData() = 0;
virtual void SetFmsAttached(bool val) = 0;
virtual void SetDsAttached(bool val) = 0;
@@ -45,7 +45,7 @@ class FMSModel : public Model {
virtual void SetEStop(bool val) = 0;
virtual void SetEnabled(bool val) = 0;
virtual void SetRobotMode(RobotMode val) = 0;
virtual void SetGameSpecificMessage(std::string_view val) = 0;
virtual void SetGameData(std::string_view val) = 0;
};
/**

View File

@@ -30,9 +30,8 @@ NTFMSModel::NTFMSModel(std::string_view path)
NTFMSModel::NTFMSModel(wpi::nt::NetworkTableInstance inst,
std::string_view path)
: m_inst{inst},
m_gameSpecificMessage{
inst.GetStringTopic(fmt::format("{}/GameSpecificMessage", path))
.Subscribe("")},
m_gameDataSubscriber{
inst.GetStringTopic(fmt::format("{}/GameData", path)).Subscribe("")},
m_alliance{inst.GetBooleanTopic(fmt::format("{}/IsRedAlliance", path))
.Subscribe(false)},
m_station{inst.GetIntegerTopic(fmt::format("{}/StationNumber", path))
@@ -45,8 +44,7 @@ NTFMSModel::NTFMSModel(wpi::nt::NetworkTableInstance inst,
m_estop{fmt::format("NT_FMS:EStop:{}", path)},
m_enabled{fmt::format("NT_FMS:RobotEnabled:{}", path)},
m_robotMode{fmt::format("NT_FMS:RobotMode:{}", path)},
m_gameSpecificMessageData{
fmt::format("NT_FMS:GameSpecificMessage:{}", path)} {}
m_gameData{fmt::format("NT_FMS:GameData:{}", path)} {}
void NTFMSModel::Update() {
for (auto&& v : m_alliance.ReadQueue()) {
@@ -82,8 +80,8 @@ void NTFMSModel::Update() {
((controlWord & HAL_CONTROLWORD_DS_ATTACHED_MASK) != 0) ? 1 : 0,
v.time);
}
for (auto&& v : m_gameSpecificMessage.ReadQueue()) {
m_gameSpecificMessageData.SetValue(std::move(v.value), v.time);
for (auto&& v : m_gameDataSubscriber.ReadQueue()) {
m_gameData.SetValue(std::move(v.value), v.time);
}
}

View File

@@ -34,9 +34,7 @@ class NTFMSModel : public FMSModel {
BooleanSource* GetEStopData() override { return &m_estop; }
BooleanSource* GetEnabledData() override { return &m_enabled; }
IntegerSource* GetRobotModeData() override { return &m_robotMode; }
StringSource* GetGameSpecificMessageData() override {
return &m_gameSpecificMessageData;
}
StringSource* GetGameData() override { return &m_gameData; }
// NT is read-only (it's continually set by robot code)
void SetFmsAttached(bool val) override {}
@@ -46,7 +44,7 @@ class NTFMSModel : public FMSModel {
void SetEStop(bool val) override {}
void SetEnabled(bool val) override {}
void SetRobotMode(RobotMode val) override {}
void SetGameSpecificMessage(std::string_view val) override {}
void SetGameData(std::string_view val) override {}
void Update() override;
bool Exists() override;
@@ -54,7 +52,7 @@ class NTFMSModel : public FMSModel {
private:
wpi::nt::NetworkTableInstance m_inst;
wpi::nt::StringSubscriber m_gameSpecificMessage;
wpi::nt::StringSubscriber m_gameDataSubscriber;
wpi::nt::BooleanSubscriber m_alliance;
wpi::nt::IntegerSubscriber m_station;
wpi::nt::RawSubscriber m_controlWord;
@@ -65,7 +63,7 @@ class NTFMSModel : public FMSModel {
BooleanSource m_estop;
BooleanSource m_enabled;
IntegerSource m_robotMode;
StringSource m_gameSpecificMessageData;
StringSource m_gameData;
};
} // namespace wpi::glass

View File

@@ -172,6 +172,7 @@ def wpihal_extension(srcs = [], header_to_dat_deps = [], extra_hdrs = [], includ
("HAL_JoystickTouchpads", "__HAL_JoystickTouchpads.hpp"),
("HAL_OpModeOption", "__HAL_OpModeOption.hpp"),
("wpi::hal::ControlWord", "wpi__hal__ControlWord.hpp"),
("HAL_GameData", "__HAL_GameData.hpp"),
],
),
struct(

View File

@@ -56,7 +56,7 @@ static const uint8_t file_descriptor[] {
0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x54,0x6f,
0x75,0x63,0x68,0x70,0x61,0x64,0x44,0x61,0x74,0x61,
0x52,0x09,0x54,0x6f,0x75,0x63,0x68,0x70,0x61,0x64,
0x73,0x22,0xba,0x01,0x0a,0x13,0x50,0x72,0x6f,0x74,
0x73,0x22,0xd6,0x01,0x0a,0x13,0x50,0x72,0x6f,0x74,
0x6f,0x62,0x75,0x66,0x43,0x6f,0x6e,0x74,0x72,0x6f,
0x6c,0x44,0x61,0x74,0x61,0x12,0x20,0x0a,0x0b,0x43,
0x6f,0x6e,0x74,0x72,0x6f,0x6c,0x57,0x6f,0x72,0x64,
@@ -75,467 +75,475 @@ static const uint8_t file_descriptor[] {
0x65,0x6e,0x74,0x4f,0x70,0x4d,0x6f,0x64,0x65,0x18,
0x04,0x20,0x01,0x28,0x06,0x52,0x0d,0x43,0x75,0x72,
0x72,0x65,0x6e,0x74,0x4f,0x70,0x4d,0x6f,0x64,0x65,
0x22,0xac,0x01,0x0a,0x1a,0x50,0x72,0x6f,0x74,0x6f,
0x62,0x75,0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,
0x6b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x6f,
0x72,0x12,0x22,0x0a,0x0c,0x4a,0x6f,0x79,0x73,0x74,
0x69,0x63,0x6b,0x4e,0x61,0x6d,0x65,0x18,0x01,0x20,
0x01,0x28,0x09,0x52,0x0c,0x4a,0x6f,0x79,0x73,0x74,
0x69,0x63,0x6b,0x4e,0x61,0x6d,0x65,0x12,0x1c,0x0a,
0x09,0x49,0x73,0x47,0x61,0x6d,0x65,0x70,0x61,0x64,
0x18,0x02,0x20,0x01,0x28,0x08,0x52,0x09,0x49,0x73,
0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x12,0x20,0x0a,
0x0b,0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x54,0x79,
0x70,0x65,0x18,0x03,0x20,0x01,0x28,0x0d,0x52,0x0b,
0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x54,0x79,0x70,
0x65,0x12,0x2a,0x0a,0x10,0x53,0x75,0x70,0x70,0x6f,
0x72,0x74,0x65,0x64,0x4f,0x75,0x74,0x70,0x75,0x74,
0x73,0x18,0x04,0x20,0x01,0x28,0x0d,0x52,0x10,0x53,
0x75,0x70,0x70,0x6f,0x72,0x74,0x65,0x64,0x4f,0x75,
0x74,0x70,0x75,0x74,0x73,0x22,0x66,0x0a,0x1b,0x50,
0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79,
0x73,0x74,0x69,0x63,0x6b,0x44,0x65,0x73,0x63,0x72,
0x69,0x70,0x74,0x6f,0x72,0x73,0x12,0x47,0x0a,0x0b,
0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72,
0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32,0x25,0x2e,
0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x2e,
0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,
0x79,0x73,0x74,0x69,0x63,0x6b,0x44,0x65,0x73,0x63,
0x72,0x69,0x70,0x74,0x6f,0x72,0x52,0x0b,0x44,0x65,
0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72,0x73,0x22,
0x6a,0x0a,0x16,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,
0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x4f,
0x75,0x74,0x70,0x75,0x74,0x12,0x12,0x0a,0x04,0x4c,
0x45,0x44,0x73,0x18,0x01,0x20,0x01,0x28,0x0d,0x52,
0x04,0x4c,0x45,0x44,0x73,0x12,0x16,0x0a,0x06,0x52,
0x75,0x6d,0x62,0x6c,0x65,0x18,0x02,0x20,0x01,0x28,
0x0d,0x52,0x06,0x52,0x75,0x6d,0x62,0x6c,0x65,0x12,
0x24,0x0a,0x0d,0x54,0x72,0x69,0x67,0x67,0x65,0x72,
0x52,0x75,0x6d,0x62,0x6c,0x65,0x18,0x03,0x20,0x01,
0x28,0x0d,0x52,0x0d,0x54,0x72,0x69,0x67,0x67,0x65,
0x72,0x52,0x75,0x6d,0x62,0x6c,0x65,0x22,0x56,0x0a,
0x17,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,
0x12,0x1a,0x0a,0x08,0x47,0x61,0x6d,0x65,0x44,0x61,
0x74,0x61,0x18,0x06,0x20,0x01,0x28,0x09,0x52,0x08,
0x47,0x61,0x6d,0x65,0x44,0x61,0x74,0x61,0x22,0xac,
0x01,0x0a,0x1a,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,
0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x44,
0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72,0x12,
0x22,0x0a,0x0c,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,
0x6b,0x4e,0x61,0x6d,0x65,0x18,0x01,0x20,0x01,0x28,
0x09,0x52,0x0c,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,
0x6b,0x4e,0x61,0x6d,0x65,0x12,0x1c,0x0a,0x09,0x49,
0x73,0x47,0x61,0x6d,0x65,0x70,0x61,0x64,0x18,0x02,
0x20,0x01,0x28,0x08,0x52,0x09,0x49,0x73,0x47,0x61,
0x6d,0x65,0x70,0x61,0x64,0x12,0x20,0x0a,0x0b,0x47,
0x61,0x6d,0x65,0x70,0x61,0x64,0x54,0x79,0x70,0x65,
0x18,0x03,0x20,0x01,0x28,0x0d,0x52,0x0b,0x47,0x61,
0x6d,0x65,0x70,0x61,0x64,0x54,0x79,0x70,0x65,0x12,
0x2a,0x0a,0x10,0x53,0x75,0x70,0x70,0x6f,0x72,0x74,
0x65,0x64,0x4f,0x75,0x74,0x70,0x75,0x74,0x73,0x18,
0x04,0x20,0x01,0x28,0x0d,0x52,0x10,0x53,0x75,0x70,
0x70,0x6f,0x72,0x74,0x65,0x64,0x4f,0x75,0x74,0x70,
0x75,0x74,0x73,0x22,0x66,0x0a,0x1b,0x50,0x72,0x6f,
0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79,0x73,0x74,
0x69,0x63,0x6b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,
0x74,0x6f,0x72,0x73,0x12,0x47,0x0a,0x0b,0x44,0x65,
0x73,0x63,0x72,0x69,0x70,0x74,0x6f,0x72,0x73,0x18,
0x01,0x20,0x03,0x28,0x0b,0x32,0x25,0x2e,0x6d,0x72,
0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x2e,0x50,0x72,
0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79,0x73,
0x74,0x69,0x63,0x6b,0x44,0x65,0x73,0x63,0x72,0x69,
0x70,0x74,0x6f,0x72,0x52,0x0b,0x44,0x65,0x73,0x63,
0x72,0x69,0x70,0x74,0x6f,0x72,0x73,0x22,0x6a,0x0a,
0x16,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,
0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x4f,0x75,0x74,
0x70,0x75,0x74,0x73,0x12,0x3b,0x0a,0x07,0x4f,0x75,
0x74,0x70,0x75,0x74,0x73,0x18,0x01,0x20,0x03,0x28,
0x0b,0x32,0x21,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72,
0x6f,0x74,0x6f,0x2e,0x50,0x72,0x6f,0x74,0x6f,0x62,
0x75,0x66,0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,
0x4f,0x75,0x74,0x70,0x75,0x74,0x52,0x07,0x4f,0x75,
0x74,0x70,0x75,0x74,0x73,0x22,0x95,0x01,0x0a,0x11,
0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4d,0x61,
0x74,0x63,0x68,0x49,0x6e,0x66,0x6f,0x12,0x1c,0x0a,
0x09,0x45,0x76,0x65,0x6e,0x74,0x4e,0x61,0x6d,0x65,
0x18,0x01,0x20,0x01,0x28,0x09,0x52,0x09,0x45,0x76,
0x65,0x6e,0x74,0x4e,0x61,0x6d,0x65,0x12,0x20,0x0a,
0x0b,0x4d,0x61,0x74,0x63,0x68,0x4e,0x75,0x6d,0x62,
0x65,0x72,0x18,0x02,0x20,0x01,0x28,0x05,0x52,0x0b,
0x4d,0x61,0x74,0x63,0x68,0x4e,0x75,0x6d,0x62,0x65,
0x72,0x12,0x22,0x0a,0x0c,0x52,0x65,0x70,0x6c,0x61,
0x79,0x4e,0x75,0x6d,0x62,0x65,0x72,0x18,0x03,0x20,
0x01,0x28,0x05,0x52,0x0c,0x52,0x65,0x70,0x6c,0x61,
0x79,0x4e,0x75,0x6d,0x62,0x65,0x72,0x12,0x1c,0x0a,
0x09,0x4d,0x61,0x74,0x63,0x68,0x54,0x79,0x70,0x65,
0x18,0x04,0x20,0x01,0x28,0x05,0x52,0x09,0x4d,0x61,
0x74,0x63,0x68,0x54,0x79,0x70,0x65,0x22,0x9f,0x01,
0x0a,0x11,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,
0x45,0x72,0x72,0x6f,0x72,0x49,0x6e,0x66,0x6f,0x12,
0x18,0x0a,0x07,0x49,0x73,0x45,0x72,0x72,0x6f,0x72,
0x18,0x01,0x20,0x01,0x28,0x08,0x52,0x07,0x49,0x73,
0x45,0x72,0x72,0x6f,0x72,0x12,0x1c,0x0a,0x09,0x45,
0x72,0x72,0x6f,0x72,0x43,0x6f,0x64,0x65,0x18,0x02,
0x20,0x01,0x28,0x11,0x52,0x09,0x45,0x72,0x72,0x6f,
0x72,0x43,0x6f,0x64,0x65,0x12,0x18,0x0a,0x07,0x44,
0x65,0x74,0x61,0x69,0x6c,0x73,0x18,0x03,0x20,0x01,
0x28,0x09,0x52,0x07,0x44,0x65,0x74,0x61,0x69,0x6c,
0x73,0x12,0x1a,0x0a,0x08,0x4c,0x6f,0x63,0x61,0x74,
0x69,0x6f,0x6e,0x18,0x04,0x20,0x01,0x28,0x09,0x52,
0x08,0x4c,0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x12,
0x1c,0x0a,0x09,0x43,0x61,0x6c,0x6c,0x53,0x74,0x61,
0x63,0x6b,0x18,0x05,0x20,0x01,0x28,0x09,0x52,0x09,
0x43,0x61,0x6c,0x6c,0x53,0x74,0x61,0x63,0x6b,0x22,
0xb8,0x01,0x0a,0x0e,0x50,0x72,0x6f,0x74,0x6f,0x62,
0x75,0x66,0x4f,0x70,0x4d,0x6f,0x64,0x65,0x12,0x12,
0x0a,0x04,0x48,0x61,0x73,0x68,0x18,0x01,0x20,0x01,
0x28,0x06,0x52,0x04,0x48,0x61,0x73,0x68,0x12,0x12,
0x0a,0x04,0x4e,0x61,0x6d,0x65,0x18,0x02,0x20,0x01,
0x28,0x09,0x52,0x04,0x4e,0x61,0x6d,0x65,0x12,0x14,
0x0a,0x05,0x47,0x72,0x6f,0x75,0x70,0x18,0x03,0x20,
0x01,0x28,0x09,0x52,0x05,0x47,0x72,0x6f,0x75,0x70,
0x12,0x20,0x0a,0x0b,0x44,0x65,0x73,0x63,0x72,0x69,
0x70,0x74,0x69,0x6f,0x6e,0x18,0x04,0x20,0x01,0x28,
0x09,0x52,0x0b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,
0x74,0x69,0x6f,0x6e,0x12,0x1c,0x0a,0x09,0x54,0x65,
0x78,0x74,0x43,0x6f,0x6c,0x6f,0x72,0x18,0x05,0x20,
0x01,0x28,0x05,0x52,0x09,0x54,0x65,0x78,0x74,0x43,
0x6f,0x6c,0x6f,0x72,0x12,0x28,0x0a,0x0f,0x42,0x61,
0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x43,0x6f,
0x6c,0x6f,0x72,0x18,0x06,0x20,0x01,0x28,0x05,0x52,
0x0f,0x42,0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,
0x64,0x43,0x6f,0x6c,0x6f,0x72,0x22,0x4b,0x0a,0x18,
0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x41,0x76,
0x61,0x69,0x6c,0x61,0x62,0x6c,0x65,0x4f,0x70,0x4d,
0x6f,0x64,0x65,0x73,0x12,0x2f,0x0a,0x05,0x4d,0x6f,
0x64,0x65,0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32,
0x19,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,
0x70,0x75,0x74,0x12,0x12,0x0a,0x04,0x4c,0x45,0x44,
0x73,0x18,0x01,0x20,0x01,0x28,0x0d,0x52,0x04,0x4c,
0x45,0x44,0x73,0x12,0x16,0x0a,0x06,0x52,0x75,0x6d,
0x62,0x6c,0x65,0x18,0x02,0x20,0x01,0x28,0x0d,0x52,
0x06,0x52,0x75,0x6d,0x62,0x6c,0x65,0x12,0x24,0x0a,
0x0d,0x54,0x72,0x69,0x67,0x67,0x65,0x72,0x52,0x75,
0x6d,0x62,0x6c,0x65,0x18,0x03,0x20,0x01,0x28,0x0d,
0x52,0x0d,0x54,0x72,0x69,0x67,0x67,0x65,0x72,0x52,
0x75,0x6d,0x62,0x6c,0x65,0x22,0x56,0x0a,0x17,0x50,
0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4a,0x6f,0x79,
0x73,0x74,0x69,0x63,0x6b,0x4f,0x75,0x74,0x70,0x75,
0x74,0x73,0x12,0x3b,0x0a,0x07,0x4f,0x75,0x74,0x70,
0x75,0x74,0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32,
0x21,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,
0x6f,0x2e,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,
0x4f,0x70,0x4d,0x6f,0x64,0x65,0x52,0x05,0x4d,0x6f,
0x64,0x65,0x73,0x22,0xc6,0x01,0x0a,0x1a,0x50,0x72,
0x6f,0x74,0x6f,0x62,0x75,0x66,0x45,0x72,0x72,0x6f,
0x72,0x49,0x6e,0x66,0x6f,0x54,0x69,0x6d,0x65,0x73,
0x74,0x61,0x6d,0x70,0x12,0x3a,0x0a,0x09,0x45,0x72,
0x72,0x6f,0x72,0x49,0x6e,0x66,0x6f,0x18,0x01,0x20,
0x01,0x28,0x0b,0x32,0x1c,0x2e,0x6d,0x72,0x63,0x2e,
0x70,0x72,0x6f,0x74,0x6f,0x2e,0x50,0x72,0x6f,0x74,
0x4a,0x6f,0x79,0x73,0x74,0x69,0x63,0x6b,0x4f,0x75,
0x74,0x70,0x75,0x74,0x52,0x07,0x4f,0x75,0x74,0x70,
0x75,0x74,0x73,0x22,0x95,0x01,0x0a,0x11,0x50,0x72,
0x6f,0x74,0x6f,0x62,0x75,0x66,0x4d,0x61,0x74,0x63,
0x68,0x49,0x6e,0x66,0x6f,0x12,0x1c,0x0a,0x09,0x45,
0x76,0x65,0x6e,0x74,0x4e,0x61,0x6d,0x65,0x18,0x01,
0x20,0x01,0x28,0x09,0x52,0x09,0x45,0x76,0x65,0x6e,
0x74,0x4e,0x61,0x6d,0x65,0x12,0x20,0x0a,0x0b,0x4d,
0x61,0x74,0x63,0x68,0x4e,0x75,0x6d,0x62,0x65,0x72,
0x18,0x02,0x20,0x01,0x28,0x05,0x52,0x0b,0x4d,0x61,
0x74,0x63,0x68,0x4e,0x75,0x6d,0x62,0x65,0x72,0x12,
0x22,0x0a,0x0c,0x52,0x65,0x70,0x6c,0x61,0x79,0x4e,
0x75,0x6d,0x62,0x65,0x72,0x18,0x03,0x20,0x01,0x28,
0x05,0x52,0x0c,0x52,0x65,0x70,0x6c,0x61,0x79,0x4e,
0x75,0x6d,0x62,0x65,0x72,0x12,0x1c,0x0a,0x09,0x4d,
0x61,0x74,0x63,0x68,0x54,0x79,0x70,0x65,0x18,0x04,
0x20,0x01,0x28,0x05,0x52,0x09,0x4d,0x61,0x74,0x63,
0x68,0x54,0x79,0x70,0x65,0x22,0x9f,0x01,0x0a,0x11,
0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x45,0x72,
0x72,0x6f,0x72,0x49,0x6e,0x66,0x6f,0x12,0x18,0x0a,
0x07,0x49,0x73,0x45,0x72,0x72,0x6f,0x72,0x18,0x01,
0x20,0x01,0x28,0x08,0x52,0x07,0x49,0x73,0x45,0x72,
0x72,0x6f,0x72,0x12,0x1c,0x0a,0x09,0x45,0x72,0x72,
0x6f,0x72,0x43,0x6f,0x64,0x65,0x18,0x02,0x20,0x01,
0x28,0x11,0x52,0x09,0x45,0x72,0x72,0x6f,0x72,0x43,
0x6f,0x64,0x65,0x12,0x18,0x0a,0x07,0x44,0x65,0x74,
0x61,0x69,0x6c,0x73,0x18,0x03,0x20,0x01,0x28,0x09,
0x52,0x07,0x44,0x65,0x74,0x61,0x69,0x6c,0x73,0x12,
0x1a,0x0a,0x08,0x4c,0x6f,0x63,0x61,0x74,0x69,0x6f,
0x6e,0x18,0x04,0x20,0x01,0x28,0x09,0x52,0x08,0x4c,
0x6f,0x63,0x61,0x74,0x69,0x6f,0x6e,0x12,0x1c,0x0a,
0x09,0x43,0x61,0x6c,0x6c,0x53,0x74,0x61,0x63,0x6b,
0x18,0x05,0x20,0x01,0x28,0x09,0x52,0x09,0x43,0x61,
0x6c,0x6c,0x53,0x74,0x61,0x63,0x6b,0x22,0xb8,0x01,
0x0a,0x0e,0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,
0x4f,0x70,0x4d,0x6f,0x64,0x65,0x12,0x12,0x0a,0x04,
0x48,0x61,0x73,0x68,0x18,0x01,0x20,0x01,0x28,0x06,
0x52,0x04,0x48,0x61,0x73,0x68,0x12,0x12,0x0a,0x04,
0x4e,0x61,0x6d,0x65,0x18,0x02,0x20,0x01,0x28,0x09,
0x52,0x04,0x4e,0x61,0x6d,0x65,0x12,0x14,0x0a,0x05,
0x47,0x72,0x6f,0x75,0x70,0x18,0x03,0x20,0x01,0x28,
0x09,0x52,0x05,0x47,0x72,0x6f,0x75,0x70,0x12,0x20,
0x0a,0x0b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,
0x69,0x6f,0x6e,0x18,0x04,0x20,0x01,0x28,0x09,0x52,
0x0b,0x44,0x65,0x73,0x63,0x72,0x69,0x70,0x74,0x69,
0x6f,0x6e,0x12,0x1c,0x0a,0x09,0x54,0x65,0x78,0x74,
0x43,0x6f,0x6c,0x6f,0x72,0x18,0x05,0x20,0x01,0x28,
0x05,0x52,0x09,0x54,0x65,0x78,0x74,0x43,0x6f,0x6c,
0x6f,0x72,0x12,0x28,0x0a,0x0f,0x42,0x61,0x63,0x6b,
0x67,0x72,0x6f,0x75,0x6e,0x64,0x43,0x6f,0x6c,0x6f,
0x72,0x18,0x06,0x20,0x01,0x28,0x05,0x52,0x0f,0x42,
0x61,0x63,0x6b,0x67,0x72,0x6f,0x75,0x6e,0x64,0x43,
0x6f,0x6c,0x6f,0x72,0x22,0x4b,0x0a,0x18,0x50,0x72,
0x6f,0x74,0x6f,0x62,0x75,0x66,0x41,0x76,0x61,0x69,
0x6c,0x61,0x62,0x6c,0x65,0x4f,0x70,0x4d,0x6f,0x64,
0x65,0x73,0x12,0x2f,0x0a,0x05,0x4d,0x6f,0x64,0x65,
0x73,0x18,0x01,0x20,0x03,0x28,0x0b,0x32,0x19,0x2e,
0x6d,0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x2e,
0x50,0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x4f,0x70,
0x4d,0x6f,0x64,0x65,0x52,0x05,0x4d,0x6f,0x64,0x65,
0x73,0x22,0xc6,0x01,0x0a,0x1a,0x50,0x72,0x6f,0x74,
0x6f,0x62,0x75,0x66,0x45,0x72,0x72,0x6f,0x72,0x49,
0x6e,0x66,0x6f,0x52,0x09,0x45,0x72,0x72,0x6f,0x72,
0x49,0x6e,0x66,0x6f,0x12,0x1c,0x0a,0x09,0x54,0x69,
0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x18,0x02,0x20,
0x01,0x28,0x04,0x52,0x09,0x54,0x69,0x6d,0x65,0x73,
0x74,0x61,0x6d,0x70,0x12,0x26,0x0a,0x0e,0x53,0x65,
0x6e,0x66,0x6f,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
0x6d,0x70,0x12,0x3a,0x0a,0x09,0x45,0x72,0x72,0x6f,
0x72,0x49,0x6e,0x66,0x6f,0x18,0x01,0x20,0x01,0x28,
0x0b,0x32,0x1c,0x2e,0x6d,0x72,0x63,0x2e,0x70,0x72,
0x6f,0x74,0x6f,0x2e,0x50,0x72,0x6f,0x74,0x6f,0x62,
0x75,0x66,0x45,0x72,0x72,0x6f,0x72,0x49,0x6e,0x66,
0x6f,0x52,0x09,0x45,0x72,0x72,0x6f,0x72,0x49,0x6e,
0x66,0x6f,0x12,0x1c,0x0a,0x09,0x54,0x69,0x6d,0x65,
0x73,0x74,0x61,0x6d,0x70,0x18,0x02,0x20,0x01,0x28,
0x04,0x52,0x09,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
0x6d,0x70,0x12,0x26,0x0a,0x0e,0x53,0x65,0x71,0x75,
0x65,0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,
0x18,0x03,0x20,0x01,0x28,0x05,0x52,0x0e,0x53,0x65,
0x71,0x75,0x65,0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,
0x65,0x72,0x18,0x03,0x20,0x01,0x28,0x05,0x52,0x0e,
0x53,0x65,0x71,0x75,0x65,0x6e,0x63,0x65,0x4e,0x75,
0x6d,0x62,0x65,0x72,0x12,0x26,0x0a,0x0e,0x4e,0x75,
0x65,0x72,0x12,0x26,0x0a,0x0e,0x4e,0x75,0x6d,0x4f,
0x63,0x63,0x75,0x72,0x72,0x65,0x6e,0x63,0x65,0x73,
0x18,0x04,0x20,0x01,0x28,0x05,0x52,0x0e,0x4e,0x75,
0x6d,0x4f,0x63,0x63,0x75,0x72,0x72,0x65,0x6e,0x63,
0x65,0x73,0x18,0x04,0x20,0x01,0x28,0x05,0x52,0x0e,
0x4e,0x75,0x6d,0x4f,0x63,0x63,0x75,0x72,0x72,0x65,
0x6e,0x63,0x65,0x73,0x22,0x86,0x01,0x0a,0x1c,0x50,
0x72,0x6f,0x74,0x6f,0x62,0x75,0x66,0x43,0x6f,0x6e,
0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e,0x65,0x54,0x69,
0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x12,0x20,0x0a,
0x0b,0x43,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69,
0x6e,0x65,0x18,0x01,0x20,0x01,0x28,0x09,0x52,0x0b,
0x43,0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e,
0x65,0x12,0x1c,0x0a,0x09,0x54,0x69,0x6d,0x65,0x73,
0x74,0x61,0x6d,0x70,0x18,0x02,0x20,0x01,0x28,0x04,
0x52,0x09,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,0x6d,
0x70,0x12,0x26,0x0a,0x0e,0x53,0x65,0x71,0x75,0x65,
0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x18,
0x03,0x20,0x01,0x28,0x05,0x52,0x0e,0x53,0x65,0x71,
0x75,0x65,0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65,
0x72,0x42,0x0f,0x0a,0x0d,0x63,0x6f,0x6d,0x2e,0x6d,
0x72,0x63,0x2e,0x70,0x72,0x6f,0x74,0x6f,0x4a,0xef,
0x18,0x0a,0x06,0x12,0x04,0x00,0x00,0x5f,0x01,0x0a,
0x08,0x0a,0x01,0x0c,0x12,0x03,0x00,0x00,0x12,0x0a,
0x08,0x0a,0x01,0x02,0x12,0x03,0x02,0x00,0x12,0x0a,
0x08,0x0a,0x01,0x08,0x12,0x03,0x04,0x00,0x26,0x0a,
0x09,0x0a,0x02,0x08,0x01,0x12,0x03,0x04,0x00,0x26,
0x0a,0x0a,0x0a,0x02,0x04,0x00,0x12,0x04,0x06,0x00,
0x0a,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x00,0x01,0x12,
0x03,0x06,0x08,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x00,
0x02,0x00,0x12,0x03,0x07,0x04,0x11,0x0a,0x0c,0x0a,
0x05,0x04,0x00,0x02,0x00,0x05,0x12,0x03,0x07,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x00,0x01,
0x12,0x03,0x07,0x0b,0x0c,0x0a,0x0c,0x0a,0x05,0x04,
0x00,0x02,0x00,0x03,0x12,0x03,0x07,0x0f,0x10,0x0a,
0x0b,0x0a,0x04,0x04,0x00,0x02,0x01,0x12,0x03,0x08,
0x04,0x11,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x01,
0x05,0x12,0x03,0x08,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x00,0x02,0x01,0x01,0x12,0x03,0x08,0x0b,0x0c,
0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x01,0x03,0x12,
0x03,0x08,0x0f,0x10,0x0a,0x0b,0x0a,0x04,0x04,0x00,
0x02,0x02,0x12,0x03,0x09,0x04,0x12,0x0a,0x0c,0x0a,
0x05,0x04,0x00,0x02,0x02,0x05,0x12,0x03,0x09,0x04,
0x08,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x02,0x01,
0x12,0x03,0x09,0x09,0x0d,0x0a,0x0c,0x0a,0x05,0x04,
0x00,0x02,0x02,0x03,0x12,0x03,0x09,0x10,0x11,0x0a,
0x0a,0x0a,0x02,0x04,0x01,0x12,0x04,0x0c,0x00,0x0e,
0x01,0x0a,0x0a,0x0a,0x03,0x04,0x01,0x01,0x12,0x03,
0x0c,0x08,0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x01,0x02,
0x00,0x12,0x03,0x0d,0x04,0x2c,0x0a,0x0c,0x0a,0x05,
0x04,0x01,0x02,0x00,0x04,0x12,0x03,0x0d,0x04,0x0c,
0x0a,0x0c,0x0a,0x05,0x04,0x01,0x02,0x00,0x06,0x12,
0x03,0x0d,0x0d,0x1f,0x0a,0x0c,0x0a,0x05,0x04,0x01,
0x02,0x00,0x01,0x12,0x03,0x0d,0x20,0x27,0x0a,0x0c,
0x0a,0x05,0x04,0x01,0x02,0x00,0x03,0x12,0x03,0x0d,
0x2a,0x2b,0x0a,0x0a,0x0a,0x02,0x04,0x02,0x12,0x04,
0x10,0x00,0x1a,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x02,
0x01,0x12,0x03,0x10,0x08,0x1c,0x0a,0x0b,0x0a,0x04,
0x04,0x02,0x02,0x00,0x12,0x03,0x11,0x04,0x20,0x0a,
0x0c,0x0a,0x05,0x04,0x02,0x02,0x00,0x05,0x12,0x03,
0x11,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,
0x00,0x01,0x12,0x03,0x11,0x0b,0x1b,0x0a,0x0c,0x0a,
0x05,0x04,0x02,0x02,0x00,0x03,0x12,0x03,0x11,0x1e,
0x1f,0x0a,0x0b,0x0a,0x04,0x04,0x02,0x02,0x01,0x12,
0x03,0x12,0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x02,
0x02,0x01,0x05,0x12,0x03,0x12,0x04,0x0a,0x0a,0x0c,
0x0a,0x05,0x04,0x02,0x02,0x01,0x01,0x12,0x03,0x12,
0x0b,0x12,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x01,
0x03,0x12,0x03,0x12,0x15,0x16,0x0a,0x0b,0x0a,0x04,
0x04,0x02,0x02,0x02,0x12,0x03,0x13,0x04,0x1d,0x0a,
0x0c,0x0a,0x05,0x04,0x02,0x02,0x02,0x05,0x12,0x03,
0x13,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,
0x02,0x01,0x12,0x03,0x13,0x0b,0x18,0x0a,0x0c,0x0a,
0x05,0x04,0x02,0x02,0x02,0x03,0x12,0x03,0x13,0x1b,
0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x02,0x02,0x03,0x12,
0x03,0x14,0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x02,
0x02,0x03,0x04,0x12,0x03,0x14,0x04,0x0c,0x0a,0x0c,
0x0a,0x05,0x04,0x02,0x02,0x03,0x05,0x12,0x03,0x14,
0x0d,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x03,
0x01,0x12,0x03,0x14,0x14,0x18,0x0a,0x0c,0x0a,0x05,
0x04,0x02,0x02,0x03,0x03,0x12,0x03,0x14,0x1b,0x1c,
0x0a,0x3e,0x0a,0x04,0x04,0x02,0x02,0x04,0x12,0x03,
0x17,0x04,0x18,0x1a,0x31,0x20,0x45,0x61,0x63,0x68,
0x20,0x50,0x4f,0x56,0x20,0x74,0x61,0x6b,0x65,0x73,
0x20,0x75,0x70,0x20,0x34,0x20,0x62,0x69,0x74,0x73,
0x0a,0x20,0x57,0x65,0x20,0x63,0x61,0x6e,0x20,0x66,
0x69,0x74,0x20,0x38,0x20,0x69,0x6e,0x20,0x68,0x65,
0x72,0x65,0x2e,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,
0x02,0x04,0x05,0x12,0x03,0x17,0x04,0x0a,0x0a,0x0c,
0x0a,0x05,0x04,0x02,0x02,0x04,0x01,0x12,0x03,0x17,
0x0b,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x04,
0x03,0x12,0x03,0x17,0x16,0x17,0x0a,0x0b,0x0a,0x04,
0x04,0x02,0x02,0x05,0x12,0x03,0x18,0x04,0x14,0x0a,
0x0c,0x0a,0x05,0x04,0x02,0x02,0x05,0x05,0x12,0x03,
0x18,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,
0x05,0x01,0x12,0x03,0x18,0x0b,0x0f,0x0a,0x0c,0x0a,
0x05,0x04,0x02,0x02,0x05,0x03,0x12,0x03,0x18,0x12,
0x13,0x0a,0x0b,0x0a,0x04,0x04,0x02,0x02,0x06,0x12,
0x03,0x19,0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04,0x02,
0x02,0x06,0x04,0x12,0x03,0x19,0x04,0x0c,0x0a,0x0c,
0x0a,0x05,0x04,0x02,0x02,0x06,0x06,0x12,0x03,0x19,
0x0d,0x21,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x06,
0x01,0x12,0x03,0x19,0x22,0x2b,0x0a,0x0c,0x0a,0x05,
0x04,0x02,0x02,0x06,0x03,0x12,0x03,0x19,0x2e,0x2f,
0x0a,0x0a,0x0a,0x02,0x04,0x03,0x12,0x04,0x1c,0x00,
0x21,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x03,0x01,0x12,
0x03,0x1c,0x08,0x1b,0x0a,0x0b,0x0a,0x04,0x04,0x03,
0x02,0x00,0x12,0x03,0x1d,0x04,0x1b,0x0a,0x0c,0x0a,
0x05,0x04,0x03,0x02,0x00,0x05,0x12,0x03,0x1d,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x00,0x01,
0x12,0x03,0x1d,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,
0x03,0x02,0x00,0x03,0x12,0x03,0x1d,0x19,0x1a,0x0a,
0x0b,0x0a,0x04,0x04,0x03,0x02,0x01,0x12,0x03,0x1e,
0x04,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x01,
0x05,0x12,0x03,0x1e,0x04,0x09,0x0a,0x0c,0x0a,0x05,
0x04,0x03,0x02,0x01,0x01,0x12,0x03,0x1e,0x0a,0x13,
0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x01,0x03,0x12,
0x03,0x1e,0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x03,
0x02,0x02,0x12,0x03,0x1f,0x04,0x30,0x0a,0x0c,0x0a,
0x05,0x04,0x03,0x02,0x02,0x04,0x12,0x03,0x1f,0x04,
0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x02,0x06,
0x12,0x03,0x1f,0x0d,0x21,0x0a,0x0c,0x0a,0x05,0x04,
0x03,0x02,0x02,0x01,0x12,0x03,0x1f,0x22,0x2b,0x0a,
0x0c,0x0a,0x05,0x04,0x03,0x02,0x02,0x03,0x12,0x03,
0x1f,0x2e,0x2f,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02,
0x03,0x12,0x03,0x20,0x04,0x1e,0x0a,0x0c,0x0a,0x05,
0x04,0x03,0x02,0x03,0x05,0x12,0x03,0x20,0x04,0x0b,
0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x03,0x01,0x12,
0x03,0x20,0x0c,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x03,
0x02,0x03,0x03,0x12,0x03,0x20,0x1c,0x1d,0x0a,0x0a,
0x0a,0x02,0x04,0x04,0x12,0x04,0x23,0x00,0x28,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x04,0x01,0x12,0x03,0x23,
0x08,0x22,0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x00,
0x12,0x03,0x24,0x04,0x1c,0x0a,0x0c,0x0a,0x05,0x04,
0x04,0x02,0x00,0x05,0x12,0x03,0x24,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x04,0x02,0x00,0x01,0x12,0x03,
0x24,0x0b,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,
0x00,0x03,0x12,0x03,0x24,0x1a,0x1b,0x0a,0x0b,0x0a,
0x04,0x04,0x04,0x02,0x01,0x12,0x03,0x25,0x04,0x17,
0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x01,0x05,0x12,
0x03,0x25,0x04,0x08,0x0a,0x0c,0x0a,0x05,0x04,0x04,
0x02,0x01,0x01,0x12,0x03,0x25,0x09,0x12,0x0a,0x0c,
0x0a,0x05,0x04,0x04,0x02,0x01,0x03,0x12,0x03,0x25,
0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x02,
0x12,0x03,0x26,0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04,
0x04,0x02,0x02,0x05,0x12,0x03,0x26,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x04,0x02,0x02,0x01,0x12,0x03,
0x26,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,
0x02,0x03,0x12,0x03,0x26,0x19,0x1a,0x0a,0x0b,0x0a,
0x04,0x04,0x04,0x02,0x03,0x12,0x03,0x27,0x04,0x20,
0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x03,0x05,0x12,
0x03,0x27,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x04,
0x02,0x03,0x01,0x12,0x03,0x27,0x0b,0x1b,0x0a,0x0c,
0x0a,0x05,0x04,0x04,0x02,0x03,0x03,0x12,0x03,0x27,
0x1e,0x1f,0x0a,0x0a,0x0a,0x02,0x04,0x05,0x12,0x04,
0x2a,0x00,0x2c,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x05,
0x01,0x12,0x03,0x2a,0x08,0x23,0x0a,0x0b,0x0a,0x04,
0x04,0x05,0x02,0x00,0x12,0x03,0x2b,0x04,0x38,0x0a,
0x0c,0x0a,0x05,0x04,0x05,0x02,0x00,0x04,0x12,0x03,
0x2b,0x04,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02,
0x00,0x06,0x12,0x03,0x2b,0x0d,0x27,0x0a,0x0c,0x0a,
0x05,0x04,0x05,0x02,0x00,0x01,0x12,0x03,0x2b,0x28,
0x33,0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02,0x00,0x03,
0x12,0x03,0x2b,0x36,0x37,0x0a,0x0a,0x0a,0x02,0x04,
0x06,0x12,0x04,0x2e,0x00,0x32,0x01,0x0a,0x0a,0x0a,
0x03,0x04,0x06,0x01,0x12,0x03,0x2e,0x08,0x1e,0x0a,
0x0b,0x0a,0x04,0x04,0x06,0x02,0x00,0x12,0x03,0x2f,
0x04,0x14,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x00,
0x05,0x12,0x03,0x2f,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x06,0x02,0x00,0x01,0x12,0x03,0x2f,0x0b,0x0f,
0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x00,0x03,0x12,
0x03,0x2f,0x12,0x13,0x0a,0x2b,0x0a,0x04,0x04,0x06,
0x02,0x01,0x12,0x03,0x30,0x04,0x16,0x22,0x1e,0x20,
0x65,0x73,0x22,0x86,0x01,0x0a,0x1c,0x50,0x72,0x6f,
0x74,0x6f,0x62,0x75,0x66,0x43,0x6f,0x6e,0x73,0x6f,
0x6c,0x65,0x4c,0x69,0x6e,0x65,0x54,0x69,0x6d,0x65,
0x73,0x74,0x61,0x6d,0x70,0x12,0x20,0x0a,0x0b,0x43,
0x6f,0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e,0x65,
0x18,0x01,0x20,0x01,0x28,0x09,0x52,0x0b,0x43,0x6f,
0x6e,0x73,0x6f,0x6c,0x65,0x4c,0x69,0x6e,0x65,0x12,
0x1c,0x0a,0x09,0x54,0x69,0x6d,0x65,0x73,0x74,0x61,
0x6d,0x70,0x18,0x02,0x20,0x01,0x28,0x04,0x52,0x09,
0x54,0x69,0x6d,0x65,0x73,0x74,0x61,0x6d,0x70,0x12,
0x26,0x0a,0x0e,0x53,0x65,0x71,0x75,0x65,0x6e,0x63,
0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x18,0x03,0x20,
0x01,0x28,0x05,0x52,0x0e,0x53,0x65,0x71,0x75,0x65,
0x6e,0x63,0x65,0x4e,0x75,0x6d,0x62,0x65,0x72,0x42,
0x0f,0x0a,0x0d,0x63,0x6f,0x6d,0x2e,0x6d,0x72,0x63,
0x2e,0x70,0x72,0x6f,0x74,0x6f,0x4a,0xa6,0x19,0x0a,
0x06,0x12,0x04,0x00,0x00,0x60,0x01,0x0a,0x08,0x0a,
0x01,0x0c,0x12,0x03,0x00,0x00,0x12,0x0a,0x08,0x0a,
0x01,0x02,0x12,0x03,0x02,0x00,0x12,0x0a,0x08,0x0a,
0x01,0x08,0x12,0x03,0x04,0x00,0x26,0x0a,0x09,0x0a,
0x02,0x08,0x01,0x12,0x03,0x04,0x00,0x26,0x0a,0x0a,
0x0a,0x02,0x04,0x00,0x12,0x04,0x06,0x00,0x0a,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x00,0x01,0x12,0x03,0x06,
0x08,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x00,0x02,0x00,
0x12,0x03,0x07,0x04,0x11,0x0a,0x0c,0x0a,0x05,0x04,
0x00,0x02,0x00,0x05,0x12,0x03,0x07,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x00,0x02,0x00,0x01,0x12,0x03,
0x07,0x0b,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,
0x00,0x03,0x12,0x03,0x07,0x0f,0x10,0x0a,0x0b,0x0a,
0x04,0x04,0x00,0x02,0x01,0x12,0x03,0x08,0x04,0x11,
0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,0x01,0x05,0x12,
0x03,0x08,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x00,
0x02,0x01,0x01,0x12,0x03,0x08,0x0b,0x0c,0x0a,0x0c,
0x0a,0x05,0x04,0x00,0x02,0x01,0x03,0x12,0x03,0x08,
0x0f,0x10,0x0a,0x0b,0x0a,0x04,0x04,0x00,0x02,0x02,
0x12,0x03,0x09,0x04,0x12,0x0a,0x0c,0x0a,0x05,0x04,
0x00,0x02,0x02,0x05,0x12,0x03,0x09,0x04,0x08,0x0a,
0x0c,0x0a,0x05,0x04,0x00,0x02,0x02,0x01,0x12,0x03,
0x09,0x09,0x0d,0x0a,0x0c,0x0a,0x05,0x04,0x00,0x02,
0x02,0x03,0x12,0x03,0x09,0x10,0x11,0x0a,0x0a,0x0a,
0x02,0x04,0x01,0x12,0x04,0x0c,0x00,0x0e,0x01,0x0a,
0x0a,0x0a,0x03,0x04,0x01,0x01,0x12,0x03,0x0c,0x08,
0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x01,0x02,0x00,0x12,
0x03,0x0d,0x04,0x2c,0x0a,0x0c,0x0a,0x05,0x04,0x01,
0x02,0x00,0x04,0x12,0x03,0x0d,0x04,0x0c,0x0a,0x0c,
0x0a,0x05,0x04,0x01,0x02,0x00,0x06,0x12,0x03,0x0d,
0x0d,0x1f,0x0a,0x0c,0x0a,0x05,0x04,0x01,0x02,0x00,
0x01,0x12,0x03,0x0d,0x20,0x27,0x0a,0x0c,0x0a,0x05,
0x04,0x01,0x02,0x00,0x03,0x12,0x03,0x0d,0x2a,0x2b,
0x0a,0x0a,0x0a,0x02,0x04,0x02,0x12,0x04,0x10,0x00,
0x1a,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x02,0x01,0x12,
0x03,0x10,0x08,0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x02,
0x02,0x00,0x12,0x03,0x11,0x04,0x20,0x0a,0x0c,0x0a,
0x05,0x04,0x02,0x02,0x00,0x05,0x12,0x03,0x11,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x00,0x01,
0x12,0x03,0x11,0x0b,0x1b,0x0a,0x0c,0x0a,0x05,0x04,
0x02,0x02,0x00,0x03,0x12,0x03,0x11,0x1e,0x1f,0x0a,
0x0b,0x0a,0x04,0x04,0x02,0x02,0x01,0x12,0x03,0x12,
0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x01,
0x05,0x12,0x03,0x12,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x02,0x02,0x01,0x01,0x12,0x03,0x12,0x0b,0x12,
0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x01,0x03,0x12,
0x03,0x12,0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04,0x02,
0x02,0x02,0x12,0x03,0x13,0x04,0x1d,0x0a,0x0c,0x0a,
0x05,0x04,0x02,0x02,0x02,0x05,0x12,0x03,0x13,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x02,0x01,
0x12,0x03,0x13,0x0b,0x18,0x0a,0x0c,0x0a,0x05,0x04,
0x02,0x02,0x02,0x03,0x12,0x03,0x13,0x1b,0x1c,0x0a,
0x0b,0x0a,0x04,0x04,0x02,0x02,0x03,0x12,0x03,0x14,
0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x03,
0x04,0x12,0x03,0x14,0x04,0x0c,0x0a,0x0c,0x0a,0x05,
0x04,0x02,0x02,0x03,0x05,0x12,0x03,0x14,0x0d,0x13,
0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x03,0x01,0x12,
0x03,0x14,0x14,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x02,
0x02,0x03,0x03,0x12,0x03,0x14,0x1b,0x1c,0x0a,0x3e,
0x0a,0x04,0x04,0x02,0x02,0x04,0x12,0x03,0x17,0x04,
0x18,0x1a,0x31,0x20,0x45,0x61,0x63,0x68,0x20,0x50,
0x4f,0x56,0x20,0x74,0x61,0x6b,0x65,0x73,0x20,0x75,
0x70,0x20,0x34,0x20,0x62,0x69,0x74,0x73,0x0a,0x20,
0x57,0x65,0x20,0x63,0x61,0x6e,0x20,0x66,0x69,0x74,
0x20,0x38,0x20,0x69,0x6e,0x20,0x68,0x65,0x72,0x65,
0x2e,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x04,
0x05,0x12,0x03,0x17,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x02,0x02,0x04,0x01,0x12,0x03,0x17,0x0b,0x13,
0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x04,0x03,0x12,
0x03,0x17,0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x02,
0x02,0x05,0x12,0x03,0x18,0x04,0x14,0x0a,0x0c,0x0a,
0x05,0x04,0x02,0x02,0x05,0x05,0x12,0x03,0x18,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x05,0x01,
0x12,0x03,0x18,0x0b,0x0f,0x0a,0x0c,0x0a,0x05,0x04,
0x02,0x02,0x05,0x03,0x12,0x03,0x18,0x12,0x13,0x0a,
0x0b,0x0a,0x04,0x04,0x02,0x02,0x06,0x12,0x03,0x19,
0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x06,
0x04,0x12,0x03,0x19,0x04,0x0c,0x0a,0x0c,0x0a,0x05,
0x04,0x02,0x02,0x06,0x06,0x12,0x03,0x19,0x0d,0x21,
0x0a,0x0c,0x0a,0x05,0x04,0x02,0x02,0x06,0x01,0x12,
0x03,0x19,0x22,0x2b,0x0a,0x0c,0x0a,0x05,0x04,0x02,
0x02,0x06,0x03,0x12,0x03,0x19,0x2e,0x2f,0x0a,0x0a,
0x0a,0x02,0x04,0x03,0x12,0x04,0x1c,0x00,0x22,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x03,0x01,0x12,0x03,0x1c,
0x08,0x1b,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02,0x00,
0x12,0x03,0x1d,0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04,
0x03,0x02,0x00,0x05,0x12,0x03,0x1d,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x03,0x02,0x00,0x01,0x12,0x03,
0x1d,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,
0x00,0x03,0x12,0x03,0x1d,0x19,0x1a,0x0a,0x0b,0x0a,
0x04,0x04,0x03,0x02,0x01,0x12,0x03,0x1e,0x04,0x18,
0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x01,0x05,0x12,
0x03,0x1e,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x03,
0x02,0x01,0x01,0x12,0x03,0x1e,0x0a,0x13,0x0a,0x0c,
0x0a,0x05,0x04,0x03,0x02,0x01,0x03,0x12,0x03,0x1e,
0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02,0x02,
0x12,0x03,0x1f,0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04,
0x03,0x02,0x02,0x04,0x12,0x03,0x1f,0x04,0x0c,0x0a,
0x0c,0x0a,0x05,0x04,0x03,0x02,0x02,0x06,0x12,0x03,
0x1f,0x0d,0x21,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,
0x02,0x01,0x12,0x03,0x1f,0x22,0x2b,0x0a,0x0c,0x0a,
0x05,0x04,0x03,0x02,0x02,0x03,0x12,0x03,0x1f,0x2e,
0x2f,0x0a,0x0b,0x0a,0x04,0x04,0x03,0x02,0x03,0x12,
0x03,0x20,0x04,0x1e,0x0a,0x0c,0x0a,0x05,0x04,0x03,
0x02,0x03,0x05,0x12,0x03,0x20,0x04,0x0b,0x0a,0x0c,
0x0a,0x05,0x04,0x03,0x02,0x03,0x01,0x12,0x03,0x20,
0x0c,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,0x03,
0x03,0x12,0x03,0x20,0x1c,0x1d,0x0a,0x0b,0x0a,0x04,
0x04,0x03,0x02,0x04,0x12,0x03,0x21,0x04,0x18,0x0a,
0x0c,0x0a,0x05,0x04,0x03,0x02,0x04,0x05,0x12,0x03,
0x21,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x03,0x02,
0x04,0x01,0x12,0x03,0x21,0x0b,0x13,0x0a,0x0c,0x0a,
0x05,0x04,0x03,0x02,0x04,0x03,0x12,0x03,0x21,0x16,
0x17,0x0a,0x0a,0x0a,0x02,0x04,0x04,0x12,0x04,0x24,
0x00,0x29,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x04,0x01,
0x12,0x03,0x24,0x08,0x22,0x0a,0x0b,0x0a,0x04,0x04,
0x04,0x02,0x00,0x12,0x03,0x25,0x04,0x1c,0x0a,0x0c,
0x0a,0x05,0x04,0x04,0x02,0x00,0x05,0x12,0x03,0x25,
0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x00,
0x01,0x12,0x03,0x25,0x0b,0x17,0x0a,0x0c,0x0a,0x05,
0x04,0x04,0x02,0x00,0x03,0x12,0x03,0x25,0x1a,0x1b,
0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x01,0x12,0x03,
0x26,0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,
0x01,0x05,0x12,0x03,0x26,0x04,0x08,0x0a,0x0c,0x0a,
0x05,0x04,0x04,0x02,0x01,0x01,0x12,0x03,0x26,0x09,
0x12,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x01,0x03,
0x12,0x03,0x26,0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04,
0x04,0x02,0x02,0x12,0x03,0x27,0x04,0x1b,0x0a,0x0c,
0x0a,0x05,0x04,0x04,0x02,0x02,0x05,0x12,0x03,0x27,
0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x02,
0x01,0x12,0x03,0x27,0x0b,0x16,0x0a,0x0c,0x0a,0x05,
0x04,0x04,0x02,0x02,0x03,0x12,0x03,0x27,0x19,0x1a,
0x0a,0x0b,0x0a,0x04,0x04,0x04,0x02,0x03,0x12,0x03,
0x28,0x04,0x20,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,
0x03,0x05,0x12,0x03,0x28,0x04,0x0a,0x0a,0x0c,0x0a,
0x05,0x04,0x04,0x02,0x03,0x01,0x12,0x03,0x28,0x0b,
0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x04,0x02,0x03,0x03,
0x12,0x03,0x28,0x1e,0x1f,0x0a,0x0a,0x0a,0x02,0x04,
0x05,0x12,0x04,0x2b,0x00,0x2d,0x01,0x0a,0x0a,0x0a,
0x03,0x04,0x05,0x01,0x12,0x03,0x2b,0x08,0x23,0x0a,
0x0b,0x0a,0x04,0x04,0x05,0x02,0x00,0x12,0x03,0x2c,
0x04,0x38,0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02,0x00,
0x04,0x12,0x03,0x2c,0x04,0x0c,0x0a,0x0c,0x0a,0x05,
0x04,0x05,0x02,0x00,0x06,0x12,0x03,0x2c,0x0d,0x27,
0x0a,0x0c,0x0a,0x05,0x04,0x05,0x02,0x00,0x01,0x12,
0x03,0x2c,0x28,0x33,0x0a,0x0c,0x0a,0x05,0x04,0x05,
0x02,0x00,0x03,0x12,0x03,0x2c,0x36,0x37,0x0a,0x0a,
0x0a,0x02,0x04,0x06,0x12,0x04,0x2f,0x00,0x33,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x06,0x01,0x12,0x03,0x2f,
0x08,0x1e,0x0a,0x0b,0x0a,0x04,0x04,0x06,0x02,0x00,
0x12,0x03,0x30,0x04,0x14,0x0a,0x0c,0x0a,0x05,0x04,
0x06,0x02,0x00,0x05,0x12,0x03,0x30,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x06,0x02,0x00,0x01,0x12,0x03,
0x30,0x0b,0x0f,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,
0x00,0x03,0x12,0x03,0x30,0x12,0x13,0x0a,0x2b,0x0a,
0x04,0x04,0x06,0x02,0x01,0x12,0x03,0x31,0x04,0x16,
0x22,0x1e,0x20,0x31,0x36,0x20,0x62,0x69,0x74,0x73,
0x2c,0x20,0x6c,0x65,0x66,0x74,0x20,0x6d,0x73,0x62,
0x2c,0x20,0x72,0x69,0x67,0x68,0x74,0x20,0x6c,0x73,
0x62,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x01,
0x05,0x12,0x03,0x31,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x06,0x02,0x01,0x01,0x12,0x03,0x31,0x0b,0x11,
0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x01,0x03,0x12,
0x03,0x31,0x14,0x15,0x0a,0x2b,0x0a,0x04,0x04,0x06,
0x02,0x02,0x12,0x03,0x32,0x04,0x1d,0x22,0x1e,0x20,
0x31,0x36,0x20,0x62,0x69,0x74,0x73,0x2c,0x20,0x6c,
0x65,0x66,0x74,0x20,0x6d,0x73,0x62,0x2c,0x20,0x72,
0x69,0x67,0x68,0x74,0x20,0x6c,0x73,0x62,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x06,0x02,0x01,0x05,0x12,0x03,
0x30,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,
0x01,0x01,0x12,0x03,0x30,0x0b,0x11,0x0a,0x0c,0x0a,
0x05,0x04,0x06,0x02,0x01,0x03,0x12,0x03,0x30,0x14,
0x15,0x0a,0x2b,0x0a,0x04,0x04,0x06,0x02,0x02,0x12,
0x03,0x31,0x04,0x1d,0x22,0x1e,0x20,0x31,0x36,0x20,
0x62,0x69,0x74,0x73,0x2c,0x20,0x6c,0x65,0x66,0x74,
0x20,0x6d,0x73,0x62,0x2c,0x20,0x72,0x69,0x67,0x68,
0x74,0x20,0x6c,0x73,0x62,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x06,0x02,0x02,0x05,0x12,0x03,0x31,0x04,0x0a,
0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,0x02,0x01,0x12,
0x03,0x31,0x0b,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x06,
0x02,0x02,0x03,0x12,0x03,0x31,0x1b,0x1c,0x0a,0x0a,
0x0a,0x02,0x04,0x07,0x12,0x04,0x34,0x00,0x36,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x07,0x01,0x12,0x03,0x34,
0x08,0x1f,0x0a,0x0b,0x0a,0x04,0x04,0x07,0x02,0x00,
0x12,0x03,0x35,0x04,0x30,0x0a,0x0c,0x0a,0x05,0x04,
0x07,0x02,0x00,0x04,0x12,0x03,0x35,0x04,0x0c,0x0a,
0x0c,0x0a,0x05,0x04,0x07,0x02,0x00,0x06,0x12,0x03,
0x35,0x0d,0x23,0x0a,0x0c,0x0a,0x05,0x04,0x07,0x02,
0x00,0x01,0x12,0x03,0x35,0x24,0x2b,0x0a,0x0c,0x0a,
0x05,0x04,0x07,0x02,0x00,0x03,0x12,0x03,0x35,0x2e,
0x2f,0x0a,0x0a,0x0a,0x02,0x04,0x08,0x12,0x04,0x38,
0x00,0x3d,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x08,0x01,
0x12,0x03,0x38,0x08,0x19,0x0a,0x0b,0x0a,0x04,0x04,
0x08,0x02,0x00,0x12,0x03,0x39,0x04,0x19,0x0a,0x0c,
0x0a,0x05,0x04,0x08,0x02,0x00,0x05,0x12,0x03,0x39,
0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x00,
0x01,0x12,0x03,0x39,0x0b,0x14,0x0a,0x0c,0x0a,0x05,
0x04,0x08,0x02,0x00,0x03,0x12,0x03,0x39,0x17,0x18,
0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02,0x01,0x12,0x03,
0x3a,0x04,0x1a,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,
0x01,0x05,0x12,0x03,0x3a,0x04,0x09,0x0a,0x0c,0x0a,
0x05,0x04,0x08,0x02,0x01,0x01,0x12,0x03,0x3a,0x0a,
0x15,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x01,0x03,
0x12,0x03,0x3a,0x18,0x19,0x0a,0x0b,0x0a,0x04,0x04,
0x08,0x02,0x02,0x12,0x03,0x3b,0x04,0x1b,0x0a,0x0c,
0x0a,0x05,0x04,0x08,0x02,0x02,0x05,0x12,0x03,0x3b,
0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x02,
0x01,0x12,0x03,0x3b,0x0a,0x16,0x0a,0x0c,0x0a,0x05,
0x04,0x08,0x02,0x02,0x03,0x12,0x03,0x3b,0x19,0x1a,
0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02,0x03,0x12,0x03,
0x3c,0x04,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,
0x03,0x05,0x12,0x03,0x3c,0x04,0x09,0x0a,0x0c,0x0a,
0x05,0x04,0x08,0x02,0x03,0x01,0x12,0x03,0x3c,0x0a,
0x13,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x03,0x03,
0x12,0x03,0x3c,0x16,0x17,0x0a,0x0a,0x0a,0x02,0x04,
0x09,0x12,0x04,0x3f,0x00,0x45,0x01,0x0a,0x0a,0x0a,
0x03,0x04,0x09,0x01,0x12,0x03,0x3f,0x08,0x19,0x0a,
0x0b,0x0a,0x04,0x04,0x09,0x02,0x00,0x12,0x03,0x40,
0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x00,
0x05,0x12,0x03,0x40,0x04,0x08,0x0a,0x0c,0x0a,0x05,
0x04,0x09,0x02,0x00,0x01,0x12,0x03,0x40,0x09,0x10,
0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x00,0x03,0x12,
0x03,0x40,0x13,0x14,0x0a,0x0b,0x0a,0x04,0x04,0x09,
0x02,0x01,0x12,0x03,0x41,0x04,0x19,0x0a,0x0c,0x0a,
0x05,0x04,0x09,0x02,0x01,0x05,0x12,0x03,0x41,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x01,0x01,
0x12,0x03,0x41,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04,
0x09,0x02,0x01,0x03,0x12,0x03,0x41,0x17,0x18,0x0a,
0x0b,0x0a,0x04,0x04,0x09,0x02,0x02,0x12,0x03,0x42,
0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x02,
0x05,0x12,0x03,0x42,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x09,0x02,0x02,0x01,0x12,0x03,0x42,0x0b,0x12,
0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x02,0x03,0x12,
0x03,0x42,0x15,0x16,0x0a,0x0b,0x0a,0x04,0x04,0x09,
0x02,0x03,0x12,0x03,0x43,0x04,0x18,0x0a,0x0c,0x0a,
0x05,0x04,0x09,0x02,0x03,0x05,0x12,0x03,0x43,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x03,0x01,
0x12,0x03,0x43,0x0b,0x13,0x0a,0x0c,0x0a,0x05,0x04,
0x09,0x02,0x03,0x03,0x12,0x03,0x43,0x16,0x17,0x0a,
0x0b,0x0a,0x04,0x04,0x09,0x02,0x04,0x12,0x03,0x44,
0x04,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x04,
0x05,0x12,0x03,0x44,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x09,0x02,0x04,0x01,0x12,0x03,0x44,0x0b,0x14,
0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x04,0x03,0x12,
0x03,0x44,0x17,0x18,0x0a,0x0a,0x0a,0x02,0x04,0x0a,
0x12,0x04,0x47,0x00,0x4e,0x01,0x0a,0x0a,0x0a,0x03,
0x04,0x0a,0x01,0x12,0x03,0x47,0x08,0x16,0x0a,0x0b,
0x0a,0x04,0x04,0x0a,0x02,0x00,0x12,0x03,0x48,0x04,
0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x00,0x05,
0x12,0x03,0x48,0x04,0x0b,0x0a,0x0c,0x0a,0x05,0x04,
0x0a,0x02,0x00,0x01,0x12,0x03,0x48,0x0c,0x10,0x0a,
0x0c,0x0a,0x05,0x04,0x0a,0x02,0x00,0x03,0x12,0x03,
0x48,0x13,0x14,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,
0x01,0x12,0x03,0x49,0x04,0x14,0x0a,0x0c,0x0a,0x05,
0x04,0x0a,0x02,0x01,0x05,0x12,0x03,0x49,0x04,0x0a,
0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x01,0x01,0x12,
0x03,0x49,0x0b,0x0f,0x0a,0x0c,0x0a,0x05,0x04,0x0a,
0x02,0x01,0x03,0x12,0x03,0x49,0x12,0x13,0x0a,0x0b,
0x0a,0x04,0x04,0x0a,0x02,0x02,0x12,0x03,0x4a,0x04,
0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x02,0x05,
0x12,0x03,0x4a,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,
0x0a,0x02,0x02,0x01,0x12,0x03,0x4a,0x0b,0x10,0x0a,
0x0c,0x0a,0x05,0x04,0x0a,0x02,0x02,0x03,0x12,0x03,
0x4a,0x13,0x14,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,
0x03,0x12,0x03,0x4b,0x04,0x1b,0x0a,0x0c,0x0a,0x05,
0x04,0x0a,0x02,0x03,0x05,0x12,0x03,0x4b,0x04,0x0a,
0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x03,0x01,0x12,
0x03,0x4b,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x0a,
0x02,0x03,0x03,0x12,0x03,0x4b,0x19,0x1a,0x0a,0x0b,
0x0a,0x04,0x04,0x0a,0x02,0x04,0x12,0x03,0x4c,0x04,
0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x04,0x05,
0x12,0x03,0x4c,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,
0x0a,0x02,0x04,0x01,0x12,0x03,0x4c,0x0a,0x13,0x0a,
0x0c,0x0a,0x05,0x04,0x0a,0x02,0x04,0x03,0x12,0x03,
0x4c,0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,
0x05,0x12,0x03,0x4d,0x04,0x1e,0x0a,0x0c,0x0a,0x05,
0x04,0x0a,0x02,0x05,0x05,0x12,0x03,0x4d,0x04,0x09,
0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x05,0x01,0x12,
0x03,0x4d,0x0a,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x0a,
0x02,0x05,0x03,0x12,0x03,0x4d,0x1c,0x1d,0x0a,0x0a,
0x0a,0x02,0x04,0x0b,0x12,0x04,0x50,0x00,0x52,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x0b,0x01,0x12,0x03,0x50,
0x08,0x20,0x0a,0x0b,0x0a,0x04,0x04,0x0b,0x02,0x00,
0x12,0x03,0x51,0x04,0x26,0x0a,0x0c,0x0a,0x05,0x04,
0x0b,0x02,0x00,0x04,0x12,0x03,0x51,0x04,0x0c,0x0a,
0x0c,0x0a,0x05,0x04,0x0b,0x02,0x00,0x06,0x12,0x03,
0x51,0x0d,0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x0b,0x02,
0x00,0x01,0x12,0x03,0x51,0x1c,0x21,0x0a,0x0c,0x0a,
0x05,0x04,0x0b,0x02,0x00,0x03,0x12,0x03,0x51,0x24,
0x25,0x0a,0x0a,0x0a,0x02,0x04,0x0c,0x12,0x04,0x54,
0x00,0x59,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x0c,0x01,
0x12,0x03,0x54,0x08,0x22,0x0a,0x0b,0x0a,0x04,0x04,
0x0c,0x02,0x00,0x12,0x03,0x55,0x04,0x24,0x0a,0x0c,
0x0a,0x05,0x04,0x0c,0x02,0x00,0x06,0x12,0x03,0x55,
0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x00,
0x01,0x12,0x03,0x55,0x16,0x1f,0x0a,0x0c,0x0a,0x05,
0x04,0x0c,0x02,0x00,0x03,0x12,0x03,0x55,0x22,0x23,
0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02,0x01,0x12,0x03,
0x56,0x04,0x19,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,
0x01,0x05,0x12,0x03,0x56,0x04,0x0a,0x0a,0x0c,0x0a,
0x05,0x04,0x0c,0x02,0x01,0x01,0x12,0x03,0x56,0x0b,
0x14,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x01,0x03,
0x12,0x03,0x56,0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04,
0x0c,0x02,0x02,0x12,0x03,0x57,0x04,0x1d,0x0a,0x0c,
0x0a,0x05,0x04,0x0c,0x02,0x02,0x05,0x12,0x03,0x57,
0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x02,
0x01,0x12,0x03,0x57,0x0a,0x18,0x0a,0x0c,0x0a,0x05,
0x04,0x0c,0x02,0x02,0x03,0x12,0x03,0x57,0x1b,0x1c,
0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02,0x03,0x12,0x03,
0x58,0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,
0x03,0x05,0x12,0x03,0x58,0x04,0x09,0x0a,0x0c,0x0a,
0x05,0x04,0x0c,0x02,0x03,0x01,0x12,0x03,0x58,0x0a,
0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x03,0x03,
0x12,0x03,0x58,0x1b,0x1c,0x0a,0x0a,0x0a,0x02,0x04,
0x0d,0x12,0x04,0x5b,0x00,0x5f,0x01,0x0a,0x0a,0x0a,
0x03,0x04,0x0d,0x01,0x12,0x03,0x5b,0x08,0x24,0x0a,
0x0b,0x0a,0x04,0x04,0x0d,0x02,0x00,0x12,0x03,0x5c,
0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x00,
0x05,0x12,0x03,0x5c,0x04,0x0a,0x0a,0x0c,0x0a,0x05,
0x04,0x0d,0x02,0x00,0x01,0x12,0x03,0x5c,0x0b,0x16,
0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x00,0x03,0x12,
0x03,0x5c,0x19,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x0d,
0x02,0x01,0x12,0x03,0x5d,0x04,0x19,0x0a,0x0c,0x0a,
0x05,0x04,0x0d,0x02,0x01,0x05,0x12,0x03,0x5d,0x04,
0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x01,0x01,
0x12,0x03,0x5d,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04,
0x0d,0x02,0x01,0x03,0x12,0x03,0x5d,0x17,0x18,0x0a,
0x0b,0x0a,0x04,0x04,0x0d,0x02,0x02,0x12,0x03,0x5e,
0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x02,
0x05,0x12,0x03,0x5e,0x04,0x09,0x0a,0x0c,0x0a,0x05,
0x04,0x0d,0x02,0x02,0x01,0x12,0x03,0x5e,0x0a,0x18,
0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x02,0x03,0x12,
0x03,0x5e,0x1b,0x1c,0x62,0x06,0x70,0x72,0x6f,0x74,
0x6f,0x33,
0x0c,0x0a,0x05,0x04,0x06,0x02,0x02,0x05,0x12,0x03,
0x32,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x06,0x02,
0x02,0x01,0x12,0x03,0x32,0x0b,0x18,0x0a,0x0c,0x0a,
0x05,0x04,0x06,0x02,0x02,0x03,0x12,0x03,0x32,0x1b,
0x1c,0x0a,0x0a,0x0a,0x02,0x04,0x07,0x12,0x04,0x35,
0x00,0x37,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x07,0x01,
0x12,0x03,0x35,0x08,0x1f,0x0a,0x0b,0x0a,0x04,0x04,
0x07,0x02,0x00,0x12,0x03,0x36,0x04,0x30,0x0a,0x0c,
0x0a,0x05,0x04,0x07,0x02,0x00,0x04,0x12,0x03,0x36,
0x04,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x07,0x02,0x00,
0x06,0x12,0x03,0x36,0x0d,0x23,0x0a,0x0c,0x0a,0x05,
0x04,0x07,0x02,0x00,0x01,0x12,0x03,0x36,0x24,0x2b,
0x0a,0x0c,0x0a,0x05,0x04,0x07,0x02,0x00,0x03,0x12,
0x03,0x36,0x2e,0x2f,0x0a,0x0a,0x0a,0x02,0x04,0x08,
0x12,0x04,0x39,0x00,0x3e,0x01,0x0a,0x0a,0x0a,0x03,
0x04,0x08,0x01,0x12,0x03,0x39,0x08,0x19,0x0a,0x0b,
0x0a,0x04,0x04,0x08,0x02,0x00,0x12,0x03,0x3a,0x04,
0x19,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x00,0x05,
0x12,0x03,0x3a,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,
0x08,0x02,0x00,0x01,0x12,0x03,0x3a,0x0b,0x14,0x0a,
0x0c,0x0a,0x05,0x04,0x08,0x02,0x00,0x03,0x12,0x03,
0x3a,0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02,
0x01,0x12,0x03,0x3b,0x04,0x1a,0x0a,0x0c,0x0a,0x05,
0x04,0x08,0x02,0x01,0x05,0x12,0x03,0x3b,0x04,0x09,
0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x01,0x01,0x12,
0x03,0x3b,0x0a,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x08,
0x02,0x01,0x03,0x12,0x03,0x3b,0x18,0x19,0x0a,0x0b,
0x0a,0x04,0x04,0x08,0x02,0x02,0x12,0x03,0x3c,0x04,
0x1b,0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x02,0x05,
0x12,0x03,0x3c,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,
0x08,0x02,0x02,0x01,0x12,0x03,0x3c,0x0a,0x16,0x0a,
0x0c,0x0a,0x05,0x04,0x08,0x02,0x02,0x03,0x12,0x03,
0x3c,0x19,0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x08,0x02,
0x03,0x12,0x03,0x3d,0x04,0x18,0x0a,0x0c,0x0a,0x05,
0x04,0x08,0x02,0x03,0x05,0x12,0x03,0x3d,0x04,0x09,
0x0a,0x0c,0x0a,0x05,0x04,0x08,0x02,0x03,0x01,0x12,
0x03,0x3d,0x0a,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x08,
0x02,0x03,0x03,0x12,0x03,0x3d,0x16,0x17,0x0a,0x0a,
0x0a,0x02,0x04,0x09,0x12,0x04,0x40,0x00,0x46,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x09,0x01,0x12,0x03,0x40,
0x08,0x19,0x0a,0x0b,0x0a,0x04,0x04,0x09,0x02,0x00,
0x12,0x03,0x41,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,
0x09,0x02,0x00,0x05,0x12,0x03,0x41,0x04,0x08,0x0a,
0x0c,0x0a,0x05,0x04,0x09,0x02,0x00,0x01,0x12,0x03,
0x41,0x09,0x10,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,
0x00,0x03,0x12,0x03,0x41,0x13,0x14,0x0a,0x0b,0x0a,
0x04,0x04,0x09,0x02,0x01,0x12,0x03,0x42,0x04,0x19,
0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x01,0x05,0x12,
0x03,0x42,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09,
0x02,0x01,0x01,0x12,0x03,0x42,0x0b,0x14,0x0a,0x0c,
0x0a,0x05,0x04,0x09,0x02,0x01,0x03,0x12,0x03,0x42,
0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04,0x09,0x02,0x02,
0x12,0x03,0x43,0x04,0x17,0x0a,0x0c,0x0a,0x05,0x04,
0x09,0x02,0x02,0x05,0x12,0x03,0x43,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x09,0x02,0x02,0x01,0x12,0x03,
0x43,0x0b,0x12,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,
0x02,0x03,0x12,0x03,0x43,0x15,0x16,0x0a,0x0b,0x0a,
0x04,0x04,0x09,0x02,0x03,0x12,0x03,0x44,0x04,0x18,
0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,0x03,0x05,0x12,
0x03,0x44,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x09,
0x02,0x03,0x01,0x12,0x03,0x44,0x0b,0x13,0x0a,0x0c,
0x0a,0x05,0x04,0x09,0x02,0x03,0x03,0x12,0x03,0x44,
0x16,0x17,0x0a,0x0b,0x0a,0x04,0x04,0x09,0x02,0x04,
0x12,0x03,0x45,0x04,0x19,0x0a,0x0c,0x0a,0x05,0x04,
0x09,0x02,0x04,0x05,0x12,0x03,0x45,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x09,0x02,0x04,0x01,0x12,0x03,
0x45,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04,0x09,0x02,
0x04,0x03,0x12,0x03,0x45,0x17,0x18,0x0a,0x0a,0x0a,
0x02,0x04,0x0a,0x12,0x04,0x48,0x00,0x4f,0x01,0x0a,
0x0a,0x0a,0x03,0x04,0x0a,0x01,0x12,0x03,0x48,0x08,
0x16,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,0x00,0x12,
0x03,0x49,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a,
0x02,0x00,0x05,0x12,0x03,0x49,0x04,0x0b,0x0a,0x0c,
0x0a,0x05,0x04,0x0a,0x02,0x00,0x01,0x12,0x03,0x49,
0x0c,0x10,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x00,
0x03,0x12,0x03,0x49,0x13,0x14,0x0a,0x0b,0x0a,0x04,
0x04,0x0a,0x02,0x01,0x12,0x03,0x4a,0x04,0x14,0x0a,
0x0c,0x0a,0x05,0x04,0x0a,0x02,0x01,0x05,0x12,0x03,
0x4a,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,
0x01,0x01,0x12,0x03,0x4a,0x0b,0x0f,0x0a,0x0c,0x0a,
0x05,0x04,0x0a,0x02,0x01,0x03,0x12,0x03,0x4a,0x12,
0x13,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,0x02,0x12,
0x03,0x4b,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,0x0a,
0x02,0x02,0x05,0x12,0x03,0x4b,0x04,0x0a,0x0a,0x0c,
0x0a,0x05,0x04,0x0a,0x02,0x02,0x01,0x12,0x03,0x4b,
0x0b,0x10,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x02,
0x03,0x12,0x03,0x4b,0x13,0x14,0x0a,0x0b,0x0a,0x04,
0x04,0x0a,0x02,0x03,0x12,0x03,0x4c,0x04,0x1b,0x0a,
0x0c,0x0a,0x05,0x04,0x0a,0x02,0x03,0x05,0x12,0x03,
0x4c,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,
0x03,0x01,0x12,0x03,0x4c,0x0b,0x16,0x0a,0x0c,0x0a,
0x05,0x04,0x0a,0x02,0x03,0x03,0x12,0x03,0x4c,0x19,
0x1a,0x0a,0x0b,0x0a,0x04,0x04,0x0a,0x02,0x04,0x12,
0x03,0x4d,0x04,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0a,
0x02,0x04,0x05,0x12,0x03,0x4d,0x04,0x09,0x0a,0x0c,
0x0a,0x05,0x04,0x0a,0x02,0x04,0x01,0x12,0x03,0x4d,
0x0a,0x13,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,0x04,
0x03,0x12,0x03,0x4d,0x16,0x17,0x0a,0x0b,0x0a,0x04,
0x04,0x0a,0x02,0x05,0x12,0x03,0x4e,0x04,0x1e,0x0a,
0x0c,0x0a,0x05,0x04,0x0a,0x02,0x05,0x05,0x12,0x03,
0x4e,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,0x0a,0x02,
0x05,0x01,0x12,0x03,0x4e,0x0a,0x19,0x0a,0x0c,0x0a,
0x05,0x04,0x0a,0x02,0x05,0x03,0x12,0x03,0x4e,0x1c,
0x1d,0x0a,0x0a,0x0a,0x02,0x04,0x0b,0x12,0x04,0x51,
0x00,0x53,0x01,0x0a,0x0a,0x0a,0x03,0x04,0x0b,0x01,
0x12,0x03,0x51,0x08,0x20,0x0a,0x0b,0x0a,0x04,0x04,
0x0b,0x02,0x00,0x12,0x03,0x52,0x04,0x26,0x0a,0x0c,
0x0a,0x05,0x04,0x0b,0x02,0x00,0x04,0x12,0x03,0x52,
0x04,0x0c,0x0a,0x0c,0x0a,0x05,0x04,0x0b,0x02,0x00,
0x06,0x12,0x03,0x52,0x0d,0x1b,0x0a,0x0c,0x0a,0x05,
0x04,0x0b,0x02,0x00,0x01,0x12,0x03,0x52,0x1c,0x21,
0x0a,0x0c,0x0a,0x05,0x04,0x0b,0x02,0x00,0x03,0x12,
0x03,0x52,0x24,0x25,0x0a,0x0a,0x0a,0x02,0x04,0x0c,
0x12,0x04,0x55,0x00,0x5a,0x01,0x0a,0x0a,0x0a,0x03,
0x04,0x0c,0x01,0x12,0x03,0x55,0x08,0x22,0x0a,0x0b,
0x0a,0x04,0x04,0x0c,0x02,0x00,0x12,0x03,0x56,0x04,
0x24,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x00,0x06,
0x12,0x03,0x56,0x04,0x15,0x0a,0x0c,0x0a,0x05,0x04,
0x0c,0x02,0x00,0x01,0x12,0x03,0x56,0x16,0x1f,0x0a,
0x0c,0x0a,0x05,0x04,0x0c,0x02,0x00,0x03,0x12,0x03,
0x56,0x22,0x23,0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02,
0x01,0x12,0x03,0x57,0x04,0x19,0x0a,0x0c,0x0a,0x05,
0x04,0x0c,0x02,0x01,0x05,0x12,0x03,0x57,0x04,0x0a,
0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x01,0x01,0x12,
0x03,0x57,0x0b,0x14,0x0a,0x0c,0x0a,0x05,0x04,0x0c,
0x02,0x01,0x03,0x12,0x03,0x57,0x17,0x18,0x0a,0x0b,
0x0a,0x04,0x04,0x0c,0x02,0x02,0x12,0x03,0x58,0x04,
0x1d,0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x02,0x05,
0x12,0x03,0x58,0x04,0x09,0x0a,0x0c,0x0a,0x05,0x04,
0x0c,0x02,0x02,0x01,0x12,0x03,0x58,0x0a,0x18,0x0a,
0x0c,0x0a,0x05,0x04,0x0c,0x02,0x02,0x03,0x12,0x03,
0x58,0x1b,0x1c,0x0a,0x0b,0x0a,0x04,0x04,0x0c,0x02,
0x03,0x12,0x03,0x59,0x04,0x1d,0x0a,0x0c,0x0a,0x05,
0x04,0x0c,0x02,0x03,0x05,0x12,0x03,0x59,0x04,0x09,
0x0a,0x0c,0x0a,0x05,0x04,0x0c,0x02,0x03,0x01,0x12,
0x03,0x59,0x0a,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0c,
0x02,0x03,0x03,0x12,0x03,0x59,0x1b,0x1c,0x0a,0x0a,
0x0a,0x02,0x04,0x0d,0x12,0x04,0x5c,0x00,0x60,0x01,
0x0a,0x0a,0x0a,0x03,0x04,0x0d,0x01,0x12,0x03,0x5c,
0x08,0x24,0x0a,0x0b,0x0a,0x04,0x04,0x0d,0x02,0x00,
0x12,0x03,0x5d,0x04,0x1b,0x0a,0x0c,0x0a,0x05,0x04,
0x0d,0x02,0x00,0x05,0x12,0x03,0x5d,0x04,0x0a,0x0a,
0x0c,0x0a,0x05,0x04,0x0d,0x02,0x00,0x01,0x12,0x03,
0x5d,0x0b,0x16,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,
0x00,0x03,0x12,0x03,0x5d,0x19,0x1a,0x0a,0x0b,0x0a,
0x04,0x04,0x0d,0x02,0x01,0x12,0x03,0x5e,0x04,0x19,
0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,0x01,0x05,0x12,
0x03,0x5e,0x04,0x0a,0x0a,0x0c,0x0a,0x05,0x04,0x0d,
0x02,0x01,0x01,0x12,0x03,0x5e,0x0b,0x14,0x0a,0x0c,
0x0a,0x05,0x04,0x0d,0x02,0x01,0x03,0x12,0x03,0x5e,
0x17,0x18,0x0a,0x0b,0x0a,0x04,0x04,0x0d,0x02,0x02,
0x12,0x03,0x5f,0x04,0x1d,0x0a,0x0c,0x0a,0x05,0x04,
0x0d,0x02,0x02,0x05,0x12,0x03,0x5f,0x04,0x09,0x0a,
0x0c,0x0a,0x05,0x04,0x0d,0x02,0x02,0x01,0x12,0x03,
0x5f,0x0a,0x18,0x0a,0x0c,0x0a,0x05,0x04,0x0d,0x02,
0x02,0x03,0x12,0x03,0x5f,0x1b,0x1c,0x62,0x06,0x70,
0x72,0x6f,0x74,0x6f,0x33,
};
static const char file_name[] = "MrcComm.proto";
static const char mrc_proto_ProtobufFingerData_name[] = "mrc.proto.ProtobufFingerData";

View File

@@ -58,6 +58,7 @@ typedef struct _mrc_proto_ProtobufControlData {
pb_callback_t Joysticks;
uint64_t CurrentOpMode;
uint32_t ControlWord;
pb_callback_t GameData;
} mrc_proto_ProtobufControlData;
typedef struct _mrc_proto_ProtobufJoystickDescriptor {
@@ -167,7 +168,7 @@ typedef struct _mrc_proto_ProtobufConsoleLineTimestamp {
#define mrc_proto_ProtobufFingerData_init_default {0, 0, 0}
#define mrc_proto_ProtobufTouchpadData_init_default {{{NULL}, NULL}}
#define mrc_proto_ProtobufJoystickData_init_default {0, 0, 0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}}
#define mrc_proto_ProtobufControlData_init_default {0, {{NULL}, NULL}, 0, 0}
#define mrc_proto_ProtobufControlData_init_default {0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}}
#define mrc_proto_ProtobufJoystickDescriptor_init_default {{{NULL}, NULL}, 0, 0, 0}
#define mrc_proto_ProtobufJoystickDescriptors_init_default {{{NULL}, NULL}}
#define mrc_proto_ProtobufJoystickOutput_init_default {0, 0, 0}
@@ -181,7 +182,7 @@ typedef struct _mrc_proto_ProtobufConsoleLineTimestamp {
#define mrc_proto_ProtobufFingerData_init_zero {0, 0, 0}
#define mrc_proto_ProtobufTouchpadData_init_zero {{{NULL}, NULL}}
#define mrc_proto_ProtobufJoystickData_init_zero {0, 0, 0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}}
#define mrc_proto_ProtobufControlData_init_zero {0, {{NULL}, NULL}, 0, 0}
#define mrc_proto_ProtobufControlData_init_zero {0, {{NULL}, NULL}, 0, 0, {{NULL}, NULL}}
#define mrc_proto_ProtobufJoystickDescriptor_init_zero {{{NULL}, NULL}, 0, 0, 0}
#define mrc_proto_ProtobufJoystickDescriptors_init_zero {{{NULL}, NULL}}
#define mrc_proto_ProtobufJoystickOutput_init_zero {0, 0, 0}
@@ -209,6 +210,7 @@ typedef struct _mrc_proto_ProtobufConsoleLineTimestamp {
#define mrc_proto_ProtobufControlData_Joysticks_tag 3
#define mrc_proto_ProtobufControlData_CurrentOpMode_tag 4
#define mrc_proto_ProtobufControlData_ControlWord_tag 5
#define mrc_proto_ProtobufControlData_GameData_tag 6
#define mrc_proto_ProtobufJoystickDescriptor_JoystickName_tag 1
#define mrc_proto_ProtobufJoystickDescriptor_IsGamepad_tag 2
#define mrc_proto_ProtobufJoystickDescriptor_GamepadType_tag 3
@@ -272,7 +274,8 @@ X(a, CALLBACK, REPEATED, MESSAGE, Touchpads, 7)
X(a, STATIC, SINGULAR, INT32, MatchTime, 2) \
X(a, CALLBACK, REPEATED, MESSAGE, Joysticks, 3) \
X(a, STATIC, SINGULAR, FIXED64, CurrentOpMode, 4) \
X(a, STATIC, SINGULAR, UINT32, ControlWord, 5)
X(a, STATIC, SINGULAR, UINT32, ControlWord, 5) \
X(a, CALLBACK, SINGULAR, STRING, GameData, 6)
#define mrc_proto_ProtobufControlData_CALLBACK pb_default_field_callback
#define mrc_proto_ProtobufControlData_DEFAULT NULL
#define mrc_proto_ProtobufControlData_Joysticks_MSGTYPE mrc_proto_ProtobufJoystickData

View File

@@ -266,6 +266,15 @@ public class DriverStationJNI extends JNIWrapper {
*/
public static native int getMatchInfo(MatchInfoData info);
/**
* Gets the game-specific data for the current match.
*
* @param gameData The existing game data string.
* @return the game-specific data
* @see "HAL_GetGameData"
*/
public static native String getGameData(String gameData);
/**
* Sends an error to the driver station.
*

View File

@@ -10,9 +10,6 @@ public class MatchInfoData {
/** Stores the event name. */
public String eventName = "";
/** Stores the game specific message. */
public String gameSpecificMessage = "";
/** Stores the match number. */
public int matchNumber;
@@ -29,19 +26,12 @@ public class MatchInfoData {
* Called from JNI to set the structure data.
*
* @param eventName Event name.
* @param gameSpecificMessage Game-specific message.
* @param matchNumber Match number.
* @param replayNumber Replay number.
* @param matchType Match type.
*/
public void setData(
String eventName,
String gameSpecificMessage,
int matchNumber,
int replayNumber,
int matchType) {
public void setData(String eventName, int matchNumber, int replayNumber, int matchType) {
this.eventName = eventName;
this.gameSpecificMessage = gameSpecificMessage;
this.matchNumber = matchNumber;
this.replayNumber = replayNumber;
this.matchType = matchType;

View File

@@ -109,11 +109,9 @@ public class DriverStationDataJNI extends JNIWrapper {
public static native int getJoystickRumble(int stick, int rumbleNum);
public static native void setMatchInfo(
String eventName,
String gameSpecificMessage,
int matchNumber,
int replayNumber,
int matchType);
String eventName, int matchNumber, int replayNumber, int matchType);
public static native void setGameData(String gameData);
public static native void registerAllCallbacks(NotifyCallback callback, boolean initialNotify);
@@ -150,8 +148,6 @@ public class DriverStationDataJNI extends JNIWrapper {
public static native void setJoystickSupportedOutputs(int stick, int supportedOutputs);
public static native void setGameSpecificMessage(String message);
public static native void setEventName(String name);
public static native void setMatchType(int type);

View File

@@ -312,6 +312,29 @@ Java_org_wpilib_hardware_hal_DriverStationJNI_getMatchInfo
return status;
}
/*
* Class: org_wpilib_hardware_hal_DriverStationJNI
* Method: getGameData
* Signature: (Ljava/lang/String;)Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL
Java_org_wpilib_hardware_hal_DriverStationJNI_getGameData
(JNIEnv* env, jclass, jstring existing)
{
HAL_GameData gameData;
HAL_GetGameData(&gameData);
std::string_view newView{gameData.gameData};
if (existing != nullptr) {
// Load existing, see if it matches return old
JStringRef existingStr{env, existing};
std::string_view existingView{existingStr};
if (existingView == newView) {
return existing;
}
}
return MakeJString(env, newView);
}
/*
* Class: org_wpilib_hardware_hal_DriverStationJNI
* Method: sendError

View File

@@ -284,17 +284,12 @@ void SetCanStatusObject(JNIEnv* env, jobject canStatus,
void SetMatchInfoObject(JNIEnv* env, jobject matchStatus,
const HAL_MatchInfo& matchInfo) {
static jmethodID func =
env->GetMethodID(matchInfoDataCls, "setData",
"(Ljava/lang/String;Ljava/lang/String;III)V");
env->GetMethodID(matchInfoDataCls, "setData", "(Ljava/lang/String;III)V");
env->CallVoidMethod(
matchStatus, func, MakeJString(env, matchInfo.eventName),
MakeJString(env,
{reinterpret_cast<const char*>(matchInfo.gameSpecificMessage),
matchInfo.gameSpecificMessageSize}),
static_cast<jint>(matchInfo.matchNumber),
static_cast<jint>(matchInfo.replayNumber),
static_cast<jint>(matchInfo.matchType));
env->CallVoidMethod(matchStatus, func, MakeJString(env, matchInfo.eventName),
static_cast<jint>(matchInfo.matchNumber),
static_cast<jint>(matchInfo.replayNumber),
static_cast<jint>(matchInfo.matchType));
}
jbyteArray SetCANReceiveMessageObject(JNIEnv* env, jobject canData,

View File

@@ -583,31 +583,39 @@ Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_getJoystickRumble
/*
* Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI
* Method: setMatchInfo
* Signature: (Ljava/lang/String;Ljava/lang/String;III)V
* Signature: (Ljava/lang/String;III)V
*/
JNIEXPORT void JNICALL
Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setMatchInfo
(JNIEnv* env, jclass, jstring eventName, jstring gameSpecificMessage,
jint matchNumber, jint replayNumber, jint matchType)
(JNIEnv* env, jclass, jstring eventName, jint matchNumber, jint replayNumber,
jint matchType)
{
JStringRef eventNameRef{env, eventName};
JStringRef gameSpecificMessageRef{env, gameSpecificMessage};
HAL_MatchInfo halMatchInfo;
wpi::util::format_to_n_c_str(halMatchInfo.eventName,
sizeof(halMatchInfo.eventName), "{}",
eventNameRef.str());
wpi::util::format_to_n_c_str(
reinterpret_cast<char*>(halMatchInfo.gameSpecificMessage),
sizeof(halMatchInfo.gameSpecificMessage), "{}",
gameSpecificMessageRef.str());
halMatchInfo.gameSpecificMessageSize = gameSpecificMessageRef.size();
halMatchInfo.matchType = (HAL_MatchType)matchType;
halMatchInfo.matchNumber = matchNumber;
halMatchInfo.replayNumber = replayNumber;
HALSIM_SetMatchInfo(&halMatchInfo);
}
/*
* Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI
* Method: setGameData
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setGameData
(JNIEnv* env, jclass, jstring gameData)
{
JStringRef gameDataRef{env, gameData};
auto str = wpi::util::make_string(gameDataRef.str());
HALSIM_SetGameDataString(&str);
}
/*
* Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI
* Method: registerAllCallbacks
@@ -838,20 +846,6 @@ Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setJoystickName
HALSIM_SetJoystickName(stick, &str);
}
/*
* Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI
* Method: setGameSpecificMessage
* Signature: (Ljava/lang/String;)V
*/
JNIEXPORT void JNICALL
Java_org_wpilib_hardware_hal_simulation_DriverStationDataJNI_setGameSpecificMessage
(JNIEnv* env, jclass, jstring message)
{
JStringRef messageJString{env, message};
auto str = wpi::util::make_string(messageJString);
HALSIM_SetGameSpecificMessage(&str);
}
/*
* Class: org_wpilib_hardware_hal_simulation_DriverStationDataJNI
* Method: setEventName

View File

@@ -2,6 +2,7 @@
// Open Source Software; you can modify and/or share it under the terms of
// the WPILib BSD license file in the root directory of this project.
#include <string>
#include <utility>
#include "wpi/hal/proto/ControlData.h"
@@ -65,12 +66,14 @@ constexpr mrc::ControlFlags ToControlWord(uint32_t Word) {
std::optional<mrc::ControlData> wpi::util::Protobuf<mrc::ControlData>::Unpack(
InputStream& Stream) {
wpi::util::UnpackCallback<mrc::Joystick, MRC_MAX_NUM_JOYSTICKS> JoystickCb;
wpi::util::UnpackCallback<std::string> GameDataCb;
mrc_proto_ProtobufControlData Msg{
.MatchTime = 0,
.Joysticks = JoystickCb.Callback(),
.CurrentOpMode = 0,
.ControlWord = 0,
.GameData = GameDataCb.Callback(),
};
if (!Stream.Decode(Msg)) {
@@ -78,6 +81,7 @@ std::optional<mrc::ControlData> wpi::util::Protobuf<mrc::ControlData>::Unpack(
}
auto Joysticks = JoystickCb.Items();
auto GameData = GameDataCb.Items();
mrc::ControlData ControlData;
@@ -90,6 +94,10 @@ std::optional<mrc::ControlData> wpi::util::Protobuf<mrc::ControlData>::Unpack(
ControlData.Joysticks()[i] = std::move(Joysticks[i]);
}
if (GameData.size() >= 1) {
ControlData.MoveGameData(std::move(GameData[0]));
}
return ControlData;
}
@@ -97,12 +105,15 @@ bool wpi::util::Protobuf<mrc::ControlData>::Pack(
OutputStream& Stream, const mrc::ControlData& Value) {
std::span<const mrc::Joystick> Sticks = Value.Joysticks();
wpi::util::PackCallback Joysticks{Sticks};
std::string_view GameData = Value.GetGameData();
wpi::util::PackCallback GameDataCb{&GameData};
mrc_proto_ProtobufControlData Msg{
.MatchTime = Value.MatchTime,
.Joysticks = Joysticks.Callback(),
.CurrentOpMode = Value.CurrentOpMode.ToValue(),
.ControlWord = FromControlWord(Value.ControlWord),
.GameData = GameDataCb.Callback(),
};
return Stream.Encode(Msg);

View File

@@ -179,6 +179,14 @@ HAL_Bool HAL_GetJoystickIsGamepad(int32_t joystickNum);
*/
int32_t HAL_GetJoystickGamepadType(int32_t joystickNum);
/**
* Gets the game-specific message for the current match.
*
* @param gameData the game-specific message (output)
* @return the error code, or 0 for success
*/
int32_t HAL_GetGameData(HAL_GameData* gameData);
/**
* Gets the supported outputs of a specific joystick.
*

View File

@@ -153,6 +153,11 @@ struct HAL_JoystickTouchpads {
};
typedef struct HAL_JoystickTouchpads HAL_JoystickTouchpads;
struct HAL_GameData {
char gameData[9];
};
typedef struct HAL_GameData HAL_GameData;
struct HAL_JoystickDescriptor {
uint8_t isGamepad;
uint8_t gamepadType;
@@ -166,8 +171,6 @@ struct HAL_MatchInfo {
HAL_MatchType matchType;
uint16_t matchNumber;
uint8_t replayNumber;
uint8_t gameSpecificMessage[64];
uint16_t gameSpecificMessageSize;
};
typedef struct HAL_MatchInfo HAL_MatchInfo;

View File

@@ -36,6 +36,8 @@ typedef void (*HAL_JoystickRumblesCallback)(
int32_t rightRumble, int32_t leftTriggerRumble, int32_t rightTriggerRumble);
typedef void (*HAL_MatchInfoCallback)(const char* name, void* param,
const HAL_MatchInfo* info);
typedef void (*HAL_GameDataCallback)(const char* name, void* param,
const HAL_GameData* gameData);
#ifdef __cplusplus
extern "C" {
@@ -171,6 +173,12 @@ void HALSIM_CancelMatchInfoCallback(int32_t uid);
void HALSIM_GetMatchInfo(HAL_MatchInfo* info);
void HALSIM_SetMatchInfo(const HAL_MatchInfo* info);
int32_t HALSIM_RegisterGameDataCallback(HAL_GameDataCallback callback,
void* param, HAL_Bool initialNotify);
void HALSIM_CancelGameDataCallback(int32_t uid);
void HALSIM_GetGameData(HAL_GameData* gameData);
void HALSIM_SetGameData(const HAL_GameData* gameData);
void HALSIM_SetJoystickButton(int32_t stick, int32_t button, HAL_Bool state);
void HALSIM_SetJoystickAxis(int32_t stick, int32_t axis, double value);
void HALSIM_SetJoystickPOV(int32_t stick, int32_t pov, HAL_JoystickPOV value);
@@ -193,7 +201,7 @@ void HALSIM_SetJoystickName(int32_t stick, const struct WPI_String* name);
void HALSIM_SetJoystickSupportedOutputs(int32_t stick,
int32_t supportedOutputs);
void HALSIM_SetGameSpecificMessage(const struct WPI_String* message);
void HALSIM_SetGameDataString(const struct WPI_String* name);
void HALSIM_SetEventName(const struct WPI_String* name);
void HALSIM_SetMatchType(HAL_MatchType type);
void HALSIM_SetMatchNumber(int32_t matchNumber);

View File

@@ -47,6 +47,7 @@ struct JoystickDataCache {
HAL_AllianceStationID allianceStation;
double matchTime;
HAL_ControlWord controlWord;
HAL_GameData gameData;
};
static_assert(std::is_standard_layout_v<JoystickDataCache>);
// static_assert(std::is_trivial_v<JoystickDataCache>);
@@ -75,6 +76,7 @@ void JoystickDataCache::Update() {
SimDriverStationData->opMode, SimDriverStationData->robotMode,
SimDriverStationData->enabled, SimDriverStationData->eStop,
SimDriverStationData->fmsAttached, SimDriverStationData->dsAttached);
SimDriverStationData->GetGameData(&gameData);
}
#define CHECK_JOYSTICK_NUMBER(stickNum) \
@@ -345,6 +347,15 @@ int32_t HAL_GetJoystickGamepadType(int32_t joystickNum) {
}
}
int32_t HAL_GetGameData(HAL_GameData* gameData) {
if (gShutdown) {
return INCOMPATIBLE_STATE;
}
std::scoped_lock lock{driverStation->cacheMutex};
*gameData = currentRead->gameData;
return 0;
}
int32_t HAL_GetJoystickSupportedOutputs(int32_t joystickNum) {
HAL_JoystickDescriptor joystickDesc;
if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {

View File

@@ -336,6 +336,33 @@ void DriverStationData::SetMatchInfo(const HAL_MatchInfo* info) {
m_matchInfoCallbacks(info);
}
int32_t DriverStationData::RegisterGameDataCallback(
HAL_GameDataCallback callback, void* param, HAL_Bool initialNotify) {
std::scoped_lock lock(m_gameDataMutex);
int32_t uid = m_gameDataCallbacks.Register(callback, param);
if (initialNotify) {
callback(GetGameDataName(), param, &m_gameData);
}
return uid;
}
void DriverStationData::CancelGameDataCallback(int32_t uid) {
m_gameDataCallbacks.Cancel(uid);
}
void DriverStationData::GetGameData(HAL_GameData* gameData) {
std::scoped_lock lock(m_gameDataMutex);
*gameData = m_gameData;
}
void DriverStationData::SetGameData(std::string_view gameData) {
std::scoped_lock lock(m_gameDataMutex);
auto copied =
gameData.copy(m_gameData.gameData, sizeof(m_gameData.gameData) - 1);
m_gameData.gameData[copied] = '\0';
m_gameDataCallbacks(&m_gameData);
}
int32_t DriverStationData::RegisterNewDataCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {
@@ -537,15 +564,6 @@ void DriverStationData::SetJoystickName(int32_t stick, std::string_view name) {
m_joystickDescriptorCallbacks(stick, &m_joystickData[stick].descriptor);
}
void DriverStationData::SetGameSpecificMessage(std::string_view message) {
std::scoped_lock lock(m_matchInfoMutex);
auto copied =
message.copy(reinterpret_cast<char*>(m_matchInfo.gameSpecificMessage),
sizeof(m_matchInfo.gameSpecificMessage));
m_matchInfo.gameSpecificMessageSize = copied;
m_matchInfoCallbacks(&m_matchInfo);
}
void DriverStationData::SetEventName(std::string_view name) {
std::scoped_lock lock(m_matchInfoMutex);
auto copied =
@@ -708,6 +726,24 @@ void HALSIM_SetMatchInfo(const HAL_MatchInfo* info) {
SimDriverStationData->SetMatchInfo(info);
}
int32_t HALSIM_RegisterGameDataCallback(HAL_GameDataCallback callback,
void* param, HAL_Bool initialNotify) {
return SimDriverStationData->RegisterGameDataCallback(callback, param,
initialNotify);
}
void HALSIM_CancelGameDataCallback(int32_t uid) {
SimDriverStationData->CancelGameDataCallback(uid);
}
void HALSIM_GetGameData(HAL_GameData* gameData) {
SimDriverStationData->GetGameData(gameData);
}
void HALSIM_SetGameData(const HAL_GameData* gameData) {
SimDriverStationData->SetGameData(gameData->gameData);
}
int32_t HALSIM_RegisterDriverStationNewDataCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {
@@ -788,9 +824,8 @@ void HALSIM_SetJoystickName(int32_t stick, const WPI_String* name) {
SimDriverStationData->SetJoystickName(stick, wpi::util::to_string_view(name));
}
void HALSIM_SetGameSpecificMessage(const WPI_String* message) {
SimDriverStationData->SetGameSpecificMessage(
wpi::util::to_string_view(message));
void HALSIM_SetGameDataString(const WPI_String* message) {
SimDriverStationData->SetGameData(wpi::util::to_string_view(message));
}
void HALSIM_SetEventName(const WPI_String* name) {

View File

@@ -36,6 +36,7 @@ class DriverStationData {
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickRumbles)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(JoystickTouchpads)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(MatchInfo)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(GameData)
HAL_SIMCALLBACKREGISTRY_DEFINE_NAME(NewData)
static LLVM_ATTRIBUTE_ALWAYS_INLINE HAL_Value
@@ -124,6 +125,11 @@ class DriverStationData {
void GetMatchInfo(HAL_MatchInfo* info);
void SetMatchInfo(const HAL_MatchInfo* info);
int32_t RegisterGameDataCallback(HAL_GameDataCallback callback, void* param,
HAL_Bool initialNotify);
void CancelGameDataCallback(int32_t uid);
void GetGameData(HAL_GameData* gameData);
void FreeMatchInfo(const HAL_MatchInfo* info);
int32_t RegisterNewDataCallback(HAL_NotifyCallback callback, void* param,
@@ -154,7 +160,7 @@ class DriverStationData {
void SetJoystickName(int32_t stick, std::string_view message);
void SetJoystickSupportedOutputs(int32_t stick, int32_t supportedOutputs);
void SetGameSpecificMessage(std::string_view message);
void SetGameData(std::string_view message);
void SetEventName(std::string_view name);
void SetMatchType(HAL_MatchType type);
void SetMatchNumber(int32_t matchNumber);
@@ -192,6 +198,8 @@ class DriverStationData {
m_joystickDescriptorCallbacks;
SimCallbackRegistry<HAL_MatchInfoCallback, GetMatchInfoName>
m_matchInfoCallbacks;
SimCallbackRegistry<HAL_GameDataCallback, GetGameDataName>
m_gameDataCallbacks;
SimCallbackRegistry<HAL_NotifyCallback, GetNewDataName> m_newDataCallbacks;
struct JoystickOutputStore {
@@ -218,6 +226,9 @@ class DriverStationData {
wpi::util::spinlock m_matchInfoMutex;
HAL_MatchInfo m_matchInfo;
wpi::util::spinlock m_gameDataMutex;
HAL_GameData m_gameData;
wpi::util::spinlock m_opModeMutex;
std::vector<HAL_OpModeOption> m_opModeOptions;
};

View File

@@ -63,6 +63,7 @@ struct JoystickDataCache {
HAL_AllianceStationID allianceStation;
float matchTime;
HAL_ControlWord controlWord;
HAL_GameData gameData;
};
static_assert(std::is_standard_layout_v<JoystickDataCache>);
// static_assert(std::is_trivial_v<JoystickDataCache>);
@@ -77,7 +78,6 @@ struct SystemServerDriverStation {
wpi::nt::ProtobufSubscriber<mrc::ControlData> controlDataSubscriber;
wpi::nt::ProtobufSubscriber<mrc::MatchInfo> matchInfoSubscriber;
wpi::nt::StringSubscriber gameSpecificMessageSubscriber;
wpi::nt::ProtobufSubscriber<mrc::JoystickDescriptors>
joystickDescriptorsTopic;
@@ -145,8 +145,6 @@ struct SystemServerDriverStation {
matchInfoSubscriber =
ntInst.GetProtobufTopic<mrc::MatchInfo>(ROBOT_MATCH_INFO_PATH)
.Subscribe({});
gameSpecificMessageSubscriber =
ntInst.GetStringTopic(ROBOT_GAME_SPECIFIC_MESSAGE_PATH).Subscribe({});
joystickDescriptorsTopic = ntInst
.GetProtobufTopic<mrc::JoystickDescriptors>(
@@ -239,6 +237,13 @@ void JoystickDataCache::Update(const mrc::ControlData& data) {
allianceInt += 1;
allianceStation = static_cast<HAL_AllianceStationID>(allianceInt);
auto gameData = data.GetGameData();
if (gameData.size() > 8) {
gameData = gameData.substr(0, 8);
}
std::memcpy(this->gameData.gameData, gameData.data(), gameData.size());
this->gameData.gameData[gameData.size()] = '\0';
if (data.ControlWord.SupportsOpModes) {
controlWord = HAL_MakeControlWord(
data.CurrentOpMode.ToValue(),
@@ -328,7 +333,6 @@ static wpi::util::mutex tcpCacheMutex;
void TcpCache::Update() {
auto newMatchInfo = systemServerDs->matchInfoSubscriber.Get();
auto gameMsg = systemServerDs->gameSpecificMessageSubscriber.Get();
matchInfo.matchNumber = newMatchInfo.MatchNumber;
matchInfo.matchType = static_cast<HAL_MatchType>(newMatchInfo.Type);
@@ -343,14 +347,6 @@ void TcpCache::Update() {
}
matchInfo.eventName[nameLen] = '\0';
auto gameDataLen =
(std::min)(sizeof(matchInfo.gameSpecificMessage), gameMsg.size());
if (gameDataLen > 0) {
std::memcpy(matchInfo.gameSpecificMessage, gameMsg.data(), gameDataLen);
}
matchInfo.gameSpecificMessageSize = gameDataLen;
const auto descriptorsMsg = systemServerDs->joystickDescriptorsTopic.Get();
size_t descriptorCount = descriptorsMsg.GetDescriptorCount();
@@ -617,6 +613,12 @@ int32_t HAL_GetJoystickGamepadType(int32_t joystickNum) {
}
}
int32_t HAL_GetGameData(HAL_GameData* gameData) {
std::scoped_lock lock{cacheMutex};
*gameData = currentRead->gameData;
return 0;
}
int32_t HAL_GetJoystickSupportedOutputs(int32_t joystickNum) {
HAL_JoystickDescriptor joystickDesc;
if (HAL_GetJoystickDescriptor(joystickNum, &joystickDesc) < 0) {

View File

@@ -101,6 +101,17 @@ void HALSIM_GetMatchInfo(HAL_MatchInfo* info) {}
void HALSIM_SetMatchInfo(const HAL_MatchInfo* info) {}
int32_t HALSIM_RegisterGameDataCallback(HAL_GameDataCallback callback,
void* param, HAL_Bool initialNotify) {
return 0;
}
void HALSIM_CancelGameDataCallback(int32_t uid) {}
void HALSIM_GetGameData(HAL_GameData* info) {}
void HALSIM_SetGameData(const HAL_GameData* info) {}
int32_t HALSIM_RegisterDriverStationNewDataCallback(HAL_NotifyCallback callback,
void* param,
HAL_Bool initialNotify) {
@@ -149,7 +160,7 @@ void HALSIM_SetJoystickName(int32_t stick, const struct WPI_String* name) {}
void HALSIM_SetJoystickSupportedOutputs(int32_t stick,
int32_t supportedOutputs) {}
void HALSIM_SetGameSpecificMessage(const struct WPI_String* message) {}
void HALSIM_SetGameDataString(const struct WPI_String* message) {}
void HALSIM_SetEventName(const struct WPI_String* name) {}

View File

@@ -43,3 +43,4 @@ functions:
HAL_ObserveUserProgram:
GetControlWord:
GetUncachedControlWord:
HAL_GetGameData:

View File

@@ -45,8 +45,6 @@ classes:
matchType:
matchNumber:
replayNumber:
gameSpecificMessage:
gameSpecificMessageSize:
HAL_JoystickTouchpadFinger:
attributes:
down:
@@ -93,6 +91,9 @@ classes:
IsTest:
IsTestEnabled:
GetValue:
HAL_GameData:
attributes:
gameData:
functions:
HAL_MakeControlWord:
HAL_ControlWord_GetOpModeHash:

View File

@@ -68,6 +68,11 @@ functions:
HALSIM_CancelMatchInfoCallback:
HALSIM_GetMatchInfo:
HALSIM_SetMatchInfo:
HALSIM_RegisterGameDataCallback:
ignore: true
HALSIM_CancelGameDataCallback:
HALSIM_GetGameData:
HALSIM_SetGameData:
HALSIM_SetJoystickButton:
HALSIM_SetJoystickAxis:
HALSIM_SetJoystickPOV:
@@ -80,11 +85,11 @@ functions:
auto s = wpi::util::make_string(sv);
HALSIM_SetJoystickName(stick, &s);
}
HALSIM_SetGameSpecificMessage:
HALSIM_SetGameDataString:
cpp_code: |
[](std::string_view sv) {
auto s = wpi::util::make_string(sv);
HALSIM_SetGameSpecificMessage(&s);
HALSIM_SetGameDataString(&s);
}
HALSIM_SetEventName:
cpp_code: |

View File

@@ -253,6 +253,22 @@ struct ControlData {
uint16_t MatchTime{0};
OpModeHash CurrentOpMode;
void SetGameData(std::string_view Data) {
if (Data.size() > MRC_MAX_GAME_DATA_LEN) {
Data = Data.substr(0, MRC_MAX_GAME_DATA_LEN);
}
GameData = Data;
}
void MoveGameData(std::string&& Data) {
GameData = std::move(Data);
if (GameData.size() > MRC_MAX_GAME_DATA_LEN) {
GameData.resize(MRC_MAX_GAME_DATA_LEN);
}
}
std::string_view GetGameData() const { return GameData; }
std::span<Joystick> Joysticks() {
return std::span{JoysticksStore.data(), GetJoystickCount()};
}
@@ -269,6 +285,7 @@ struct ControlData {
}
private:
std::string GameData;
std::array<Joystick, MRC_MAX_NUM_JOYSTICKS> JoysticksStore;
uint8_t JoystickCount{0};
};
@@ -514,24 +531,24 @@ struct OpMode {
OpModeHash Hash;
void SetName(std::string_view NewName) {
if (NewName.size() > MRC_MAX_OPMODE_LEN) {
NewName = NewName.substr(0, MRC_MAX_OPMODE_LEN);
if (NewName.size() > MRC_MAX_OPMODE_STRING_LEN) {
NewName = NewName.substr(0, MRC_MAX_OPMODE_STRING_LEN);
}
Name = NewName;
}
void MoveName(std::string&& NewName) {
Name = std::move(NewName);
if (Name.size() > MRC_MAX_OPMODE_LEN) {
Name.resize(MRC_MAX_OPMODE_LEN);
if (Name.size() > MRC_MAX_OPMODE_STRING_LEN) {
Name.resize(MRC_MAX_OPMODE_STRING_LEN);
}
}
std::string_view GetName() const { return Name; }
std::span<uint8_t> WritableNameBuffer(size_t Len) {
if (Len > MRC_MAX_OPMODE_LEN) {
Len = MRC_MAX_OPMODE_LEN;
if (Len > MRC_MAX_OPMODE_STRING_LEN) {
Len = MRC_MAX_OPMODE_STRING_LEN;
}
Name.resize(Len);
return std::span<uint8_t>{reinterpret_cast<uint8_t*>(Name.data()),
@@ -539,24 +556,24 @@ struct OpMode {
}
void SetGroup(std::string_view NewGroup) {
if (NewGroup.size() > MRC_MAX_OPMODE_LEN) {
NewGroup = NewGroup.substr(0, MRC_MAX_OPMODE_LEN);
if (NewGroup.size() > MRC_MAX_OPMODE_STRING_LEN) {
NewGroup = NewGroup.substr(0, MRC_MAX_OPMODE_STRING_LEN);
}
Group = NewGroup;
}
void MoveGroup(std::string&& NewGroup) {
Group = std::move(NewGroup);
if (Group.size() > MRC_MAX_OPMODE_LEN) {
Group.resize(MRC_MAX_OPMODE_LEN);
if (Group.size() > MRC_MAX_OPMODE_STRING_LEN) {
Group.resize(MRC_MAX_OPMODE_STRING_LEN);
}
}
std::string_view GetGroup() const { return Group; }
std::span<uint8_t> WritableGroupBuffer(size_t Len) {
if (Len > MRC_MAX_OPMODE_LEN) {
Len = MRC_MAX_OPMODE_LEN;
if (Len > MRC_MAX_OPMODE_STRING_LEN) {
Len = MRC_MAX_OPMODE_STRING_LEN;
}
Group.resize(Len);
return std::span<uint8_t>{reinterpret_cast<uint8_t*>(Group.data()),
@@ -564,24 +581,24 @@ struct OpMode {
}
void SetDescription(std::string_view NewDescription) {
if (NewDescription.size() > MRC_MAX_OPMODE_LEN) {
NewDescription = NewDescription.substr(0, MRC_MAX_OPMODE_LEN);
if (NewDescription.size() > MRC_MAX_OPMODE_STRING_LEN) {
NewDescription = NewDescription.substr(0, MRC_MAX_OPMODE_STRING_LEN);
}
Description = NewDescription;
}
void MoveDescription(std::string&& NewDescription) {
Description = std::move(NewDescription);
if (Description.size() > MRC_MAX_OPMODE_LEN) {
Description.resize(MRC_MAX_OPMODE_LEN);
if (Description.size() > MRC_MAX_OPMODE_STRING_LEN) {
Description.resize(MRC_MAX_OPMODE_STRING_LEN);
}
}
std::string_view GetDescription() const { return Description; }
std::span<uint8_t> WritableDescriptionBuffer(size_t Len) {
if (Len > MRC_MAX_OPMODE_LEN) {
Len = MRC_MAX_OPMODE_LEN;
if (Len > MRC_MAX_OPMODE_STRING_LEN) {
Len = MRC_MAX_OPMODE_STRING_LEN;
}
Description.resize(Len);
return std::span<uint8_t>{reinterpret_cast<uint8_t*>(Description.data()),

View File

@@ -10,8 +10,6 @@
#define ROBOT_WATCHDOG_ACTIVE_PATH (ROBOT_CONTROL_DATA_PREFIX "WatchdogActive")
#define ROBOT_CONTROL_DATA_PATH (ROBOT_CONTROL_DATA_PREFIX "ControlData")
#define ROBOT_GAME_SPECIFIC_MESSAGE_PATH \
(ROBOT_CONTROL_DATA_PREFIX "GameSpecificMessage")
#define ROBOT_MATCH_INFO_PATH (ROBOT_CONTROL_DATA_PREFIX "MatchInfo")
#define ROBOT_JOYSTICK_DESCRIPTORS_PATH \
(ROBOT_CONTROL_DATA_PREFIX "JoystickDescriptors")
@@ -58,8 +56,8 @@
#define MRC_MAX_NUM_AXES 12
#define MRC_MAX_NUM_POVS 8
#define MRC_MAX_NUM_BUTTONS 64
#define MRC_MAX_OPMODE_LEN 128
#define MRC_MAX_GAME_SPECIFIC_MESSAGE_LEN 128
#define MRC_MAX_OPMODE_STRING_LEN 64
#define MRC_MAX_GAME_DATA_LEN 8
#define MRC_MAX_EVENT_NAME_LEN 64
#define MRC_MAX_JOYSTICK_NAME_LEN 256
#define MRC_MAX_VERSION_SIZE 256

View File

@@ -31,6 +31,7 @@ message ProtobufControlData {
int32 MatchTime = 2;
repeated ProtobufJoystickData Joysticks = 3;
fixed64 CurrentOpMode = 4;
string GameData = 6;
}
message ProtobufJoystickDescriptor {

View File

@@ -121,14 +121,9 @@ TEST(DriverStationTest, Joystick) {
TEST(DriverStationTest, EventInfo) {
constexpr std::string_view eventName = "UnitTest";
constexpr std::string_view gameData = "Insert game specific info here :D";
HAL_MatchInfo info;
wpi::util::format_to_n_c_str(info.eventName, sizeof(info.eventName),
eventName);
wpi::util::format_to_n_c_str(
reinterpret_cast<char*>(info.gameSpecificMessage),
sizeof(info.gameSpecificMessage), gameData);
info.gameSpecificMessageSize = gameData.size();
info.matchNumber = 5;
info.matchType = HAL_MatchType::HAL_kMatchType_qualification;
info.replayNumber = 42;
@@ -139,11 +134,7 @@ TEST(DriverStationTest, EventInfo) {
HAL_MatchInfo dataBack;
HAL_GetMatchInfo(&dataBack);
std::string gsm{reinterpret_cast<char*>(dataBack.gameSpecificMessage),
dataBack.gameSpecificMessageSize};
EXPECT_EQ(eventName, dataBack.eventName);
EXPECT_EQ(gameData, gsm);
EXPECT_EQ(5, dataBack.matchNumber);
EXPECT_EQ(HAL_MatchType::HAL_kMatchType_qualification, dataBack.matchType);
EXPECT_EQ(42, dataBack.replayNumber);

View File

@@ -44,7 +44,6 @@ DSCommPacket::DSCommPacket() {
i.ResetTcp();
i.ResetUdp();
}
matchInfo.gameSpecificMessageSize = 0;
}
/*----------------------------------------------------------------------------
@@ -160,9 +159,6 @@ void DSCommPacket::DecodeTCP(std::span<const uint8_t> packet) {
case kJoystickNameTag:
ReadJoystickDescriptionTag(tagPacket);
break;
case kGameDataTag:
ReadGameSpecificMessageTag(tagPacket);
break;
case kMatchInfoTag:
ReadNewMatchInfoTag(tagPacket);
break;
@@ -240,22 +236,6 @@ void DSCommPacket::ReadNewMatchInfoTag(std::span<const uint8_t> data) {
HALSIM_SetMatchInfo(&matchInfo);
}
void DSCommPacket::ReadGameSpecificMessageTag(std::span<const uint8_t> data) {
// Size 2 bytes, tag 1 byte
if (data.size() <= 3) {
return;
}
int length = std::min<size_t>(((data[0] << 8) | data[1]) - 1,
sizeof(matchInfo.gameSpecificMessage));
for (int i = 0; i < length; i++) {
matchInfo.gameSpecificMessage[i] = data[3 + i];
}
matchInfo.gameSpecificMessageSize = length;
HALSIM_SetMatchInfo(&matchInfo);
}
void DSCommPacket::ReadJoystickDescriptionTag(std::span<const uint8_t> data) {
if (data.size() < 3) {
return;

View File

@@ -55,7 +55,6 @@ class DSCommPacket {
void ReadMatchtimeTag(std::span<const uint8_t> tagData);
void ReadJoystickTag(std::span<const uint8_t> data, int index);
void ReadNewMatchInfoTag(std::span<const uint8_t> data);
void ReadGameSpecificMessageTag(std::span<const uint8_t> data);
void ReadJoystickDescriptionTag(std::span<const uint8_t> data);
uint8_t m_hi;

View File

@@ -29,11 +29,6 @@ class DSCommPacketTest : public ::testing::Test {
return commPacket.matchInfo;
}
HAL_MatchInfo& ReadGameSpecificTag(std::span<const uint8_t> data) {
commPacket.ReadGameSpecificMessageTag(data);
return commPacket.matchInfo;
}
protected:
halsim::DSCommPacket commPacket;
};
@@ -132,24 +127,3 @@ TEST_F(DSCommPacketTest, MatchInfoTag) {
ASSERT_EQ(matchInfo.matchNumber, 18);
ASSERT_EQ(matchInfo.replayNumber, 1);
}
TEST_F(DSCommPacketTest, GameDataTag) {
uint8_t arr[]{
// Size (2), tag
0,
0,
17,
// Match data (length is taglength - 1)
'W',
'C',
'B',
'C',
};
arr[1] = sizeof(arr) - 2;
auto& matchInfo = ReadGameSpecificTag(arr);
ASSERT_EQ(matchInfo.gameSpecificMessageSize, 4);
ASSERT_EQ(matchInfo.gameSpecificMessage[0], 'W');
ASSERT_EQ(matchInfo.gameSpecificMessage[1], 'C');
ASSERT_EQ(matchInfo.gameSpecificMessage[2], 'B');
ASSERT_EQ(matchInfo.gameSpecificMessage[3], 'C');
}

View File

@@ -231,9 +231,7 @@ class FMSSimModel : public wpi::glass::FMSModel {
wpi::glass::IntegerSource* GetRobotModeData() override {
return &m_robotMode;
}
wpi::glass::StringSource* GetGameSpecificMessageData() override {
return &m_gameMessage;
}
wpi::glass::StringSource* GetGameData() override { return &m_gameMessage; }
void SetFmsAttached(bool val) override { m_fmsAttached.SetValue(val); }
void SetDsAttached(bool val) override { m_dsAttached.SetValue(val); }
@@ -244,7 +242,7 @@ class FMSSimModel : public wpi::glass::FMSModel {
void SetEStop(bool val) override { m_estop.SetValue(val); }
void SetEnabled(bool val) override { m_enabled.SetValue(val); }
void SetRobotMode(RobotMode val) override { m_robotMode.SetValue(val); }
void SetGameSpecificMessage(std::string_view val) override {
void SetGameData(std::string_view val) override {
m_gameMessage.SetValue(val);
}
@@ -265,7 +263,7 @@ class FMSSimModel : public wpi::glass::FMSModel {
wpi::glass::BooleanSource m_enabled{"FMS:RobotEnabled"};
wpi::glass::IntegerSource m_robotMode{"FMS:RobotMode"};
double m_startMatchTime = -1.0;
wpi::glass::StringSource m_gameMessage{"FMS:GameSpecificMessage"};
wpi::glass::StringSource m_gameMessage{"FMS:GameData"};
};
} // namespace
@@ -1319,7 +1317,7 @@ void FMSSimModel::UpdateHAL() {
static_cast<HAL_RobotMode>(m_robotMode.GetValue()));
HALSIM_SetDriverStationMatchTime(m_matchTime.GetValue());
auto str = wpi::util::make_string(m_gameMessage.GetValue());
HALSIM_SetGameSpecificMessage(&str);
HALSIM_SetGameDataString(&str);
HALSIM_SetDriverStationDsAttached(m_dsAttached.GetValue());
}
@@ -1353,12 +1351,10 @@ void FMSSimModel::Update() {
}
m_matchTime.SetValue(matchTime);
HAL_MatchInfo info;
HALSIM_GetMatchInfo(&info);
HAL_GameData info;
HALSIM_GetGameData(&info);
m_gameMessage.SetValue(
std::string_view{reinterpret_cast<const char*>(info.gameSpecificMessage),
reinterpret_cast<const char*>(info.gameSpecificMessage) +
info.gameSpecificMessageSize});
std::string_view{reinterpret_cast<const char*>(info.gameData)});
}
bool FMSSimModel::IsReadOnly() {

View File

@@ -166,7 +166,7 @@ void HALSimWSProviderDriverStation::OnNetValueChanged(
if ((it = json.find(">game_data")) != json.end()) {
std::string message = it.value().get_ref<const std::string&>();
auto str = wpi::util::make_string(message);
HALSIM_SetGameSpecificMessage(&str);
HALSIM_SetGameDataString(&str);
}
// Only notify usercode if we get the new data message

View File

@@ -93,8 +93,7 @@ struct MatchDataSender {
".type",
kSmartDashboardType,
{{"SmartDashboard", kSmartDashboardType}}};
MatchDataSenderEntry<wpi::nt::StringTopic> gameSpecificMessage{
table, "GameSpecificMessage", ""};
MatchDataSenderEntry<wpi::nt::StringTopic> gameData{table, "GameData", ""};
MatchDataSenderEntry<wpi::nt::StringTopic> eventName{table, "EventName", ""};
MatchDataSenderEntry<wpi::nt::IntegerTopic> matchNumber{table, "MatchNumber",
0};
@@ -701,11 +700,14 @@ std::string DriverStation::GetOpMode() {
return GetInstance().OpModeToString(GetOpModeId());
}
std::string DriverStation::GetGameSpecificMessage() {
HAL_MatchInfo info;
HAL_GetMatchInfo(&info);
return std::string(reinterpret_cast<char*>(info.gameSpecificMessage),
info.gameSpecificMessageSize);
std::optional<std::string> DriverStation::GetGameData() {
HAL_GameData info;
HAL_GetGameData(&info);
std::string_view gameDataView{reinterpret_cast<char*>(info.gameData)};
if (gameDataView.empty()) {
return std::nullopt;
}
return std::string(gameDataView);
}
std::string DriverStation::GetEventName() {
@@ -900,13 +902,15 @@ void SendMatchData() {
HAL_MatchInfo tmpDataStore;
HAL_GetMatchInfo(&tmpDataStore);
HAL_GameData tmpGameData;
HAL_GetGameData(&tmpGameData);
auto& inst = GetInstance();
inst.matchDataSender.alliance.Set(isRedAlliance);
inst.matchDataSender.station.Set(stationNumber);
inst.matchDataSender.eventName.Set(tmpDataStore.eventName);
inst.matchDataSender.gameSpecificMessage.Set(
std::string(reinterpret_cast<char*>(tmpDataStore.gameSpecificMessage),
tmpDataStore.gameSpecificMessageSize));
inst.matchDataSender.gameData.Set(
std::string(reinterpret_cast<char*>(tmpGameData.gameData)));
inst.matchDataSender.matchNumber.Set(tmpDataStore.matchNumber);
inst.matchDataSender.replayNumber.Set(tmpDataStore.replayNumber);
inst.matchDataSender.matchType.Set(static_cast<int>(tmpDataStore.matchType));

View File

@@ -301,9 +301,9 @@ void DriverStationSim::SetJoystickName(int stick, std::string_view name) {
HALSIM_SetJoystickName(stick, &str);
}
void DriverStationSim::SetGameSpecificMessage(std::string_view message) {
void DriverStationSim::SetGameData(std::string_view message) {
auto str = wpi::util::make_string(message);
HALSIM_SetGameSpecificMessage(&str);
HALSIM_SetGameDataString(&str);
}
void DriverStationSim::SetEventName(std::string_view name) {

View File

@@ -519,7 +519,7 @@ class DriverStation final {
*
* @return A string containing the game specific message.
*/
static std::string GetGameSpecificMessage();
static std::optional<std::string> GetGameData();
/**
* Returns the name of the competition event provided by the FMS.

View File

@@ -419,7 +419,7 @@ class DriverStationSim {
*
* @param message the game specific message
*/
static void SetGameSpecificMessage(std::string_view message);
static void SetGameData(std::string_view message);
/**
* Sets the event name.

View File

@@ -32,7 +32,7 @@ classes:
IsTestEnabled:
IsDSAttached:
IsFMSAttached:
GetGameSpecificMessage:
GetGameData:
GetEventName:
GetMatchType:
GetMatchNumber:

View File

@@ -55,7 +55,7 @@ classes:
SetJoystickGamepadType:
SetJoystickSupportedOutputs:
SetJoystickName:
SetGameSpecificMessage:
SetGameData:
SetEventName:
SetMatchType:
SetMatchNumber:

View File

@@ -240,14 +240,26 @@ TEST(DriverStationTest, MatchTime) {
EXPECT_EQ(kTestTime, callback.GetLastValue());
}
TEST(DriverStationTest, SetGameSpecificMessage) {
TEST(DriverStationTest, SetGameData) {
HAL_Initialize(500, 0);
DriverStationSim::ResetData();
constexpr auto message = "Hello World!";
DriverStationSim::SetGameSpecificMessage(message);
constexpr auto message = "Hello";
DriverStationSim::SetGameData(message);
DriverStationSim::NotifyNewData();
EXPECT_EQ(message, DriverStation::GetGameSpecificMessage());
auto gameData = DriverStation::GetGameData();
ASSERT_TRUE(gameData.has_value());
EXPECT_EQ(message, gameData.value());
}
TEST(DriverStationTest, SetGameDataEmpty) {
HAL_Initialize(500, 0);
DriverStationSim::ResetData();
DriverStationSim::SetGameData("");
DriverStationSim::NotifyNewData();
auto gameData = DriverStation::GetGameData();
EXPECT_FALSE(gameData.has_value());
}
TEST(DriverStationTest, SetEventName) {

View File

@@ -268,7 +268,7 @@ public final class DriverStation {
private static class MatchDataSender {
private static final String kSmartDashboardType = "FMSInfo";
final StringPublisher gameSpecificMessage;
final StringPublisher gameData;
final StringPublisher eventName;
final IntegerPublisher matchNumber;
final IntegerPublisher replayNumber;
@@ -280,7 +280,7 @@ public final class DriverStation {
boolean oldIsRedAlliance = true;
int oldStationNumber = 1;
String oldEventName = "";
String oldGameSpecificMessage = "";
String oldGameData = "";
int oldMatchNumber;
int oldReplayNumber;
int oldMatchType;
@@ -294,8 +294,8 @@ public final class DriverStation {
.publishEx(
StringTopic.kTypeString, "{\"SmartDashboard\":\"" + kSmartDashboardType + "\"}")
.set(kSmartDashboardType);
gameSpecificMessage = table.getStringTopic("GameSpecificMessage").publish();
gameSpecificMessage.set("");
gameData = table.getStringTopic("GameData").publish();
gameData.set("");
eventName = table.getStringTopic("EventName").publish();
eventName.set("");
matchNumber = table.getIntegerTopic("MatchNumber").publish();
@@ -330,14 +330,14 @@ public final class DriverStation {
};
String currentEventName;
String currentGameSpecificMessage;
String currentGameData;
int currentMatchNumber;
int currentReplayNumber;
int currentMatchType;
m_cacheDataMutex.lock();
try {
currentEventName = DriverStation.m_matchInfo.eventName;
currentGameSpecificMessage = DriverStation.m_matchInfo.gameSpecificMessage;
currentGameData = DriverStation.m_gameData;
currentMatchNumber = DriverStation.m_matchInfo.matchNumber;
currentReplayNumber = DriverStation.m_matchInfo.replayNumber;
currentMatchType = DriverStation.m_matchInfo.matchType;
@@ -358,9 +358,9 @@ public final class DriverStation {
eventName.set(currentEventName);
oldEventName = currentEventName;
}
if (!oldGameSpecificMessage.equals(currentGameSpecificMessage)) {
gameSpecificMessage.set(currentGameSpecificMessage);
oldGameSpecificMessage = currentGameSpecificMessage;
if (!oldGameData.equals(currentGameData)) {
gameData.set(currentGameData);
oldGameData = currentGameData;
}
if (currentMatchNumber != oldMatchNumber) {
matchNumber.set(currentMatchNumber);
@@ -547,6 +547,7 @@ public final class DriverStation {
private static HALJoystickTouchpads[] m_joystickTouchpads =
new HALJoystickTouchpads[kJoystickPorts];
private static MatchInfoData m_matchInfo = new MatchInfoData();
private static String m_gameData = "";
private static ControlWord m_controlWord = new ControlWord();
private static String m_opMode = "";
private static EventVector m_refreshEvents = new EventVector();
@@ -561,6 +562,7 @@ public final class DriverStation {
private static HALJoystickTouchpads[] m_joystickTouchpadsCache =
new HALJoystickTouchpads[kJoystickPorts];
private static MatchInfoData m_matchInfoCache = new MatchInfoData();
private static String m_gameDataCache = "";
private static ControlWord m_controlWordCache = new ControlWord();
private static String m_opModeCache = "";
@@ -1581,10 +1583,13 @@ public final class DriverStation {
*
* @return the game specific message
*/
public static String getGameSpecificMessage() {
public static Optional<String> getGameData() {
m_cacheDataMutex.lock();
try {
return m_matchInfo.gameSpecificMessage;
if (m_gameData == null || m_gameData.isEmpty()) {
return Optional.empty();
}
return Optional.of(m_gameData);
} finally {
m_cacheDataMutex.unlock();
}
@@ -1812,6 +1817,10 @@ public final class DriverStation {
DriverStationJNI.getMatchInfo(m_matchInfoCache);
// This is a pass through, so if it hasn't changed, it doesn't
// reallocate
m_gameDataCache = DriverStationJNI.getGameData(m_gameDataCache);
DriverStationJNI.getControlWord(m_controlWordCache);
m_opModeCache = opModeToString(m_controlWordCache.getOpModeId());
@@ -1855,6 +1864,8 @@ public final class DriverStation {
m_matchInfo = m_matchInfoCache;
m_matchInfoCache = currentInfo;
m_gameData = m_gameDataCache;
ControlWord currentWord = m_controlWord;
m_controlWord = m_controlWordCache;
m_controlWordCache = currentWord;

View File

@@ -505,8 +505,8 @@ public final class DriverStationSim {
*
* @param message the game specific message
*/
public static void setGameSpecificMessage(String message) {
DriverStationDataJNI.setGameSpecificMessage(message);
public static void setGameData(String message) {
DriverStationDataJNI.setGameData(message);
}
/**

View File

@@ -18,7 +18,7 @@ class MatchInfoDataTest {
@Test
void testSetMatchInfo() {
MatchType matchType = MatchType.Qualification;
DriverStationDataJNI.setMatchInfo("Event Name", "Game Message", 174, 191, matchType.ordinal());
DriverStationDataJNI.setMatchInfo("Event Name", 174, 191, matchType.ordinal());
DriverStationSim.notifyNewData();
@@ -29,7 +29,6 @@ class MatchInfoDataTest {
() -> assertEquals("Event Name", outMatchInfo.eventName),
() -> assertEquals(matchType.ordinal(), outMatchInfo.matchType),
() -> assertEquals(174, outMatchInfo.matchNumber),
() -> assertEquals(191, outMatchInfo.replayNumber),
() -> assertEquals("Game Message", outMatchInfo.gameSpecificMessage));
() -> assertEquals(191, outMatchInfo.replayNumber));
}
}

View File

@@ -262,14 +262,36 @@ class DriverStationSimTest {
}
@Test
void testSetGameSpecificMessage() {
void testSetGameData() {
HAL.initialize(500, 0);
DriverStationSim.resetData();
final String message = "Hello World!";
DriverStationSim.setGameSpecificMessage(message);
final String message = "Hello";
DriverStationSim.setGameData(message);
DriverStationSim.notifyNewData();
assertEquals(message, DriverStation.getGameSpecificMessage());
var gameData = DriverStation.getGameData();
assertTrue(gameData.isPresent());
assertEquals(message, gameData.get());
}
@Test
void testSetGameDataEmpty() {
HAL.initialize(500, 0);
DriverStationSim.resetData();
DriverStationSim.setGameData("");
DriverStationSim.notifyNewData();
assertTrue(DriverStation.getGameData().isEmpty());
}
@Test
void testSetGameDataNull() {
HAL.initialize(500, 0);
DriverStationSim.resetData();
DriverStationSim.setGameData(null);
DriverStationSim.notifyNewData();
assertTrue(DriverStation.getGameData().isEmpty());
}
@Test