Some updates to netplay, now using UDP to transmit pad data, it shouldn't be slow as molasses anymore, but may be unrealiable. Netplay now saves settings to ini, also fixed possible desync.

+cookie update : Updated Dolphin's icon to be Win7 ready by making it 32x32, so it now shows fine when alt-tabbing :p

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3290 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
sl1nk3.s 2009-05-27 21:24:29 +00:00
parent 9fd0802b4f
commit 0259cc388e
7 changed files with 1011 additions and 461 deletions

View File

@ -325,7 +325,7 @@ CFrame::CFrame(bool showLogWindow,
// Give it an icon // Give it an icon
wxIcon IconTemp; wxIcon IconTemp;
IconTemp.CopyFromBitmap(wxGetBitmapFromMemory(dolphin_png)); IconTemp.CopyFromBitmap(wxGetBitmapFromMemory(dolphin_ico32x32));
SetIcon(IconTemp); SetIcon(IconTemp);
// Give it a status bar // Give it a status bar

View File

@ -127,12 +127,15 @@ void ClientSide::OnClientData(unsigned char data)
case 0x50: // Everyone is Ready message received case 0x50: // Everyone is Ready message received
{ {
// Load the game and start synching // Load the game and start synching
Event->SendEvent(CLIENTS_READY, "NULL", 1); m_netptr->LoadGame();
break; break;
} }
case 0xA1: // Received pad data from host in versus mode case 0xA1: // Received pad data from host in versus mode
{ {
if (m_data_received)
wxThread::Sleep(10);
m_socket.Receive((char*)m_netvalues[0], 8, recv_size); m_socket.Receive((char*)m_netvalues[0], 8, recv_size);
m_data_received = true; m_data_received = true;
@ -265,6 +268,9 @@ void ServerSide::OnServerData(char sock, unsigned char data)
} }
case 0xA1: // Received pad data from a client case 0xA1: // Received pad data from a client
{ {
if (m_data_received)
wxThread::Sleep(10);
m_client[sock].socket.Receive((char*)m_netvalues[sock], 8, recv_size); m_client[sock].socket.Receive((char*)m_netvalues[sock], 8, recv_size);
m_data_received = true; m_data_received = true;

View File

@ -27,9 +27,7 @@ void NetPlay::IsGameFound(unsigned char * ptr, std::string m_selected)
m_selectedGame = m_selected; m_selectedGame = m_selected;
if (m_games.find(m_selected) != std::string::npos) if (m_games.find(m_selected) != std::string::npos)
{
*ptr = 0x1F; *ptr = 0x1F;
}
else else
*ptr = 0x1A; *ptr = 0x1A;
@ -68,6 +66,7 @@ void NetPlay::OnNetEvent(wxCommandEvent& event)
// has been killed and so we tell the GUI thread. // has been killed and so we tell the GUI thread.
AppendText(_("*Connection to Host lost.\n*You have been Disconnected.\n\n")); AppendText(_("*Connection to Host lost.\n*You have been Disconnected.\n\n"));
m_isHosting = 2; m_isHosting = 2;
m_numClients--;
} }
break; break;
case HOST_PLAYERLEFT: case HOST_PLAYERLEFT:
@ -84,7 +83,9 @@ void NetPlay::OnNetEvent(wxCommandEvent& event)
case CLIENTS_READY: case CLIENTS_READY:
{ {
m_clients_ready = true; m_clients_ready = true;
if (m_ready || event.GetInt())
// Tell clients everyone is ready...
if (m_ready)
LoadGame(); LoadGame();
} }
break; break;
@ -136,16 +137,27 @@ void NetPlay::LoadGame()
// -> P2P model is faster, but is limited to 2 players // -> P2P model is faster, but is limited to 2 players
// -> Server model is slower, but supports up to 4 players // -> Server model is slower, but supports up to 4 players
m_Logging->AppendText(_("** Everyone is ready... Loading Game ! **\n"));
// Tell clients everyone is ready...
if (m_isHosting == 1) if (m_isHosting == 1)
{ {
long ping[3] = {0};
unsigned char value = 0x50; unsigned char value = 0x50;
// Get ping
m_sock_server->Write(0, 0, 0, ping);
float fping = (ping[0]+ping[1]+ping[2])/(float)m_numClients;
// Tell client everyone is ready
for (int i=0; i < m_numClients ; i++) for (int i=0; i < m_numClients ; i++)
m_sock_server->Write(i, (const char*)&value, 1); m_sock_server->Write(i, (const char*)&value, 1);
// Sleep a bit to start the game at more or less the same time than the peer
wxMilliSleep(fping/2);
m_Logging->AppendText(wxString::Format(wxT("** Everyone is ready... Loading Game ! **\n"
"** Ping to client(s) is : %f ms\n"), fping));
} }
else
m_Logging->AppendText(_("** Everyone is ready... Loading Game ! **\n"));
// TODO : Throttle should be on by default, to avoid stuttering // TODO : Throttle should be on by default, to avoid stuttering
//soundStream->GetMixer()->SetThrottle(true); //soundStream->GetMixer()->SetThrottle(true);
@ -153,7 +165,9 @@ void NetPlay::LoadGame()
int line_p = 0; int line_p = 0;
int line_n = 0; int line_n = 0;
m_critical.Enter();
std::string tmp = m_games.substr(0, m_games.find(m_selectedGame)); std::string tmp = m_games.substr(0, m_games.find(m_selectedGame));
for (int i=0; i < (int)tmp.size(); i++) for (int i=0; i < (int)tmp.size(); i++)
if (tmp.c_str()[i] == '\n') if (tmp.c_str()[i] == '\n')
line_n++; line_n++;
@ -162,6 +176,7 @@ void NetPlay::LoadGame()
NetClass_ptr = this; NetClass_ptr = this;
m_timer.Start(); m_timer.Start();
m_data_received = false; m_data_received = false;
m_critical.Leave();
// Find corresponding game path // Find corresponding game path
for (int i=0; i < (int)m_paths.size(); i++) for (int i=0; i < (int)m_paths.size(); i++)
@ -182,6 +197,15 @@ void NetPlay::LoadGame()
bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues) bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
{ {
if (m_numClients < 1)
{
m_Logging->AppendText(_("** WARNING : "
"Ping too high (>2000ms) or connection lost ! \n"
"** WARNING : Stopping Netplay... \n"));
NetClass_ptr = NULL;
return false;
}
// Store current pad status in netValues[] // Store current pad status in netValues[]
netValues[0] = (u32)((u8)PadStatus.stickY); netValues[0] = (u32)((u8)PadStatus.stickY);
netValues[0] |= (u32)((u8)PadStatus.stickX << 8); netValues[0] |= (u32)((u8)PadStatus.stickX << 8);
@ -192,7 +216,14 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
netValues[1] |= (u32)((u8)PadStatus.substickY << 16); netValues[1] |= (u32)((u8)PadStatus.substickY << 16);
netValues[1] |= (u32)((u8)PadStatus.substickX << 24); netValues[1] |= (u32)((u8)PadStatus.substickX << 24);
if (m_frame == 0) if (m_NetModel == 0) // Use 2 players Model
{
if (padnb == 0)
{
// Update the timer and increment total frame number
m_frame++;
if (m_frame == 1)
{ {
// We make sure everyone's pad is enabled // We make sure everyone's pad is enabled
for (int i = 0; i < m_numClients+1; i++) for (int i = 0; i < m_numClients+1; i++)
@ -203,13 +234,7 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
SerialInterface::ChangeDevice(SI_DUMMY, i); SerialInterface::ChangeDevice(SI_DUMMY, i);
} }
if (m_NetModel == 0 && m_numClients == 1) // Use P2P Model if (m_timer.GetTimeDifference() > 1000)
{
if (padnb == 0)
{
// TODO : actually show this on the GUI :p
// Update the timer and increment total frame number
m_frame++;
m_timer.Update(); m_timer.Update();
#ifdef NET_DEBUG #ifdef NET_DEBUG
@ -217,9 +242,11 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
sprintf(sent, "Sent Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]); sprintf(sent, "Sent Values: 0x%08x : 0x%08x \n", netValues[0], netValues[1]);
m_Logging->AppendText(wxString::FromAscii(sent)); m_Logging->AppendText(wxString::FromAscii(sent));
#endif #endif
unsigned char init_value = 0xA1;
unsigned char player = 0; unsigned char player = 0;
#ifdef USE_TCP
unsigned char init_value = 0xA1;
if (m_isHosting == 1) { if (m_isHosting == 1) {
// Send pads values // Send pads values
m_sock_server->Write(0, (const char*)&init_value, 1); m_sock_server->Write(0, (const char*)&init_value, 1);
@ -231,6 +258,23 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
m_sock_client->Write((const char*)netValues, 8); m_sock_client->Write((const char*)netValues, 8);
player = 1; player = 1;
} }
#else // UDP
u32 padsValues[3];
padsValues[0] = m_frame;
padsValues[1] = netValues[0];
padsValues[2] = netValues[1];
if (m_isHosting == 1) {
// Send pads values
m_sock_server->WriteUDP(0, (const char*)padsValues, 12);
}
else {
// Send pads values
m_sock_client->WriteUDP((const char*)padsValues, 12);
player = 1;
}
#endif
if (!m_data_received) if (!m_data_received)
{ {
@ -257,9 +301,10 @@ bool NetPlay::GetNetPads(u8 padnb, SPADStatus PadStatus, u32 *netValues)
else { else {
if (m_loopframe > 126) if (m_loopframe > 126)
{ {
m_Logging->AppendText(_("** Ping too high (>2000ms) or connection lost ! \n")); m_Logging->AppendText(_("** WARNING : "
m_Logging->AppendText(_("** Stopping game... \n")); "Ping too high (>2000ms) or connection lost ! \n"
BootManager::Stop(); "** WARNING : Stopping Netplay... \n"));
NetClass_ptr = NULL;
} }
m_loopframe++; m_loopframe++;
@ -367,7 +412,6 @@ void NetPlay::ChangeSelectedGame(std::string game)
m_sock_server->Write(i, (const char*)&value, 1); // 0x35 -> Change game m_sock_server->Write(i, (const char*)&value, 1); // 0x35 -> Change game
m_sock_server->Write(i, (const char*)&game_size, 4); m_sock_server->Write(i, (const char*)&game_size, 4);
//m_sock_server->Write(i, m_selectedGame.c_str(), game_size + 1);
m_sock_server->Write(i, game.c_str(), game_size + 1); m_sock_server->Write(i, game.c_str(), game_size + 1);
} }
@ -379,20 +423,19 @@ void NetPlay::ChangeSelectedGame(std::string game)
void NetPlay::OnQuit(wxCloseEvent& WXUNUSED(event)) void NetPlay::OnQuit(wxCloseEvent& WXUNUSED(event))
{ {
// Disable netplay
NetClass_ptr = NULL; NetClass_ptr = NULL;
// We Kill the threads // Destroy the Window
Destroy();
// Then Kill the threads
if (m_isHosting == 0) if (m_isHosting == 0)
m_sock_client->Delete(); m_sock_client->Delete();
else if (m_isHosting == 1) { else if (m_isHosting == 1) {
m_sock_server->Delete(); m_sock_server->Delete();
// Stop listening, we're doing it here cause Doing it in the thread
// Cause SFML to crash when built in release build, odd ? :(
m_listensocket.Close();
} }
// Destroy the Frame
Destroy();
} }
void NetPlay::OnDisconnect(wxCommandEvent& WXUNUSED(event)) void NetPlay::OnDisconnect(wxCommandEvent& WXUNUSED(event))
@ -403,7 +446,7 @@ void NetPlay::OnDisconnect(wxCommandEvent& WXUNUSED(event))
bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus) bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus)
{ {
// TODO : adapt it to more than 2 players #ifdef USE_TCP
if (current) if (current)
{ {
while (1) while (1)
@ -419,6 +462,9 @@ bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus)
break; break;
} }
m_CriticalSection.Leave(); m_CriticalSection.Leave();
if (TestDestroy())
break;
} }
return true; return true;
@ -427,10 +473,54 @@ bool ClientSide::isNewPadData(u32 *netValues, bool current, bool isVersus)
wxCriticalSectionLocker lock(m_CriticalSection); wxCriticalSectionLocker lock(m_CriticalSection);
return m_data_received; return m_data_received;
#else
size_t recv_size;
if (current)
{
m_CriticalSection.Enter();
if (isVersus)
{
if (m_netvalues[0][1] != 0)
{
netValues[0] = m_netvalues[0][1];
netValues[1] = m_netvalues[0][2];
}
else
{
while (true)
{
u32 frame_saved = m_netvalues[0][0];
bool pass = RecvT(m_socketUDP, (char*)&m_netvalues[0], 12, recv_size, 5);
if (m_netvalues[0][0] < frame_saved+1)
continue;
if (m_netvalues[0][0] > frame_saved+1 || !pass)
PanicAlert("Network ERROR !");
netValues[0] = m_netvalues[0][1];
netValues[1] = m_netvalues[0][2];
break;
}
}
}
m_netvalues[0][1] = 0;
m_CriticalSection.Leave();
return true;
}
else
return RecvT(m_socketUDP, (char*)&m_netvalues[0], 12, recv_size, 1/1000);
#endif
} }
bool ServerSide::isNewPadData(u32 *netValues, bool current, char client) bool ServerSide::isNewPadData(u32 *netValues, bool current, char client)
{ {
#ifdef USE_TCP
if (current) if (current)
{ {
while (1) while (1)
@ -446,6 +536,9 @@ bool ServerSide::isNewPadData(u32 *netValues, bool current, char client)
break; break;
} }
m_CriticalSection.Leave(); m_CriticalSection.Leave();
if (TestDestroy())
break;
} }
return true; return true;
@ -454,5 +547,44 @@ bool ServerSide::isNewPadData(u32 *netValues, bool current, char client)
wxCriticalSectionLocker lock(m_CriticalSection); wxCriticalSectionLocker lock(m_CriticalSection);
return m_data_received; return m_data_received;
#else
size_t recv_size;
if (current)
{
m_CriticalSection.Enter();
if (m_netvalues[0][1] != 0)
{
netValues[0] = m_netvalues[client][1];
netValues[1] = m_netvalues[client][2];
}
else
{
while (true)
{
u32 frame_saved = m_netvalues[client][0];
bool pass = RecvT(m_socketUDP, (char*)&m_netvalues[client], 12, recv_size, 5);
if (m_netvalues[client][0] < frame_saved+1)
continue;
if (m_netvalues[client][0] > frame_saved+1 || !pass)
PanicAlert("Network ERROR !");
netValues[0] = m_netvalues[client][1];
netValues[1] = m_netvalues[client][2];
break;
}
}
m_netvalues[client][1] = 0;
m_CriticalSection.Leave();
return true;
}
else
return RecvT(m_socketUDP, (char*)&m_netvalues[client], 12, recv_size, 1/1000);
#endif
} }

View File

@ -23,9 +23,9 @@
void NetEvent::AppendText(const wxString text) void NetEvent::AppendText(const wxString text)
{ {
// I have the feeling SendEvent may be a bit better... // I have the feeling SendEvent may be a bit safer/better...
#if 0 #if 1
SendEvent(ADD_TEXT, std::string(text.mb_str())) SendEvent(ADD_TEXT, std::string(text.mb_str()));
#else #else
wxMutexGuiEnter(); wxMutexGuiEnter();
m_netptr->AppendText(text); m_netptr->AppendText(text);
@ -48,13 +48,14 @@ void NetEvent::SendEvent(int EventType, const std::string text, int integer)
// SERVER SIDE THREAD // SERVER SIDE THREAD
//-------------------------------- //--------------------------------
ServerSide::ServerSide(NetPlay* netptr, sf::SocketTCP socket, int netmodel, std::string nick) ServerSide::ServerSide(NetPlay* netptr, sf::SocketTCP socket, sf::SocketUDP socketUDP, int netmodel, std::string nick)
: wxThread() : wxThread()
{ {
m_numplayers = 0; m_numplayers = 0;
m_data_received = false; m_data_received = false;
m_netmodel = netmodel; m_netmodel = netmodel;
m_socket = socket; m_socket = socket;
m_socketUDP = socketUDP;
m_netptr = netptr; m_netptr = netptr;
m_nick = nick; m_nick = nick;
Event = new NetEvent(m_netptr); Event = new NetEvent(m_netptr);
@ -71,6 +72,23 @@ char ServerSide::GetSocket(sf::SocketTCP Socket)
return 0xE; return 0xE;
} }
bool ServerSide::RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time)
{
sf::SelectorUDP Selector;
sf::IPAddress Addr;
Selector.Add(Socket);
if (Selector.Wait(Time) > 0)
{
Socket.Receive(Data, Max, Recvd, Addr);
return true;
}
else
{
return false;
}
}
void *ServerSide::Entry() void *ServerSide::Entry()
{ {
// Add listening socket // Add listening socket
@ -100,16 +118,17 @@ void *ServerSide::Entry()
{ {
Incoming.Send((const char *)&sent, 1); // Tell it the server is full... Incoming.Send((const char *)&sent, 1); // Tell it the server is full...
Incoming.Close(); // Then close the connection Incoming.Close(); // Then close the connection
Event->AppendText(_(" Server is Full !\n")); Event->AppendText(_(" Server is Full !\n"));
} }
else else
{ {
Event->AppendText(_(" Connection accepted\n")); Event->AppendText(_(" Connection accepted\n"));
m_client[m_numplayers].socket = Incoming; m_client[m_numplayers].socket = Incoming;
m_client[m_numplayers].address = Address;
SyncValues(m_numplayers, Address); if (SyncValues(m_numplayers, Address))
} {
// Add it to the selector // Add it to the selector
m_selector.Add(Incoming); m_selector.Add(Incoming);
Event->SendEvent(HOST_NEWPLAYER); Event->SendEvent(HOST_NEWPLAYER);
@ -117,14 +136,19 @@ void *ServerSide::Entry()
m_numplayers++; m_numplayers++;
} }
else else
{
Event->AppendText(_("ERROR : Unable to establish UDP connection !\n"));
Incoming.Close();
}
}
}
else
{ {
unsigned char recv; unsigned char recv;
int socket_nb; int socket_nb;
size_t recv_size; size_t recv_size;
sf::Socket::Status recv_status; sf::Socket::Status recv_status;
socket_nb = GetSocket(Socket);
if ((socket_nb = GetSocket(Socket)) == 0xE)
PanicAlert("ERROR: How did you get there ?! Is that even possible ?!");
if ((recv_status = Socket.Receive((char *)&recv, 1, recv_size)) == sf::Socket::Done) if ((recv_status = Socket.Receive((char *)&recv, 1, recv_size)) == sf::Socket::Done)
{ {
@ -182,6 +206,9 @@ void *ServerSide::Entry()
if(TestDestroy()) if(TestDestroy())
{ {
// Stop listening
m_socket.Close();
// Delete the Thread and close clients sockets // Delete the Thread and close clients sockets
for (char i=0; i < m_numplayers ; i++) for (char i=0; i < m_numplayers ; i++)
m_client[i].socket.Close(); m_client[i].socket.Close();
@ -193,7 +220,7 @@ void *ServerSide::Entry()
return NULL; return NULL;
} }
void ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address) bool ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address)
{ {
sf::SocketTCP Socket = m_client[socketnb].socket; sf::SocketTCP Socket = m_client[socketnb].socket;
@ -202,6 +229,7 @@ void ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address)
unsigned char init_number; unsigned char init_number;
u32 buffer_size = (u32)buffer_str.size(); u32 buffer_size = (u32)buffer_str.size();
size_t received; size_t received;
bool errorUDP = false;
// First, Send the number of connected clients & netmodel // First, Send the number of connected clients & netmodel
Socket.Send((const char *)&m_numplayers, 1); Socket.Send((const char *)&m_numplayers, 1);
@ -216,6 +244,8 @@ void ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address)
Socket.Send((const char *)&buffer_size, 4); Socket.Send((const char *)&buffer_size, 4);
Socket.Send(m_nick.c_str(), buffer_size + 1); Socket.Send(m_nick.c_str(), buffer_size + 1);
// Read client's UDP Port
Socket.Receive((char *)&m_client[m_numplayers].port, sizeof(short), received);
// Read returned nickname // Read returned nickname
Socket.Receive((char *)&buffer_size, 4, received); Socket.Receive((char *)&buffer_size, 4, received);
@ -225,9 +255,25 @@ void ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address)
m_client[socketnb].nick = std::string(buffer); m_client[socketnb].nick = std::string(buffer);
m_client[socketnb].ready = false; m_client[socketnb].ready = false;
///////////////////
// Test UDP Socket
///////////////////
if (m_socketUDP.Send((const char*)&m_numplayers, 1, Address, m_client[m_numplayers].port) == sf::Socket::Done)
{
// Test UDP Socket Receive, 2s timeout
if (!RecvT(m_socketUDP, (char*)&init_number, 1, received, 2))
errorUDP = true;
}
else
errorUDP = true;
// Check if the client has the game // Check if the client has the game
Socket.Receive((char *)&init_number, 1, received); Socket.Receive((char *)&init_number, 1, received);
delete[] buffer;
if (!errorUDP)
{
// Send to all connected clients // Send to all connected clients
if (m_numplayers > 0) if (m_numplayers > 0)
{ {
@ -246,14 +292,26 @@ void ServerSide::SyncValues(unsigned char socketnb, sf::IPAddress Address)
} }
} }
Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s)\n"), Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s:%d)\n"),
m_client[socketnb].nick.c_str(), Address.ToString().c_str()) ); m_client[socketnb].nick.c_str(), Address.ToString().c_str(), m_client[m_numplayers].port) );
if (init_number != 0x1F) // Not Found if (init_number != 0x1F) // Not Found
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
Event->AppendText(_("WARNING : Game Not Found on Client Side !\n")); Event->AppendText(_("WARNING : Game Not Found on Client Side !\n"));
delete[] buffer; // UDP connecton successful
init_number = 0x16;
Socket.Send((const char *)&init_number, 1);
}
else // UDP Error, disconnect client
{
// UDP connecton failed
init_number = 0x17;
Socket.Send((const char *)&init_number, 1);
return false;
}
return true;
} }
void ServerSide::Write(char socknb, const char *data, size_t size, long *ping) void ServerSide::Write(char socknb, const char *data, size_t size, long *ping)
@ -265,7 +323,7 @@ void ServerSide::Write(char socknb, const char *data, size_t size, long *ping)
// Ask for ping // Ask for ping
unsigned char value = 0x15; unsigned char value = 0x15;
size_t recv_size; size_t recv_size;
int four_bytes = 0x101A7FA6; u32 four_bytes = 0x101A7FA6;
Common::Timer timer; Common::Timer timer;
timer.Start(); timer.Start();
@ -287,39 +345,81 @@ void ServerSide::Write(char socknb, const char *data, size_t size, long *ping)
m_client[socknb].socket.Send(data, size); m_client[socknb].socket.Send(data, size);
} }
void ServerSide::WriteUDP(char socknb, const char *data, size_t size)
{
wxCriticalSectionLocker lock(m_CriticalSection);
m_socketUDP.Send(data, size, m_client[socknb].address, m_client[socknb].port);
}
//-------------------------------- //--------------------------------
// CLIENT SIDE THREAD // CLIENT SIDE THREAD
//-------------------------------- //--------------------------------
ClientSide::ClientSide(NetPlay* netptr, sf::SocketTCP socket, std::string addr, std::string nick) ClientSide::ClientSide(NetPlay* netptr, sf::SocketTCP socket, sf::SocketUDP socketUDP, std::string addr, std::string nick)
: wxThread() : wxThread()
{ {
m_numplayers = 0; m_numplayers = 0;
m_data_received = false; m_data_received = false;
m_netmodel = 0; m_netmodel = 0;
m_socket = socket; m_socket = socket;
m_socketUDP = socketUDP;
m_port = m_socketUDP.GetPort();
m_netptr = netptr; m_netptr = netptr;
m_nick = nick; m_nick = nick;
m_addr = addr; m_addr = addr;
Event = new NetEvent(m_netptr); Event = new NetEvent(m_netptr);
} }
bool ClientSide::RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time)
{
sf::SelectorUDP Selector;
sf::IPAddress addr;
Selector.Add(Socket);
if (Selector.Wait(Time) > 0)
{
Socket.Receive(Data, Max, Recvd, addr);
return true;
}
else
{
return false;
}
}
void *ClientSide::Entry() void *ClientSide::Entry()
{ {
Event->AppendText(_("*Connection Request... ")); Event->AppendText(_("*Connection Request... "));
// If we get here, the connection is already accepted, however the game may be full // If we get here, the connection is already accepted, however the game may be full
if (SyncValues()) if (SyncValues())
{
// Tell the server if the client has the game
CheckGameFound();
// Check UDP connection
unsigned char value;
size_t val_sz;
m_socket.Receive((char *)&value, 1, val_sz);
if (value == 0x16) // UDP connection successful
{ {
Event->AppendText(_("Connection successful !\n")); Event->AppendText(_("Connection successful !\n"));
Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s)\n*Game is : %s\n"), Event->AppendText( wxString::Format(wxT("*Connection established to %s (%s)\n*Game is : %s\n"),
m_hostnick.c_str(), m_addr.c_str(), m_selectedgame.c_str() ) ); m_hostnick.c_str(), m_addr.c_str(), m_selectedgame.c_str() ) );
// Tell the server if the client has the game
CheckGameFound();
} }
else { else
// Post ServerFull event to GUI {
Event->AppendText(_("UDP Connection FAILED !\n"
"ERROR : Unable to establish UDP Connection, please Check UDP Port forwarding !"));
m_socket.Close();
Event->SendEvent(HOST_ERROR);
return NULL;
}
}
else // Server is Full
{
m_socket.Close(); m_socket.Close();
Event->SendEvent(HOST_FULL); Event->SendEvent(HOST_FULL);
return NULL; return NULL;
@ -385,15 +485,24 @@ void *ClientSide::Entry()
bool ClientSide::SyncValues() bool ClientSide::SyncValues()
{ {
unsigned int buffer_size = (int)m_nick.size(); unsigned int buffer_size = (int)m_nick.size();
unsigned char byterecv;
bool errorUDP;
char *buffer = NULL; char *buffer = NULL;
size_t recv_size; size_t recv_size;
unsigned short server_port;
std::string host = m_addr.substr(0, m_addr.find(':'));
TryParseInt(m_addr.substr(m_addr.find(':')+1).c_str(), (int *)&server_port);
// First, Read the init number : nbplayers (0-2) or server full (0x12) // First, Read the init number : nbplayers (0-2) or server full (0x12)
m_socket.Receive((char *)&m_numplayers, 1, recv_size); m_socket.Receive((char *)&m_numplayers, 1, recv_size);
if (m_numplayers == 0x12) if (m_numplayers == 0x12)
return false; return false;
m_socket.Receive((char *)&m_netmodel, 4, recv_size); m_socket.Receive((char *)&m_netmodel, 4, recv_size);
// Send client's UDP Port
m_socket.Send((const char *)&m_port, sizeof(short));
// Send client's nickname // Send client's nickname
m_socket.Send((const char *)&buffer_size, 4); m_socket.Send((const char *)&buffer_size, 4);
m_socket.Send(m_nick.c_str(), buffer_size + 1); m_socket.Send(m_nick.c_str(), buffer_size + 1);
@ -410,6 +519,18 @@ bool ClientSide::SyncValues()
m_socket.Receive(buffer, buffer_size + 1, recv_size); m_socket.Receive(buffer, buffer_size + 1, recv_size);
m_hostnick = std::string(buffer); m_hostnick = std::string(buffer);
///////////////////
// Test UDP Socket
///////////////////
if (m_socketUDP.Send((const char*)&m_numplayers, 1, host.c_str(), server_port) == sf::Socket::Done)
{
// Test UDP Socket Receive, 2s timeout
if (!RecvT(m_socketUDP, (char*)&byterecv, 1, recv_size, 2))
errorUDP = true;
}
else
errorUDP = true;
delete[] buffer; delete[] buffer;
return true; return true;
} }
@ -460,3 +581,13 @@ void ClientSide::Write(const char *data, size_t size, long *ping)
m_socket.Send(data, size); m_socket.Send(data, size);
} }
void ClientSide::WriteUDP(const char *data, size_t size)
{
wxCriticalSectionLocker lock(m_CriticalSection);
unsigned short server_port;
std::string host = m_addr.substr(0, m_addr.find(':'));
TryParseInt(m_addr.substr(m_addr.find(':')+1).c_str(), (int *)&server_port);
m_socketUDP.Send(data, size, host.c_str(), server_port);
}

View File

@ -20,7 +20,7 @@
/////////////////////// ///////////////////////
// Main Frame window // Main Frame window
BEGIN_EVENT_TABLE(NetPlay, wxDialog) BEGIN_EVENT_TABLE(NetPlay, wxFrame)
EVT_BUTTON(ID_BUTTON_JOIN, NetPlay::OnJoin) EVT_BUTTON(ID_BUTTON_JOIN, NetPlay::OnJoin)
EVT_BUTTON(ID_BUTTON_HOST, NetPlay::OnHost) EVT_BUTTON(ID_BUTTON_HOST, NetPlay::OnHost)
@ -38,7 +38,7 @@ BEGIN_EVENT_TABLE(NetPlay, wxDialog)
END_EVENT_TABLE() END_EVENT_TABLE()
NetPlay::NetPlay(wxWindow* parent, std::string GamePaths, std::string GameNames) : NetPlay::NetPlay(wxWindow* parent, std::string GamePaths, std::string GameNames) :
wxDialog(parent, wxID_ANY, _T("Net Play"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~ wxMAXIMIZE_BOX ) wxFrame(parent, wxID_ANY, _T("Net Play"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_FRAME_STYLE & ~ wxMAXIMIZE_BOX)
{ {
m_selectedGame = 'a'; m_hostaddr = 'a'; m_selectedGame = 'a'; m_hostaddr = 'a';
m_games = GameNames; m_paths = GamePaths; m_games = GameNames; m_paths = GamePaths;
@ -48,23 +48,45 @@ NetPlay::NetPlay(wxWindow* parent, std::string GamePaths, std::string GameNames)
DrawGUI(); DrawGUI();
} }
NetPlay::~NetPlay()
{
ConfigIni.Load(CONFIG_FILE);
ConfigIni.Set("Netplay", "Nickname", m_nick);
ConfigIni.Set("Netplay", "UsedPort", (int)m_port);
ConfigIni.Set("Netplay", "LastIP", m_address);
ConfigIni.Save(CONFIG_FILE);
}
void NetPlay::OnJoin(wxCommandEvent& WXUNUSED(event)) void NetPlay::OnJoin(wxCommandEvent& WXUNUSED(event))
{ {
wxString addr = m_ConAddr->GetValue(); unsigned short server_port;
wxString host = addr.substr(0, addr.find(':'));
wxString port_str = addr.substr(addr.find(':')+1);
int port; TryParseInt(port_str.mb_str(), &port);
m_address = std::string(m_ConAddr->GetValue().mb_str());
m_nick = std::string(m_SetNick->GetValue().mb_str()); m_nick = std::string(m_SetNick->GetValue().mb_str());
wxString host = m_address.substr(0, m_address.find(':'));
wxString port_str = m_address.substr(m_address.find(':')+1);
TryParseInt(port_str.mb_str(), (int *)&server_port); // Server port
TryParseInt(m_SetPort->GetValue().mb_str(), (int *)&m_port); // User port
if (m_nick.size() > 255) if (m_nick.size() > 255)
m_nick = m_nick.substr(0 , 255); m_nick = m_nick.substr(0 , 255);
SetTitle(_("Net Play : Connecting to Host..."));
// Create the client socket // Create the client socket
sf::SocketTCP sock_client; sf::SocketTCP sock_client;
sf::SocketUDP sock_client_UDP;
if (sock_client.Connect(port, (const char *)host.mb_str(), 1.5) == sf::Socket::Done) if (sock_client.Connect(server_port, (const char*)host.mb_str(), 1.5) == sf::Socket::Done)
{ {
m_sock_client = new ClientSide(this, sock_client, std::string(addr.mb_str()), m_nick); // Try to Bind the UDP Socket
if (sock_client_UDP.Bind(m_port))
{
m_sock_client = new ClientSide(this, sock_client, sock_client_UDP, m_address, m_nick);
m_sock_client->Create(); m_sock_client->Create();
m_sock_client->Run(); m_sock_client->Run();
@ -74,6 +96,14 @@ void NetPlay::OnJoin(wxCommandEvent& WXUNUSED(event))
} }
else else
{ {
SetTitle(_("Net Play"));
PanicAlert("Can't Bind UDP socket on the specified Port: %d ! \n"
"Make sure port is forwarded and not in use !", m_port);
}
}
else
{
SetTitle(_("Net Play"));
PanicAlert("Can't connect to the specified IP Address ! \nMake sure Hosting port is forwarded !"); PanicAlert("Can't connect to the specified IP Address ! \nMake sure Hosting port is forwarded !");
} }
} }
@ -82,26 +112,30 @@ void NetPlay::OnHost(wxCommandEvent& WXUNUSED(event))
{ {
TryParseInt(m_SetPort->GetValue().mb_str(), (int*)&m_port); TryParseInt(m_SetPort->GetValue().mb_str(), (int*)&m_port);
m_nick = std::string(m_SetNick->GetValue().mb_str());
if (m_GameList->GetSelection() == wxNOT_FOUND) { if (m_GameList->GetSelection() == wxNOT_FOUND) {
PanicAlert("No Game Selected ! Please select a Game..."); PanicAlert("No Game Selected ! Please select a Game...");
return; return;
} }
if (!m_SetPort->GetValue().size() || m_port < 100 || m_port > 65535) { if (!m_SetPort->GetValue().size() || m_port < 1000 || m_port > 65535) {
PanicAlert("Bad Port entered (%d) ! Please enter a working socket port...", m_port); PanicAlert("Bad Port entered (%d) ! Please enter a working socket port...", m_port);
return; return;
} }
if (m_nick.size() > 255)
m_nick = std::string(m_SetNick->GetValue().mb_str()); m_nick = m_nick.substr(0 , 255);
if (m_nick.size() > 255) m_nick = m_nick.substr(0 , 255);
m_NetModel = m_NetMode->GetSelection(); m_NetModel = m_NetMode->GetSelection();
m_selectedGame = std::string(m_GameList_str[m_GameList->GetSelection()].mb_str()); m_selectedGame = std::string(m_GameList_str[m_GameList->GetSelection()].mb_str());
m_numClients = 0;
// Start the listening socket // Create the listening socket
if (m_listensocket.Listen(m_port)) sf::SocketTCP sock_server;
sf::SocketUDP sock_server_UDP;
// Start the listening socket and bind UDP socket port
if (sock_server.Listen(m_port) && sock_server_UDP.Bind(m_port))
{ {
m_sock_server = new ServerSide(this, m_listensocket, m_NetModel, m_nick); m_sock_server = new ServerSide(this, sock_server, sock_server_UDP, m_NetModel, m_nick);
m_sock_server->Create(); m_sock_server->Create();
m_sock_server->Run(); m_sock_server->Run();
@ -137,27 +171,27 @@ void NetPlay::DrawGUI()
} }
netmodes_str.Add(wxT("P2P Versus (2 players, faster)")); netmodes_str.Add(wxT("P2P Versus (2 players, faster)"));
// TODO : // TODO : netmodes_str.Add(wxT("Server Mode (4 players, slower)"));
// netmodes_str.Add(wxT("Server Mode (4 players, slower)"));
wxPanel *panel = new wxPanel(this);
// Tabs // Tabs
m_Notebook = new wxNotebook(this, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize); m_Notebook = new wxNotebook(panel, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize);
m_Tab_Connect = new wxPanel(m_Notebook, ID_TAB_CONN, wxDefaultPosition, wxDefaultSize); m_Tab_Connect = new wxPanel(m_Notebook, ID_TAB_CONN, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Tab_Connect, wxT("Connect")); m_Notebook->AddPage(m_Tab_Connect, wxT("Connect"));
m_Tab_Host = new wxPanel(m_Notebook, ID_TAB_HOST, wxDefaultPosition, wxDefaultSize); m_Tab_Host = new wxPanel(m_Notebook, ID_TAB_HOST, wxDefaultPosition, wxDefaultSize);
m_Notebook->AddPage(m_Tab_Host, wxT("Host")); m_Notebook->AddPage(m_Tab_Host, wxT("Host"));
// Nickname setting // Tow window, Nickname & Port settings
m_SetNick_text = new wxStaticText(this, ID_SETNICK_TXT, wxT(" Nickname : "), wxDefaultPosition, wxDefaultSize); m_SetNick_text = new wxStaticText(panel, wxID_ANY, wxT(" Nickname : "), wxDefaultPosition, wxDefaultSize);
m_SetNick = new wxTextCtrl(this, ID_SETNICK, wxT("Mingebag"), wxDefaultPosition, wxDefaultSize, 0); m_SetNick = new wxTextCtrl(panel, ID_SETNICK, wxT("LOLWUT!"), wxDefaultPosition, wxDefaultSize);
m_NetMode = new wxChoice(this, ID_NETMODE, wxDefaultPosition, wxDefaultSize, netmodes_str, 0, wxDefaultValidator); m_SetPort_text = new wxStaticText(panel, wxID_ANY, wxT(" Port to Use : "), wxDefaultPosition, wxDefaultSize);
m_NetMode->SetSelection(0); m_SetPort = new wxTextCtrl(panel, ID_SETPORT, wxT("12345"), wxDefaultPosition, wxDefaultSize);
// CONNECTION TAB // CONNECTION TAB
m_ConAddr_text = new wxStaticText(m_Tab_Connect, ID_CONNADDR_TXT, wxT(" IP Address :"), wxDefaultPosition, wxDefaultSize); m_ConAddr_text = new wxStaticText(m_Tab_Connect, wxID_ANY, wxT(" IP Address :"), wxDefaultPosition, wxDefaultSize);
m_ConAddr = new wxTextCtrl(m_Tab_Connect, ID_CONNADDR, wxT("127.0.0.1:12345"), wxDefaultPosition, wxSize(250,20), 0); m_ConAddr = new wxTextCtrl(m_Tab_Connect, ID_CONNADDR, wxT("127.0.0.1:12345"), wxDefaultPosition, wxSize(250,20), 0);
m_UseRandomPort = new wxCheckBox(m_Tab_Connect, ID_USE_RANDOMPORT, wxT("Use random client port for connection")); m_UseRandomPort = new wxCheckBox(m_Tab_Connect, ID_USE_RANDOMPORT, wxT("Use random client port for connection"));
m_UseRandomPort->SetValue(true); m_UseRandomPort->Enable(false);
m_JoinGame = new wxButton(m_Tab_Connect, ID_BUTTON_JOIN, wxT("Connect"), wxDefaultPosition, wxDefaultSize); m_JoinGame = new wxButton(m_Tab_Connect, ID_BUTTON_JOIN, wxT("Connect"), wxDefaultPosition, wxDefaultSize);
// Sizers CONNECT // Sizers CONNECT
@ -165,7 +199,7 @@ void NetPlay::DrawGUI()
wxBoxSizer* sConnectSizer = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sConnectSizer = new wxBoxSizer(wxVERTICAL);
sConnectTop->Add(m_ConAddr_text, 0, wxALL|wxALIGN_CENTER, 5); sConnectTop->Add(m_ConAddr_text, 0, wxALL|wxALIGN_CENTER, 5);
sConnectTop->Add(m_ConAddr, 3, wxALL|wxEXPAND, 5); sConnectTop->Add(m_ConAddr, 1, wxALL|wxEXPAND, 5);
sConnectTop->Add(m_JoinGame, 0, wxALL|wxALIGN_RIGHT, 5); sConnectTop->Add(m_JoinGame, 0, wxALL|wxALIGN_RIGHT, 5);
sConnectSizer->Add(sConnectTop, 0, wxALL|wxEXPAND, 5); sConnectSizer->Add(sConnectTop, 0, wxALL|wxEXPAND, 5);
sConnectSizer->Add(m_UseRandomPort, 0, wxALL|wxALIGN_CENTER, 5); sConnectSizer->Add(m_UseRandomPort, 0, wxALL|wxALIGN_CENTER, 5);
@ -173,44 +207,57 @@ void NetPlay::DrawGUI()
m_Tab_Connect->SetSizer(sConnectSizer); m_Tab_Connect->SetSizer(sConnectSizer);
// HOSTING TAB // HOSTING TAB
m_SetPort_text = new wxStaticText(m_Tab_Host, ID_SETPORT_TXT, wxT(" Use Port : "), wxDefaultPosition, wxDefaultSize); m_GameList_text = new wxStaticText(m_Tab_Host, wxID_ANY,
m_SetPort = new wxTextCtrl(m_Tab_Host, ID_SETPORT, wxT("12345"), wxDefaultPosition, wxDefaultSize, 0); wxT("Warning: Use a forwarded port ! Select Game and press Host :"), wxDefaultPosition, wxDefaultSize);
m_GameList_text = new wxStaticText(m_Tab_Host, ID_GAMELIST_TXT, wxT("Warning: Use a forwarded port ! Select Game and press Host :"), wxDefaultPosition, wxDefaultSize);
m_GameList = new wxListBox(m_Tab_Host, ID_GAMELIST, wxDefaultPosition, wxDefaultSize, m_GameList = new wxListBox(m_Tab_Host, ID_GAMELIST, wxDefaultPosition, wxDefaultSize,
m_GameList_str, wxLB_SINGLE | wxLB_NEEDED_SB); m_GameList_str, wxLB_SINGLE | wxLB_NEEDED_SB);
m_HostGame = new wxButton(m_Tab_Host, ID_BUTTON_HOST, wxT("Host"), wxDefaultPosition, wxDefaultSize); m_HostGame = new wxButton(m_Tab_Host, ID_BUTTON_HOST, wxT("Host"), wxDefaultPosition, wxDefaultSize);
m_NetMode = new wxChoice(m_Tab_Host, ID_NETMODE, wxDefaultPosition, wxDefaultSize, netmodes_str, 0, wxDefaultValidator);
m_NetMode->SetSelection(0);
// Sizers HOST // Sizers HOST
wxBoxSizer *sHostBox = new wxBoxSizer(wxVERTICAL); wxBoxSizer *sHostBox = new wxBoxSizer(wxVERTICAL);
wxBoxSizer *sHostTop = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer *sHostBottom = new wxBoxSizer(wxHORIZONTAL);
wxBoxSizer *sHostMid = new wxBoxSizer(wxHORIZONTAL);
sHostTop->Add(m_SetPort_text, 0, wxALL|wxALIGN_CENTER, 5); sHostBottom->Add(m_NetMode, 0, wxALL|wxALIGN_CENTER, 5);
sHostTop->Add(m_SetPort, 1, wxALL|wxEXPAND, 5); sHostBottom->AddStretchSpacer();
sHostMid->Add(m_GameList, 1, wxALL|wxEXPAND, 5); sHostBottom->Add(m_HostGame, 0, wxALL, 10);
sHostBox->Add(m_GameList_text, 0, wxALL|wxALIGN_CENTER, 5); sHostBox->Add(m_GameList_text, 0, wxALL|wxALIGN_CENTER, 5);
sHostBox->Add(sHostTop, 0, wxALL|wxEXPAND, 1); sHostBox->Add(m_GameList, 1, wxALL|wxEXPAND, 6);
sHostBox->Add(sHostMid, 1, wxALL|wxEXPAND, 1); sHostBox->Add(sHostBottom, 0, wxALL|wxEXPAND, 1);
sHostBox->Add(m_HostGame, 0, wxALL|wxALIGN_RIGHT, 10);
m_Tab_Host->SetSizer(sHostBox); m_Tab_Host->SetSizer(sHostBox);
sHostBox->Layout();
// main sizers // Main sizers
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sMain_top = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sMain_top = new wxBoxSizer(wxHORIZONTAL);
sMain_top->Add(m_SetNick_text, 0, wxALL|wxALIGN_CENTER, 3); sMain_top->Add(m_SetNick_text, 0, wxALL|wxALIGN_CENTER, 3);
sMain_top->Add(m_SetNick, 0, wxALL, 3); sMain_top->Add(m_SetNick, 1, wxALL|wxALIGN_CENTER, 3);
sMain_top->AddStretchSpacer(1); sMain_top->AddStretchSpacer();
sMain_top->Add(m_NetMode, 0, wxALL|wxALIGN_RIGHT, 3); sMain_top->Add(m_SetPort_text, 0, wxALL|wxALIGN_CENTER, 3);
sMain_top->Add(m_SetPort, 1, wxALL|wxALIGN_CENTER, 3);
sMain->Add(sMain_top, 0, wxALL|wxEXPAND, 5); sMain->Add(sMain_top, 0, wxALL|wxEXPAND, 5);
sMain->Add(m_Notebook, 1, wxALL|wxEXPAND, 5); sMain->Add(m_Notebook, 1, wxALL|wxEXPAND, 5);
SetSizerAndFit(sMain); // Adjust panel to window's size, and set resizing minimum boundaries
Center(); Layout(); Show(); panel->SetSizerAndFit(sMain);
sMain->SetSizeHints((wxWindow*)this);
if (ConfigIni.Load(CONFIG_FILE))
{
ConfigIni.Get("Netplay", "Nickname", &m_nick, "Unnamed");
ConfigIni.Get("Netplay", "UsedPort", (int*)&m_port, 12345);
ConfigIni.Get("Netplay", "LastIP", &m_address, "127.0.0.1:54321");
m_SetNick->SetValue(_(m_nick.c_str()));
m_SetPort->SetValue(wxString::Format(wxT("%d"), m_port));
m_ConAddr->SetValue(_(m_address.c_str()));
}
Center(); Show();
} }
void NetPlay::DrawNetWindow() void NetPlay::DrawNetWindow()
@ -218,33 +265,31 @@ void NetPlay::DrawNetWindow()
// Remove everything from the precedent GUI :D // Remove everything from the precedent GUI :D
DestroyChildren(); DestroyChildren();
SetTitle(_("Connection Window")); SetTitle(_("Net Play : Connection Window"));
wxPanel *panel = new wxPanel(this);
wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sMain = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sTop = new wxBoxSizer(wxVERTICAL); wxBoxSizer* sTop = new wxBoxSizer(wxVERTICAL);
wxBoxSizer* sBottom = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sBottom = new wxBoxSizer(wxHORIZONTAL);
m_Game_str = new wxButton(this, wxID_ANY, wxT(" Game : "), wxDefaultPosition, wxSize(400, 25), wxBU_LEFT); m_Game_str = new wxButton(panel, wxID_ANY, wxT(" Game : "), wxDefaultPosition, wxSize(400, 25), wxBU_LEFT);
m_Game_str->Disable(); m_Game_str->Disable();
m_Logging = new wxTextCtrl(this, ID_LOGGING_TXT, wxEmptyString, m_Logging = new wxTextCtrl(panel, ID_LOGGING_TXT, wxEmptyString,
wxDefaultPosition, wxSize(400, 250), wxDefaultPosition, wxSize(400, 250),
wxTE_RICH2 | wxTE_MULTILINE | wxTE_READONLY); wxTE_RICH2 | wxTE_MULTILINE | wxTE_READONLY);
// Too bad this doesn't work... m_Chat = new wxTextCtrl(panel, ID_CHAT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER);
//m_Logging->SetDefaultStyle(wxTextAttr(*wxRED)); m_Chat_ok = new wxButton(panel, ID_BUTTON_CHAT, wxT("Send"));;
m_Chat = new wxTextCtrl(this, ID_CHAT, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxTE_PROCESS_ENTER); m_Ready = new wxCheckBox(panel, ID_READY, wxT("Click here when ready"), wxDefaultPosition, wxDefaultSize, 0);
m_Chat_ok = new wxButton(this, ID_BUTTON_CHAT, wxT("Send"));; m_RecordGame = new wxCheckBox(panel, ID_RECORD, wxT("Record Game Input"), wxDefaultPosition, wxDefaultSize, 0);
m_Ready = new wxCheckBox(this, ID_READY, wxT("Click here when ready"), wxDefaultPosition, wxDefaultSize, 0);
m_RecordGame = new wxCheckBox(this, ID_RECORD, wxT("Record Game Input"), wxDefaultPosition, wxDefaultSize, 0);
// TODO: Fix the recording ? // TODO: Fix the recording ?
m_RecordGame->Disable(); m_RecordGame->Disable();
m_ConInfo_text = new wxStaticText(this, ID_CONNINFO_TXT, wxT(" Fps : 0 | Ping : 00 ms")); m_ConInfo_text = new wxStaticText(panel, ID_CONNINFO_TXT, wxT(" Fps : 0 | Ping : 00 ms"));
m_GetPing = new wxButton(this, ID_BUTTON_GETPING, wxT("Ping"), wxDefaultPosition, wxDefaultSize); m_GetPing = new wxButton(panel, ID_BUTTON_GETPING, wxT("Ping"), wxDefaultPosition, wxDefaultSize);
m_Disconnect = new wxButton(this, ID_BUTTON_QUIT, wxT("Disconnect"), wxDefaultPosition, wxDefaultSize); m_Disconnect = new wxButton(panel, ID_BUTTON_QUIT, wxT("Disconnect"), wxDefaultPosition, wxDefaultSize);
wxBoxSizer* sChat = new wxBoxSizer(wxHORIZONTAL); wxBoxSizer* sChat = new wxBoxSizer(wxHORIZONTAL);
@ -274,10 +319,10 @@ void NetPlay::DrawNetWindow()
if (m_isHosting) if (m_isHosting)
{ {
m_wtfismyip = new wxButton(this, ID_BUTTON_GETIP, wxT("What is my IP")); m_wtfismyip = new wxButton(panel, ID_BUTTON_GETIP, wxT("What is my IP"));
m_ChangeGame = new wxButton(this, ID_CHANGEGAME, wxT("Change Game")); m_ChangeGame = new wxButton(panel, ID_CHANGEGAME, wxT("Change Game"));
wxStaticBoxSizer* sBottom3 = new wxStaticBoxSizer(wxVERTICAL, this, _("Host")); wxStaticBoxSizer* sBottom3 = new wxStaticBoxSizer(wxVERTICAL, panel, _("Host"));
sBottom3->Add(m_ChangeGame, 0, wxALL | wxEXPAND, 5); sBottom3->Add(m_ChangeGame, 0, wxALL | wxEXPAND, 5);
sBottom3->Add(m_wtfismyip, 0, wxALL | wxEXPAND, 5); sBottom3->Add(m_wtfismyip, 0, wxALL | wxEXPAND, 5);
@ -289,18 +334,19 @@ void NetPlay::DrawNetWindow()
sMain->Add(sTop, 1, wxALL | wxEXPAND, 5); sMain->Add(sTop, 1, wxALL | wxEXPAND, 5);
sMain->Add(sBottom, 0, wxALL | wxEXPAND | wxALIGN_CENTER, 2); sMain->Add(sBottom, 0, wxALL | wxEXPAND | wxALIGN_CENTER, 2);
SetSizerAndFit(sMain); panel->SetSizerAndFit(sMain);
Center(); Layout(); sMain->SetSizeHints((wxWindow*)this);
Show(); Show();
} }
void NetPlay::UpdateNetWindow(bool update_infos, wxString infos/*int fps, float ping, int frame_delay*/) // String of the type : FPSxPINGxFRAME_DELAY
void NetPlay::UpdateNetWindow(bool update_infos, wxString infos)
{ {
std::vector<std::string> str_arr; std::vector<std::string> str_arr;
if (update_infos) if (update_infos)
{ {
// String of the type : FPSxPINGxFRAME_DELAY
SplitString(std::string(infos.mb_str()), "x", str_arr); SplitString(std::string(infos.mb_str()), "x", str_arr);
m_ConInfo_text->SetLabel m_ConInfo_text->SetLabel
@ -349,6 +395,7 @@ void NetPlay::OnGUIEvent(wxCommandEvent& event)
m_Logging->AppendText(wxString::FromAscii(buffer.c_str())); m_Logging->AppendText(wxString::FromAscii(buffer.c_str()));
// Everyone is ready
if (m_ready && m_clients_ready) if (m_ready && m_clients_ready)
LoadGame(); LoadGame();
} }
@ -388,7 +435,6 @@ void NetPlay::OnGUIEvent(wxCommandEvent& event)
if (m_numClients == 0) if (m_numClients == 0)
return; return;
// TODO : This is not designed for > 2 players
long ping[3] = {0}; long ping[3] = {0};
float fping; float fping;
@ -442,8 +488,7 @@ void NetPlay::OnGUIEvent(wxCommandEvent& event)
m_Chat->Clear(); m_Chat->Clear();
// We should maybe wait for the server to send it... // Do not wait for the server, just write as soon as sent
// but we write it anyway :p
m_Logging->AppendText(chat_str); m_Logging->AppendText(chat_str);
break; break;

View File

@ -43,6 +43,10 @@
#define NET_DEBUG #define NET_DEBUG
#endif #endif
// Use TCP instead of UDP to send pad data @ 60fps. Suitable and better for LAN netplay,
// Unrealistic for Internet netplay, unless you have an uberfast connexion (<10ms ping)
// #define USE_TCP
class NetPlay; class NetPlay;
struct Netpads { struct Netpads {
@ -53,6 +57,8 @@ struct Netpads {
struct Clients { struct Clients {
std::string nick; std::string nick;
sf::SocketTCP socket; sf::SocketTCP socket;
unsigned short port;
sf::IPAddress address;
bool ready; bool ready;
}; };
@ -72,16 +78,18 @@ class NetEvent
class ServerSide : public wxThread class ServerSide : public wxThread
{ {
public: public:
ServerSide(NetPlay* netptr, sf::SocketTCP socket, int netmodel, std::string nick); ServerSide(NetPlay* netptr, sf::SocketTCP, sf::SocketUDP, int netmodel, std::string nick);
~ServerSide() {}; ~ServerSide() {};
virtual void *Entry(); virtual void *Entry();
void Write(char socknb, const char *data, size_t size, long *ping=NULL); void Write(char socknb, const char *data, size_t size, long *ping=NULL);
void WriteUDP(char socknb, const char *data, size_t size);
bool isNewPadData(u32 *netValues, bool current, char client=0); bool isNewPadData(u32 *netValues, bool current, char client=0);
private: private:
void SyncValues(unsigned char, sf::IPAddress); bool SyncValues(unsigned char, sf::IPAddress);
bool RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time = 0);
char GetSocket(sf::SocketTCP Socket); char GetSocket(sf::SocketTCP Socket);
void OnServerData(char sock, unsigned char data); void OnServerData(char sock, unsigned char data);
void IsEveryoneReady(); void IsEveryoneReady();
@ -89,7 +97,7 @@ class ServerSide : public wxThread
NetPlay *m_netptr; NetPlay *m_netptr;
NetEvent *Event; NetEvent *Event;
u32 m_netvalues[3][2]; u32 m_netvalues[3][3];
bool m_data_received; // New Pad data received ? bool m_data_received; // New Pad data received ?
unsigned char m_numplayers; unsigned char m_numplayers;
@ -99,6 +107,7 @@ class ServerSide : public wxThread
Clients m_client[3]; // Connected client objects Clients m_client[3]; // Connected client objects
sf::SelectorTCP m_selector; sf::SelectorTCP m_selector;
sf::SocketTCP m_socket; // Server 'listening' socket sf::SocketTCP m_socket; // Server 'listening' socket
sf::SocketUDP m_socketUDP;
wxCriticalSection m_CriticalSection; wxCriticalSection m_CriticalSection;
}; };
@ -106,23 +115,25 @@ class ServerSide : public wxThread
class ClientSide : public wxThread class ClientSide : public wxThread
{ {
public: public:
ClientSide(NetPlay* netptr, sf::SocketTCP socket, std::string addr, std::string nick); ClientSide(NetPlay* netptr, sf::SocketTCP, sf::SocketUDP, std::string addr, std::string nick);
~ClientSide() {} ~ClientSide() {}
virtual void *Entry(); virtual void *Entry();
void Write(const char *data, size_t size, long *ping=NULL); void Write(const char *data, size_t size, long *ping=NULL);
void WriteUDP(const char *data, size_t size);
bool isNewPadData(u32 *netValues, bool current, bool isVersus=true); bool isNewPadData(u32 *netValues, bool current, bool isVersus=true);
private: private:
bool SyncValues(); bool SyncValues();
void CheckGameFound(); void CheckGameFound();
void OnClientData(unsigned char data); void OnClientData(unsigned char data);
bool RecvT(sf::SocketUDP Socket, char * Data, size_t Max, size_t& Recvd, float Time=0);
NetPlay *m_netptr; NetPlay *m_netptr;
NetEvent *Event; NetEvent *Event;
u32 m_netvalues[3][2]; u32 m_netvalues[3][3];
bool m_data_received; // New Pad data received ? bool m_data_received; // New Pad data received ?
unsigned char m_numplayers; unsigned char m_numplayers;
@ -133,16 +144,18 @@ class ClientSide : public wxThread
sf::SelectorTCP m_selector; sf::SelectorTCP m_selector;
sf::SocketTCP m_socket; // Client I/O socket sf::SocketTCP m_socket; // Client I/O socket
sf::SocketUDP m_socketUDP;
unsigned short m_port;
std::string m_addr; // Contains the server addr std::string m_addr; // Contains the server addr
wxCriticalSection m_CriticalSection; wxCriticalSection m_CriticalSection;
}; };
class NetPlay : public wxDialog class NetPlay : public wxFrame
{ {
public: public:
NetPlay(wxWindow* parent, std::string GamePath = "", std::string GameName = ""); NetPlay(wxWindow* parent, std::string GamePath = "", std::string GameName = "");
~NetPlay() {} ~NetPlay();
void UpdateNetWindow(bool update_infos, wxString=wxT("NULL")); void UpdateNetWindow(bool update_infos, wxString=wxT("NULL"));
void AppendText(const wxString text) { m_Logging->AppendText(text); } void AppendText(const wxString text) { m_Logging->AppendText(text); }
@ -151,9 +164,10 @@ class NetPlay : public wxDialog
bool GetNetPads(u8 pad_nb, SPADStatus, u32 *netvalues); bool GetNetPads(u8 pad_nb, SPADStatus, u32 *netvalues);
void ChangeSelectedGame(std::string game); void ChangeSelectedGame(std::string game);
void IsGameFound(unsigned char*, std::string); void IsGameFound(unsigned char*, std::string);
bool IsReady() { wxCriticalSectionLocker lock(m_critical); return m_ready; }
std::string GetSelectedGame() { wxCriticalSectionLocker lock(m_critical); return m_selectedGame; } std::string GetSelectedGame() { wxCriticalSectionLocker lock(m_critical); return m_selectedGame; }
void LoadGame();
protected: protected:
// Protects our vars from being fuxored by threads // Protects our vars from being fuxored by threads
wxCriticalSection m_critical; wxCriticalSection m_critical;
@ -171,10 +185,9 @@ class NetPlay : public wxDialog
void OnJoin(wxCommandEvent& event); void OnJoin(wxCommandEvent& event);
void OnHost(wxCommandEvent& event); void OnHost(wxCommandEvent& event);
void LoadGame();
// Net play vars (used ingame) // Net play vars (used ingame)
int m_frame; int m_frame;
int m_lastframe;
Common::Timer m_timer; Common::Timer m_timer;
int m_loopframe; int m_loopframe;
int m_frameDelay; int m_frameDelay;
@ -192,12 +205,13 @@ class NetPlay : public wxDialog
int m_NetModel; // Using P2P model (0) or Server model (1) int m_NetModel; // Using P2P model (0) or Server model (1)
int m_isHosting; // 0 = false ; 1 = true ; 2 = Not set int m_isHosting; // 0 = false ; 1 = true ; 2 = Not set
unsigned char m_numClients; // starting from 0, 4 players max thus 3 clients unsigned char m_numClients; // starting from 0, 4 players max thus 3 clients
std::string m_address; // The address entered into connection box
unsigned short m_port; unsigned short m_port;
Netpads m_pads[4]; // this struct is used to save synced pad values Netpads m_pads[4]; // this struct is used to save synced pad values
IniFile ConfigIni;
// Sockets objects // Sockets objects
sf::SocketTCP m_listensocket;
ServerSide *m_sock_server; ServerSide *m_sock_server;
ClientSide *m_sock_client; ClientSide *m_sock_client;
@ -268,15 +282,11 @@ enum
ID_BUTTON_JOIN, ID_BUTTON_JOIN,
ID_NETMODE, ID_NETMODE,
ID_GAMELIST, ID_GAMELIST,
ID_GAMELIST_TXT,
ID_LOGGING_TXT, ID_LOGGING_TXT,
ID_CHAT, ID_CHAT,
ID_SETNICK_TXT,
ID_SETNICK, ID_SETNICK,
ID_SETPORT, ID_SETPORT,
ID_SETPORT_TXT,
ID_CONNADDR, ID_CONNADDR,
ID_CONNADDR_TXT,
ID_CONNINFO_TXT, ID_CONNINFO_TXT,
ID_USE_RANDOMPORT, ID_USE_RANDOMPORT,
ID_BUTTON_GETPING, ID_BUTTON_GETPING,

View File

@ -1,288 +1,514 @@
static const unsigned char dolphin_png[] = { static const unsigned char dolphin_ico32x32[] = {
0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0x00, 0x00, 0x00, 0x0d, 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00,
0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x20,
0x08, 0x02, 0x00, 0x00, 0x00, 0x90, 0x91, 0x68, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0x06, 0x00, 0x00, 0x00, 0x73,
0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0b, 0x13, 0x00, 0x00, 0x0b, 0x7A, 0x7A, 0xF4, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59,
0x13, 0x01, 0x00, 0x9a, 0x9c, 0x18, 0x00, 0x00, 0x0a, 0x4f, 0x69, 0x43, 0x73, 0x00, 0x00, 0x0B, 0x13, 0x00, 0x00, 0x0B, 0x13, 0x01,
0x43, 0x50, 0x50, 0x68, 0x6f, 0x74, 0x6f, 0x73, 0x68, 0x6f, 0x70, 0x20, 0x00, 0x9A, 0x9C, 0x18, 0x00, 0x00, 0x0A, 0x4F, 0x69, 0x43,
0x49, 0x43, 0x43, 0x20, 0x70, 0x72, 0x6f, 0x66, 0x69, 0x6c, 0x65, 0x00, 0x43, 0x50, 0x50, 0x68, 0x6F, 0x74, 0x6F, 0x73, 0x68, 0x6F,
0x00, 0x78, 0xda, 0x9d, 0x53, 0x67, 0x54, 0x53, 0xe9, 0x16, 0x3d, 0xf7, 0x70, 0x20, 0x49, 0x43, 0x43, 0x20, 0x70, 0x72, 0x6F, 0x66,
0xde, 0xf4, 0x42, 0x4b, 0x88, 0x80, 0x94, 0x4b, 0x6f, 0x52, 0x15, 0x08, 0x69, 0x6C, 0x65, 0x00, 0x00, 0x78, 0xDA, 0x9D, 0x53, 0x67,
0x20, 0x52, 0x42, 0x8b, 0x80, 0x14, 0x91, 0x26, 0x2a, 0x21, 0x09, 0x10, 0x54, 0x53, 0xE9, 0x16, 0x3D, 0xF7, 0xDE, 0xF4, 0x42, 0x4B,
0x4a, 0x88, 0x21, 0xa1, 0xd9, 0x15, 0x51, 0xc1, 0x11, 0x45, 0x45, 0x04, 0x88, 0x80, 0x94, 0x4B, 0x6F, 0x52, 0x15, 0x08, 0x20, 0x52,
0x1b, 0xc8, 0xa0, 0x88, 0x03, 0x8e, 0x8e, 0x80, 0x8c, 0x15, 0x51, 0x2c, 0x42, 0x8B, 0x80, 0x14, 0x91, 0x26, 0x2A, 0x21, 0x09, 0x10,
0x0c, 0x8a, 0x0a, 0xd8, 0x07, 0xe4, 0x21, 0xa2, 0x8e, 0x83, 0xa3, 0x88, 0x4A, 0x88, 0x21, 0xA1, 0xD9, 0x15, 0x51, 0xC1, 0x11, 0x45,
0x8a, 0xca, 0xfb, 0xe1, 0x7b, 0xa3, 0x6b, 0xd6, 0xbc, 0xf7, 0xe6, 0xcd, 0x45, 0x04, 0x1B, 0xC8, 0xA0, 0x88, 0x03, 0x8E, 0x8E, 0x80,
0xfe, 0xb5, 0xd7, 0x3e, 0xe7, 0xac, 0xf3, 0x9d, 0xb3, 0xcf, 0x07, 0xc0, 0x8C, 0x15, 0x51, 0x2C, 0x0C, 0x8A, 0x0A, 0xD8, 0x07, 0xE4,
0x08, 0x0c, 0x96, 0x48, 0x33, 0x51, 0x35, 0x80, 0x0c, 0xa9, 0x42, 0x1e, 0x21, 0xA2, 0x8E, 0x83, 0xA3, 0x88, 0x8A, 0xCA, 0xFB, 0xE1,
0x11, 0xe0, 0x83, 0xc7, 0xc4, 0xc6, 0xe1, 0xe4, 0x2e, 0x40, 0x81, 0x0a, 0x7B, 0xA3, 0x6B, 0xD6, 0xBC, 0xF7, 0xE6, 0xCD, 0xFE, 0xB5,
0x24, 0x70, 0x00, 0x10, 0x08, 0xb3, 0x64, 0x21, 0x73, 0xfd, 0x23, 0x01, 0xD7, 0x3E, 0xE7, 0xAC, 0xF3, 0x9D, 0xB3, 0xCF, 0x07, 0xC0,
0x00, 0xf8, 0x7e, 0x3c, 0x3c, 0x2b, 0x22, 0xc0, 0x07, 0xbe, 0x00, 0x01, 0x08, 0x0C, 0x96, 0x48, 0x33, 0x51, 0x35, 0x80, 0x0C, 0xA9,
0x78, 0xd3, 0x0b, 0x08, 0x00, 0xc0, 0x4d, 0x9b, 0xc0, 0x30, 0x1c, 0x87, 0x42, 0x1E, 0x11, 0xE0, 0x83, 0xC7, 0xC4, 0xC6, 0xE1, 0xE4,
0xff, 0x0f, 0xea, 0x42, 0x99, 0x5c, 0x01, 0x80, 0x84, 0x01, 0xc0, 0x74, 0x2E, 0x40, 0x81, 0x0A, 0x24, 0x70, 0x00, 0x10, 0x08, 0xB3,
0x91, 0x38, 0x4b, 0x08, 0x80, 0x14, 0x00, 0x40, 0x7a, 0x8e, 0x42, 0xa6, 0x64, 0x21, 0x73, 0xFD, 0x23, 0x01, 0x00, 0xF8, 0x7E, 0x3C,
0x00, 0x40, 0x46, 0x01, 0x80, 0x9d, 0x98, 0x26, 0x53, 0x00, 0xa0, 0x04, 0x3C, 0x2B, 0x22, 0xC0, 0x07, 0xBE, 0x00, 0x01, 0x78, 0xD3,
0x00, 0x60, 0xcb, 0x63, 0x62, 0xe3, 0x00, 0x50, 0x2d, 0x00, 0x60, 0x27, 0x0B, 0x08, 0x00, 0xC0, 0x4D, 0x9B, 0xC0, 0x30, 0x1C, 0x87,
0x7f, 0xe6, 0xd3, 0x00, 0x80, 0x9d, 0xf8, 0x99, 0x7b, 0x01, 0x00, 0x5b, 0xFF, 0x0F, 0xEA, 0x42, 0x99, 0x5C, 0x01, 0x80, 0x84, 0x01,
0x94, 0x21, 0x15, 0x01, 0xa0, 0x91, 0x00, 0x20, 0x13, 0x65, 0x88, 0x44, 0xC0, 0x74, 0x91, 0x38, 0x4B, 0x08, 0x80, 0x14, 0x00, 0x40,
0x00, 0x68, 0x3b, 0x00, 0xac, 0xcf, 0x56, 0x8a, 0x45, 0x00, 0x58, 0x30, 0x7A, 0x8E, 0x42, 0xA6, 0x00, 0x40, 0x46, 0x01, 0x80, 0x9D,
0x00, 0x14, 0x66, 0x4b, 0xc4, 0x39, 0x00, 0xd8, 0x2d, 0x00, 0x30, 0x49, 0x98, 0x26, 0x53, 0x00, 0xA0, 0x04, 0x00, 0x60, 0xCB, 0x63,
0x57, 0x66, 0x48, 0x00, 0xb0, 0xb7, 0x00, 0xc0, 0xce, 0x10, 0x0b, 0xb2, 0x62, 0xE3, 0x00, 0x50, 0x2D, 0x00, 0x60, 0x27, 0x7F, 0xE6,
0x00, 0x08, 0x0c, 0x00, 0x30, 0x51, 0x88, 0x85, 0x29, 0x00, 0x04, 0x7b, 0xD3, 0x00, 0x80, 0x9D, 0xF8, 0x99, 0x7B, 0x01, 0x00, 0x5B,
0x00, 0x60, 0xc8, 0x23, 0x23, 0x78, 0x00, 0x84, 0x99, 0x00, 0x14, 0x46, 0x94, 0x21, 0x15, 0x01, 0xA0, 0x91, 0x00, 0x20, 0x13, 0x65,
0xf2, 0x57, 0x3c, 0xf1, 0x2b, 0xae, 0x10, 0xe7, 0x2a, 0x00, 0x00, 0x78, 0x88, 0x44, 0x00, 0x68, 0x3B, 0x00, 0xAC, 0xCF, 0x56, 0x8A,
0x99, 0xb2, 0x3c, 0xb9, 0x24, 0x39, 0x45, 0x81, 0x5b, 0x08, 0x2d, 0x71, 0x45, 0x00, 0x58, 0x30, 0x00, 0x14, 0x66, 0x4B, 0xC4, 0x39,
0x07, 0x57, 0x57, 0x2e, 0x1e, 0x28, 0xce, 0x49, 0x17, 0x2b, 0x14, 0x36, 0x00, 0xD8, 0x2D, 0x00, 0x30, 0x49, 0x57, 0x66, 0x48, 0x00,
0x61, 0x02, 0x61, 0x9a, 0x40, 0x2e, 0xc2, 0x79, 0x99, 0x19, 0x32, 0x81, 0xB0, 0xB7, 0x00, 0xC0, 0xCE, 0x10, 0x0B, 0xB2, 0x00, 0x08,
0x34, 0x0f, 0xe0, 0xf3, 0xcc, 0x00, 0x00, 0xa0, 0x91, 0x15, 0x11, 0xe0, 0x0C, 0x00, 0x30, 0x51, 0x88, 0x85, 0x29, 0x00, 0x04, 0x7B,
0x83, 0xf3, 0xfd, 0x78, 0xce, 0x0e, 0xae, 0xce, 0xce, 0x36, 0x8e, 0xb6, 0x00, 0x60, 0xC8, 0x23, 0x23, 0x78, 0x00, 0x84, 0x99, 0x00,
0x0e, 0x5f, 0x2d, 0xea, 0xbf, 0x06, 0xff, 0x22, 0x62, 0x62, 0xe3, 0xfe, 0x14, 0x46, 0xF2, 0x57, 0x3C, 0xF1, 0x2B, 0xAE, 0x10, 0xE7,
0xe5, 0xcf, 0xab, 0x70, 0x40, 0x00, 0x00, 0xe1, 0x74, 0x7e, 0xd1, 0xfe, 0x2A, 0x00, 0x00, 0x78, 0x99, 0xB2, 0x3C, 0xB9, 0x24, 0x39,
0x2c, 0x2f, 0xb3, 0x1a, 0x80, 0x3b, 0x06, 0x80, 0x6d, 0xfe, 0xa2, 0x25, 0x45, 0x81, 0x5B, 0x08, 0x2D, 0x71, 0x07, 0x57, 0x57, 0x2E,
0xee, 0x04, 0x68, 0x5e, 0x0b, 0xa0, 0x75, 0xf7, 0x8b, 0x66, 0xb2, 0x0f, 0x1E, 0x28, 0xCE, 0x49, 0x17, 0x2B, 0x14, 0x36, 0x61, 0x02,
0x40, 0xb5, 0x00, 0xa0, 0xe9, 0xda, 0x57, 0xf3, 0x70, 0xf8, 0x7e, 0x3c, 0x61, 0x9A, 0x40, 0x2E, 0xC2, 0x79, 0x99, 0x19, 0x32, 0x81,
0x3c, 0x45, 0xa1, 0x90, 0xb9, 0xd9, 0xd9, 0xe5, 0xe4, 0xe4, 0xd8, 0x4a, 0x34, 0x0F, 0xE0, 0xF3, 0xCC, 0x00, 0x00, 0xA0, 0x91, 0x15,
0xc4, 0x42, 0x5b, 0x61, 0xca, 0x57, 0x7d, 0xfe, 0x67, 0xc2, 0x5f, 0xc0, 0x11, 0xE0, 0x83, 0xF3, 0xFD, 0x78, 0xCE, 0x0E, 0xAE, 0xCE,
0x57, 0xfd, 0x6c, 0xf9, 0x7e, 0x3c, 0xfc, 0xf7, 0xf5, 0xe0, 0xbe, 0xe2, 0xCE, 0x36, 0x8E, 0xB6, 0x0E, 0x5F, 0x2D, 0xEA, 0xBF, 0x06,
0x24, 0x81, 0x32, 0x5d, 0x81, 0x47, 0x04, 0xf8, 0xe0, 0xc2, 0xcc, 0xf4, 0xFF, 0x22, 0x62, 0x62, 0xE3, 0xFE, 0xE5, 0xCF, 0xAB, 0x70,
0x4c, 0xa5, 0x1c, 0xcf, 0x92, 0x09, 0x84, 0x62, 0xdc, 0xe6, 0x8f, 0x47, 0x40, 0x00, 0x00, 0xE1, 0x74, 0x7E, 0xD1, 0xFE, 0x2C, 0x2F,
0xfc, 0xb7, 0x0b, 0xff, 0xfc, 0x1d, 0xd3, 0x22, 0xc4, 0x49, 0x62, 0xb9, 0xB3, 0x1A, 0x80, 0x3B, 0x06, 0x80, 0x6D, 0xFE, 0xA2, 0x25,
0x58, 0x2a, 0x14, 0xe3, 0x51, 0x12, 0x71, 0x8e, 0x44, 0x9a, 0x8c, 0xf3, 0xEE, 0x04, 0x68, 0x5E, 0x0B, 0xA0, 0x75, 0xF7, 0x8B, 0x66,
0x32, 0xa5, 0x22, 0x89, 0x42, 0x92, 0x29, 0xc5, 0x25, 0xd2, 0xff, 0x64, 0xB2, 0x0F, 0x40, 0xB5, 0x00, 0xA0, 0xE9, 0xDA, 0x57, 0xF3,
0xe2, 0xdf, 0x2c, 0xfb, 0x03, 0x3e, 0xdf, 0x35, 0x00, 0xb0, 0x6a, 0x3e, 0x70, 0xF8, 0x7E, 0x3C, 0x3C, 0x45, 0xA1, 0x90, 0xB9, 0xD9,
0x01, 0x7b, 0x91, 0x2d, 0xa8, 0x5d, 0x63, 0x03, 0xf6, 0x4b, 0x27, 0x10, 0xD9, 0xE5, 0xE4, 0xE4, 0xD8, 0x4A, 0xC4, 0x42, 0x5B, 0x61,
0x58, 0x74, 0xc0, 0xe2, 0xf7, 0x00, 0x00, 0xf2, 0xbb, 0x6f, 0xc1, 0xd4, 0xCA, 0x57, 0x7D, 0xFE, 0x67, 0xC2, 0x5F, 0xC0, 0x57, 0xFD,
0x28, 0x08, 0x03, 0x80, 0x68, 0x83, 0xe1, 0xcf, 0x77, 0xff, 0xef, 0x3f, 0x6C, 0xF9, 0x7E, 0x3C, 0xFC, 0xF7, 0xF5, 0xE0, 0xBE, 0xE2,
0xfd, 0x47, 0xa0, 0x25, 0x00, 0x80, 0x66, 0x49, 0x92, 0x71, 0x00, 0x00, 0x24, 0x81, 0x32, 0x5D, 0x81, 0x47, 0x04, 0xF8, 0xE0, 0xC2,
0x5e, 0x44, 0x24, 0x2e, 0x54, 0xca, 0xb3, 0x3f, 0xc7, 0x08, 0x00, 0x00, 0xCC, 0xF4, 0x4C, 0xA5, 0x1C, 0xCF, 0x92, 0x09, 0x84, 0x62,
0x44, 0xa0, 0x81, 0x2a, 0xb0, 0x41, 0x1b, 0xf4, 0xc1, 0x18, 0x2c, 0xc0, 0xDC, 0xE6, 0x8F, 0x47, 0xFC, 0xB7, 0x0B, 0xFF, 0xFC, 0x1D,
0x06, 0x1c, 0xc1, 0x05, 0xdc, 0xc1, 0x0b, 0xfc, 0x60, 0x36, 0x84, 0x42, 0xD3, 0x22, 0xC4, 0x49, 0x62, 0xB9, 0x58, 0x2A, 0x14, 0xE3,
0x24, 0xc4, 0xc2, 0x42, 0x10, 0x42, 0x0a, 0x64, 0x80, 0x1c, 0x72, 0x60, 0x51, 0x12, 0x71, 0x8E, 0x44, 0x9A, 0x8C, 0xF3, 0x32, 0xA5,
0x29, 0xac, 0x82, 0x42, 0x28, 0x86, 0xcd, 0xb0, 0x1d, 0x2a, 0x60, 0x2f, 0x22, 0x89, 0x42, 0x92, 0x29, 0xC5, 0x25, 0xD2, 0xFF, 0x64,
0xd4, 0x40, 0x1d, 0x34, 0xc0, 0x51, 0x68, 0x86, 0x93, 0x70, 0x0e, 0x2e, 0xE2, 0xDF, 0x2C, 0xFB, 0x03, 0x3E, 0xDF, 0x35, 0x00, 0xB0,
0xc2, 0x55, 0xb8, 0x0e, 0x3d, 0x70, 0x0f, 0xfa, 0x61, 0x08, 0x9e, 0xc1, 0x6A, 0x3E, 0x01, 0x7B, 0x91, 0x2D, 0xA8, 0x5D, 0x63, 0x03,
0x28, 0xbc, 0x81, 0x09, 0x04, 0x41, 0xc8, 0x08, 0x13, 0x61, 0x21, 0xda, 0xF6, 0x4B, 0x27, 0x10, 0x58, 0x74, 0xC0, 0xE2, 0xF7, 0x00,
0x88, 0x01, 0x62, 0x8a, 0x58, 0x23, 0x8e, 0x08, 0x17, 0x99, 0x85, 0xf8, 0x00, 0xF2, 0xBB, 0x6F, 0xC1, 0xD4, 0x28, 0x08, 0x03, 0x80,
0x21, 0xc1, 0x48, 0x04, 0x12, 0x8b, 0x24, 0x20, 0xc9, 0x88, 0x14, 0x51, 0x68, 0x83, 0xE1, 0xCF, 0x77, 0xFF, 0xEF, 0x3F, 0xFD, 0x47,
0x22, 0x4b, 0x91, 0x35, 0x48, 0x31, 0x52, 0x8a, 0x54, 0x20, 0x55, 0x48, 0xA0, 0x25, 0x00, 0x80, 0x66, 0x49, 0x92, 0x71, 0x00, 0x00,
0x1d, 0xf2, 0x3d, 0x72, 0x02, 0x39, 0x87, 0x5c, 0x46, 0xba, 0x91, 0x3b, 0x5E, 0x44, 0x24, 0x2E, 0x54, 0xCA, 0xB3, 0x3F, 0xC7, 0x08,
0xc8, 0x00, 0x32, 0x82, 0xfc, 0x86, 0xbc, 0x47, 0x31, 0x94, 0x81, 0xb2, 0x00, 0x00, 0x44, 0xA0, 0x81, 0x2A, 0xB0, 0x41, 0x1B, 0xF4,
0x51, 0x3d, 0xd4, 0x0c, 0xb5, 0x43, 0xb9, 0xa8, 0x37, 0x1a, 0x84, 0x46, 0xC1, 0x18, 0x2C, 0xC0, 0x06, 0x1C, 0xC1, 0x05, 0xDC, 0xC1,
0xa2, 0x0b, 0xd0, 0x64, 0x74, 0x31, 0x9a, 0x8f, 0x16, 0xa0, 0x9b, 0xd0, 0x0B, 0xFC, 0x60, 0x36, 0x84, 0x42, 0x24, 0xC4, 0xC2, 0x42,
0x72, 0xb4, 0x1a, 0x3d, 0x8c, 0x36, 0xa1, 0xe7, 0xd0, 0xab, 0x68, 0x0f, 0x10, 0x42, 0x0A, 0x64, 0x80, 0x1C, 0x72, 0x60, 0x29, 0xAC,
0xda, 0x8f, 0x3e, 0x43, 0xc7, 0x30, 0xc0, 0xe8, 0x18, 0x07, 0x33, 0xc4, 0x82, 0x42, 0x28, 0x86, 0xCD, 0xB0, 0x1D, 0x2A, 0x60, 0x2F,
0x6c, 0x30, 0x2e, 0xc6, 0xc3, 0x42, 0xb1, 0x38, 0x2c, 0x09, 0x93, 0x63, 0xD4, 0x40, 0x1D, 0x34, 0xC0, 0x51, 0x68, 0x86, 0x93, 0x70,
0xcb, 0xb1, 0x22, 0xac, 0x0c, 0xab, 0xc6, 0x1a, 0xb0, 0x56, 0xac, 0x03, 0x0E, 0x2E, 0xC2, 0x55, 0xB8, 0x0E, 0x3D, 0x70, 0x0F, 0xFA,
0xbb, 0x89, 0xf5, 0x63, 0xcf, 0xb1, 0x77, 0x04, 0x12, 0x81, 0x45, 0xc0, 0x61, 0x08, 0x9E, 0xC1, 0x28, 0xBC, 0x81, 0x09, 0x04, 0x41,
0x09, 0x36, 0x04, 0x77, 0x42, 0x20, 0x61, 0x1e, 0x41, 0x48, 0x58, 0x4c, 0xC8, 0x08, 0x13, 0x61, 0x21, 0xDA, 0x88, 0x01, 0x62, 0x8A,
0x58, 0x4e, 0xd8, 0x48, 0xa8, 0x20, 0x1c, 0x24, 0x34, 0x11, 0xda, 0x09, 0x58, 0x23, 0x8E, 0x08, 0x17, 0x99, 0x85, 0xF8, 0x21, 0xC1,
0x37, 0x09, 0x03, 0x84, 0x51, 0xc2, 0x27, 0x22, 0x93, 0xa8, 0x4b, 0xb4, 0x48, 0x04, 0x12, 0x8B, 0x24, 0x20, 0xC9, 0x88, 0x14, 0x51,
0x26, 0xba, 0x11, 0xf9, 0xc4, 0x18, 0x62, 0x32, 0x31, 0x87, 0x58, 0x48, 0x22, 0x4B, 0x91, 0x35, 0x48, 0x31, 0x52, 0x8A, 0x54, 0x20,
0x2c, 0x23, 0xd6, 0x12, 0x8f, 0x13, 0x2f, 0x10, 0x7b, 0x88, 0x43, 0xc4, 0x55, 0x48, 0x1D, 0xF2, 0x3D, 0x72, 0x02, 0x39, 0x87, 0x5C,
0x37, 0x24, 0x12, 0x89, 0x43, 0x32, 0x27, 0xb9, 0x90, 0x02, 0x49, 0xb1, 0x46, 0xBA, 0x91, 0x3B, 0xC8, 0x00, 0x32, 0x82, 0xFC, 0x86,
0xa4, 0x54, 0xd2, 0x12, 0xd2, 0x46, 0xd2, 0x6e, 0x52, 0x23, 0xe9, 0x2c, 0xBC, 0x47, 0x31, 0x94, 0x81, 0xB2, 0x51, 0x3D, 0xD4, 0x0C,
0xa9, 0x9b, 0x34, 0x48, 0x1a, 0x23, 0x93, 0xc9, 0xda, 0x64, 0x6b, 0xb2, 0xB5, 0x43, 0xB9, 0xA8, 0x37, 0x1A, 0x84, 0x46, 0xA2, 0x0B,
0x07, 0x39, 0x94, 0x2c, 0x20, 0x2b, 0xc8, 0x85, 0xe4, 0x9d, 0xe4, 0xc3, 0xD0, 0x64, 0x74, 0x31, 0x9A, 0x8F, 0x16, 0xA0, 0x9B, 0xD0,
0xe4, 0x33, 0xe4, 0x1b, 0xe4, 0x21, 0xf2, 0x5b, 0x0a, 0x9d, 0x62, 0x40, 0x72, 0xB4, 0x1A, 0x3D, 0x8C, 0x36, 0xA1, 0xE7, 0xD0, 0xAB,
0x71, 0xa4, 0xf8, 0x53, 0xe2, 0x28, 0x52, 0xca, 0x6a, 0x4a, 0x19, 0xe5, 0x68, 0x0F, 0xDA, 0x8F, 0x3E, 0x43, 0xC7, 0x30, 0xC0, 0xE8,
0x10, 0xe5, 0x34, 0xe5, 0x06, 0x65, 0x98, 0x32, 0x41, 0x55, 0xa3, 0x9a, 0x18, 0x07, 0x33, 0xC4, 0x6C, 0x30, 0x2E, 0xC6, 0xC3, 0x42,
0x52, 0xdd, 0xa8, 0xa1, 0x54, 0x11, 0x35, 0x8f, 0x5a, 0x42, 0xad, 0xa1, 0xB1, 0x38, 0x2C, 0x09, 0x93, 0x63, 0xCB, 0xB1, 0x22, 0xAC,
0xb6, 0x52, 0xaf, 0x51, 0x87, 0xa8, 0x13, 0x34, 0x75, 0x9a, 0x39, 0xcd, 0x0C, 0xAB, 0xC6, 0x1A, 0xB0, 0x56, 0xAC, 0x03, 0xBB, 0x89,
0x83, 0x16, 0x49, 0x4b, 0xa5, 0xad, 0xa2, 0x95, 0xd3, 0x1a, 0x68, 0x17, 0xF5, 0x63, 0xCF, 0xB1, 0x77, 0x04, 0x12, 0x81, 0x45, 0xC0,
0x68, 0xf7, 0x69, 0xaf, 0xe8, 0x74, 0xba, 0x11, 0xdd, 0x95, 0x1e, 0x4e, 0x09, 0x36, 0x04, 0x77, 0x42, 0x20, 0x61, 0x1E, 0x41, 0x48,
0x97, 0xd0, 0x57, 0xd2, 0xcb, 0xe9, 0x47, 0xe8, 0x97, 0xe8, 0x03, 0xf4, 0x58, 0x4C, 0x58, 0x4E, 0xD8, 0x48, 0xA8, 0x20, 0x1C, 0x24,
0x77, 0x0c, 0x0d, 0x86, 0x15, 0x83, 0xc7, 0x88, 0x67, 0x28, 0x19, 0x9b, 0x34, 0x11, 0xDA, 0x09, 0x37, 0x09, 0x03, 0x84, 0x51, 0xC2,
0x18, 0x07, 0x18, 0x67, 0x19, 0x77, 0x18, 0xaf, 0x98, 0x4c, 0xa6, 0x19, 0x27, 0x22, 0x93, 0xA8, 0x4B, 0xB4, 0x26, 0xBA, 0x11, 0xF9,
0xd3, 0x8b, 0x19, 0xc7, 0x54, 0x30, 0x37, 0x31, 0xeb, 0x98, 0xe7, 0x99, 0xC4, 0x18, 0x62, 0x32, 0x31, 0x87, 0x58, 0x48, 0x2C, 0x23,
0x0f, 0x99, 0x6f, 0x55, 0x58, 0x2a, 0xb6, 0x2a, 0x7c, 0x15, 0x91, 0xca, 0xD6, 0x12, 0x8F, 0x13, 0x2F, 0x10, 0x7B, 0x88, 0x43, 0xC4,
0x0a, 0x95, 0x4a, 0x95, 0x26, 0x95, 0x1b, 0x2a, 0x2f, 0x54, 0xa9, 0xaa, 0x37, 0x24, 0x12, 0x89, 0x43, 0x32, 0x27, 0xB9, 0x90, 0x02,
0xa6, 0xaa, 0xde, 0xaa, 0x0b, 0x55, 0xf3, 0x55, 0xcb, 0x54, 0x8f, 0xa9, 0x49, 0xB1, 0xA4, 0x54, 0xD2, 0x12, 0xD2, 0x46, 0xD2, 0x6E,
0x5e, 0x53, 0x7d, 0xae, 0x46, 0x55, 0x33, 0x53, 0xe3, 0xa9, 0x09, 0xd4, 0x52, 0x23, 0xE9, 0x2C, 0xA9, 0x9B, 0x34, 0x48, 0x1A, 0x23,
0x96, 0xab, 0x55, 0xaa, 0x9d, 0x50, 0xeb, 0x53, 0x1b, 0x53, 0x67, 0xa9, 0x93, 0xC9, 0xDA, 0x64, 0x6B, 0xB2, 0x07, 0x39, 0x94, 0x2C,
0x3b, 0xa8, 0x87, 0xaa, 0x67, 0xa8, 0x6f, 0x54, 0x3f, 0xa4, 0x7e, 0x59, 0x20, 0x2B, 0xC8, 0x85, 0xE4, 0x9D, 0xE4, 0xC3, 0xE4, 0x33,
0xfd, 0x89, 0x06, 0x59, 0xc3, 0x4c, 0xc3, 0x4f, 0x43, 0xa4, 0x51, 0xa0, 0xE4, 0x1B, 0xE4, 0x21, 0xF2, 0x5B, 0x0A, 0x9D, 0x62, 0x40,
0xb1, 0x5f, 0xe3, 0xbc, 0xc6, 0x20, 0x0b, 0x63, 0x19, 0xb3, 0x78, 0x2c, 0x71, 0xA4, 0xF8, 0x53, 0xE2, 0x28, 0x52, 0xCA, 0x6A, 0x4A,
0x21, 0x6b, 0x0d, 0xab, 0x86, 0x75, 0x81, 0x35, 0xc4, 0x26, 0xb1, 0xcd, 0x19, 0xE5, 0x10, 0xE5, 0x34, 0xE5, 0x06, 0x65, 0x98, 0x32,
0xd9, 0x7c, 0x76, 0x2a, 0xbb, 0x98, 0xfd, 0x1d, 0xbb, 0x8b, 0x3d, 0xaa, 0x41, 0x55, 0xA3, 0x9A, 0x52, 0xDD, 0xA8, 0xA1, 0x54, 0x11,
0xa9, 0xa1, 0x39, 0x43, 0x33, 0x4a, 0x33, 0x57, 0xb3, 0x52, 0xf3, 0x94, 0x35, 0x8F, 0x5A, 0x42, 0xAD, 0xA1, 0xB6, 0x52, 0xAF, 0x51,
0x66, 0x3f, 0x07, 0xe3, 0x98, 0x71, 0xf8, 0x9c, 0x74, 0x4e, 0x09, 0xe7, 0x87, 0xA8, 0x13, 0x34, 0x75, 0x9A, 0x39, 0xCD, 0x83, 0x16,
0x28, 0xa7, 0x97, 0xf3, 0x7e, 0x8a, 0xde, 0x14, 0xef, 0x29, 0xe2, 0x29, 0x49, 0x4B, 0xA5, 0xAD, 0xA2, 0x95, 0xD3, 0x1A, 0x68, 0x17,
0x1b, 0xa6, 0x34, 0x4c, 0xb9, 0x31, 0x65, 0x5c, 0x6b, 0xaa, 0x96, 0x97, 0x68, 0xF7, 0x69, 0xAF, 0xE8, 0x74, 0xBA, 0x11, 0xDD, 0x95,
0x96, 0x58, 0xab, 0x48, 0xab, 0x51, 0xab, 0x47, 0xeb, 0xbd, 0x36, 0xae, 0x1E, 0x4E, 0x97, 0xD0, 0x57, 0xD2, 0xCB, 0xE9, 0x47, 0xE8,
0xed, 0xa7, 0x9d, 0xa6, 0xbd, 0x45, 0xbb, 0x59, 0xfb, 0x81, 0x0e, 0x41, 0x97, 0xE8, 0x03, 0xF4, 0x77, 0x0C, 0x0D, 0x86, 0x15, 0x83,
0xc7, 0x4a, 0x27, 0x5c, 0x27, 0x47, 0x67, 0x8f, 0xce, 0x05, 0x9d, 0xe7, 0xC7, 0x88, 0x67, 0x28, 0x19, 0x9B, 0x18, 0x07, 0x18, 0x67,
0x53, 0xd9, 0x53, 0xdd, 0xa7, 0x0a, 0xa7, 0x16, 0x4d, 0x3d, 0x3a, 0xf5, 0x19, 0x77, 0x18, 0xAF, 0x98, 0x4C, 0xA6, 0x19, 0xD3, 0x8B,
0xae, 0x2e, 0xaa, 0x6b, 0xa5, 0x1b, 0xa1, 0xbb, 0x44, 0x77, 0xbf, 0x6e, 0x19, 0xC7, 0x54, 0x30, 0x37, 0x31, 0xEB, 0x98, 0xE7, 0x99,
0xa7, 0xee, 0x98, 0x9e, 0xbe, 0x5e, 0x80, 0x9e, 0x4c, 0x6f, 0xa7, 0xde, 0x0F, 0x99, 0x6F, 0x55, 0x58, 0x2A, 0xB6, 0x2A, 0x7C, 0x15,
0x79, 0xbd, 0xe7, 0xfa, 0x1c, 0x7d, 0x2f, 0xfd, 0x54, 0xfd, 0x6d, 0xfa, 0x91, 0xCA, 0x0A, 0x95, 0x4A, 0x95, 0x26, 0x95, 0x1B, 0x2A,
0xa7, 0xf5, 0x47, 0x0c, 0x58, 0x06, 0xb3, 0x0c, 0x24, 0x06, 0xdb, 0x0c, 0x2F, 0x54, 0xA9, 0xAA, 0xA6, 0xAA, 0xDE, 0xAA, 0x0B, 0x55,
0xce, 0x18, 0x3c, 0xc5, 0x35, 0x71, 0x6f, 0x3c, 0x1d, 0x2f, 0xc7, 0xdb, 0xF3, 0x55, 0xCB, 0x54, 0x8F, 0xA9, 0x5E, 0x53, 0x7D, 0xAE,
0xf1, 0x51, 0x43, 0x5d, 0xc3, 0x40, 0x43, 0xa5, 0x61, 0x95, 0x61, 0x97, 0x46, 0x55, 0x33, 0x53, 0xE3, 0xA9, 0x09, 0xD4, 0x96, 0xAB,
0xe1, 0x84, 0x91, 0xb9, 0xd1, 0x3c, 0xa3, 0xd5, 0x46, 0x8d, 0x46, 0x0f, 0x55, 0xAA, 0x9D, 0x50, 0xEB, 0x53, 0x1B, 0x53, 0x67, 0xA9,
0x8c, 0x69, 0xc6, 0x5c, 0xe3, 0x24, 0xe3, 0x6d, 0xc6, 0x6d, 0xc6, 0xa3, 0x3B, 0xA8, 0x87, 0xAA, 0x67, 0xA8, 0x6F, 0x54, 0x3F, 0xA4,
0x26, 0x06, 0x26, 0x21, 0x26, 0x4b, 0x4d, 0xea, 0x4d, 0xee, 0x9a, 0x52, 0x7E, 0x59, 0xFD, 0x89, 0x06, 0x59, 0xC3, 0x4C, 0xC3, 0x4F,
0x4d, 0xb9, 0xa6, 0x29, 0xa6, 0x3b, 0x4c, 0x3b, 0x4c, 0xc7, 0xcd, 0xcc, 0x43, 0xA4, 0x51, 0xA0, 0xB1, 0x5F, 0xE3, 0xBC, 0xC6, 0x20,
0xcd, 0xa2, 0xcd, 0xd6, 0x99, 0x35, 0x9b, 0x3d, 0x31, 0xd7, 0x32, 0xe7, 0x0B, 0x63, 0x19, 0xB3, 0x78, 0x2C, 0x21, 0x6B, 0x0D, 0xAB,
0x9b, 0xe7, 0x9b, 0xd7, 0x9b, 0xdf, 0xb7, 0x60, 0x5a, 0x78, 0x5a, 0x2c, 0x86, 0x75, 0x81, 0x35, 0xC4, 0x26, 0xB1, 0xCD, 0xD9, 0x7C,
0xb6, 0xa8, 0xb6, 0xb8, 0x65, 0x49, 0xb2, 0xe4, 0x5a, 0xa6, 0x59, 0xee, 0x76, 0x2A, 0xBB, 0x98, 0xFD, 0x1D, 0xBB, 0x8B, 0x3D, 0xAA,
0xb6, 0xbc, 0x6e, 0x85, 0x5a, 0x39, 0x59, 0xa5, 0x58, 0x55, 0x5a, 0x5d, 0xA9, 0xA1, 0x39, 0x43, 0x33, 0x4A, 0x33, 0x57, 0xB3, 0x52,
0xb3, 0x46, 0xad, 0x9d, 0xad, 0x25, 0xd6, 0xbb, 0xad, 0xbb, 0xa7, 0x11, 0xF3, 0x94, 0x66, 0x3F, 0x07, 0xE3, 0x98, 0x71, 0xF8, 0x9C,
0xa7, 0xb9, 0x4e, 0x93, 0x4e, 0xab, 0x9e, 0xd6, 0x67, 0xc3, 0xb0, 0xf1, 0x74, 0x4E, 0x09, 0xE7, 0x28, 0xA7, 0x97, 0xF3, 0x7E, 0x8A,
0xb6, 0xc9, 0xb6, 0xa9, 0xb7, 0x19, 0xb0, 0xe5, 0xd8, 0x06, 0xdb, 0xae, 0xDE, 0x14, 0xEF, 0x29, 0xE2, 0x29, 0x1B, 0xA6, 0x34, 0x4C,
0xb6, 0x6d, 0xb6, 0x7d, 0x61, 0x67, 0x62, 0x17, 0x67, 0xb7, 0xc5, 0xae, 0xB9, 0x31, 0x65, 0x5C, 0x6B, 0xAA, 0x96, 0x97, 0x96, 0x58,
0xc3, 0xee, 0x93, 0xbd, 0x93, 0x7d, 0xba, 0x7d, 0x8d, 0xfd, 0x3d, 0x07, 0xAB, 0x48, 0xAB, 0x51, 0xAB, 0x47, 0xEB, 0xBD, 0x36, 0xAE,
0x0d, 0x87, 0xd9, 0x0e, 0xab, 0x1d, 0x5a, 0x1d, 0x7e, 0x73, 0xb4, 0x72, 0xED, 0xA7, 0x9D, 0xA6, 0xBD, 0x45, 0xBB, 0x59, 0xFB, 0x81,
0x14, 0x3a, 0x56, 0x3a, 0xde, 0x9a, 0xce, 0x9c, 0xee, 0x3f, 0x7d, 0xc5, 0x0E, 0x41, 0xC7, 0x4A, 0x27, 0x5C, 0x27, 0x47, 0x67, 0x8F,
0xf4, 0x96, 0xe9, 0x2f, 0x67, 0x58, 0xcf, 0x10, 0xcf, 0xd8, 0x33, 0xe3, 0xCE, 0x05, 0x9D, 0xE7, 0x53, 0xD9, 0x53, 0xDD, 0xA7, 0x0A,
0xb6, 0x13, 0xcb, 0x29, 0xc4, 0x69, 0x9d, 0x53, 0x9b, 0xd3, 0x47, 0x67, 0xA7, 0x16, 0x4D, 0x3D, 0x3A, 0xF5, 0xAE, 0x2E, 0xAA, 0x6B,
0x17, 0x67, 0xb9, 0x73, 0x83, 0xf3, 0x88, 0x8b, 0x89, 0x4b, 0x82, 0xcb, 0xA5, 0x1B, 0xA1, 0xBB, 0x44, 0x77, 0xBF, 0x6E, 0xA7, 0xEE,
0x2e, 0x97, 0x3e, 0x2e, 0x9b, 0x1b, 0xc6, 0xdd, 0xc8, 0xbd, 0xe4, 0x4a, 0x98, 0x9E, 0xBE, 0x5E, 0x80, 0x9E, 0x4C, 0x6F, 0xA7, 0xDE,
0x74, 0xf5, 0x71, 0x5d, 0xe1, 0x7a, 0xd2, 0xf5, 0x9d, 0x9b, 0xb3, 0x9b, 0x79, 0xBD, 0xE7, 0xFA, 0x1C, 0x7D, 0x2F, 0xFD, 0x54, 0xFD,
0xc2, 0xed, 0xa8, 0xdb, 0xaf, 0xee, 0x36, 0xee, 0x69, 0xee, 0x87, 0xdc, 0x6D, 0xFA, 0xA7, 0xF5, 0x47, 0x0C, 0x58, 0x06, 0xB3, 0x0C,
0x9f, 0xcc, 0x34, 0x9f, 0x29, 0x9e, 0x59, 0x33, 0x73, 0xd0, 0xc3, 0xc8, 0x24, 0x06, 0xDB, 0x0C, 0xCE, 0x18, 0x3C, 0xC5, 0x35, 0x71,
0x43, 0xe0, 0x51, 0xe5, 0xd1, 0x3f, 0x0b, 0x9f, 0x95, 0x30, 0x6b, 0xdf, 0x6F, 0x3C, 0x1D, 0x2F, 0xC7, 0xDB, 0xF1, 0x51, 0x43, 0x5D,
0xac, 0x7e, 0x4f, 0x43, 0x4f, 0x81, 0x67, 0xb5, 0xe7, 0x23, 0x2f, 0x63, 0xC3, 0x40, 0x43, 0xA5, 0x61, 0x95, 0x61, 0x97, 0xE1, 0x84,
0x2f, 0x91, 0x57, 0xad, 0xd7, 0xb0, 0xb7, 0xa5, 0x77, 0xaa, 0xf7, 0x61, 0x91, 0xB9, 0xD1, 0x3C, 0xA3, 0xD5, 0x46, 0x8D, 0x46, 0x0F,
0xef, 0x17, 0x3e, 0xf6, 0x3e, 0x72, 0x9f, 0xe3, 0x3e, 0xe3, 0x3c, 0x37, 0x8C, 0x69, 0xC6, 0x5C, 0xE3, 0x24, 0xE3, 0x6D, 0xC6, 0x6D,
0xde, 0x32, 0xde, 0x59, 0x5f, 0xcc, 0x37, 0xc0, 0xb7, 0xc8, 0xb7, 0xcb, 0xC6, 0xA3, 0x26, 0x06, 0x26, 0x21, 0x26, 0x4B, 0x4D, 0xEA,
0x4f, 0xc3, 0x6f, 0x9e, 0x5f, 0x85, 0xdf, 0x43, 0x7f, 0x23, 0xff, 0x64, 0x4D, 0xEE, 0x9A, 0x52, 0x4D, 0xB9, 0xA6, 0x29, 0xA6, 0x3B,
0xff, 0x7a, 0xff, 0xd1, 0x00, 0xa7, 0x80, 0x25, 0x01, 0x67, 0x03, 0x89, 0x4C, 0x3B, 0x4C, 0xC7, 0xCD, 0xCC, 0xCD, 0xA2, 0xCD, 0xD6,
0x81, 0x41, 0x81, 0x5b, 0x02, 0xfb, 0xf8, 0x7a, 0x7c, 0x21, 0xbf, 0x8e, 0x99, 0x35, 0x9B, 0x3D, 0x31, 0xD7, 0x32, 0xE7, 0x9B, 0xE7,
0x3f, 0x3a, 0xdb, 0x65, 0xf6, 0xb2, 0xd9, 0xed, 0x41, 0x8c, 0xa0, 0xb9, 0x9B, 0xD7, 0x9B, 0xDF, 0xB7, 0x60, 0x5A, 0x78, 0x5A, 0x2C,
0x41, 0x15, 0x41, 0x8f, 0x82, 0xad, 0x82, 0xe5, 0xc1, 0xad, 0x21, 0x68, 0xB6, 0xA8, 0xB6, 0xB8, 0x65, 0x49, 0xB2, 0xE4, 0x5A, 0xA6,
0xc8, 0xec, 0x90, 0xad, 0x21, 0xf7, 0xe7, 0x98, 0xce, 0x91, 0xce, 0x69, 0x59, 0xEE, 0xB6, 0xBC, 0x6E, 0x85, 0x5A, 0x39, 0x59, 0xA5,
0x0e, 0x85, 0x50, 0x7e, 0xe8, 0xd6, 0xd0, 0x07, 0x61, 0xe6, 0x61, 0x8b, 0x58, 0x55, 0x5A, 0x5D, 0xB3, 0x46, 0xAD, 0x9D, 0xAD, 0x25,
0xc3, 0x7e, 0x0c, 0x27, 0x85, 0x87, 0x85, 0x57, 0x86, 0x3f, 0x8e, 0x70, 0xD6, 0xBB, 0xAD, 0xBB, 0xA7, 0x11, 0xA7, 0xB9, 0x4E, 0x93,
0x88, 0x58, 0x1a, 0xd1, 0x31, 0x97, 0x35, 0x77, 0xd1, 0xdc, 0x43, 0x73, 0x4E, 0xAB, 0x9E, 0xD6, 0x67, 0xC3, 0xB0, 0xF1, 0xB6, 0xC9,
0xdf, 0x44, 0xfa, 0x44, 0x96, 0x44, 0xde, 0x9b, 0x67, 0x31, 0x4f, 0x39, 0xB6, 0xA9, 0xB7, 0x19, 0xB0, 0xE5, 0xD8, 0x06, 0xDB, 0xAE,
0xaf, 0x2d, 0x4a, 0x35, 0x2a, 0x3e, 0xaa, 0x2e, 0x6a, 0x3c, 0xda, 0x37, 0xB6, 0x6D, 0xB6, 0x7D, 0x61, 0x67, 0x62, 0x17, 0x67, 0xB7,
0xba, 0x34, 0xba, 0x3f, 0xc6, 0x2e, 0x66, 0x59, 0xcc, 0xd5, 0x58, 0x9d, 0xC5, 0xAE, 0xC3, 0xEE, 0x93, 0xBD, 0x93, 0x7D, 0xBA, 0x7D,
0x58, 0x49, 0x6c, 0x4b, 0x1c, 0x39, 0x2e, 0x2a, 0xae, 0x36, 0x6e, 0x6c, 0x8D, 0xFD, 0x3D, 0x07, 0x0D, 0x87, 0xD9, 0x0E, 0xAB, 0x1D,
0xbe, 0xdf, 0xfc, 0xed, 0xf3, 0x87, 0xe2, 0x9d, 0xe2, 0x0b, 0xe3, 0x7b, 0x5A, 0x1D, 0x7E, 0x73, 0xB4, 0x72, 0x14, 0x3A, 0x56, 0x3A,
0x17, 0x98, 0x2f, 0xc8, 0x5d, 0x70, 0x79, 0xa1, 0xce, 0xc2, 0xf4, 0x85, 0xDE, 0x9A, 0xCE, 0x9C, 0xEE, 0x3F, 0x7D, 0xC5, 0xF4, 0x96,
0xa7, 0x16, 0xa9, 0x2e, 0x12, 0x2c, 0x3a, 0x96, 0x40, 0x4c, 0x88, 0x4e, 0xE9, 0x2F, 0x67, 0x58, 0xCF, 0x10, 0xCF, 0xD8, 0x33, 0xE3,
0x38, 0x94, 0xf0, 0x41, 0x10, 0x2a, 0xa8, 0x16, 0x8c, 0x25, 0xf2, 0x13, 0xB6, 0x13, 0xCB, 0x29, 0xC4, 0x69, 0x9D, 0x53, 0x9B, 0xD3,
0x77, 0x25, 0x8e, 0x0a, 0x79, 0xc2, 0x1d, 0xc2, 0x67, 0x22, 0x2f, 0xd1, 0x47, 0x67, 0x17, 0x67, 0xB9, 0x73, 0x83, 0xF3, 0x88, 0x8B,
0x36, 0xd1, 0x88, 0xd8, 0x43, 0x5c, 0x2a, 0x1e, 0x4e, 0xf2, 0x48, 0x2a, 0x89, 0x4B, 0x82, 0xCB, 0x2E, 0x97, 0x3E, 0x2E, 0x9B, 0x1B,
0x4d, 0x7a, 0x92, 0xec, 0x91, 0xbc, 0x35, 0x79, 0x24, 0xc5, 0x33, 0xa5, 0xC6, 0xDD, 0xC8, 0xBD, 0xE4, 0x4A, 0x74, 0xF5, 0x71, 0x5D,
0x2c, 0xe5, 0xb9, 0x84, 0x27, 0xa9, 0x90, 0xbc, 0x4c, 0x0d, 0x4c, 0xdd, 0xE1, 0x7A, 0xD2, 0xF5, 0x9D, 0x9B, 0xB3, 0x9B, 0xC2, 0xED,
0x9b, 0x3a, 0x9e, 0x16, 0x9a, 0x76, 0x20, 0x6d, 0x32, 0x3d, 0x3a, 0xbd, 0xA8, 0xDB, 0xAF, 0xEE, 0x36, 0xEE, 0x69, 0xEE, 0x87, 0xDC,
0x31, 0x83, 0x92, 0x91, 0x90, 0x71, 0x42, 0xaa, 0x21, 0x4d, 0x93, 0xb6, 0x9F, 0xCC, 0x34, 0x9F, 0x29, 0x9E, 0x59, 0x33, 0x73, 0xD0,
0x67, 0xea, 0x67, 0xe6, 0x66, 0x76, 0xcb, 0xac, 0x65, 0x85, 0xb2, 0xfe, 0xC3, 0xC8, 0x43, 0xE0, 0x51, 0xE5, 0xD1, 0x3F, 0x0B, 0x9F,
0xc5, 0x6e, 0x8b, 0xb7, 0x2f, 0x1e, 0x95, 0x07, 0xc9, 0x6b, 0xb3, 0x90, 0x95, 0x30, 0x6B, 0xDF, 0xAC, 0x7E, 0x4F, 0x43, 0x4F, 0x81,
0xac, 0x05, 0x59, 0x2d, 0x0a, 0xb6, 0x42, 0xa6, 0xe8, 0x54, 0x5a, 0x28, 0x67, 0xB5, 0xE7, 0x23, 0x2F, 0x63, 0x2F, 0x91, 0x57, 0xAD,
0xd7, 0x2a, 0x07, 0xb2, 0x67, 0x65, 0x57, 0x66, 0xbf, 0xcd, 0x89, 0xca, 0xD7, 0xB0, 0xB7, 0xA5, 0x77, 0xAA, 0xF7, 0x61, 0xEF, 0x17,
0x39, 0x96, 0xab, 0x9e, 0x2b, 0xcd, 0xed, 0xcc, 0xb3, 0xca, 0xdb, 0x90, 0x3E, 0xF6, 0x3E, 0x72, 0x9F, 0xE3, 0x3E, 0xE3, 0x3C, 0x37,
0x37, 0x9c, 0xef, 0x9f, 0xff, 0xed, 0x12, 0xc2, 0x12, 0xe1, 0x92, 0xb6, 0xDE, 0x32, 0xDE, 0x59, 0x5F, 0xCC, 0x37, 0xC0, 0xB7, 0xC8,
0xa5, 0x86, 0x4b, 0x57, 0x2d, 0x1d, 0x58, 0xe6, 0xbd, 0xac, 0x6a, 0x39, 0xB7, 0xCB, 0x4F, 0xC3, 0x6F, 0x9E, 0x5F, 0x85, 0xDF, 0x43,
0xb2, 0x3c, 0x71, 0x79, 0xdb, 0x0a, 0xe3, 0x15, 0x05, 0x2b, 0x86, 0x56, 0x7F, 0x23, 0xFF, 0x64, 0xFF, 0x7A, 0xFF, 0xD1, 0x00, 0xA7,
0x06, 0xac, 0x3c, 0xb8, 0x8a, 0xb6, 0x2a, 0x6d, 0xd5, 0x4f, 0xab, 0xed, 0x80, 0x25, 0x01, 0x67, 0x03, 0x89, 0x81, 0x41, 0x81, 0x5B,
0x57, 0x97, 0xae, 0x7e, 0xbd, 0x26, 0x7a, 0x4d, 0x6b, 0x81, 0x5e, 0xc1, 0x02, 0xFB, 0xF8, 0x7A, 0x7C, 0x21, 0xBF, 0x8E, 0x3F, 0x3A,
0xca, 0x82, 0xc1, 0xb5, 0x01, 0x6b, 0xeb, 0x0b, 0x55, 0x0a, 0xe5, 0x85, 0xDB, 0x65, 0xF6, 0xB2, 0xD9, 0xED, 0x41, 0x8C, 0xA0, 0xB9,
0x7d, 0xeb, 0xdc, 0xd7, 0xed, 0x5d, 0x4f, 0x58, 0x2f, 0x59, 0xdf, 0xb5, 0x41, 0x15, 0x41, 0x8F, 0x82, 0xAD, 0x82, 0xE5, 0xC1, 0xAD,
0x61, 0xfa, 0x86, 0x9d, 0x1b, 0x3e, 0x15, 0x89, 0x8a, 0xae, 0x14, 0xdb, 0x21, 0x68, 0xC8, 0xEC, 0x90, 0xAD, 0x21, 0xF7, 0xE7, 0x98,
0x17, 0x97, 0x15, 0x7f, 0xd8, 0x28, 0xdc, 0x78, 0xe5, 0x1b, 0x87, 0x6f, 0xCE, 0x91, 0xCE, 0x69, 0x0E, 0x85, 0x50, 0x7E, 0xE8, 0xD6,
0xca, 0xbf, 0x99, 0xdc, 0x94, 0xb4, 0xa9, 0xab, 0xc4, 0xb9, 0x64, 0xcf, 0xD0, 0x07, 0x61, 0xE6, 0x61, 0x8B, 0xC3, 0x7E, 0x0C, 0x27,
0x66, 0xd2, 0x66, 0xe9, 0xe6, 0xde, 0x2d, 0x9e, 0x5b, 0x0e, 0x96, 0xaa, 0x85, 0x87, 0x85, 0x57, 0x86, 0x3F, 0x8E, 0x70, 0x88, 0x58,
0x97, 0xe6, 0x97, 0x0e, 0x6e, 0x0d, 0xd9, 0xda, 0xb4, 0x0d, 0xdf, 0x56, 0x1A, 0xD1, 0x31, 0x97, 0x35, 0x77, 0xD1, 0xDC, 0x43, 0x73,
0xb4, 0xed, 0xf5, 0xf6, 0x45, 0xdb, 0x2f, 0x97, 0xcd, 0x28, 0xdb, 0xbb, 0xDF, 0x44, 0xFA, 0x44, 0x96, 0x44, 0xDE, 0x9B, 0x67, 0x31,
0x83, 0xb6, 0x43, 0xb9, 0xa3, 0xbf, 0x3c, 0xb8, 0xbc, 0x65, 0xa7, 0xc9, 0x4F, 0x39, 0xAF, 0x2D, 0x4A, 0x35, 0x2A, 0x3E, 0xAA, 0x2E,
0xce, 0xcd, 0x3b, 0x3f, 0x54, 0xa4, 0x54, 0xf4, 0x54, 0xfa, 0x54, 0x36, 0x6A, 0x3C, 0xDA, 0x37, 0xBA, 0x34, 0xBA, 0x3F, 0xC6, 0x2E,
0xee, 0xd2, 0xdd, 0xb5, 0x61, 0xd7, 0xf8, 0x6e, 0xd1, 0xee, 0x1b, 0x7b, 0x66, 0x59, 0xCC, 0xD5, 0x58, 0x9D, 0x58, 0x49, 0x6C, 0x4B,
0xbc, 0xf6, 0x34, 0xec, 0xd5, 0xdb, 0x5b, 0xbc, 0xf7, 0xfd, 0x3e, 0xc9, 0x1C, 0x39, 0x2E, 0x2A, 0xAE, 0x36, 0x6E, 0x6C, 0xBE, 0xDF,
0xbe, 0xdb, 0x55, 0x01, 0x55, 0x4d, 0xd5, 0x66, 0xd5, 0x65, 0xfb, 0x49, 0xFC, 0xED, 0xF3, 0x87, 0xE2, 0x9D, 0xE2, 0x0B, 0xE3, 0x7B,
0xfb, 0xb3, 0xf7, 0x3f, 0xae, 0x89, 0xaa, 0xe9, 0xf8, 0x96, 0xfb, 0x6d, 0x17, 0x98, 0x2F, 0xC8, 0x5D, 0x70, 0x79, 0xA1, 0xCE, 0xC2,
0x5d, 0xad, 0x4e, 0x6d, 0x71, 0xed, 0xc7, 0x03, 0xd2, 0x03, 0xfd, 0x07, 0xF4, 0x85, 0xA7, 0x16, 0xA9, 0x2E, 0x12, 0x2C, 0x3A, 0x96,
0x23, 0x0e, 0xb6, 0xd7, 0xb9, 0xd4, 0xd5, 0x1d, 0xd2, 0x3d, 0x54, 0x52, 0x40, 0x4C, 0x88, 0x4E, 0x38, 0x94, 0xF0, 0x41, 0x10, 0x2A,
0x8f, 0xd6, 0x2b, 0xeb, 0x47, 0x0e, 0xc7, 0x1f, 0xbe, 0xfe, 0x9d, 0xef, 0xA8, 0x16, 0x8C, 0x25, 0xF2, 0x13, 0x77, 0x25, 0x8E, 0x0A,
0x77, 0x2d, 0x0d, 0x36, 0x0d, 0x55, 0x8d, 0x9c, 0xc6, 0xe2, 0x23, 0x70, 0x79, 0xC2, 0x1D, 0xC2, 0x67, 0x22, 0x2F, 0xD1, 0x36, 0xD1,
0x44, 0x79, 0xe4, 0xe9, 0xf7, 0x09, 0xdf, 0xf7, 0x1e, 0x0d, 0x3a, 0xda, 0x88, 0xD8, 0x43, 0x5C, 0x2A, 0x1E, 0x4E, 0xF2, 0x48, 0x2A,
0x76, 0x8c, 0x7b, 0xac, 0xe1, 0x07, 0xd3, 0x1f, 0x76, 0x1d, 0x67, 0x1d, 0x4D, 0x7A, 0x92, 0xEC, 0x91, 0xBC, 0x35, 0x79, 0x24, 0xC5,
0x2f, 0x6a, 0x42, 0x9a, 0xf2, 0x9a, 0x46, 0x9b, 0x53, 0x9a, 0xfb, 0x5b, 0x33, 0xA5, 0x2C, 0xE5, 0xB9, 0x84, 0x27, 0xA9, 0x90, 0xBC,
0x62, 0x5b, 0xba, 0x4f, 0xcc, 0x3e, 0xd1, 0xd6, 0xea, 0xde, 0x7a, 0xfc, 0x4C, 0x0D, 0x4C, 0xDD, 0x9B, 0x3A, 0x9E, 0x16, 0x9A, 0x76,
0x47, 0xdb, 0x1f, 0x0f, 0x9c, 0x34, 0x3c, 0x59, 0x79, 0x4a, 0xf3, 0x54, 0x20, 0x6D, 0x32, 0x3D, 0x3A, 0xBD, 0x31, 0x83, 0x92, 0x91,
0xc9, 0x69, 0xda, 0xe9, 0x82, 0xd3, 0x93, 0x67, 0xf2, 0xcf, 0x8c, 0x9d, 0x90, 0x71, 0x42, 0xAA, 0x21, 0x4D, 0x93, 0xB6, 0x67, 0xEA,
0x95, 0x9d, 0x7d, 0x7e, 0x2e, 0xf9, 0xdc, 0x60, 0xdb, 0xa2, 0xb6, 0x7b, 0x67, 0xE6, 0x66, 0x76, 0xCB, 0xAC, 0x65, 0x85, 0xB2, 0xFE,
0xe7, 0x63, 0xce, 0xdf, 0x6a, 0x0f, 0x6f, 0xef, 0xba, 0x10, 0x74, 0xe1, 0xC5, 0x6E, 0x8B, 0xB7, 0x2F, 0x1E, 0x95, 0x07, 0xC9, 0x6B,
0xd2, 0x45, 0xff, 0x8b, 0xe7, 0x3b, 0xbc, 0x3b, 0xce, 0x5c, 0xf2, 0xb8, 0xB3, 0x90, 0xAC, 0x05, 0x59, 0x2D, 0x0A, 0xB6, 0x42, 0xA6,
0x74, 0xf2, 0xb2, 0xdb, 0xe5, 0x13, 0x57, 0xb8, 0x57, 0x9a, 0xaf, 0x3a, 0xE8, 0x54, 0x5A, 0x28, 0xD7, 0x2A, 0x07, 0xB2, 0x67, 0x65,
0x5f, 0x6d, 0xea, 0x74, 0xea, 0x3c, 0xfe, 0x93, 0xd3, 0x4f, 0xc7, 0xbb, 0x57, 0x66, 0xBF, 0xCD, 0x89, 0xCA, 0x39, 0x96, 0xAB, 0x9E,
0x9c, 0xbb, 0x9a, 0xae, 0xb9, 0x5c, 0x6b, 0xb9, 0xee, 0x7a, 0xbd, 0xb5, 0x2B, 0xCD, 0xED, 0xCC, 0xB3, 0xCA, 0xDB, 0x90, 0x37, 0x9C,
0x7b, 0x66, 0xf7, 0xe9, 0x1b, 0x9e, 0x37, 0xce, 0xdd, 0xf4, 0xbd, 0x79, 0xEF, 0x9F, 0xFF, 0xED, 0x12, 0xC2, 0x12, 0xE1, 0x92, 0xB6,
0xf1, 0x16, 0xff, 0xd6, 0xd5, 0x9e, 0x39, 0x3d, 0xdd, 0xbd, 0xf3, 0x7a, 0xA5, 0x86, 0x4B, 0x57, 0x2D, 0x1D, 0x58, 0xE6, 0xBD, 0xAC,
0x6f, 0xf7, 0xc5, 0xf7, 0xf5, 0xdf, 0x16, 0xdd, 0x7e, 0x72, 0x27, 0xfd, 0x6A, 0x39, 0xB2, 0x3C, 0x71, 0x79, 0xDB, 0x0A, 0xE3, 0x15,
0xce, 0xcb, 0xbb, 0xd9, 0x77, 0x27, 0xee, 0xad, 0xbc, 0x4f, 0xbc, 0x5f, 0x05, 0x2B, 0x86, 0x56, 0x06, 0xAC, 0x3C, 0xB8, 0x8A, 0xB6,
0xf4, 0x40, 0xed, 0x41, 0xd9, 0x43, 0xdd, 0x87, 0xd5, 0x3f, 0x5b, 0xfe, 0x2A, 0x6D, 0xD5, 0x4F, 0xAB, 0xED, 0x57, 0x97, 0xAE, 0x7E,
0xdc, 0xd8, 0xef, 0xdc, 0x7f, 0x6a, 0xc0, 0x77, 0xa0, 0xf3, 0xd1, 0xdc, 0xBD, 0x26, 0x7A, 0x4D, 0x6B, 0x81, 0x5E, 0xC1, 0xCA, 0x82,
0x47, 0xf7, 0x06, 0x85, 0x83, 0xcf, 0xfe, 0x91, 0xf5, 0x8f, 0x0f, 0x43, 0xC1, 0xB5, 0x01, 0x6B, 0xEB, 0x0B, 0x55, 0x0A, 0xE5, 0x85,
0x05, 0x8f, 0x99, 0x8f, 0xcb, 0x86, 0x0d, 0x86, 0xeb, 0x9e, 0x38, 0x3e, 0x7D, 0xEB, 0xDC, 0xD7, 0xED, 0x5D, 0x4F, 0x58, 0x2F, 0x59,
0x39, 0x39, 0xe2, 0x3f, 0x72, 0xfd, 0xe9, 0xfc, 0xa7, 0x43, 0xcf, 0x64, 0xDF, 0xB5, 0x61, 0xFA, 0x86, 0x9D, 0x1B, 0x3E, 0x15, 0x89,
0xcf, 0x26, 0x9e, 0x17, 0xfe, 0xa2, 0xfe, 0xcb, 0xae, 0x17, 0x16, 0x2f, 0x8A, 0xAE, 0x14, 0xDB, 0x17, 0x97, 0x15, 0x7F, 0xD8, 0x28,
0x7e, 0xf8, 0xd5, 0xeb, 0xd7, 0xce, 0xd1, 0x98, 0xd1, 0xa1, 0x97, 0xf2, 0xDC, 0x78, 0xE5, 0x1B, 0x87, 0x6F, 0xCA, 0xBF, 0x99, 0xDC,
0x97, 0x93, 0xbf, 0x6d, 0x7c, 0xa5, 0xfd, 0xea, 0xc0, 0xeb, 0x19, 0xaf, 0x94, 0xB4, 0xA9, 0xAB, 0xC4, 0xB9, 0x64, 0xCF, 0x66, 0xD2,
0xdb, 0xc6, 0xc2, 0xc6, 0x1e, 0xbe, 0xc9, 0x78, 0x33, 0x31, 0x5e, 0xf4, 0x66, 0xE9, 0xE6, 0xDE, 0x2D, 0x9E, 0x5B, 0x0E, 0x96, 0xAA,
0x56, 0xfb, 0xed, 0xc1, 0x77, 0xdc, 0x77, 0x1d, 0xef, 0xa3, 0xdf, 0x0f, 0x97, 0xE6, 0x97, 0x0E, 0x6E, 0x0D, 0xD9, 0xDA, 0xB4, 0x0D,
0x4f, 0xe4, 0x7c, 0x20, 0x7f, 0x28, 0xff, 0x68, 0xf9, 0xb1, 0xf5, 0x53, 0xDF, 0x56, 0xB4, 0xED, 0xF5, 0xF6, 0x45, 0xDB, 0x2F, 0x97,
0xd0, 0xa7, 0xfb, 0x93, 0x19, 0x93, 0x93, 0xff, 0x04, 0x03, 0x98, 0xf3, 0xCD, 0x28, 0xDB, 0xBB, 0x83, 0xB6, 0x43, 0xB9, 0xA3, 0xBF,
0xfc, 0x63, 0x33, 0x2d, 0xdb, 0x00, 0x00, 0x00, 0x20, 0x63, 0x48, 0x52, 0x3C, 0xB8, 0xBC, 0x65, 0xA7, 0xC9, 0xCE, 0xCD, 0x3B, 0x3F,
0x4d, 0x00, 0x00, 0x7a, 0x25, 0x00, 0x00, 0x80, 0x83, 0x00, 0x00, 0xf9, 0x54, 0xA4, 0x54, 0xF4, 0x54, 0xFA, 0x54, 0x36, 0xEE, 0xD2,
0xff, 0x00, 0x00, 0x80, 0xe9, 0x00, 0x00, 0x75, 0x30, 0x00, 0x00, 0xea, 0xDD, 0xB5, 0x61, 0xD7, 0xF8, 0x6E, 0xD1, 0xEE, 0x1B, 0x7B,
0x60, 0x00, 0x00, 0x3a, 0x98, 0x00, 0x00, 0x17, 0x6f, 0x92, 0x5f, 0xc5, 0xBC, 0xF6, 0x34, 0xEC, 0xD5, 0xDB, 0x5B, 0xBC, 0xF7, 0xFD,
0x46, 0x00, 0x00, 0x02, 0x8c, 0x49, 0x44, 0x41, 0x54, 0x78, 0xda, 0x4c, 0x3E, 0xC9, 0xBE, 0xDB, 0x55, 0x01, 0x55, 0x4D, 0xD5, 0x66,
0xcf, 0x4b, 0x6b, 0x13, 0x51, 0x18, 0xc6, 0xf1, 0xf7, 0x72, 0xce, 0xcc, 0xD5, 0x65, 0xFB, 0x49, 0xFB, 0xB3, 0xF7, 0x3F, 0xAE, 0x89,
0x9c, 0x99, 0xc9, 0x4c, 0x12, 0x43, 0x9a, 0x36, 0x58, 0x5b, 0xc5, 0x3b, 0xAA, 0xE9, 0xF8, 0x96, 0xFB, 0x6D, 0x5D, 0xAD, 0x4E, 0x6D,
0x08, 0x0a, 0xe2, 0xca, 0x9d, 0x60, 0x41, 0xd1, 0x95, 0x75, 0xa3, 0xae, 0x71, 0xED, 0xC7, 0x03, 0xD2, 0x03, 0xFD, 0x07, 0x23, 0x0E,
0x5c, 0xfa, 0x01, 0xfc, 0x0c, 0x22, 0x6e, 0xdc, 0x76, 0xa5, 0x1b, 0x05, 0xB6, 0xD7, 0xB9, 0xD4, 0xD5, 0x1D, 0xD2, 0x3D, 0x54, 0x52,
0x11, 0xdc, 0x88, 0x97, 0x8a, 0x20, 0xd5, 0x62, 0x15, 0xbc, 0x94, 0x16, 0x8F, 0xD6, 0x2B, 0xEB, 0x47, 0x0E, 0xC7, 0x1F, 0xBE, 0xFE,
0xad, 0xd5, 0xd6, 0xd6, 0xd6, 0xb4, 0x35, 0xe9, 0x2d, 0x93, 0xcb, 0x64, 0x9D, 0xEF, 0x77, 0x2D, 0x0D, 0x36, 0x0D, 0x55, 0x8D, 0x9C,
0xce, 0x1c, 0x17, 0x42, 0xed, 0xb3, 0xfe, 0xff, 0x16, 0x0f, 0x3e, 0x79, 0xC6, 0xE2, 0x23, 0x70, 0x44, 0x79, 0xE4, 0xE9, 0xF7, 0x09,
0xf9, 0xf6, 0xfb, 0xcc, 0x6c, 0xb9, 0xbb, 0x4b, 0xa7, 0x06, 0x8c, 0x01, 0xDF, 0xF7, 0x1E, 0x0D, 0x3A, 0xDA, 0x76, 0x8C, 0x7B, 0xAC,
0x00, 0x66, 0x51, 0x8f, 0xa2, 0xd5, 0xd5, 0x55, 0xdf, 0xcf, 0xe4, 0xf2, 0xE1, 0x07, 0xD3, 0x1F, 0x76, 0x1D, 0x67, 0x1D, 0x2F, 0x6A,
0x79, 0x9d, 0xc4, 0x60, 0x0c, 0x13, 0x2e, 0xfc, 0xae, 0xec, 0xd9, 0xdd, 0x42, 0x9A, 0xF2, 0x9A, 0x46, 0x9B, 0x53, 0x9A, 0xFB, 0x5B,
0xcf, 0x5e, 0xb1, 0x7f, 0x57, 0xdf, 0xae, 0x4c, 0x98, 0x37, 0x6c, 0x91, 0x62, 0x5B, 0xBA, 0x4F, 0xCC, 0x3E, 0xD1, 0xD6, 0xEA, 0xDE,
0xed, 0x49, 0xc7, 0xad, 0xad, 0xd6, 0x28, 0x5e, 0xdf, 0xdb, 0xdf, 0x13, 0x7A, 0xFC, 0x47, 0xDB, 0x1F, 0x0F, 0x9C, 0x34, 0x3C, 0x59,
0x37, 0x37, 0x57, 0x6a, 0x1b, 0xd9, 0x62, 0x19, 0x48, 0xb0, 0x74, 0xe2, 0x79, 0x4A, 0xF3, 0x54, 0xC9, 0x69, 0xDA, 0xE9, 0x82, 0xD3,
0x4e, 0xfc, 0xe2, 0xd5, 0xa8, 0x20, 0xb7, 0x34, 0x3e, 0xdf, 0xe2, 0xb5, 0x93, 0x67, 0xF2, 0xCF, 0x8C, 0x9D, 0x95, 0x9D, 0x7D, 0x7E,
0xa8, 0xd1, 0x6c, 0x60, 0xb4, 0x94, 0xd8, 0xc1, 0xb1, 0x1d, 0x8d, 0xcb, 0x2E, 0xF9, 0xDC, 0x60, 0xDB, 0xA2, 0xB6, 0x7B, 0xE7, 0x63,
0x97, 0x2e, 0xb0, 0x90, 0x00, 0xf0, 0xe4, 0xe9, 0xf3, 0x87, 0x23, 0x9f, 0xCE, 0xDF, 0x6A, 0x0F, 0x6F, 0xEF, 0xBA, 0x10, 0x74, 0xE1,
0xc3, 0x62, 0x1f, 0xe8, 0xa4, 0xbd, 0xd1, 0x64, 0xb7, 0x4c, 0x1b, 0x71, 0xD2, 0x45, 0xFF, 0x8B, 0xE7, 0x3B, 0xBC, 0x3B, 0xCE, 0x5C,
0x76, 0x64, 0x5a, 0x4f, 0xcf, 0xcf, 0x43, 0xe5, 0xc3, 0xd1, 0x1e, 0x5e, 0xF2, 0xB8, 0x74, 0xF2, 0xB2, 0xDB, 0xE5, 0x13, 0x57, 0xB8,
0x1c, 0x1f, 0xb9, 0x32, 0x78, 0xfe, 0x5f, 0x0d, 0x00, 0x03, 0xa7, 0x4f, 0x57, 0x9A, 0xAF, 0x3A, 0x5F, 0x6D, 0xEA, 0x74, 0xEA, 0x3C,
0x31, 0x25, 0x6f, 0x16, 0xf4, 0xfb, 0xc5, 0xce, 0xdb, 0x1f, 0xa6, 0xae, 0xFE, 0x93, 0xD3, 0x4F, 0xC7, 0xBB, 0x9C, 0xBB, 0x9A, 0xAE,
0x0b, 0xa2, 0x99, 0x78, 0x93, 0x7f, 0x30, 0x15, 0xcb, 0xb7, 0xae, 0x9d, 0xB9, 0x5C, 0x6B, 0xB9, 0xEE, 0x7A, 0xBD, 0xB5, 0x7B, 0x66,
0x2b, 0x74, 0x97, 0x43, 0x57, 0x4a, 0xcb, 0x86, 0xff, 0xc3, 0xbe, 0x82, 0xF7, 0xE9, 0x1B, 0x9E, 0x37, 0xCE, 0xDD, 0xF4, 0xBD, 0x79,
0x7f, 0xef, 0x43, 0xd3, 0x57, 0x99, 0xcd, 0x6a, 0xb2, 0x33, 0x60, 0x02, 0xF1, 0x16, 0xFF, 0xD6, 0xD5, 0x9E, 0x39, 0x3D, 0xDD, 0xBD,
0x69, 0x27, 0xaa, 0x6b, 0x2e, 0x0d, 0x1a, 0x71, 0x27, 0x08, 0xc2, 0x0b, 0xF3, 0x7A, 0x6F, 0xF7, 0xC5, 0xF7, 0xF5, 0xDF, 0x16, 0xDD,
0x83, 0x83, 0xcc, 0xbc, 0x0d, 0xc0, 0xc9, 0x83, 0x65, 0x76, 0x6c, 0x93, 0x7E, 0x72, 0x27, 0xFD, 0xCE, 0xCB, 0xBB, 0xD9, 0x77, 0x27,
0x2b, 0x45, 0x9c, 0xd3, 0x40, 0x24, 0x7c, 0xe1, 0x15, 0x03, 0xd9, 0xd3, 0xEE, 0xAD, 0xBC, 0x4F, 0xBC, 0x5F, 0xF4, 0x40, 0xED, 0x41,
0xf7, 0x60, 0x74, 0x6a, 0x71, 0xf6, 0x3b, 0x00, 0x20, 0xe2, 0x56, 0x3d, 0xD9, 0x43, 0xDD, 0x87, 0xD5, 0x3F, 0x5B, 0xFE, 0xDC, 0xD8,
0x31, 0x39, 0x79, 0xfd, 0xd9, 0x5c, 0x76, 0xef, 0x21, 0x2f, 0x50, 0x7e, 0xEF, 0xDC, 0x7F, 0x6A, 0xC0, 0x77, 0xA0, 0xF3, 0xD1, 0xDC,
0xa9, 0xc0, 0xae, 0x45, 0x68, 0x83, 0x50, 0x3a, 0xdf, 0x5d, 0xba, 0xd3, 0x47, 0xF7, 0x06, 0x85, 0x83, 0xCF, 0xFE, 0x91, 0xF5, 0x8F,
0x38, 0x38, 0x30, 0xf4, 0xf9, 0xe6, 0xdd, 0x47, 0x9d, 0x56, 0x73, 0x0b, 0x0F, 0x43, 0x05, 0x8F, 0x99, 0x8F, 0xCB, 0x86, 0x0D, 0x86,
0x30, 0x0b, 0x4b, 0x90, 0xb0, 0x12, 0x92, 0x1a, 0x44, 0x9b, 0xec, 0x94, 0xEB, 0x9E, 0x38, 0x3E, 0x39, 0x39, 0xE2, 0x3F, 0x72, 0xFD,
0x10, 0x53, 0xa9, 0x50, 0x71, 0x92, 0x2b, 0x14, 0xf4, 0xfe, 0x93, 0xb7, 0xE9, 0xFC, 0xA7, 0x43, 0xCF, 0x64, 0xCF, 0x26, 0x9E, 0x17,
0x7f, 0xb8, 0x9f, 0x26, 0xbe, 0x6e, 0x81, 0x03, 0xfb, 0xf7, 0x3d, 0xbc, 0xFE, 0xA2, 0xFE, 0xCB, 0xAE, 0x17, 0x16, 0x2F, 0x7E, 0xF8,
0x7a, 0xa2, 0xab, 0xf2, 0x0e, 0x6c, 0x96, 0x0a, 0x49, 0x80, 0x80, 0x54, 0xD5, 0xEB, 0xD7, 0xCE, 0xD1, 0x98, 0xD1, 0xA1, 0x97, 0xF2,
0x2b, 0x65, 0xd9, 0x16, 0x03, 0x1a, 0x1b, 0x53, 0xc7, 0x53, 0x92, 0x68, 0x97, 0x93, 0xBF, 0x6D, 0x7C, 0xA5, 0xFD, 0xEA, 0xC0, 0xEB,
0xfb, 0x87, 0xd9, 0xea, 0x26, 0xa8, 0x4c, 0xe8, 0xda, 0xad, 0x8c, 0x62, 0x19, 0xAF, 0xDB, 0xC6, 0xC2, 0xC6, 0x1E, 0xBE, 0xC9, 0x78,
0x89, 0x84, 0x88, 0xc8, 0x64, 0x8c, 0x31, 0x3a, 0x61, 0x00, 0xad, 0x32, 0x33, 0x31, 0x5E, 0xF4, 0x56, 0xFB, 0xED, 0xC1, 0x77, 0xDC,
0x2b, 0xcd, 0x78, 0x3b, 0x18, 0x7a, 0xfd, 0x6d, 0xa3, 0x78, 0x88, 0x75, 0x77, 0x1D, 0xEF, 0xA3, 0xDF, 0x0F, 0x4F, 0xE4, 0x7C, 0x20,
0x02, 0x44, 0x48, 0x4c, 0x44, 0xc0, 0xa0, 0x2d, 0x41, 0x96, 0x60, 0xc7, 0x7F, 0x28, 0xFF, 0x68, 0xF9, 0xB1, 0xF5, 0x53, 0xD0, 0xA7,
0x22, 0xb2, 0xad, 0xf5, 0x56, 0x07, 0x00, 0xa2, 0x28, 0x8a, 0xe3, 0xb8, 0xFB, 0x93, 0x19, 0x93, 0x93, 0xFF, 0x04, 0x03, 0x98, 0xF3,
0x5e, 0x5b, 0xf9, 0xd9, 0x14, 0xb9, 0xc0, 0x27, 0x48, 0x6d, 0x5b, 0x90, 0xFC, 0x63, 0x33, 0x2D, 0xDB, 0x00, 0x00, 0x00, 0x20, 0x63,
0x60, 0x12, 0x8c, 0x59, 0x4f, 0x64, 0x7d, 0x99, 0x51, 0xe4, 0xda, 0xe8, 0x48, 0x52, 0x4D, 0x00, 0x00, 0x7A, 0x25, 0x00, 0x00, 0x80,
0xb6, 0xab, 0xbd, 0xa1, 0x03, 0x00, 0xc3, 0xc3, 0xc3, 0x95, 0x4a, 0xa5, 0x83, 0x00, 0x00, 0xF9, 0xFF, 0x00, 0x00, 0x80, 0xE9, 0x00,
0x95, 0x68, 0x8e, 0xd7, 0x5c, 0x53, 0x0f, 0x3d, 0x11, 0xba, 0x88, 0xba, 0x00, 0x75, 0x30, 0x00, 0x00, 0xEA, 0x60, 0x00, 0x00, 0x3A,
0x43, 0x42, 0x70, 0xce, 0x25, 0x8f, 0x75, 0xa8, 0x84, 0xab, 0xa3, 0xb3, 0x98, 0x00, 0x00, 0x17, 0x6F, 0x92, 0x5F, 0xC5, 0x46, 0x00,
0x99, 0x95, 0xe3, 0xc7, 0x8e, 0x00, 0xc0, 0xe2, 0xaf, 0x39, 0x47, 0x72, 0x00, 0x09, 0x20, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0x9C,
0xa1, 0x58, 0xba, 0x71, 0xe6, 0x70, 0x50, 0x9d, 0x2a, 0xe4, 0xbc, 0xbc, 0x97, 0x7F, 0x90, 0x5E, 0x65, 0x75, 0xC7, 0x3F, 0xE7, 0x3C,
0x02, 0x46, 0x23, 0x74, 0xa7, 0x2d, 0x09, 0x9d, 0xd4, 0x20, 0x52, 0x42, 0x3F, 0xEE, 0x8F, 0xF7, 0x7D, 0xF7, 0x67, 0xC8, 0x86, 0xD0,
0xc2, 0x41, 0x1c, 0x1d, 0xfb, 0x38, 0x53, 0xa9, 0x8e, 0xad, 0x79, 0x33, 0x95, 0x60, 0x48, 0x03, 0x6A, 0x90, 0x08, 0xE3, 0x80, 0x44,
0x8f, 0x3f, 0xed, 0x70, 0xc6, 0xd7, 0x3b, 0xc6, 0xef, 0x3e, 0x22, 0x8c, 0x99, 0xA0, 0x16, 0xE5, 0x87, 0x05, 0x6B, 0x07, 0x61, 0xFC,
0xb6, 0x19, 0xd3, 0xb8, 0x85, 0x4f, 0x47, 0xbf, 0xdc, 0x1f, 0xfb, 0x65, 0xC3, 0x01, 0x9D, 0x01, 0x95, 0x4E, 0xF9, 0xA3, 0xA5, 0x33,
0x79, 0x1e, 0x9a, 0x94, 0xa4, 0x5c, 0x5f, 0x5a, 0xae, 0xd7, 0xaa, 0x42, 0xB6, 0x76, 0x3A, 0xC2, 0x50, 0x99, 0x71, 0x44, 0x51, 0x92,
0x79, 0xd9, 0x52, 0x19, 0x00, 0x52, 0x48, 0x85, 0x64, 0x4b, 0x90, 0x8e, 0x51, 0x0B, 0x28, 0x30, 0xAD, 0x75, 0x2A, 0x19, 0x61, 0x6C,
0xe3, 0x76, 0x54, 0xbf, 0x78, 0xa2, 0xf7, 0xef, 0x00, 0x3c, 0x80, 0x08, 0x1D, 0x48, 0x75, 0x87, 0x76, 0xA8, 0xA8, 0x24, 0x1A, 0x24,
0x61, 0x0e, 0x41, 0xd5, 0x83, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4e, 0x1A, 0xC2, 0xC6, 0x00, 0xD9, 0x24, 0xCB, 0x66, 0xB3, 0xBB,
0x44, 0xae, 0x42, 0x60, 0x82, 0xEF, 0xEE, 0xFB, 0xEB, 0xDE, 0xFB, 0x3C, 0xFD, 0xE3, 0x5D,
0x62, 0x77, 0x5A, 0x65, 0xEB, 0x77, 0xE6, 0xCE, 0xDC, 0xE7,
0xDC, 0x7B, 0x9F, 0xF3, 0x3D, 0xCF, 0x73, 0xEE, 0xF7, 0x9C,
0x47, 0x1E, 0x7D, 0xF4, 0x51, 0x76, 0xEE, 0xD8, 0x71, 0xF1,
0xA5, 0xEF, 0xBD, 0xE2, 0xF1, 0x10, 0x24, 0xB1, 0xCE, 0x11,
0x45, 0x00, 0x20, 0xC6, 0xFE, 0xC5, 0xF2, 0xB8, 0x6F, 0x3C,
0x75, 0x27, 0xA2, 0x88, 0x48, 0xFF, 0x71, 0x84, 0x18, 0x03,
0x11, 0xF9, 0xCD, 0xEB, 0x21, 0xAE, 0xF8, 0x46, 0x80, 0xB2,
0x2C, 0x50, 0xA1, 0x3B, 0xF1, 0xE4, 0xF7, 0xAE, 0xBA, 0xF9,
0x96, 0x5B, 0x9E, 0xB6, 0xCE, 0xE8, 0xA5, 0x7B, 0x0E, 0xBE,
0xBA, 0xAB, 0xB1, 0x61, 0x7A, 0xE8, 0xFA, 0x0F, 0xBC, 0x9B,
0xA2, 0x0C, 0x20, 0x86, 0x28, 0x20, 0x21, 0x10, 0x89, 0xC8,
0xF2, 0x8C, 0x71, 0x99, 0x94, 0x8A, 0xE0, 0xD3, 0x94, 0xB9,
0xB9, 0x79, 0x9A, 0x0B, 0xF3, 0x20, 0x4A, 0x92, 0x24, 0x8C,
0x8E, 0x8E, 0x22, 0x22, 0xF4, 0x8A, 0xA2, 0xEF, 0x30, 0x86,
0x95, 0xA4, 0x63, 0xC4, 0x59, 0xE5, 0x1F, 0x77, 0x3D, 0x51,
0xDB, 0x73, 0x60, 0xFA, 0x7B, 0xCE, 0xE8, 0x35, 0x76, 0xFF,
0xE4, 0xD4, 0x63, 0xED, 0x90, 0x34, 0x6E, 0xBD, 0xE9, 0x3A,
0xD2, 0xC4, 0xD3, 0x2B, 0x2A, 0x40, 0x41, 0x5E, 0x63, 0xFD,
0x5A, 0x78, 0x10, 0x55, 0x50, 0xA0, 0x96, 0xD7, 0xF8, 0xF1,
0x33, 0xFF, 0xC5, 0xA1, 0x83, 0xFB, 0xD1, 0x58, 0x22, 0xAA,
0xF4, 0x8A, 0x92, 0xE3, 0x03, 0x43, 0x5C, 0xF2, 0xAE, 0xF7,
0x30, 0x3C, 0x3C, 0xC2, 0xD2, 0xD2, 0x22, 0x88, 0xF4, 0xE3,
0x0E, 0x11, 0x11, 0x88, 0x12, 0xF1, 0x2A, 0xDC, 0xFA, 0xF1,
0xEB, 0xF9, 0xFE, 0xBF, 0x3F, 0x35, 0xB4, 0x7F, 0x72, 0xEA,
0x31, 0xFB, 0xCA, 0xF1, 0x59, 0xBB, 0xE5, 0xBC, 0xB7, 0x30,
0x7D, 0x62, 0x9E, 0xA5, 0x6E, 0x44, 0x8C, 0x25, 0xA2, 0x20,
0x10, 0x43, 0x58, 0x5E, 0x6A, 0x21, 0x56, 0x15, 0x36, 0xF1,
0x64, 0x69, 0xCE, 0x93, 0x8F, 0xFC, 0x03, 0x23, 0x59, 0xC5,
0xC7, 0x6E, 0xBA, 0x91, 0xB3, 0xCE, 0x7A, 0x23, 0x00, 0x0B,
0x0B, 0xF3, 0xEC, 0xDE, 0xBD, 0x9B, 0x1D, 0x5F, 0xFE, 0x02,
0xEF, 0x78, 0xEF, 0x07, 0x19, 0xDF, 0xB0, 0x91, 0xE6, 0xC2,
0x02, 0xC6, 0x18, 0x42, 0x08, 0x40, 0x44, 0x55, 0x08, 0x45,
0x41, 0x3D, 0x81, 0x2D, 0xE7, 0xBD, 0x85, 0x57, 0x8E, 0x9F,
0xB4, 0xD6, 0xF8, 0x7A, 0xE8, 0x52, 0xE7, 0xC8, 0x4C, 0x9B,
0x66, 0x61, 0x50, 0x13, 0x29, 0x81, 0x10, 0x22, 0xCE, 0x19,
0xAC, 0x4F, 0x89, 0x40, 0xD1, 0x29, 0xA9, 0x0F, 0x26, 0x3C,
0xFD, 0xF8, 0xB7, 0xD9, 0xB6, 0x69, 0x88, 0x3F, 0xFB, 0xF3,
0xDB, 0xF8, 0x9F, 0x18, 0x18, 0x18, 0xE4, 0xDA, 0x6B, 0x3F,
0xC8, 0x39, 0x9B, 0x37, 0xF3, 0xE9, 0x3B, 0x3E, 0xCF, 0xE6,
0x6D, 0x7F, 0x42, 0xBD, 0x31, 0x48, 0x51, 0xB6, 0x91, 0xE5,
0x20, 0x8C, 0x2A, 0x45, 0xBB, 0xC5, 0x50, 0x0A, 0xBD, 0xD8,
0xC0, 0x24, 0xF5, 0x60, 0xD5, 0xD5, 0x98, 0xEF, 0x35, 0x78,
0x69, 0xA6, 0xCB, 0x52, 0x70, 0x88, 0x03, 0x49, 0x6A, 0xA8,
0xB5, 0x34, 0x5F, 0x9D, 0x65, 0xEA, 0x3F, 0xBF, 0x81, 0xA9,
0xAF, 0xE1, 0xDC, 0xCB, 0xAE, 0xE7, 0x27, 0x13, 0x4F, 0xB1,
0x31, 0xEB, 0xF0, 0x89, 0x4F, 0x7C, 0x92, 0xDF, 0x86, 0x73,
0xDF, 0xF4, 0x66, 0xFE, 0xF2, 0x53, 0x37, 0x72, 0xDB, 0xE7,
0x1E, 0x64, 0xEB, 0xD5, 0x1F, 0xA7, 0x6A, 0x17, 0xFD, 0x44,
0x05, 0x62, 0xD9, 0xA3, 0xE8, 0x74, 0x68, 0x26, 0x96, 0x66,
0x39, 0x82, 0xBA, 0x1A, 0x56, 0xAD, 0x67, 0xB1, 0xDB, 0xE0,
0xF0, 0x74, 0x97, 0xB6, 0x06, 0x74, 0x20, 0x67, 0xEE, 0xD0,
0x3E, 0xDA, 0xD3, 0x2F, 0x33, 0x77, 0xE4, 0x30, 0x0F, 0xDD,
0xF9, 0x31, 0x9E, 0x7A, 0xFA, 0xC7, 0x3C, 0xF2, 0x83, 0x1F,
0x90, 0x4F, 0xFF, 0x94, 0xFB, 0x1F, 0xF8, 0x1C, 0xD6, 0x7B,
0x7E, 0x17, 0x2E, 0x7A, 0xC7, 0x36, 0xAE, 0x7A, 0xFB, 0x04,
0x8F, 0xEF, 0x7D, 0x96, 0x33, 0xCE, 0x7E, 0x1B, 0x9D, 0xA5,
0x45, 0xAC, 0x31, 0x14, 0xDD, 0x82, 0xD0, 0x81, 0xA6, 0x96,
0xB4, 0xCA, 0x51, 0xAC, 0x49, 0x50, 0x35, 0x86, 0xA5, 0x22,
0x67, 0x6A, 0x36, 0x30, 0x5B, 0x64, 0xBC, 0x74, 0xE4, 0x28,
0xE7, 0x96, 0x87, 0xB8, 0xF3, 0x86, 0x0B, 0xD9, 0x54, 0x5F,
0x60, 0xBE, 0xB9, 0xC4, 0xAD, 0x9F, 0xBC, 0x99, 0x43, 0x4F,
0xDC, 0xCF, 0x15, 0xEF, 0xBC, 0x80, 0xD1, 0xB5, 0xEB, 0x59,
0x0D, 0xDE, 0x79, 0xD1, 0xDB, 0x99, 0x69, 0x2D, 0x31, 0xDD,
0x35, 0xCC, 0xB4, 0x61, 0xBA, 0x15, 0x99, 0x5E, 0x8C, 0x4C,
0x37, 0x23, 0x47, 0x4F, 0x0A, 0xAD, 0x22, 0x45, 0xAD, 0x60,
0xAD, 0x85, 0x6E, 0x35, 0xC8, 0xD1, 0x79, 0x25, 0xC9, 0x32,
0x16, 0x7B, 0x2D, 0xB0, 0x05, 0x97, 0x5F, 0xF9, 0x01, 0x2E,
0xDE, 0xF6, 0x2E, 0x0E, 0xBF, 0xF4, 0x32, 0x59, 0x96, 0x73,
0xD9, 0x85, 0x1B, 0x09, 0xDD, 0x05, 0x56, 0x8B, 0xD9, 0x93,
0x73, 0x1C, 0x79, 0x65, 0x8A, 0xB8, 0x41, 0x31, 0x65, 0x42,
0x59, 0x16, 0x48, 0x95, 0xA2, 0xD1, 0xD3, 0x6C, 0x16, 0x2C,
0xF5, 0x12, 0x44, 0x4A, 0x14, 0x2A, 0x8A, 0x90, 0x33, 0xD7,
0xAB, 0x71, 0xB2, 0x15, 0x89, 0x6B, 0x37, 0xF1, 0xCF, 0x87,
0xC7, 0xD8, 0x71, 0xDF, 0x4E, 0x06, 0x06, 0x87, 0xD8, 0xB2,
0x65, 0x0B, 0x00, 0xF7, 0xDE, 0xFB, 0x25, 0xCE, 0x3F, 0xFF,
0x3C, 0xAA, 0xAA, 0x5A, 0x15, 0x81, 0x8B, 0x2E, 0xB9, 0x84,
0xF7, 0x8F, 0xB5, 0x99, 0x3A, 0x72, 0x8C, 0xD9, 0xE0, 0x98,
0xAF, 0x2C, 0x4D, 0x12, 0xE6, 0x0A, 0xC7, 0xCC, 0x52, 0xA4,
0x53, 0x08, 0x22, 0x01, 0x2B, 0x52, 0x12, 0xC5, 0x82, 0x1D,
0x82, 0x24, 0xA5, 0x52, 0x21, 0x0C, 0xAD, 0x67, 0x61, 0x71,
0x6A, 0xC5, 0x84, 0xE3, 0xE3, 0xE3, 0x8C, 0x8F, 0x8F, 0x13,
0x63, 0x5C, 0x15, 0x81, 0x75, 0xA7, 0xAF, 0xE7, 0xAA, 0x4B,
0xDE, 0xC6, 0xEE, 0x89, 0x79, 0xF2, 0xB3, 0x37, 0x53, 0x2D,
0x75, 0x28, 0x3B, 0x25, 0x65, 0xAB, 0x45, 0x37, 0x96, 0x40,
0x1B, 0xA1, 0x85, 0x8A, 0x46, 0xCC, 0x60, 0x8A, 0xAB, 0x37,
0x88, 0x46, 0x30, 0x3E, 0xA1, 0x1E, 0x8F, 0xF2, 0xEE, 0x4B,
0xB7, 0xFE, 0x9F, 0x13, 0xBF, 0x96, 0xD1, 0xAB, 0xC1, 0x73,
0x07, 0x0F, 0x12, 0xD7, 0xAF, 0xC3, 0xF9, 0x84, 0xA4, 0x5E,
0xC3, 0xE5, 0x19, 0xB6, 0x56, 0x23, 0xA9, 0x0F, 0x83, 0xF7,
0x7D, 0x6D, 0x80, 0x88, 0x6D, 0x24, 0xB8, 0xA1, 0x01, 0x92,
0x7A, 0x4E, 0x96, 0x67, 0xB4, 0xCE, 0xB8, 0x90, 0xAF, 0x3E,
0xF0, 0x5D, 0x28, 0xBB, 0xFC, 0x3E, 0x58, 0x9A, 0x9B, 0xE1,
0xA1, 0x9D, 0x5F, 0xE6, 0x5F, 0x8F, 0x66, 0xAC, 0xD9, 0x7C,
0x0E, 0x46, 0x05, 0x75, 0x16, 0x9F, 0xA7, 0x7D, 0x1F, 0xA7,
0xAD, 0x41, 0x73, 0x0F, 0x02, 0x4A, 0x04, 0x5C, 0x44, 0x6C,
0x85, 0xCF, 0x13, 0x94, 0x8A, 0xC6, 0x99, 0x6F, 0x64, 0x57,
0xF1, 0x87, 0xFC, 0xC5, 0xA7, 0xEF, 0xE0, 0x97, 0x3F, 0xDF,
0xCB, 0xD4, 0xE1, 0xC9, 0xFF, 0x17, 0x81, 0xBB, 0xBF, 0xB8,
0x83, 0x1B, 0x27, 0x0A, 0xAA, 0xF7, 0xDC, 0x4C, 0x6E, 0x1D,
0x6A, 0x04, 0xE7, 0x15, 0xE7, 0x2D, 0x62, 0x05, 0x4C, 0x40,
0xFD, 0x72, 0x5D, 0x01, 0xB0, 0xA9, 0x80, 0x54, 0xA0, 0x81,
0x24, 0x73, 0x0C, 0x58, 0x65, 0xE4, 0xB2, 0x0F, 0xF3, 0x2D,
0x7B, 0x31, 0xEF, 0xBF, 0xFB, 0xBB, 0x5C, 0x76, 0xF3, 0x5D,
0x7C, 0x6D, 0xE7, 0x4E, 0x62, 0xB1, 0x8A, 0x15, 0x89, 0x81,
0x12, 0xC7, 0xA0, 0x7A, 0xAC, 0x17, 0x7C, 0x62, 0x70, 0x5E,
0x11, 0x13, 0xA9, 0x42, 0x97, 0x10, 0x7A, 0x54, 0x55, 0x0B,
0xC9, 0x40, 0x54, 0xFA, 0x2B, 0xA0, 0x99, 0x62, 0x32, 0x03,
0x5A, 0xA1, 0x4E, 0x70, 0x4E, 0x91, 0x66, 0x93, 0xE1, 0x73,
0x2E, 0x60, 0xE4, 0x8F, 0x6F, 0x43, 0xAF, 0xFB, 0x2C, 0xB7,
0x3F, 0xD3, 0xE5, 0xF6, 0xBF, 0xB9, 0x83, 0xAA, 0xF7, 0x3A,
0x24, 0x44, 0xB9, 0xF3, 0x6F, 0xFF, 0x8A, 0xAF, 0x5D, 0x39,
0x48, 0xEF, 0x5F, 0xFE, 0x9E, 0x66, 0xB9, 0x80, 0x49, 0x95,
0x48, 0x45, 0x94, 0x80, 0xDA, 0x88, 0xF1, 0x8A, 0xFA, 0x7E,
0xAD, 0xD1, 0x18, 0x22, 0xB1, 0x2A, 0xF0, 0xB9, 0xC7, 0x18,
0x41, 0x63, 0x85, 0xF3, 0x4A, 0xAD, 0x96, 0x52, 0x76, 0xDA,
0x74, 0x4E, 0xCE, 0xE0, 0xA4, 0x62, 0xFD, 0xFB, 0x3E, 0xC2,
0xFD, 0x33, 0x6B, 0x78, 0xF8, 0xE1, 0x47, 0x56, 0xB5, 0x0D,
0xD7, 0xDE, 0xF0, 0x11, 0xBE, 0x72, 0xC3, 0x45, 0x94, 0x4F,
0xDC, 0x4F, 0x17, 0xC1, 0x5A, 0xC1, 0x3B, 0xC1, 0x18, 0xC1,
0x98, 0x88, 0x9A, 0x7E, 0x9F, 0xA1, 0x04, 0x50, 0x2A, 0x44,
0xC0, 0x1A, 0x88, 0xA1, 0xC4, 0x02, 0xCE, 0x09, 0xA9, 0x33,
0x24, 0x4E, 0xA1, 0xD7, 0xC5, 0x17, 0x1D, 0x06, 0x36, 0x5C,
0xC8, 0x89, 0x66, 0x7B, 0xD5, 0xB9, 0xF0, 0x47, 0x1F, 0xBA,
0x8E, 0xAB, 0xD7, 0x09, 0x9D, 0xE3, 0x87, 0x70, 0xDE, 0x62,
0x8D, 0x62, 0x9D, 0xA0, 0xCE, 0x60, 0xAC, 0x20, 0x44, 0x2C,
0x11, 0x62, 0x59, 0x62, 0x24, 0x90, 0xD5, 0x52, 0x92, 0xDC,
0x82, 0x04, 0x08, 0x90, 0x26, 0x0E, 0x6B, 0x94, 0x4E, 0xA7,
0x87, 0x58, 0x43, 0xBE, 0xF0, 0x0A, 0x1B, 0xCE, 0x1C, 0x5A,
0x35, 0x81, 0xD0, 0x5E, 0xE0, 0xE5, 0xF9, 0x2E, 0xF9, 0xE6,
0x61, 0x52, 0x03, 0xD9, 0x40, 0x8D, 0xD0, 0xAD, 0x20, 0x33,
0xF8, 0x01, 0x07, 0x11, 0x34, 0xC6, 0x88, 0x18, 0x30, 0x89,
0xC3, 0x3A, 0x8F, 0xA1, 0x5F, 0x36, 0xBD, 0x35, 0x28, 0x91,
0x50, 0x95, 0xA4, 0xA9, 0x47, 0x55, 0x81, 0x80, 0xAE, 0x52,
0x06, 0x4E, 0x1C, 0x3B, 0xCA, 0x2D, 0x7F, 0x7D, 0x37, 0xFB,
0x37, 0x6C, 0x63, 0xF4, 0xB4, 0x35, 0x84, 0xAA, 0x42, 0x55,
0x49, 0xB3, 0x0C, 0x11, 0xA1, 0xEC, 0xF4, 0x15, 0x55, 0x79,
0xAD, 0xEF, 0x51, 0x45, 0x55, 0x40, 0x85, 0x10, 0x2A, 0xDA,
0x9D, 0x0E, 0x65, 0x55, 0x50, 0x55, 0x25, 0x45, 0xAF, 0x87,
0x12, 0x88, 0x6B, 0x36, 0x30, 0x39, 0x3B, 0xBF, 0x2A, 0x02,
0x3F, 0xFA, 0xC9, 0x4F, 0xD9, 0xD5, 0x5E, 0xC7, 0xDA, 0xF3,
0xB7, 0x53, 0x34, 0x17, 0x31, 0xC6, 0x40, 0x8C, 0x74, 0xDB,
0x6D, 0x8C, 0x77, 0x18, 0xA7, 0x10, 0xC1, 0x02, 0xA8, 0x11,
0x42, 0x08, 0x14, 0x45, 0x05, 0xAA, 0x58, 0xA3, 0x38, 0xE7,
0x88, 0x21, 0xE0, 0xBC, 0x25, 0x84, 0x08, 0xD1, 0x21, 0xA3,
0x23, 0x1C, 0x7C, 0x71, 0xB6, 0xDF, 0xA8, 0xBE, 0x8E, 0x22,
0xCE, 0x2E, 0x75, 0x19, 0x1D, 0x1D, 0xC3, 0x55, 0x01, 0xBC,
0x27, 0x8A, 0xD2, 0xED, 0x74, 0x89, 0x21, 0xA2, 0xCE, 0xA1,
0xDE, 0x12, 0xE3, 0xB2, 0x10, 0x89, 0x80, 0x11, 0x08, 0x45,
0x8F, 0x58, 0x15, 0xA8, 0x51, 0x8C, 0x0A, 0x84, 0x0A, 0xEF,
0x2D, 0x02, 0xA8, 0x04, 0x12, 0x55, 0x8E, 0xB5, 0xA0, 0xAA,
0x8A, 0xD7, 0xD1, 0x82, 0x8A, 0x3D, 0xFB, 0x7E, 0x41, 0x3A,
0x3C, 0x86, 0xB3, 0x10, 0x42, 0x85, 0x55, 0x21, 0x96, 0x15,
0xD6, 0x0A, 0xC6, 0x82, 0x51, 0xB3, 0xBC, 0x05, 0x22, 0xA8,
0x82, 0x33, 0x81, 0x3C, 0x4B, 0xA8, 0xE7, 0x19, 0x59, 0xEA,
0xF0, 0x56, 0xB0, 0x02, 0x86, 0x48, 0x96, 0x58, 0x9C, 0x01,
0x35, 0x81, 0xB5, 0xB9, 0x62, 0xEC, 0xCA, 0x86, 0x64, 0xEF,
0xDE, 0xBD, 0x34, 0x9B, 0xCD, 0x53, 0xE3, 0x93, 0xD3, 0xC7,
0x99, 0x78, 0xE1, 0x55, 0x46, 0x36, 0xBE, 0x19, 0xAD, 0x7A,
0xE4, 0x89, 0xC5, 0x68, 0x20, 0xF1, 0x86, 0x34, 0x71, 0xA4,
0xDE, 0x22, 0x31, 0x10, 0x01, 0x15, 0x15, 0xAC, 0xB7, 0x78,
0x13, 0x49, 0x13, 0x83, 0xB5, 0x91, 0xCC, 0x28, 0x79, 0xEA,
0x70, 0x3E, 0x12, 0xCB, 0x2E, 0x96, 0x0A, 0xE3, 0x02, 0xA1,
0xDD, 0x61, 0x7C, 0x28, 0xF9, 0x5F, 0x01, 0xDF, 0x73, 0xCF,
0x3D, 0x1C, 0x38, 0x70, 0xE0, 0xD4, 0xF8, 0x97, 0xBF, 0x7A,
0x9E, 0x13, 0xB6, 0x41, 0x7D, 0xA8, 0x86, 0x21, 0xE0, 0x14,
0x24, 0x14, 0x64, 0x5E, 0x69, 0x34, 0x32, 0xBC, 0x06, 0x84,
0xAA, 0xFF, 0x17, 0x84, 0x10, 0x70, 0x12, 0xA9, 0xD7, 0x12,
0xBC, 0x89, 0xE4, 0x4E, 0x70, 0x2E, 0xE2, 0x4C, 0x24, 0xB3,
0x86, 0xCC, 0x19, 0x52, 0x2F, 0x8C, 0x0C, 0x35, 0xE8, 0xED,
0xFB, 0x0F, 0xB6, 0x6C, 0x38, 0x63, 0x85, 0xF3, 0xC5, 0xC5,
0x45, 0xA6, 0xA7, 0xA7, 0x19, 0x1B, 0x1B, 0x3B, 0x65, 0x7B,
0xD3, 0x96, 0xAD, 0x5C, 0xF3, 0x06, 0xE1, 0xD7, 0x0F, 0xDD,
0x81, 0x4A, 0x9B, 0xD4, 0x43, 0xE6, 0x0D, 0x59, 0x6A, 0x30,
0x94, 0xB8, 0xD8, 0x45, 0xCB, 0x62, 0x39, 0x07, 0x44, 0x30,
0x22, 0xE4, 0x4E, 0x48, 0xAD, 0xA0, 0xA1, 0xC0, 0x11, 0xC8,
0x9D, 0x52, 0x4B, 0x2D, 0xB9, 0x37, 0x9C, 0x36, 0xD2, 0x60,
0xE6, 0x99, 0xDD, 0x9C, 0xB3, 0xF4, 0x0B, 0xB6, 0x5F, 0x7E,
0xF9, 0x0A, 0x02, 0x93, 0x93, 0x93, 0xD4, 0x6A, 0x35, 0x46,
0x46, 0x46, 0x4E, 0xD9, 0x06, 0x87, 0x47, 0xF9, 0xC2, 0x9D,
0x7F, 0xC7, 0x7D, 0xD7, 0x5F, 0xCC, 0xFC, 0x13, 0x0F, 0x33,
0x76, 0xDA, 0x30, 0x43, 0xF5, 0xAC, 0x1F, 0x8C, 0x8D, 0x64,
0x36, 0x60, 0x35, 0xF6, 0xAB, 0x61, 0x8C, 0x11, 0x9F, 0x38,
0x52, 0x2F, 0x68, 0xD9, 0x25, 0xB1, 0x7D, 0x05, 0x34, 0xB1,
0xAF, 0x52, 0x89, 0x33, 0xF4, 0x4E, 0xCC, 0x30, 0xFA, 0xE2,
0x04, 0xDF, 0xF8, 0xD2, 0x5D, 0x34, 0x06, 0x87, 0x57, 0x10,
0xE8, 0xF6, 0x7A, 0x1C, 0x3F, 0x76, 0x94, 0x3C, 0x4B, 0x57,
0xEE, 0x8B, 0x5A, 0xC6, 0xCF, 0xDA, 0x8C, 0x54, 0x3D, 0x5C,
0x04, 0x2F, 0xB1, 0x2F, 0x46, 0xCE, 0x30, 0x50, 0xCF, 0xF0,
0x56, 0x99, 0x6B, 0x15, 0xD8, 0xAA, 0x0A, 0x0A, 0x50, 0x4F,
0x2D, 0xA5, 0x4D, 0x70, 0x56, 0x29, 0x5B, 0x2D, 0xD4, 0x28,
0x99, 0x75, 0x78, 0xEF, 0x28, 0xDA, 0x15, 0x59, 0x9A, 0x90,
0xE5, 0xB5, 0x15, 0x67, 0xC4, 0x76, 0x73, 0x9E, 0xE7, 0xF7,
0xEC, 0x61, 0x52, 0xD6, 0xF0, 0xF5, 0x47, 0xBE, 0x8D, 0x35,
0xCA, 0x70, 0xE6, 0xA8, 0x25, 0x96, 0x5E, 0x10, 0xBE, 0xF9,
0xD8, 0x93, 0xAC, 0xDD, 0x7E, 0x13, 0xF4, 0x3A, 0xD8, 0x18,
0x31, 0x46, 0x91, 0xE5, 0x46, 0x34, 0x02, 0xB9, 0x15, 0xB5,
0xEB, 0x06, 0x6C, 0x79, 0xF4, 0xE0, 0x34, 0xCE, 0xA4, 0x64,
0x26, 0xA2, 0xD6, 0x50, 0xC6, 0x88, 0xB1, 0x16, 0x63, 0x2D,
0xAA, 0x86, 0xC6, 0xFA, 0x37, 0xF0, 0xDC, 0xC0, 0x46, 0xEE,
0xFA, 0xCC, 0x67, 0x38, 0x6F, 0xEB, 0x05, 0xBC, 0x30, 0x75,
0x84, 0x67, 0xF7, 0xFF, 0x9A, 0xCA, 0x0D, 0xD0, 0x49, 0x47,
0xB9, 0xF2, 0xF6, 0x7B, 0xF9, 0xB7, 0x03, 0xCF, 0x01, 0x60,
0xAA, 0x0E, 0x21, 0x2C, 0x81, 0x1A, 0x06, 0xB7, 0x7F, 0x94,
0xB5, 0x67, 0x6F, 0xA6, 0xDB, 0xEE, 0x91, 0x79, 0x47, 0x08,
0xE0, 0x10, 0xAA, 0x90, 0x70, 0x6C, 0xEA, 0x38, 0xEB, 0xCF,
0xF4, 0xA5, 0xDD, 0xF4, 0x07, 0xC3, 0x57, 0xD7, 0xFF, 0xE9,
0xC9, 0x5D, 0x13, 0xDF, 0x77, 0x43, 0x5B, 0xCF, 0x5E, 0x8F,
0x7A, 0x07, 0xA1, 0x22, 0x86, 0x88, 0x18, 0x03, 0x46, 0x51,
0x51, 0x06, 0xCF, 0x78, 0x2B, 0xDF, 0xF9, 0x59, 0xE4, 0xC1,
0x6F, 0xBD, 0x40, 0x6D, 0x74, 0x98, 0x35, 0x63, 0xDB, 0x71,
0x59, 0x4E, 0x6D, 0x68, 0x84, 0xF6, 0xB1, 0x39, 0xF2, 0xC1,
0x71, 0xD4, 0x1A, 0xC4, 0x9A, 0xBE, 0xEC, 0x1A, 0x21, 0x04,
0x78, 0x79, 0xDF, 0xF3, 0x08, 0x91, 0x10, 0x2A, 0x62, 0x59,
0x11, 0x8B, 0x92, 0x3D, 0x93, 0x53, 0x34, 0x26, 0x7F, 0x38,
0xB7, 0xE9, 0x4F, 0xAF, 0xB8, 0xC6, 0x06, 0x31, 0x13, 0xEB,
0x8A, 0x5F, 0x5D, 0x71, 0xEC, 0xB9, 0xD3, 0x1F, 0xFF, 0xCE,
0xB3, 0x3F, 0x4F, 0x92, 0x91, 0x7A, 0x9F, 0x40, 0xAB, 0x0B,
0xA2, 0xFD, 0xC3, 0xA5, 0x11, 0x88, 0x60, 0x4C, 0x0A, 0x92,
0x73, 0xFC, 0x70, 0x93, 0x17, 0x0F, 0xEE, 0xEB, 0x1F, 0xC5,
0xAD, 0x05, 0x15, 0x62, 0xAF, 0x40, 0x8D, 0x40, 0x9E, 0x40,
0xD9, 0x43, 0x7A, 0x65, 0xBF, 0xBC, 0x9E, 0x2A, 0x1E, 0x91,
0x58, 0x55, 0x74, 0x5B, 0x1D, 0x86, 0x0D, 0xDD, 0xD3, 0xAB,
0x17, 0xAF, 0x0A, 0x62, 0x9F, 0xFE, 0xEF, 0x01, 0x00, 0x46,
0xBB, 0xB1, 0xB5, 0x3F, 0x50, 0x9D, 0x5B, 0x00, 0x00, 0x00,
0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82
}; };