From bbc2096e95d8d45c64c8701589982d02a7bbb56d Mon Sep 17 00:00:00 2001 From: oblivion Date: Sun, 12 Aug 2018 19:36:30 +0000 Subject: [PATCH] SSH: SshChannel and SshExec classes are refactored, and re-added to the package. Cosmetics & various cleanup. git-svn-id: svn://ultimatepp.org/upp/trunk@12164 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/Core/SSH/Channels.cpp | 331 +++++++++++++++++- uppsrc/Core/SSH/Channels.h | 203 ++++------- uppsrc/Core/SSH/Core.h | 2 +- uppsrc/Core/SSH/Exec.cpp | 64 +--- uppsrc/Core/SSH/SFtp.cpp | 4 +- uppsrc/Core/SSH/SFtp.h | 2 +- uppsrc/Core/SSH/Scp.cpp | 181 ++-------- uppsrc/Core/SSH/Session.cpp | 22 +- uppsrc/Core/SSH/Session.h | 4 +- .../SSH/src.tpp/Upp_Ssh_Channels_en-us.tpp | 36 +- .../SSH/src.tpp/Upp_Ssh_Channels_en-us.tppi | 37 +- .../Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tpp | 2 +- .../Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tppi | 14 +- 13 files changed, 473 insertions(+), 429 deletions(-) diff --git a/uppsrc/Core/SSH/Channels.cpp b/uppsrc/Core/SSH/Channels.cpp index 782174d74..df4816716 100644 --- a/uppsrc/Core/SSH/Channels.cpp +++ b/uppsrc/Core/SSH/Channels.cpp @@ -1,11 +1,320 @@ #include "SSH.h" namespace Upp { -/* + #define LLOG(x) do { if(SSH::sTrace) RLOG(SSH::GetName(ssh->otype, ssh->oid) << x); } while(false) #define VLOG(x) if(SSH::sTraceVerbose) LLOG(x); #define LDUMPHEX(x) do { if(SSH::sTraceVerbose) RDUMPHEX(x); } while(false) +bool SshChannel::Init() +{ + ASSERT(!IsOpen()); + + LIBSSH2_CHANNEL *ch = libssh2_channel_open_session(ssh->session); + if(!ch && !WouldBlock()) + SetError(-1); + if(ch) { + channel = MakeOne(ch); + LLOG("A new channel is opened."); + } + return ch; +} + +void SshChannel::Exit() +{ + if(!channel) + return; + + Run([=]() mutable { + int rc = libssh2_channel_free(*channel); + if(!WouldBlock(rc) && rc < 0) + SetError(rc); + if(!rc) { + ssh->init = false; + channel.Clear(); + LLOG("Channel succesfully freed."); + } + return !rc; + }); +} + +bool SshChannel::Open() +{ + if(IsOpen()) + Close(); + return Run([=]() mutable { return true; }); +} + +bool SshChannel::Close() +{ + return Run([=]() mutable { + int rc = libssh2_channel_close(*channel); + if(!WouldBlock(rc) && rc < 0) SetError(rc); + if(!rc) LLOG("Channel close message is sent to the server."); + return !rc; + }); +} + +bool SshChannel::WaitClose() +{ + return Run([=]() mutable { + int rc = libssh2_channel_wait_closed(*channel); + if(!WouldBlock(rc) && rc < 0) SetError(rc); + if(!rc) LLOG("Channel close message is acknowledged by the server."); + return !rc; + }); +} + +bool SshChannel::Request(const String& request, const String& params) +{ + return Run([=]() mutable { + int rc = libssh2_channel_process_startup( + *channel, + request, + request.GetLength(), + params.GetLength() ? ~params : nullptr, + params.GetLength() + ); + if(!WouldBlock(rc) && rc < 0) + SetError(rc); + if(!rc) + LLOG("\"" << request << "\" request (params: " << params << ") is successful."); + return !rc; + }); +} + +bool SshChannel::RequestTerminal(const String& term, int width, int height) +{ + return Run([=]() mutable { + int rc = libssh2_channel_request_pty_ex( + *channel, + ~term, + term.GetLength(), + nullptr, + 0, + width, + height, + LIBSSH2_TERM_WIDTH_PX, + LIBSSH2_TERM_HEIGHT_PX + ); + if(!WouldBlock(rc) && rc < 0) + SetError(rc); + if(!rc) + LLOG("Terminal (" << term << ") [W:" << width << ", H:" << height << "] opened."); + return !rc; + }); +} + +bool SshChannel::SetEnv(const String& variable, const String& value) +{ + return Run([=]() mutable { + int rc = libssh2_channel_setenv(*channel, variable, value); + if(!WouldBlock(rc) && rc < 0) SetError(rc); + if(!rc) LLOG("Environment variable '" << variable << "' set to " << value); + return !rc; + }); +} + +bool SshChannel::PutEof() +{ + return Run([=]() mutable { + int rc = libssh2_channel_send_eof(*channel); + if(!WouldBlock(rc) && rc < 0) SetError(rc); + if(!rc) LLOG("EOF message is sent to the server."); + return !rc; + }); +} + +bool SshChannel::GetEof() +{ + return Run([=]() mutable { + int rc = libssh2_channel_wait_eof(*channel); + if(!WouldBlock(rc) && rc < 0) SetError(rc); + if(!rc) LLOG("EOF message is acknowledged by the server."); + return !rc; + }); +} + +bool SshChannel::IsEof() +{ + bool b = false; + INTERLOCKED + { + b = libssh2_channel_eof(*channel) != 0; + } + if(b) + LLOG("EOF received."); + return b; +} + +bool SshChannel::SetTerminalSize(int width, int height) +{ + return Run([=]() mutable { return SetPtySz(width, height) >= 0; }); +} + +int SshChannel::SetPtySz(int w, int h) +{ + int rc = libssh2_channel_request_pty_size(*channel, w, h); + if(!WouldBlock(rc) && rc < 0) rc = 1; + if(rc == 1) LLOG("Warning: Couldn't set terminal size!"); + if(rc == 0) LLOG("Terminal size adjusted. [W:" << w << ", H:" << h << "]"); + return rc; +} + +bool SshChannel::SetReadWindowSize(uint32 size, bool force) +{ + return Run([=]() mutable { return SetWndSz(size, force); }); +} + +bool SshChannel::SetWndSz(uint32 size, bool force) +{ + int rc = libssh2_channel_receive_window_adjust2(*channel, size, (unsigned char) force, nullptr); + if(!WouldBlock(rc) && rc < 0) SetError(rc); + if(!rc) LLOG(Format("Receive window size set is to %d.", AsString(size))); + return !rc; +} + +int SshChannel::GetExitCode() +{ + int rc = 0; + INTERLOCKED + { + rc = libssh2_channel_get_exit_status(*channel); + } + LLOG("Exit code: " << rc); + return rc; +} + +String SshChannel::GetExitSignal() +{ + char **sig = nullptr; + size_t len = 0; + String s; + INTERLOCKED + { + libssh2_channel_get_exit_signal(*channel, sig, &len, nullptr, nullptr, nullptr, nullptr); + s.Set(*sig, len); + } + LLOG("Exit signal: " << s); + return s; +} + +int SshChannel::Get(void *ptr, int size, int sid) +{ + done = 0; + Run([=]() mutable { return Read(ptr, size, sid); }); + return GetDone(); +} + +String SshChannel::Get(int size, int sid) +{ + StringBuffer sb(size); + int len = Get(~sb, size, sid); + sb.SetCount(len); + return sb; +} + +String SshChannel::GetLine(int maxlen, int sid) +{ + done = 0; + String line; + Run([=, &line]{ + bool eol = false; + do { + int c = Read(sid); + if(c == -1) + break; + ssh->start_time = msecs(); + if(c == '\r') + continue; + if(line.GetLength() >= maxlen) + line = Null; + eol = c == '\n'; + if(!eol) + line.Cat(c); + } + while(!eol && !IsEof() && !IsTimeout() && InProgress()); + return eol || IsEof(); + }); + return line; +} + +int SshChannel::Put(const void *ptr, int size, int sid) +{ + done = 0; + Run([=]() mutable { return Write(ptr, size, sid); }); + return GetDone(); +} + +bool SshChannel::Read(void *ptr, int size, int sid) +{ + int sz = min(size - done, ssh->chunk_size); + Buffer buffer(sz); + + int rc = libssh2_channel_read_ex(*channel, sid, buffer, sz); + if(rc < 0 && !WouldBlock(rc)) + SetError(rc); + if(rc > 0) { + memcpy((char*) ptr + done, (const char*) buffer, rc); + done += rc; + ssh->start_time = msecs(); + VLOG("Read stream #" << sid << ": " << rc << " bytes read."); + } + return IsEof() || done == size || !rc; +} + +int SshChannel::Read(int sid) +{ + char c; + int rc = libssh2_channel_read_ex(*channel, sid, &c, 1); + if(!WouldBlock(rc) && rc < 0) SetError(rc); + return rc == 1 ? int(c) : -1; +} + +bool SshChannel::Write(const void *ptr, int size, int sid) +{ + int sz = min(size - done, ssh->chunk_size); + + int rc = libssh2_channel_write_ex(*channel, sid, (const char*) ptr + done, sz); + if(!WouldBlock(rc) && rc < 0) + SetError(rc); + if(rc > 0) { + done += rc; + ssh->start_time = msecs(); + VLOG("Write stream #" << sid << ": " << rc << " bytes written."); + } + return IsEof() || done == size;; +} + +dword SshChannel::EventWait(int fd, dword events, int tv) +{ + SocketWaitEvent we; + we.Add(fd, events); + return we.Wait(tv) > 0 ? we[0] : 0; +} + +bool SshChannel::ProcessEvents(String& input) +{ + // TODO + return IsEof(); +} + +SshChannel::SshChannel(SshSession& session) +{ + ssh->otype = CHANNEL; + ssh->session = session.GetHandle(); + ssh->socket = &session.GetSocket(); + ssh->timeout = session.GetTimeout(); + ssh->waitstep = session.GetWaitStep(); + ssh->whenwait = Proxy(session.WhenWait); +} + +SshChannel::~SshChannel() +{ + Exit(); +} + +/* int SshChannel::AdjustChunkSize(int64 sz) { return (int) clamp(sz, (int64) 1, int64(ssh->chunk_size)); @@ -43,7 +352,7 @@ bool SshChannel::Init() SetError(-1); if(*channel) LLOG("A new channel is opened."); - return *channel != NULL; + return *channel != nullptr; } void SshChannel::Exit() @@ -56,17 +365,17 @@ void SshChannel::Exit() if(!WouldBlock(rc) && rc < 0) SetError(rc); if(rc == 0) - listener = NULL; + listener = nullptr; return rc == 0; }); Cmd(CHANNEL_EXIT, [=]() mutable { - if(!channel || *channel == NULL) + if(!channel || *channel == nullptr) return true; auto rc = libssh2_channel_free(*channel); if(!WouldBlock(rc) && rc < 0) SetError(rc); if(rc == 0) { - *channel = NULL; + *channel = nullptr; LLOG("Channel succesfully freed."); } return rc == 0; @@ -114,7 +423,7 @@ bool SshChannel::Request(const String& request, const String& params) *channel, request, request.GetLength(), - params.GetLength() ? ~params : NULL, + params.GetLength() ? ~params : nullptr, params.GetLength() ); if(!WouldBlock(rc) && rc < 0) @@ -133,7 +442,7 @@ bool SshChannel::Terminal(const String& term, int width, int height) *channel, ~term, term.GetLength(), - NULL, + nullptr, 0, width, height, @@ -403,7 +712,7 @@ bool SshChannel::RecvEof0() bool SshChannel::SetWndSz(int64 size, bool force) { - auto rc = libssh2_channel_receive_window_adjust2(*channel, size, (char)force, NULL); + auto rc = libssh2_channel_receive_window_adjust2(*channel, size, (char)force, nullptr); if(!WouldBlock(rc) && rc < 0) SetError(rc); if(rc == 0) @@ -485,7 +794,7 @@ String SshChannel::GetExitSignal() { if(*channel && *channel) { Buffer sig(64, 0); - auto rc = libssh2_channel_get_exit_signal(*channel, sig, NULL, NULL, NULL, NULL, NULL); + auto rc = libssh2_channel_get_exit_signal(*channel, sig, nullptr, nullptr, nullptr, nullptr, nullptr); exitsignal = *sig; LLOG("Exit signal: " << exitsignal); } @@ -551,8 +860,8 @@ SshChannel::SshChannel(SshSession& session) ssh->wait = Proxy(session.WhenWait); channel.Create(); - *channel = NULL; - listener = NULL; + *channel = nullptr; + listener = nullptr; lock = session.GetLockPtr(); Clear(); } diff --git a/uppsrc/Core/SSH/Channels.h b/uppsrc/Core/SSH/Channels.h index d09cb2f51..d0e57bfa3 100644 --- a/uppsrc/Core/SSH/Channels.h +++ b/uppsrc/Core/SSH/Channels.h @@ -1,180 +1,95 @@ -/* class SshChannel : public Ssh { public: - SshChannel& Timeout(int ms) { ssh->timeout = ms; return *this; } - SshChannel& NonBlocking(bool b = true) { return Timeout(b ? 0 : Null); } - SshChannel& WaitStep(int ms) { ssh->waitstep = clamp(ms, 0, INT_MAX); return *this; } - SshChannel& ChunkSize(int sz) { ssh->chunk_size = clamp(sz, 128, INT_MAX); return *this; } - - - LIBSSH2_CHANNEL* GetHandle() const { return *channel; } - Value GetResult() { return pick(result); } + SshChannel& Timeout(int ms) { ssh->timeout = ms; return *this; } + SshChannel& WaitStep(int ms) { ssh->waitstep = clamp(ms, 0, INT_MAX); return *this; } + SshChannel& ChunkSize(int sz) { ssh->chunk_size = clamp(sz, 1, INT_MAX); return *this; } + LIBSSH2_CHANNEL* GetHandle() const { return channel ? *channel : nullptr; } + int GetDone() const { return done; } + + bool IsOpen() const { return channel; } + bool Open(); bool Close(); - bool CloseWait(); + bool WaitClose(); + bool Request(const String& request, const String& params = Null); - bool Exec(const String& cmdline) { return Request("exec", cmdline); } - bool Shell() { return Request("shell", Null); } - bool Subsystem(const String& subsystem) { return Request("subsystem", subsystem); } + bool RequestExec(const String& cmdline) { return Request("exec", cmdline); } + bool RequestShell() { return Request("shell", Null); } + bool RequestSubsystem(const String& subsystem) { return Request("subsystem", subsystem); } + bool RequestTerminal(const String& term, int width, int height); + bool RequestTerminal(const String& term, Size sz) { return RequestTerminal(term, sz.cx, sz.cy); } bool SetEnv(const String& variable, const String& value); - bool Terminal(const String& term, int width, int height); - bool Terminal(const String& term, Size sz) { return Terminal(term, sz.cx, sz.cy); } - - String Get(int64 size, int sid = 0); - int64 Get(Stream& out, int64 size, int sid = 0); + + int Get(void *ptr, int size, int sid = 0); + String Get(int size, int sid = 0); String GetLine(int maxlen = 65536, int sid = 0); - int GetNow(int sid = 0); - int GetNow(void* buffer, int sid = 0); - String GetStdErr(int64 size = 65536) { return Get(size, SSH_EXTENDED_DATA_STDERR); } - int64 GetStdErr(Stream& out, int64 size = 65536) { return Get(out, size, SSH_EXTENDED_DATA_STDERR); } - int64 Put(const String& s, int sid = 0); - int64 Put(Stream& in, int64 size = 65536, int sid = 0); - bool PutNow(char c, int sid = 0); - int PutNow(const void* buffer, int64 size, int sid = 0); - int64 PutStdErr(const String& err) { return Put(err, SSH_EXTENDED_DATA_STDERR); } - int64 PutStdErr(Stream& err) { return Put(err, err.GetSize(), SSH_EXTENDED_DATA_STDERR); } + String GetStdErr(int size) { return Get(size, SSH_EXTENDED_DATA_STDERR); } + int Put(const void *ptr, int size, int sid = 0); + int Put(const String& s, int sid = 0) { return Put(~s, s.GetLength(), sid); } + int PutStdErr(const String& err) { return Put(err, SSH_EXTENDED_DATA_STDERR); } - bool SendEof(); - bool RecvEof(); - bool SendRecvEof(); + bool PutEof(); + bool GetEof(); + bool PutGetEof() { return PutEof() && GetEof(); } bool IsEof(); bool SetTerminalSize(int width, int height); - bool SetTerminalSize(Size sz) { return SetTerminalSize(sz.cx, sz.cy); } - bool SetReadWindowSize(int64 size, bool force = false); - int64 GetReadWindowSize(); - int64 GetWriteWindowSize(); + bool SetTerminalSize(Size sz) { return SetTerminalSize(sz.cx, sz.cy); } + bool SetReadWindowSize(uint32 size, bool force = false); + uint32 GetReadWindowSize() { return libssh2_channel_window_read(*channel); } + uint32 GetWriteWindowSize() { return libssh2_channel_window_write(*channel); } int GetExitCode(); String GetExitSignal(); - - bool IsNullInstance() const { return !channel || !ssh; } - inline operator bool() const { return IsNullInstance();} - - Event WhenContent; - Gate WhenProgress; - - SshChannel() : Ssh(false) {} + SshChannel(SshSession& session); virtual ~SshChannel(); - + SshChannel(SshChannel&&) = default; SshChannel& operator=(SshChannel&&) = default; - + protected: bool Init() override; void Exit() override; - bool Cleanup(Error& e) override; - - int AdjustChunkSize(int64 sz); - void Clear(); - - int Read(void *buffer, int64 len, int sid = 0); + bool Read(void *ptr, int size, int sid = 0); int Read(int sid = 0); - bool ReadString(String& s, int64 len, int sid = 0, bool nb = false); - bool ReadStream(Stream& s, int64 len, int sid = 0, bool nb = false); - bool ReadContent(Event&& consumer, int64 len, int sid = 0, bool nb = false); - - int Write(const void* buffer, int64 len, int sid = 0); - bool Write(char c, int sid = 0); - bool WriteString(const String& s, int64 len, int sid = 0, bool nb = false); - bool WriteStream(Stream& s, int64 len, int sid = 0, bool nb = false); - - bool SendEof0(); - bool RecvEof0(); - - bool SetWndSz(int64 size, bool force = false); - + bool Write(const void *ptr, int size, int sid = 0); + bool SetWndSz(uint32 size, bool force = false); int SetPtySz(int w, int h); - int SetPtySz(Size sz) { return SetPtySz(sz.cx, sz.cy); } + int SetPtySz(Size sz) { return SetPtySz(sz.cx, sz.cy); } + dword EventWait(int fd, dword events, int tv = 10); bool ProcessEvents(String& input); - virtual void ReadWrite(String& in, const void* out, int out_len); - - bool Lock(); - void Unlock(); - - One channel; - LIBSSH2_LISTENER* listener; - libssh2_struct_stat filestat; - Value result; - int exitcode; - String exitsignal; - int64 done; - int64 total; - std::atomic* lock; - - enum OpCodes { - CHANNEL_INIT, - CHANNEL_EXIT, - CHANNEL_OPEN, - CHANNEL_CLOSE, - CHANNEL_REQUEST, - CHANNEL_SET_ENV, - CHANNEL_READ, - CHANNEL_WRITE, - CHANNEL_WAIT, - CHANNEL_EOF, - CHANNEL_STDERR, - CHANNEL_RC, - CHANNEL_SIGNAL, - CHANNEL_WIN_SIZE, - CHANNEL_PTY_SIZE, - CHANNEL_SCP, - CHANNEL_SCP_GET, - CHANNEL_SCP_PUT, - CHANNEL_EXEC, - CHANNEL_SHELL, - CHANNEL_TUNNEL, - CHANNEL_TUNNEL_CONNECT, - CHANNEL_TUNNEL_LISTEN, - CHANNEL_TUNNEL_ACCEPT - }; -}; - -// Channels. -class Scp : public SshChannel { -public: - bool Get(const String& path, Stream& out); - bool operator()(const String& path, Stream& out) { return Get(path, out); } - String Get(const String& path); - String operator()(const String& path) { return Get(path); } - bool Put(Stream& in, const String& path, long mode = 0744); - bool Put(const String& in, const String& path, long mode = 0744); - bool operator()(Stream& in, const String& path, long mode = 0744) { return Put(in, path, mode); } - bool operator()(const String& in, const String& path, long mode = 0744) { return Put(in, path, mode); } - - static AsyncWork AsyncGet(SshSession& session, const String& path, Gate progress = Null); - static AsyncWork AsyncGet(SshSession& session, const String& path, Stream& out, Gate progress = Null); - static AsyncWork AsyncPut(SshSession& session, String& in, const String& path, long mode = 0744, Gate progress = Null); - static AsyncWork AsyncPut(SshSession& session, Stream& in, const String& path, long mode = 0744, Gate progress = Null); - static AsyncWork AsyncGetToFile(SshSession& session, const String& src, const String& dest, Gate progress = Null); - static AsyncWork AsyncPutToFile(SshSession& session, const String& src, const String& dest, long mode = 0744, Gate progress = Null); - static AsyncWork AsyncConsumerGet(SshSession& session, const String& path, Event consumer); - - Scp(SshSession& session) : SshChannel(session) { ssh->otype = SCP; } - -private: - bool Init() override { return Lock(); } - bool Open(int opcode, const String& path, int64 size, long mode); - static void StartAsync(int cmd, SshSession& session, const String& path, Stream& io, long mode, - Gate progress, Event consumer = Null); + virtual void ReadWrite(String& in, const void* out, int out_len) {} + + + One channel; + int done; }; class SshExec : public SshChannel { public: - int Execute(const String& cmd, Stream& out, Stream& err); - int operator()(const String& cmd, Stream& out, Stream& err) { return Execute(cmd, out, err); } + int Execute(const String& cmd, String& out, String& err); + int operator()(const String& cmd, String& out, String& err) { return Execute(cmd, out, err); } - static AsyncWork> AsyncRun(SshSession& session, const String& cmd); - - SshExec(SshSession& session) : SshChannel(session) { ssh->otype = EXEC; }; - -private: - bool Init() override { return Lock(); } + SshExec(SshSession& session) : SshChannel(session) { ssh->otype = EXEC; }; }; +class Scp : public SshChannel { +public: + bool SaveFile(const char *path, const String& data); + String LoadFile(const char *path); + bool SaveFile(const char *path, Stream& in); + bool LoadFile(Stream& out, const char *path); + + Scp(SshSession& session) : SshChannel(session) { ssh->otype = SCP; ssh->init = true; } +private: + bool Open(int cmd, const String& path, libssh2_struct_stat* fs, + int64 size, dword flags, long mode); + +}; +/* class SshTunnel : public SshChannel { public: bool Connect(const String& host, int port); diff --git a/uppsrc/Core/SSH/Core.h b/uppsrc/Core/SSH/Core.h index eaab38162..68637cdba 100644 --- a/uppsrc/Core/SSH/Core.h +++ b/uppsrc/Core/SSH/Core.h @@ -49,7 +49,7 @@ protected: }; One ssh; - constexpr static int CHUNKSIZE = 1024 * 64; + const int CHUNKSIZE = 1024 * 64; enum Status { IDLE, WORKING, FAILED, ABORTED }; diff --git a/uppsrc/Core/SSH/Exec.cpp b/uppsrc/Core/SSH/Exec.cpp index a59b24d80..ba6fbebf8 100644 --- a/uppsrc/Core/SSH/Exec.cpp +++ b/uppsrc/Core/SSH/Exec.cpp @@ -1,57 +1,19 @@ #include "SSH.h" namespace Upp { -/* -#define LLOG(x) do { if(SSH::sTrace) RLOG(SSH::GetName(ssh->otype, ssh->oid) << x); } while(false) -#define LDUMPHEX(x) do { if(SSH::sTraceVerbose) RDUMPHEX(x); } while(false) -int SshExec::Execute(const String& cmd, Stream& out, Stream& err) +int SshExec::Execute(const String& cmd, String& out, String& err) { - ComplexCmd(CHANNEL_EXEC, [=, &out, &err]() mutable { - SshChannel::Open(); - SshChannel::Exec(cmd); - Cmd(CHANNEL_SHELL, [=] { Unlock(); return true; }); - SshChannel::Get(out, ssh->chunk_size); - SshChannel::GetStdErr(err); - SshChannel::SendRecvEof(); - SshChannel::Close(); - SshChannel::CloseWait(); - Cmd(CHANNEL_RC, [=]() mutable { SshChannel::GetExitCode(); return true; }); - Cmd(CHANNEL_SIGNAL, [=]() mutable { SshChannel::GetExitSignal(); return true; }); - - }); - return exitcode; + if(RequestExec(cmd)) { + int size = max(ssh->chunk_size, 1024); + out = Get(size); + err = GetStdErr(size); + if(!IsError() && + PutGetEof() && + Close() && + WaitClose()) + return GetExitCode(); + } + return GetError(); +} } - -AsyncWork> SshExec::AsyncRun(SshSession& session, const String& cmd) -{ - auto work = Upp::Async([=, cmd = String(cmd), &session]{ - SshExec worker(session); - worker.NonBlocking(); - - bool cancelled = false; - int waitstep = worker.GetWaitStep(); - - StringStream out, err; - - worker.Execute(cmd, out, err); - - while(worker.Do()) { - if(!cancelled && CoWork::IsCanceled()) { - worker.Cancel(); - cancelled = true; - } - Sleep(waitstep); - } - if(worker.IsError()) - throw Ssh::Error(worker.GetError(), worker.GetErrorDesc()); - - return MakeTuple( - worker.GetExitCode(), - pick(out.GetResult()), - pick(err.GetResult()) - ); - }); - return pick(work); -}*/ -} \ No newline at end of file diff --git a/uppsrc/Core/SSH/SFtp.cpp b/uppsrc/Core/SSH/SFtp.cpp index 98e3e8c84..7d4cd2ed5 100644 --- a/uppsrc/Core/SSH/SFtp.cpp +++ b/uppsrc/Core/SSH/SFtp.cpp @@ -196,10 +196,10 @@ bool SFtp::SaveFile(const char *path, Stream& in) return CopyStream(out, in) >= 0; } -void SFtp::LoadFile(Stream& out, const char *path) +bool SFtp::LoadFile(Stream& out, const char *path) { SFtpFileIn in(*this, path); - CopyStream(in, out) >= 0; + return CopyStream(in, out) >= 0; } SFtpHandle SFtp::OpenDir(const String& path) diff --git a/uppsrc/Core/SSH/SFtp.h b/uppsrc/Core/SSH/SFtp.h index 20a3b44b9..5c0b05fd7 100644 --- a/uppsrc/Core/SSH/SFtp.h +++ b/uppsrc/Core/SSH/SFtp.h @@ -97,7 +97,7 @@ public: bool SaveFile(const char *path, const String& data); String LoadFile(const char *path); bool SaveFile(const char *path, Stream& in); - void LoadFile(Stream& out, const char *path); + bool LoadFile(Stream& out, const char *path); int GetDone() const { return done; } diff --git a/uppsrc/Core/SSH/Scp.cpp b/uppsrc/Core/SSH/Scp.cpp index ae13a276c..a885060bb 100644 --- a/uppsrc/Core/SSH/Scp.cpp +++ b/uppsrc/Core/SSH/Scp.cpp @@ -1,184 +1,59 @@ #include "SSH.h" namespace Upp { -/* + #define LLOG(x) do { if(SSH::sTrace) RLOG(SSH::GetName(ssh->otype, ssh->oid) << x); } while(false) #define LDUMPHEX(x) do { if(SSH::sTraceVerbose) RDUMPHEX(x); } while(false) -bool Scp::Open(int opcode, const String& path, int64 size, long mode) +bool Scp::Open(int cmd, const String& path, libssh2_struct_stat* fs, + int64 size, dword flags, long mode) { - return Cmd(CHANNEL_OPEN, [=] { - if(path.IsEmpty()) - SetError(-1, "Path is not set."); - switch(opcode) { - case CHANNEL_SCP_GET: - *channel = libssh2_scp_recv2(ssh->session, path, &filestat); + return Run([=]() mutable { + LIBSSH2_CHANNEL *ch = nullptr; + switch(cmd) { + case SFtp::READ: + ch = libssh2_scp_recv2(ssh->session, path, fs); break; - case CHANNEL_SCP_PUT: - *channel = libssh2_scp_send64(ssh->session, path, mode, size, 0, 0); + case SFtp::WRITE: + ch = libssh2_scp_send64(ssh->session, path, mode, size, 0, 0); break; default: NEVER(); } - if(!*channel && !WouldBlock()) { + if(!ch && !WouldBlock()) { LLOG("Unable to obtain a channel."); SetError(-1); } - if(*channel) { - LLOG("Scp channel obtained."); - Unlock(); + if(ch) { + channel = MakeOne(ch); + LLOG("Channel obtained."); } - return *channel != NULL; + return !ch; }); } -bool Scp::Get(const String& path, Stream& out) +// TODO: These methods should better be implemented using a "ScpStream"? +bool Scp::SaveFile(const char *path, const String& data) { - Clear(); - return ComplexCmd(CHANNEL_SCP_GET, [=, &out]() mutable { - Open(CHANNEL_SCP_GET, path, 0, 0); - Cmd(CHANNEL_SCP_GET, [=, &out]{ return SshChannel::ReadStream(out, filestat.st_size); }); - SshChannel::SendRecvEof(); - SshChannel::Close(); - SshChannel::CloseWait(); - }); + // TODO + return false; } -String Scp::Get(const String& path) +String Scp::LoadFile(const char *path) { - Clear(); - ComplexCmd(CHANNEL_SCP_GET, [=]() mutable { - Open(CHANNEL_SCP_GET, path, 0, 0); - Cmd(CHANNEL_SCP_GET, [=]{ return SshChannel::ReadString((String&) result, filestat.st_size); }); - SshChannel::SendRecvEof(); - SshChannel::Close(); - SshChannel::CloseWait(); - }); - return !IsBlocking() ? Null : GetResult(); + // TODO + return Null; } -bool Scp::Put(Stream& in, const String& path, long mode) +bool Scp::SaveFile(const char *path, Stream& in) { - Clear(); - return ComplexCmd(CHANNEL_SCP_PUT, [=, &in]() mutable { - Open(CHANNEL_SCP_PUT, path, in.GetSize(), mode); - SshChannel::Put(in, in.GetSize()); - SshChannel::SendRecvEof(); - SshChannel::Close(); - SshChannel::CloseWait(); - }); + // TODO + return false; } -bool Scp::Put(const String& in, const String& path, long mode) +bool Scp::LoadFile(Stream& out, const char *path) { - Clear(); - return ComplexCmd(CHANNEL_SCP_PUT, [=, &in]() mutable { - Open(CHANNEL_SCP_PUT, path, in.GetLength(), mode); - SshChannel::Put(in); - SshChannel::SendRecvEof(); - SshChannel::Close(); - SshChannel::CloseWait(); - }); + // TODO + return false; } - -void Scp::StartAsync(int cmd, SshSession& session, const String& path, Stream& io, long mode, - Gate progress, Event consumer) -{ - Scp worker(session); - worker.NonBlocking(); - - auto wid = worker.GetId(); - - if(consumer) - worker.WhenContent = [=, &consumer](const void* b, int l) { - consumer(wid, b, l); - }; - if(progress) - worker.WhenProgress = [=, &progress](int64 d, int64 t) { - return progress(wid, d, t); - }; - - switch(cmd) { - case SshChannel::CHANNEL_SCP_GET: - worker.Get(path, io); - break; - case SshChannel::CHANNEL_SCP_PUT: - worker.Put(io, path, mode); - break; - default: - NEVER(); - } - - bool cancelled = false; - int waitstep = worker.GetWaitStep(); - - while(worker.Do()) { - if(!cancelled && CoWork::IsCanceled()) { - worker.Cancel(); - cancelled = true; - } - Sleep(waitstep); - } - if(worker.IsError()) - throw Ssh::Error(worker.GetError(), worker.GetErrorDesc()); -} - -AsyncWork Scp::AsyncGet(SshSession& session, const String& path, Gate progress) -{ - return Async([=, &session, progress = pick(progress)]{ - StringStream data; - Scp::StartAsync(SshChannel::CHANNEL_SCP_GET, session, path, data, 0, progress); - return pick(data.GetResult()); - }); -} - -AsyncWork Scp::AsyncGet(SshSession& session, const String& path, Stream& out, Gate progress) -{ - return Async([=, &session, &out, progress = pick(progress)]{ - Scp::StartAsync(SshChannel::CHANNEL_SCP_GET, session, path, out, 0, progress); - }); -} - -AsyncWork Scp::AsyncPut(SshSession& session, String& in, const String& path, long mode, Gate progress) -{ - return Async([=, &session, &in, progress = pick(progress)]{ - StringStream ss(in); - Scp::StartAsync(SshChannel::CHANNEL_SCP_PUT, session, path, ss, mode, progress); - }); -} - -AsyncWork Scp::AsyncPut(SshSession& session, Stream& in, const String& path, long mode, Gate progress) -{ - return Async([=, &session, &in, progress = pick(progress)]{ - Scp::StartAsync(SshChannel::CHANNEL_SCP_PUT, session, path, in, mode, progress); - }); -} - -AsyncWork Scp::AsyncGetToFile(SshSession& session, const String& src, const String& dest, Gate progress) -{ - return Async([=, &session, progress = pick(progress)]{ - FileOut fo(dest); - if(!fo) - throw Ssh::Error(Format("Unable to open file '%s' for writing.", dest)); - Scp::StartAsync(SshChannel::CHANNEL_SCP_GET, session, src, fo, 0, progress); - }); -} - -AsyncWork Scp::AsyncPutToFile(SshSession& session, const String& src, const String& dest, long mode, Gate progress) -{ - return Async([=, &session, progress = pick(progress)]{ - FileIn fi(src); - if(!fi) - throw Ssh::Error(Format("Unable to open file '%s' for reading.", src)); - Scp::StartAsync(SshChannel::CHANNEL_SCP_PUT, session, dest, fi, mode, progress); - }); -} - -AsyncWork Scp::AsyncConsumerGet(SshSession& session, const String& path, Event consumer) -{ - return Async([=, &session, consumer = pick(consumer)]{ - Scp::StartAsync(SshChannel::CHANNEL_SCP_GET, session, path, NilStream(), 0, Null, consumer); - }); -} -*/ } \ No newline at end of file diff --git a/uppsrc/Core/SSH/Session.cpp b/uppsrc/Core/SSH/Session.cpp index 68fba1fed..49f550c67 100644 --- a/uppsrc/Core/SSH/Session.cpp +++ b/uppsrc/Core/SSH/Session.cpp @@ -283,17 +283,17 @@ SFtp SshSession::CreateSFtp() return pick(SFtp(*this)); } -//SshChannel SshSession::CreateChannel() -//{ -// ASSERT(ssh && ssh->session); -// return pick(SshChannel(*this)); -//} -// -//SshExec SshSession::CreateExec() -//{ -// ASSERT(ssh && ssh->session); -// return pick(SshExec(*this)); -//} +SshChannel SshSession::CreateChannel() +{ + ASSERT(ssh && ssh->session); + return pick(SshChannel(*this)); +} + +SshExec SshSession::CreateExec() +{ + ASSERT(ssh && ssh->session); + return pick(SshExec(*this)); +} // //Scp SshSession::CreateScp() //{ diff --git a/uppsrc/Core/SSH/Session.h b/uppsrc/Core/SSH/Session.h index 9a3d360d5..e38c76783 100644 --- a/uppsrc/Core/SSH/Session.h +++ b/uppsrc/Core/SSH/Session.h @@ -34,8 +34,8 @@ public: ValueMap GetMethods(); SFtp CreateSFtp(); -// SshChannel CreateChannel(); -// SshExec CreateExec(); + SshChannel CreateChannel(); + SshExec CreateExec(); // Scp CreateScp(); // SshTunnel CreateTcpTunnel(); // SshShell CreateShell(); diff --git a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tpp b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tpp index f474f9394..76185031f 100644 --- a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tpp +++ b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tpp @@ -177,36 +177,20 @@ insead. SshExec class is derived from SshChannel class, and has pick semantics. &] [s3;%- &] [ {{10000F(128)G(128)@1 [s0; [* Public Method List]]}}&] -[s3;%- &] -[s5;:Upp`:`:SshExec`:`:Execute`(const Upp`:`:String`&`,Upp`:`:Stream`&`,Upp`:`:Stream`&`):%- [@(0.0.255) i +[s4;%- &] +[s5;:Upp`:`:SshExec`:`:Execute`(const Upp`:`:String`&`,Upp`:`:String`&`,Upp`:`:String`&`):%- [@(0.0.255) i nt]_[* Execute]([@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 cmd], -[_^Upp`:`:Stream^ Stream][@(0.0.255) `&]_[*@3 out], [_^Upp`:`:Stream^ Stream][@(0.0.255) `& +[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 out], [_^Upp`:`:String^ String][@(0.0.255) `& ]_[*@3 err])&] -[s5;:Upp`:`:SshExec`:`:operator`(`)`(const Upp`:`:String`&`,Upp`:`:Stream`&`,Upp`:`:Stream`&`):%- [@(0.0.255) i +[s5;:Upp`:`:SshExec`:`:operator`(`)`(const Upp`:`:String`&`,Upp`:`:String`&`,Upp`:`:String`&`):%- [@(0.0.255) i nt]_[* operator()]([@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 cmd], -[_^Upp`:`:Stream^ Stream][@(0.0.255) `&]_[*@3 out], [_^Upp`:`:Stream^ Stream][@(0.0.255) `& +[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 out], [_^Upp`:`:String^ String][@(0.0.255) `& ]_[*@3 err])&] -[s0;l288; Executes remote process defined by [%-*@3 cmd] command line, -returns its standard output in [%-*@3 out], its standard error -output in [%-*@3 err], and its exit code as return value. In non`-blocking -mode, SshChannel`::GetExitCode() and SshChannel`::GetExitSignal() -methods can be used to retrieve the exit code and message of -the executed command. &] -[s3;%- &] -[s3;%- &] -[ {{10000F(128)G(128)@1 [s0; [* Multithreaded Execution Method]]}}&] -[s3;%- &] -[s5;:Upp`:`:SshExec`:`::%- [@(0.0.255) static] [_^Upp`:`:AsyncWork^ AsyncWork]<[_^Upp`:`:Tuple^ T -uple]<[@(0.0.255) int], [_^Upp`:`:String^ String], [_^Upp`:`:String^ String]>>_[* AsyncRu -n]([_^Upp`:`:SshSession^ SshSession][@(0.0.255) `&]_[*@3 session], -[@(0.0.255) const]_[_^Upp`:`:String^ String][@(0.0.255) `&]_[*@3 cmd])&] -[s2; Executes a remote process defined by [%-*@3 cmd] command line -asynchronously, and returns a tuple containing the exit code -(int), standard output (String), and standard error output (String) -of the executed process. Throws [^topic`:`/`/SSH`/src`/Upp`_Ssh`_Base`$en`-us`#Upp`:`:Ssh`:`:Error`:`:struct^ S -sh`::Error] on failure. Requires a valid ssh [%-*@3 session] during -the operation &] -[s3; &] +[s0;l288; Executes a remote process defined by the [%-*@3 cmd] command +line,returns its standard output in [%-*@3 out], its standard error +output in [%-*@3 err], and its exit code as the return value. If +the remote process exits successfully the return code will be +0.&] [s3;%- &] [ {{10000F(128)G(128)@1 [s0; [* Constructor detail]]}}&] [s3;%- &] diff --git a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tppi b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tppi index cd7ff77fd..34acea839 100644 --- a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tppi +++ b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_Channels_en-us.tppi @@ -1,22 +1,21 @@ TITLE("Channels: Scp, Exec, Tunnel, Shell") COMPRESSED -120,156,221,28,139,114,219,198,241,87,110,162,36,37,53,20,13,128,164,72,145,173,199,137,171,36,158,54,142,198,114,38,153,225,80,194,17,56,137,87,227,193,226,33,153,78,147,111,239,238,61,128,3,248,150,168,88,109,211,49,69,220,221,222,238,222,190,111,193,49,239,118,7,35,234,244,70,31,254,241,211,217,200,33,95,126,105,183,172,163,78,223,238,12,122,29,187,235,156,194,63,118,199,118,122,78,167,107,15,156,179,238,160,211,25,88,67,47,160,105,58,25,7,206,96,32,22,57,45,231,200,233,247,28,187,223,29,116,7,118,167,63,112,96,173,99,89,142,213,119,122,118,183,51,112,122,67,159,165,222,100,108,193,244,14,236,113,118,218,57,179,108,203,234,219,182,213,113,250,86,167,215,181,237,142,3,32,156,190,99,91,189,33,139,252,201,248,135,211,17,46,232,194,2,171,119,106,89,214,41,64,235,118,45,128,142,203,186,29,187,99,57,157,158,125,214,59,29,78,217,45,143,38,227,101,146,122,91,73,234,91,67,158,177,80,81,68,187,163,227,87,189,145,13,75,79, -91,167,71,125,216,182,219,131,205,206,144,162,14,44,115,156,211,222,153,221,235,2,74,93,203,25,38,236,223,57,79,88,200,162,76,65,224,182,237,216,163,169,221,31,1,10,127,252,241,71,219,238,90,146,83,125,192,197,182,0,111,199,134,103,64,71,223,238,157,89,103,189,129,61,176,58,253,174,211,235,3,233,115,154,208,80,81,50,237,58,35,69,199,160,53,56,58,181,79,129,163,214,0,240,239,157,1,0,11,136,128,79,96,100,15,254,223,25,12,51,181,24,215,225,162,179,214,217,17,48,169,211,179,250,103,86,191,219,239,117,129,18,199,62,181,129,145,22,210,15,199,48,140,226,36,164,193,100,140,11,44,228,245,150,255,13,255,206,110,104,30,0,185,191,93,255,254,213,249,219,147,159,47,201,152,252,246,155,141,131,175,26,112,144,237,174,211,182,154,100,156,90,35,50,62,126,213,31,117,201,101,70,35,159,38,62,185,76,103,228,245,140,70,17,11,210,201,228,247,223,191,158,140,211,206,136,224,135,51,34,151,204,203,19,70,210,25,11,2,50,79,226,44,246,226,128, -52,238,88,146,242,56,34,78,19,30,50,159,221,240,136,165,36,101,240,156,6,196,147,224,72,182,152,179,180,173,32,41,136,220,238,89,200,66,114,242,159,241,85,22,207,185,231,14,221,23,238,139,203,203,31,220,23,105,226,185,47,126,158,207,221,107,192,202,189,214,104,185,215,44,114,79,242,212,61,194,177,161,59,188,244,196,135,16,252,43,98,183,53,154,62,205,40,241,226,249,66,163,208,158,28,114,215,116,118,254,145,121,198,206,78,155,188,99,97,156,49,216,52,12,129,161,132,193,132,60,67,214,60,17,6,239,115,28,50,112,232,180,201,251,215,23,238,201,155,11,130,8,204,227,36,35,55,113,114,15,103,203,163,91,210,136,88,118,31,39,31,240,240,62,46,154,79,133,214,37,10,136,129,85,23,57,67,3,247,36,227,33,107,17,30,101,32,25,94,198,239,24,73,36,199,164,72,53,52,227,2,144,32,57,237,134,122,236,79,195,179,103,226,73,126,181,109,147,119,90,142,27,112,156,33,245,102,66,200,19,56,0,28,252,21,196,61,1,121,111,46,161,168,4,254,91, -22,196,247,68,236,3,203,238,19,58,39,217,140,145,91,22,177,132,123,168,119,10,81,57,135,100,49,158,209,29,247,25,97,52,93,0,74,49,98,111,112,69,204,1,24,240,44,157,51,143,211,128,127,98,190,70,83,106,154,37,246,223,170,253,222,188,166,235,246,104,184,66,185,134,95,157,144,241,171,134,213,182,218,96,226,154,29,162,124,77,135,92,79,198,199,29,1,7,191,12,225,171,57,109,158,79,3,238,233,121,175,58,163,142,65,239,68,226,121,36,140,51,121,63,227,169,226,0,139,60,58,79,243,128,102,64,42,141,8,28,174,3,92,22,170,93,209,106,242,38,211,188,130,137,36,100,52,74,241,224,212,228,96,65,178,4,30,221,176,36,193,163,186,225,1,204,155,130,34,48,22,145,32,246,192,70,205,226,52,19,10,67,181,64,226,147,54,82,164,176,1,180,124,56,169,59,224,240,77,18,135,75,7,214,18,203,103,52,37,32,141,31,96,107,144,227,140,123,242,24,58,35,224,156,113,16,223,53,108,103,208,252,94,252,251,202,214,103,65,46,4,159,200,143,44,155, -197,62,249,39,79,179,242,88,36,128,180,87,63,152,239,89,230,130,218,68,128,191,30,200,144,76,247,107,183,85,62,96,52,132,7,205,218,1,146,105,28,7,147,107,216,25,160,76,26,230,136,128,8,67,215,87,21,168,87,68,126,154,231,75,220,175,17,198,43,56,103,154,205,38,45,82,89,4,59,139,69,12,29,223,170,69,113,158,77,154,43,73,139,231,96,37,178,56,113,27,110,243,0,52,106,112,141,230,103,39,21,236,193,223,227,251,40,136,169,159,10,51,160,132,14,69,147,208,140,140,191,58,41,54,17,114,149,176,44,79,64,170,57,72,41,202,184,68,13,173,149,124,14,234,193,194,121,182,32,169,24,32,96,162,110,40,15,64,250,219,134,86,119,31,34,69,146,161,235,152,115,96,225,121,184,32,108,71,243,240,231,191,250,44,1,94,6,225,38,137,111,42,199,58,143,209,114,251,100,186,48,143,151,76,224,60,211,253,78,19,118,124,19,145,40,6,119,54,5,243,245,1,167,132,177,15,142,85,138,18,216,76,177,123,134,182,84,82,45,66,16,0,59,101,36,158, -102,20,92,151,79,242,20,23,194,225,189,19,43,26,77,176,156,104,120,118,147,152,139,28,36,166,174,124,173,53,74,26,196,240,185,94,51,1,22,28,201,94,170,4,217,68,139,28,76,139,141,49,68,85,141,34,79,201,196,253,219,245,24,190,64,124,222,93,35,158,130,21,107,40,127,12,67,30,75,221,115,226,81,85,133,15,36,55,21,141,126,150,226,51,185,222,151,53,7,149,163,131,154,188,207,200,51,176,120,63,207,165,133,85,182,19,144,193,240,119,187,129,133,189,238,57,216,89,234,65,196,92,44,23,251,148,6,55,75,114,134,86,54,205,197,44,195,2,110,137,216,126,4,195,9,208,65,208,124,216,249,189,10,51,85,4,87,36,208,206,232,72,153,81,248,11,81,128,48,23,144,142,3,72,9,68,102,17,71,119,44,226,16,240,50,101,131,83,130,161,254,140,223,206,8,28,225,13,150,0,112,16,83,55,0,47,55,148,241,191,222,18,147,221,54,194,93,16,10,153,148,170,123,64,168,112,7,121,129,79,82,200,235,39,138,120,72,64,48,93,199,175,132,248,185,112, -49,232,57,10,87,33,99,89,216,5,50,22,156,181,45,197,250,150,166,108,85,122,133,31,231,73,2,162,13,127,128,47,203,189,12,132,227,18,158,203,199,18,131,210,187,165,109,116,108,136,190,240,94,152,217,40,118,180,32,149,246,216,60,35,223,164,139,200,123,13,130,151,135,44,1,223,213,104,182,10,186,32,7,184,5,32,233,132,220,82,76,194,165,191,3,70,250,138,83,16,151,35,157,122,158,218,165,224,225,80,30,11,79,64,211,68,165,134,65,166,85,56,82,1,147,71,62,247,100,66,66,242,136,255,27,196,134,251,130,237,152,108,196,152,113,23,11,139,148,4,247,160,97,156,203,152,64,84,37,178,25,68,121,152,44,208,0,143,114,1,136,66,46,82,164,41,76,193,132,141,19,19,100,72,23,69,86,40,48,143,51,72,94,234,176,99,36,219,128,213,34,211,60,195,4,134,162,192,73,110,192,12,75,203,191,56,127,212,128,123,14,172,167,83,172,25,136,64,38,135,213,0,88,66,85,240,218,228,45,106,156,32,64,30,81,77,40,5,16,148,94,24,229,137,22,54, -247,47,48,66,121,150,102,108,142,34,153,35,242,226,73,37,65,218,16,112,136,147,23,113,170,145,191,43,224,235,13,164,122,240,61,156,153,251,87,245,5,204,196,105,183,24,90,245,237,229,178,77,77,51,80,13,111,98,132,152,2,161,95,128,248,43,82,252,57,249,235,90,107,248,18,13,178,38,162,226,175,10,58,174,72,249,247,106,235,169,85,247,128,134,184,88,132,60,186,34,248,175,73,133,96,200,21,17,31,149,233,187,13,188,84,155,105,213,124,64,250,83,196,199,59,197,165,143,18,147,50,32,249,243,229,198,88,115,23,115,255,249,203,203,174,25,239,103,147,177,13,66,102,196,10,56,84,17,56,176,75,234,59,98,191,135,212,85,82,162,138,212,237,21,206,61,43,217,171,167,102,15,147,189,231,25,103,126,30,193,124,184,236,236,144,43,253,159,203,206,243,201,235,62,159,81,91,157,8,213,173,88,123,109,210,179,151,23,125,31,127,7,230,114,63,95,250,108,34,177,141,30,85,82,246,12,252,42,228,82,135,0,3,137,198,103,116,181,59,121,90,157,126,38,30,153, -128,200,202,155,151,53,147,4,57,70,174,129,151,134,144,209,65,90,1,105,142,74,23,101,94,38,51,68,50,126,65,252,24,146,173,40,206,32,102,204,179,56,68,41,129,140,103,1,176,2,150,201,132,9,82,169,140,203,135,10,99,188,207,1,20,218,100,47,63,127,64,189,120,150,118,251,255,85,59,158,163,69,215,6,29,229,115,163,78,32,47,180,173,87,42,38,174,16,214,105,207,1,92,128,81,105,121,80,66,117,126,199,162,172,46,208,114,9,10,157,123,236,182,224,225,19,201,177,129,252,51,144,228,165,252,73,240,230,138,136,143,77,98,182,98,227,26,205,238,113,109,30,172,213,226,230,41,38,60,200,84,43,156,229,77,17,197,170,78,226,158,200,254,30,95,207,41,54,32,55,121,228,97,249,176,189,190,142,198,138,233,197,108,44,76,225,64,81,78,211,51,111,57,112,134,164,222,92,85,152,76,177,181,118,41,206,226,249,139,162,99,156,128,70,100,224,52,182,95,167,227,199,74,65,151,2,122,44,122,28,30,41,76,250,36,12,252,218,228,91,30,169,35,193,158,3, -14,35,162,226,91,38,163,122,181,201,134,122,95,193,218,6,15,217,171,180,68,190,209,230,81,235,102,218,218,234,161,32,62,113,187,135,54,115,73,44,172,88,217,79,213,192,63,155,219,91,64,212,10,33,190,40,197,129,110,53,210,157,70,0,171,214,243,241,230,134,44,226,156,68,76,86,74,147,92,206,88,221,190,180,186,97,169,37,32,164,179,56,15,124,33,241,128,87,162,212,72,183,29,233,190,146,40,101,212,111,107,134,62,182,219,100,165,88,28,164,221,164,20,144,115,193,83,182,115,75,198,246,30,13,180,87,104,182,21,228,3,92,86,121,161,255,232,98,213,46,107,88,146,44,165,245,37,167,30,212,193,178,59,187,14,122,189,247,167,115,204,26,73,27,160,14,61,173,43,187,246,51,165,59,66,20,43,26,215,50,26,99,176,76,172,154,88,1,173,57,222,120,68,102,33,175,85,157,195,240,2,106,121,38,98,39,149,11,103,179,143,60,131,13,125,134,85,104,185,149,188,188,104,175,235,192,40,21,213,29,98,87,205,57,64,120,13,35,141,166,0,186,106,248,146,223, -70,52,40,218,47,210,250,197,21,236,155,112,118,39,19,24,3,35,0,23,2,159,232,45,211,30,83,26,59,236,1,148,60,170,90,131,93,205,66,245,78,243,188,48,185,210,78,236,102,34,30,127,123,242,62,159,7,16,131,139,143,106,148,135,210,191,161,166,184,97,232,101,25,27,190,203,163,103,16,19,162,64,235,104,160,80,3,250,0,69,0,249,4,162,102,73,28,197,121,26,44,90,149,166,49,74,50,228,162,104,76,162,60,210,215,189,165,40,53,128,165,205,214,146,254,52,36,234,77,9,109,181,230,232,57,75,34,168,144,199,88,48,137,239,33,1,217,233,18,249,203,93,47,145,211,242,18,217,108,143,34,239,228,189,119,90,185,248,174,69,80,43,239,188,201,134,176,234,32,241,101,169,28,250,207,205,113,166,10,176,14,17,107,106,75,187,46,224,84,161,199,246,160,83,81,101,237,30,118,202,6,245,205,129,103,173,137,125,135,208,83,65,125,88,240,233,172,15,59,5,55,48,238,124,255,250,226,197,154,22,250,144,97,208,201,211,48,93,31,117,194,114,208,57,220,81, -52,28,99,4,55,141,33,25,247,2,142,23,234,192,95,217,45,46,21,75,254,9,15,213,176,15,2,44,82,35,12,243,60,25,188,34,124,213,251,92,105,225,111,151,236,56,100,163,242,202,186,128,121,82,32,74,17,32,185,185,27,115,85,75,146,90,120,128,128,37,79,130,21,161,215,206,40,138,194,195,159,129,39,102,21,43,242,115,85,21,0,233,42,92,192,55,89,134,125,159,210,98,35,25,1,54,21,73,81,244,36,62,104,169,176,4,68,147,91,86,92,148,139,29,204,139,115,4,186,190,187,73,79,67,6,146,48,79,51,237,25,100,79,137,4,45,58,226,35,200,221,75,37,224,145,104,68,146,41,126,227,188,125,219,38,238,23,227,215,178,104,133,243,135,182,53,176,220,47,154,237,9,185,8,24,22,107,163,162,87,228,126,134,37,6,81,1,40,148,0,84,77,75,63,58,179,60,194,222,26,164,16,28,32,160,35,148,51,89,204,51,108,97,169,78,16,146,173,180,213,80,32,19,119,46,106,193,91,235,186,166,196,96,10,4,14,8,221,225,54,241,144,83,171,210,81, -59,213,117,71,30,200,93,174,61,236,218,41,154,221,122,27,101,89,99,182,65,148,197,63,199,15,193,251,137,164,122,105,208,61,86,195,83,160,220,119,175,31,206,37,209,1,45,93,89,165,140,85,149,6,241,210,161,2,36,236,48,88,102,30,137,205,151,181,42,221,67,127,222,200,88,71,66,86,186,129,239,187,9,161,182,90,117,193,20,29,81,41,11,96,35,49,36,43,99,244,14,2,6,58,5,165,240,23,160,103,144,136,35,32,1,156,86,30,33,108,108,231,99,169,80,4,133,163,201,67,185,195,20,43,120,115,225,201,124,217,243,40,26,207,188,44,167,129,156,46,193,129,15,128,140,163,108,126,144,88,182,171,198,164,158,132,136,55,140,110,22,160,198,52,171,189,130,164,216,128,70,1,112,55,116,79,45,226,136,181,40,197,204,193,51,243,0,251,218,37,171,220,47,240,224,225,63,247,139,150,104,251,43,121,66,125,31,139,228,44,45,104,211,152,76,185,168,218,180,201,91,118,95,57,63,61,17,56,149,99,123,59,120,181,64,148,191,209,128,168,226,11,210,251,141,120, -84,182,187,107,194,171,18,183,196,0,38,15,47,164,31,121,152,135,36,202,195,169,172,106,206,89,228,171,46,206,2,23,88,32,208,0,8,32,117,40,159,255,98,210,147,223,228,9,128,1,207,175,108,253,182,98,188,105,5,36,230,102,220,168,198,54,57,92,185,168,22,71,202,117,87,102,44,181,74,201,37,75,140,226,177,4,134,14,202,240,71,133,49,174,48,18,86,237,210,96,251,84,193,118,201,181,242,203,182,128,91,177,226,137,203,187,69,188,182,99,145,119,143,104,91,20,22,55,7,219,213,87,30,119,136,181,37,204,135,134,218,71,91,75,188,102,53,85,149,102,37,132,150,138,173,101,241,182,254,86,95,185,14,196,74,222,116,105,47,176,186,38,139,69,158,178,138,43,151,212,222,240,76,243,185,180,193,245,26,237,131,171,177,181,90,178,202,142,203,90,180,70,85,96,19,197,38,81,91,106,200,101,177,248,233,222,48,52,164,229,93,190,62,250,208,15,248,39,182,193,14,201,138,203,99,195,14,96,79,200,35,26,84,203,60,176,51,44,131,127,139,187,182,91,150,226, -215,229,152,106,39,138,118,8,0,15,79,206,202,48,232,158,251,75,189,72,229,232,140,241,219,89,153,63,0,78,104,154,245,59,197,27,213,97,173,109,190,201,3,81,26,42,252,98,129,163,22,198,41,211,14,124,158,48,217,98,94,76,34,44,68,253,22,87,52,160,176,188,69,238,50,16,200,22,249,136,51,90,132,101,94,187,41,47,8,125,80,195,40,21,238,82,55,226,107,32,119,28,124,123,3,244,9,76,1,170,3,38,8,112,108,105,83,123,101,220,191,244,232,10,81,193,43,50,65,90,117,44,35,249,35,194,143,226,74,83,137,70,121,53,185,131,15,46,164,6,141,122,28,172,189,251,216,152,79,226,194,67,202,140,56,246,83,196,183,168,122,121,10,189,147,41,197,184,133,206,49,228,18,199,81,252,242,130,18,146,218,204,103,44,43,229,251,6,216,2,36,209,150,239,157,93,94,42,51,93,237,247,201,232,7,100,5,77,138,194,184,108,171,208,107,81,4,240,53,73,254,105,135,174,114,227,236,191,147,158,2,156,198,118,195,97,88,143,74,48,129,176,174,12,183,186, -116,192,164,220,229,80,89,26,38,79,111,243,32,88,103,69,124,158,206,3,186,40,223,187,90,107,111,82,47,97,144,61,110,159,56,205,111,132,146,233,153,182,229,116,225,203,113,249,165,20,222,139,159,46,223,252,10,66,21,44,42,229,219,250,47,43,104,249,61,143,48,65,72,235,190,27,35,3,163,107,64,136,133,14,176,106,185,141,97,32,52,233,245,104,95,69,183,164,104,83,43,176,32,13,95,254,190,10,76,20,87,65,144,248,241,112,14,98,135,17,10,164,52,238,184,168,135,184,147,161,40,135,20,209,157,100,223,114,106,81,164,134,72,148,156,133,3,138,188,98,189,230,106,145,88,201,136,18,159,201,183,141,169,255,226,62,225,160,46,48,19,95,10,211,76,129,40,33,246,184,72,12,127,126,11,204,134,111,31,24,228,30,68,253,86,140,158,47,32,65,180,99,147,31,191,197,91,1,192,132,22,86,118,25,60,190,142,164,94,55,6,213,76,195,56,22,169,141,241,198,90,179,52,29,238,177,104,215,67,148,84,203,30,24,119,113,27,177,135,10,202,252,67,104,96,57, -10,95,95,23,217,136,123,188,53,23,146,170,101,170,101,5,130,80,207,202,147,170,110,233,42,198,71,219,70,49,121,184,36,23,201,84,36,206,189,204,168,52,211,150,43,15,239,141,142,199,68,239,80,211,4,249,118,23,19,106,226,171,187,204,84,72,103,166,198,132,224,137,144,115,235,173,140,206,147,86,253,120,138,26,130,111,191,204,88,4,88,152,57,146,126,54,33,12,27,156,76,51,206,168,55,171,105,168,80,9,69,3,9,241,2,18,47,172,170,92,217,199,77,95,66,78,46,235,120,75,194,32,154,196,80,24,112,206,186,2,158,183,41,114,148,192,165,7,192,0,101,149,200,109,216,101,69,19,151,132,162,141,236,174,123,111,13,62,118,64,98,191,102,204,34,210,188,200,69,17,64,103,49,58,74,19,129,86,113,124,197,227,84,244,204,200,198,69,30,225,181,161,40,142,236,113,158,23,224,178,69,126,209,88,78,54,246,244,175,26,84,197,4,212,19,136,244,83,65,234,37,83,53,198,106,116,42,76,229,114,132,106,230,242,159,38,7,182,126,223,179,172,100,132,219,20, -103,88,99,65,133,16,98,44,152,52,154,215,203,2,160,99,66,29,222,25,111,125,98,1,115,5,201,60,170,147,188,203,197,145,73,130,138,132,77,74,182,17,81,91,2,180,152,23,121,0,123,206,146,210,44,150,180,168,226,167,8,248,180,151,92,138,7,215,155,200,90,188,89,158,38,70,83,203,191,177,178,27,7,208,46,190,65,37,168,18,93,237,6,21,141,10,197,204,202,181,165,48,167,136,46,11,121,38,74,189,48,141,160,95,86,198,191,82,68,1,90,32,166,7,39,49,143,193,44,79,177,209,29,141,65,81,253,92,142,69,128,23,226,133,223,88,84,209,103,172,232,177,219,151,200,159,68,135,192,38,42,31,211,218,74,202,45,182,179,7,127,137,78,82,37,106,233,212,47,107,150,130,91,251,148,80,170,237,49,187,52,197,148,209,139,234,60,217,233,45,193,74,89,101,117,63,117,1,251,107,247,101,125,202,106,23,241,52,141,214,135,105,166,217,240,219,61,251,23,126,214,55,90,107,166,213,208,121,105,190,64,182,135,188,238,232,64,95,46,255,2,212,62,213,154,90, -127,207,255,94,109,102,69,217,165,32,2,95,97,147,106,91,18,177,100,143,218,102,47,223,218,233,9,243,24,22,146,245,175,97,252,79,180,30,85,45,235,19,221,135,148,17,164,254,123,219,109,136,140,160,158,252,50,228,178,154,8,108,107,120,215,237,255,147,201,127,1,229,197,101,108, +120,156,221,28,139,114,219,198,241,87,110,162,36,37,53,20,13,128,164,72,145,169,199,177,235,164,158,54,142,38,114,166,153,225,80,2,8,28,197,171,65,0,197,67,50,157,38,223,222,221,189,59,188,248,150,169,88,77,156,17,69,224,110,111,119,111,223,183,167,177,232,118,7,35,199,234,141,222,255,227,199,139,145,197,190,252,210,108,25,39,157,190,217,25,244,58,102,215,58,135,31,102,199,180,122,86,167,107,14,172,139,238,160,211,25,24,67,215,119,146,100,50,246,173,193,128,38,89,45,235,196,234,247,44,179,223,29,116,7,102,167,63,176,96,174,101,24,150,209,183,122,102,183,51,176,122,67,143,39,238,100,108,192,240,14,172,113,113,222,185,48,76,195,232,155,166,209,177,250,70,167,215,53,205,142,5,32,172,190,101,26,189,33,15,188,201,248,239,231,35,156,208,133,9,70,239,220,48,140,115,128,214,237,26,0,29,167,117,59,102,199,176,58,61,243,162,119,62,156,242,91,17,76,198,171,36,245,118,146,212,55,134,34,229,11,69,145,211,29,157,190,232,141,76,152,122, +222,58,63,233,195,178,221,30,44,118,129,20,117,96,154,101,157,247,46,204,94,23,80,234,26,214,48,230,255,201,68,204,23,60,72,21,4,97,154,150,57,154,154,253,17,160,240,251,239,191,183,205,174,33,57,213,7,92,76,3,240,182,76,120,6,116,244,205,222,133,113,209,27,152,3,163,211,239,90,189,62,144,30,57,177,179,80,148,76,187,214,72,209,49,104,13,78,206,205,115,224,168,49,0,252,123,23,0,192,0,34,224,19,24,217,131,255,59,131,97,170,38,227,60,156,116,209,186,56,1,38,117,122,70,255,194,232,119,251,189,46,80,98,153,231,38,48,210,64,250,97,27,134,65,24,47,28,127,50,198,9,6,242,122,199,127,195,191,241,153,147,249,64,238,175,55,191,125,245,250,237,217,207,87,108,204,126,253,213,196,151,47,26,176,145,237,174,213,54,154,108,156,24,35,54,62,125,209,31,117,217,85,234,4,158,19,123,236,42,153,179,87,115,39,8,184,159,76,38,191,253,246,245,100,156,116,70,12,63,172,17,187,226,110,22,115,150,204,185,239,179,40,14,211,208,13, +125,214,184,227,113,34,194,128,89,77,120,200,61,62,19,1,79,88,194,225,185,227,51,87,130,99,233,50,226,73,91,65,82,16,133,217,51,144,133,236,236,191,227,235,52,140,132,107,15,237,103,246,179,171,171,191,219,207,146,216,181,159,253,28,69,246,13,96,101,223,104,180,236,27,30,216,103,89,98,159,224,187,161,61,188,114,233,131,4,255,154,153,109,141,166,231,164,14,115,195,104,169,81,104,79,142,185,106,50,127,253,129,187,165,149,173,54,251,137,47,194,148,195,162,139,5,48,148,113,24,144,165,200,154,71,194,224,93,134,175,74,56,116,218,236,221,171,75,251,236,205,37,67,4,162,48,78,217,44,140,239,97,111,69,112,203,26,1,79,239,195,248,61,110,222,135,101,243,177,208,186,66,1,41,97,213,69,206,56,190,125,150,138,5,111,49,17,164,32,25,110,42,238,56,139,37,199,164,72,53,52,227,124,144,32,57,108,230,184,252,15,195,179,87,198,147,253,98,154,101,222,105,57,110,192,118,46,28,119,78,66,30,195,6,224,203,95,64,220,99,144,247,230,10,138,74, +224,95,114,63,188,103,180,14,76,187,143,157,136,165,115,206,110,121,192,99,225,162,222,41,68,229,24,150,134,184,71,119,194,227,140,59,201,18,80,10,17,251,18,87,104,12,192,128,103,73,196,93,225,248,226,35,247,52,154,82,211,12,90,127,167,246,187,81,77,215,205,209,112,141,114,13,191,58,99,227,23,13,163,109,180,193,196,53,59,76,249,154,14,187,153,140,79,59,4,7,191,12,225,107,121,88,148,77,125,225,234,113,47,58,163,78,137,222,137,196,243,132,140,51,123,55,23,137,226,0,15,92,39,74,50,223,73,129,84,39,96,176,185,22,112,153,84,187,162,213,236,77,170,121,5,3,217,130,59,65,130,27,167,6,251,75,150,198,240,104,198,227,24,183,106,38,124,24,55,5,69,224,60,96,126,232,130,141,154,135,73,74,10,227,104,129,196,39,109,164,72,97,3,104,121,176,83,119,192,225,89,28,46,86,54,172,69,211,231,78,194,64,26,223,195,210,32,199,169,112,229,54,116,70,192,185,210,70,124,215,48,173,65,243,123,250,249,194,212,123,193,46,137,79,236,7, +158,206,67,143,253,83,36,105,177,45,18,64,210,171,111,204,247,60,181,65,109,2,192,95,191,72,145,76,251,107,187,85,60,224,206,2,30,52,107,27,200,166,97,232,79,110,96,101,128,50,105,148,223,16,68,120,117,115,93,129,122,205,228,103,121,127,153,253,53,194,120,1,251,236,164,243,73,139,85,38,193,202,52,137,163,227,91,55,41,204,210,73,115,45,105,97,4,86,34,13,99,187,97,55,143,64,163,6,215,104,126,118,82,193,30,252,45,188,15,252,208,241,18,50,3,74,232,80,52,153,147,178,241,87,103,249,34,36,87,49,79,179,24,164,90,128,148,162,140,75,212,208,90,201,231,160,30,124,17,165,75,150,208,11,6,38,106,230,8,31,164,191,93,210,234,238,67,164,72,50,116,19,115,142,44,60,15,23,132,221,104,30,127,255,215,239,37,192,75,33,220,100,225,172,178,173,81,136,150,219,99,211,101,121,123,217,4,246,51,57,108,55,97,197,55,1,11,66,112,103,83,48,95,239,113,200,34,244,192,177,74,81,2,155,73,171,167,104,75,37,213,20,130,0,216,41, +103,225,52,117,192,117,121,44,75,112,34,108,222,79,52,163,209,4,203,137,134,103,63,137,185,204,64,98,234,202,215,218,160,164,126,8,159,155,53,19,96,193,150,28,164,74,144,77,180,216,209,180,184,244,14,81,85,111,145,167,108,98,255,245,102,12,95,32,62,239,110,16,79,98,197,6,202,63,133,33,159,74,221,83,226,81,85,133,143,36,55,21,141,126,146,226,51,185,57,148,53,71,149,163,163,154,188,207,200,51,176,120,63,71,210,194,42,219,9,200,96,248,187,219,192,194,90,247,2,236,172,227,66,196,156,79,167,117,10,131,155,198,25,71,43,155,100,52,170,100,1,119,68,108,63,128,225,4,232,32,104,30,172,252,78,133,153,42,130,203,19,104,107,116,162,204,40,252,134,40,64,152,11,72,135,62,164,4,148,89,132,193,29,15,4,4,188,92,217,224,132,97,168,63,23,183,115,6,91,56,195,18,0,190,196,212,13,192,203,5,101,252,175,151,196,100,183,141,112,151,204,129,76,74,213,61,32,84,184,131,188,192,99,9,228,245,19,69,60,36,32,152,174,227,87,198, +188,140,92,12,122,142,220,85,200,88,22,86,129,140,5,71,237,74,177,94,58,9,95,151,94,225,199,235,56,6,209,134,95,192,151,101,110,10,194,113,5,207,229,99,137,65,225,221,146,54,58,54,68,159,188,23,102,54,138,29,45,72,165,93,30,165,236,219,100,25,184,175,64,240,178,5,143,193,119,53,154,173,156,46,200,1,110,1,72,50,97,183,14,38,225,210,223,1,35,61,197,41,136,203,145,78,61,78,173,146,243,112,40,183,69,196,160,105,84,169,225,144,105,229,142,148,96,138,192,19,174,76,72,88,22,136,255,128,216,8,143,216,142,201,70,136,25,119,62,49,79,73,112,13,103,17,102,50,38,160,170,68,58,135,40,15,147,5,199,199,173,92,2,162,144,139,228,105,10,87,48,97,225,184,12,114,225,44,243,172,144,48,15,83,72,94,234,176,67,36,187,4,171,197,166,89,138,9,140,131,2,39,185,1,35,12,45,255,180,255,168,1,247,2,88,239,76,177,102,64,129,76,6,179,1,176,132,170,224,181,217,91,212,56,34,64,110,81,77,40,9,8,74,47,188,21, +177,22,54,251,47,240,198,17,105,146,242,8,69,50,67,228,233,73,37,65,218,18,112,208,206,83,156,90,202,223,21,240,205,6,82,61,248,30,246,204,254,70,125,1,51,113,222,205,95,173,251,246,124,213,166,38,41,168,134,59,41,133,152,132,208,191,128,248,107,150,255,58,249,102,163,53,124,142,6,89,19,81,241,87,57,29,215,172,248,125,189,245,212,170,123,68,67,156,79,66,30,93,51,252,89,166,130,24,114,205,232,163,50,124,191,23,207,213,98,90,53,31,144,254,228,241,241,94,113,233,39,137,73,17,144,252,241,114,83,154,115,23,10,239,233,203,203,190,25,239,103,147,177,45,66,86,138,21,240,85,69,224,192,46,169,239,136,253,1,82,87,73,137,42,82,119,80,56,247,164,100,175,158,154,61,76,246,158,102,156,249,121,4,243,225,178,179,71,174,244,39,151,157,167,147,215,125,62,163,182,62,17,170,91,177,246,198,164,231,32,47,250,46,252,14,204,229,97,190,244,201,68,98,91,61,170,164,236,9,248,85,200,165,142,1,6,18,141,207,232,106,247,242,180,58,253, +140,93,54,1,145,149,39,47,27,6,17,57,165,92,3,15,13,33,163,131,180,2,210,28,149,46,202,188,76,102,136,108,252,140,121,33,36,91,65,152,66,204,152,165,225,2,165,4,50,158,37,192,242,121,42,19,38,72,165,82,33,31,42,140,241,60,7,80,104,179,131,252,252,17,245,226,73,218,237,63,171,118,60,69,139,174,13,58,202,231,86,157,64,94,104,91,175,84,140,142,16,54,105,207,17,92,64,169,210,242,160,132,234,245,29,15,210,186,64,203,41,40,116,246,169,221,130,135,143,36,199,37,228,159,128,36,175,228,79,196,155,107,70,31,219,196,108,205,194,53,154,237,211,218,56,152,171,197,205,85,76,120,144,169,86,56,203,147,34,7,171,58,177,125,38,251,123,60,61,38,95,128,205,178,192,197,242,97,123,115,29,141,231,195,243,209,88,152,194,23,121,57,77,143,188,21,192,25,150,184,145,170,48,149,197,214,216,167,56,139,251,79,69,199,48,6,141,72,193,105,236,62,78,199,143,181,130,46,5,244,148,122,28,62,81,152,244,78,148,240,107,179,151,34,80,91, +130,61,7,2,222,80,197,183,72,70,245,236,50,27,234,125,5,27,27,60,100,175,210,10,249,165,54,143,90,55,211,206,86,15,5,241,145,219,61,180,153,139,67,178,98,69,63,85,3,127,109,238,110,1,81,51,72,124,81,138,125,221,106,164,59,141,0,86,173,231,227,205,140,45,195,140,5,92,86,74,227,76,142,88,223,190,180,190,97,169,69,16,146,121,152,249,30,73,60,224,21,43,53,210,109,71,186,175,36,72,184,227,181,53,67,63,181,219,100,173,88,28,220,110,178,206,43,20,2,242,154,120,202,247,104,201,216,240,96,197,216,163,189,66,179,173,32,31,225,176,202,93,120,7,23,30,234,197,170,125,230,240,56,94,73,235,11,78,29,216,193,114,40,187,142,122,188,247,135,115,204,24,73,27,160,54,61,41,244,80,171,187,246,52,213,42,29,34,90,209,187,86,209,29,131,181,98,213,201,10,184,69,120,236,17,148,171,121,173,234,24,142,167,80,171,35,17,69,169,97,56,154,127,16,41,172,231,113,44,69,75,159,137,203,201,83,12,50,23,229,128,44,183,84,180,144, +60,79,156,101,152,113,148,166,18,52,58,40,161,115,152,3,116,246,48,159,86,72,162,254,117,187,111,83,70,253,24,254,77,239,238,38,39,167,204,221,110,71,167,168,50,246,119,117,178,41,118,187,179,171,53,206,238,225,238,20,212,135,57,60,107,179,171,35,110,160,175,123,247,234,242,217,134,182,221,5,71,71,39,146,69,178,217,211,193,116,150,18,142,212,228,136,94,99,26,66,2,224,250,2,15,241,128,191,178,67,149,22,80,191,194,67,245,218,19,49,167,112,12,93,139,43,29,38,194,87,253,150,149,182,225,118,193,142,99,54,71,110,240,58,197,78,129,40,5,128,228,246,14,176,117,109,16,106,226,17,140,100,22,251,107,204,253,222,40,82,178,243,71,224,137,145,204,154,156,64,101,34,32,93,121,16,250,109,154,98,175,25,238,181,148,30,31,27,25,164,40,186,18,31,140,183,48,237,116,226,91,158,31,206,209,10,229,195,58,4,186,185,163,66,15,67,6,178,69,150,164,212,38,231,128,205,165,115,108,9,154,186,112,3,200,23,10,37,16,1,53,63,200,180,162,241, +186,125,219,102,246,23,227,87,50,81,198,241,67,211,24,24,246,23,205,246,132,93,250,28,11,68,65,126,62,125,63,199,180,134,178,142,92,9,64,213,180,244,163,15,129,172,195,149,237,113,96,192,1,29,82,206,120,25,165,120,108,94,29,64,146,173,180,181,164,64,101,220,5,213,159,118,214,146,202,18,131,97,23,15,236,6,74,198,14,241,144,67,171,210,81,219,213,77,91,238,203,85,110,92,236,20,200,27,108,122,91,101,89,99,182,69,148,233,199,233,67,240,126,36,169,94,121,9,169,177,124,61,5,202,61,251,230,225,92,162,174,75,233,202,42,169,115,85,26,232,162,147,2,68,118,24,44,179,8,104,241,85,173,74,14,208,31,21,102,72,200,74,55,240,142,13,9,181,209,170,11,38,5,23,9,247,97,33,122,37,179,113,231,14,2,6,103,10,74,225,45,65,207,32,248,71,64,4,220,169,60,66,216,216,66,196,19,82,4,133,99,153,135,121,248,18,133,17,121,50,79,246,89,81,179,139,155,102,142,47,135,75,112,224,3,196,109,41,148,147,88,182,171,198,164,222, +177,67,183,26,102,75,80,99,39,173,93,123,80,108,64,163,0,184,151,116,79,77,18,136,53,165,127,17,120,102,225,99,47,173,100,149,253,5,110,60,252,179,191,104,81,171,81,193,19,199,243,176,48,199,147,156,54,141,201,84,80,166,216,102,111,249,125,101,255,244,64,224,84,134,45,181,224,213,124,42,185,161,1,81,9,31,210,251,45,61,42,90,108,53,225,85,137,91,97,0,151,155,183,112,62,136,69,182,96,65,182,152,202,74,74,196,3,79,117,142,229,184,192,4,66,3,32,128,212,161,124,254,155,75,79,62,203,98,0,3,158,95,217,250,93,5,192,178,21,144,152,151,227,70,245,110,155,195,149,147,106,113,164,156,119,93,142,165,214,41,185,100,73,169,96,37,129,161,131,42,249,163,220,24,87,24,9,179,246,105,234,123,172,96,187,224,90,241,101,87,192,173,88,241,200,37,165,60,94,219,179,176,116,64,180,77,197,140,237,193,118,245,154,213,30,177,182,132,249,208,80,251,100,103,89,169,92,193,81,229,32,9,161,165,98,107,89,48,170,223,36,42,230,129,88,201, +234,186,246,2,235,235,64,152,83,22,149,35,57,165,118,171,44,201,34,105,131,235,117,161,7,87,128,106,245,43,89,1,227,69,253,75,163,74,216,4,97,153,168,29,117,171,162,64,245,120,183,154,74,210,242,83,182,57,250,208,15,196,71,190,197,14,1,132,35,132,29,192,158,133,8,28,191,90,234,128,149,97,26,252,204,235,251,183,60,193,175,171,49,213,94,20,237,17,0,30,159,156,181,97,208,189,240,86,250,31,138,183,115,46,110,231,69,254,0,56,161,105,214,247,24,183,170,195,70,219,60,203,124,170,152,228,126,49,199,81,11,227,148,107,7,30,197,92,182,181,230,131,24,95,160,126,83,89,24,20,86,180,216,93,10,2,217,98,31,112,68,139,241,212,109,55,229,161,132,7,106,24,36,228,46,117,243,175,6,114,39,192,183,55,64,159,192,20,160,58,96,130,0,219,150,52,181,87,198,245,11,143,174,16,37,94,177,9,210,170,99,25,201,31,10,63,242,99,20,37,26,197,113,200,30,62,56,151,26,52,234,161,191,177,222,186,53,159,196,137,199,148,25,218,246,115, +196,247,39,217,97,158,16,64,68,239,108,234,96,220,226,68,24,114,209,118,228,183,189,149,144,212,70,62,97,89,41,122,156,177,237,64,162,45,239,186,92,93,41,51,93,237,49,72,157,247,200,10,39,230,90,176,228,81,174,158,139,34,128,87,179,196,199,61,58,89,75,123,255,157,244,20,224,52,118,27,142,146,245,168,4,19,8,235,186,228,86,87,54,152,21,171,28,43,75,195,228,233,109,230,251,155,172,136,39,146,200,119,150,197,93,143,141,246,38,113,99,14,217,227,238,129,211,108,70,74,166,71,154,134,213,133,47,167,197,151,66,120,47,127,188,122,243,11,8,149,191,108,23,130,236,172,220,230,214,242,251,58,192,4,33,169,251,110,140,12,74,39,149,36,22,58,192,170,229,54,37,3,161,73,175,71,251,42,186,101,121,107,76,142,5,107,120,242,111,58,192,64,170,58,67,226,39,22,17,136,29,70,40,144,210,216,227,188,30,98,79,134,84,14,201,163,59,201,190,213,212,34,79,13,145,40,57,10,95,40,242,242,249,154,171,121,98,37,35,74,124,38,111,56,58,222, +179,251,88,128,186,192,72,188,136,162,153,2,81,66,232,10,74,12,127,126,11,204,134,111,239,57,228,30,76,253,125,10,61,158,32,65,180,99,178,31,94,178,134,8,0,19,39,183,178,171,224,241,10,132,186,226,8,170,153,44,194,144,82,155,210,45,153,102,97,58,236,83,106,17,66,148,84,155,16,24,119,17,28,166,130,50,255,32,13,44,222,194,215,87,121,54,98,159,238,204,133,164,106,149,213,178,2,129,212,179,242,164,170,91,186,138,241,193,52,81,76,30,46,201,121,50,21,208,190,23,25,149,102,218,106,229,225,93,169,203,42,214,43,212,52,65,222,40,225,164,38,158,58,58,73,72,58,83,245,142,4,143,66,206,157,127,177,65,231,73,235,254,96,131,122,5,223,254,53,231,1,96,81,206,145,244,179,9,227,216,84,81,54,227,220,113,231,53,13,37,149,80,52,176,5,94,228,138,124,94,227,202,33,110,250,10,114,114,89,199,91,17,6,106,76,65,97,192,49,155,10,120,238,182,200,81,2,151,30,0,3,148,117,34,183,101,149,53,141,35,18,138,54,178,251,174, +189,51,248,216,3,137,195,26,192,242,72,243,50,163,34,128,206,98,116,148,70,129,86,190,125,249,227,132,206,233,101,179,148,8,240,124,143,138,35,7,236,231,37,184,108,202,47,26,171,201,198,129,254,85,131,170,152,128,122,2,145,124,204,73,189,226,170,198,88,141,78,201,84,174,70,168,229,92,254,227,228,200,214,239,123,158,22,140,176,155,180,135,53,22,84,8,97,165,9,147,70,243,102,85,0,116,76,168,195,187,210,77,51,44,96,174,33,89,4,117,146,247,57,56,42,147,160,34,225,50,37,187,136,168,77,1,90,202,7,121,0,59,226,113,97,22,11,90,84,241,147,2,62,237,37,87,226,193,205,38,178,22,111,22,187,137,209,212,234,223,117,216,143,3,104,23,223,160,18,84,137,174,118,160,81,227,92,62,178,114,108,73,230,20,209,229,11,145,82,169,23,134,49,244,203,202,248,87,138,40,64,11,196,244,224,36,162,16,204,242,20,155,107,209,24,228,213,207,213,88,4,120,65,151,12,67,170,162,207,121,222,215,115,40,145,63,210,81,254,54,42,63,165,157,142,21, +75,236,102,15,254,245,43,73,21,213,210,29,175,168,89,18,183,14,41,161,84,175,25,203,74,202,158,69,20,234,132,164,186,195,218,246,205,170,61,175,148,85,214,247,112,230,176,191,182,159,215,135,172,119,17,143,211,220,41,107,33,143,117,49,233,65,133,159,205,205,157,154,105,53,116,158,151,47,173,28,32,175,123,58,208,231,171,127,117,230,144,106,13,120,26,224,243,60,14,131,48,75,48,188,252,127,171,205,172,41,187,228,68,224,181,25,169,182,5,17,43,246,168,93,110,29,218,56,60,230,46,199,66,178,190,129,31,135,247,201,238,32,151,238,204,127,185,239,157,249,164,184,51,95,246,1,229,136,191,184,231,95,171,235,175,189,226,95,181,172,143,116,30,82,68,144,250,247,93,167,33,50,130,122,244,195,144,171,106,34,176,171,201,86,183,28,79,38,255,3,215,250,52,181, diff --git a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tpp b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tpp index e1e479f22..eebf553d8 100644 --- a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tpp +++ b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tpp @@ -346,7 +346,7 @@ ile]([@(0.0.255) const]_[@(0.0.255) char]_`*[*@3 path], [_^Upp`:`:Stream^ Stream [s2;%% [%-*@3 path] [%-*@3 in] .&] [s3;%% &] [s4; &] -[s5;:Upp`:`:SFtp`:`:LoadFile`(Upp`:`:Stream`&`,const char`*`): [@(0.0.255) void]_[* LoadF +[s5;:Upp`:`:SFtp`:`:LoadFile`(Upp`:`:Stream`&`,const char`*`): [@(0.0.255) bool]_[* LoadF ile]([_^Upp`:`:Stream^ Stream][@(0.0.255) `&]_[*@3 out], [@(0.0.255) const]_[@(0.0.255) cha r]_`*[*@3 path])&] [s2;%% [%-*@3 out] [%-*@3 path] .&] diff --git a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tppi b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tppi index 03e2aced0..925ec755a 100644 --- a/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tppi +++ b/uppsrc/Core/SSH/src.tpp/Upp_Ssh_SFtp_en-us.tppi @@ -12,11 +12,11 @@ COMPRESSED 62,37,32,84,197,234,196,99,143,73,253,20,168,228,155,222,35,245,83,61,51,127,153,14,93,220,122,181,129,191,96,58,26,44,66,176,45,230,152,184,150,79,217,128,222,220,69,155,86,37,240,6,132,94,197,252,215,129,247,138,114,24,67,150,225,93,220,111,1,184,153,207,97,101,247,45,124,161,104,85,128,173,13,107,144,75,104,166,10,120,3,90,127,43,132,109,9,241,200,157,206,108,250,13,83,28,108,48,213,39,177,170,6,220,17,113,106,165,2,78,199,99,176,95,44,90,45,234,48,231,63,240,125,47,117,181,16,119,234,178,80,54,226,1,157,77,199,92,65,68,22,151,244,82,193,53,197,171,8,219,147,96,231,26,95,176,225,28,29,5,56,233,101,7,144,185,174,32,253,104,249,38,169,87,135,108,254,144,89,2,221,87,25,45,95,27,245,197,41,116,213,88,95,175,178,226,36,252,5,208,190,94,223,150,87,106,103,109,160,175,211,129,14,131,53,197,76,188,191,243,122,176,23,138,135,150,131,254,21,214,125,111,166,146,148,81,180,106,95,115,234,140,221,194,209,14, 53,59,62,118,124,239,69,138,62,232,134,15,2,143,131,20,171,95,81,70,225,140,160,189,0,36,127,2,48,225,20,219,100,240,158,65,235,222,84,36,5,18,115,136,201,108,9,4,151,226,31,115,152,85,47,37,217,20,48,224,52,220,22,16,90,109,175,69,96,90,130,60,196,58,21,50,42,94,229,26,91,138,161,121,116,230,81,78,23,250,191,164,151,101,100,155,0,8,102,34,19,211,10,24,94,90,188,113,57,55,173,74,27,67,200,68,22,26,128,149,105,61,131,247,250,90,134,179,74,238,229,120,117,134,241,84,41,127,78,220,26,129,72,179,169,32,189,15,113,234,47,0,85,129,95,58,51,185,127,238,90,108,252,130,89,172,133,12,5,11,222,139,164,215,192,76,146,68,94,215,96,108,104,11,3,122,108,204,70,210,253,96,54,173,66,101,9,161,24,38,155,249,161,98,56,37,71,84,81,114,165,115,122,29,224,114,70,213,152,254,210,151,70,248,38,197,18,151,145,15,214,58,80,225,181,108,243,64,212,217,208,54,35,34,127,129,109,170,208,179,0,229,53,173,49,31, 153,117,172,177,122,168,94,211,26,99,88,103,121,128,77,237,16,55,106,142,69,230,95,217,184,127,84,243,21,173,14,101,98,11,86,22,206,50,130,93,169,130,162,30,5,65,205,245,228,93,168,254,150,66,135,225,217,194,91,250,83,12,247,173,39,119,162,242,91,74,157,8,13,22,149,220,29,125,165,254,154,130,199,234,190,169,220,130,143,130,2,95,178,217,154,253,57,170,249,150,194,202,196,228,25,240,82,80,224,95,108,128,103,61,137,99,85,223,82,228,33,178,33,179,171,77,187,140,67,187,150,85,214,119,225,75,4,222,18,134,209,196,244,204,145,79,189,117,160,128,153,208,145,235,36,142,229,44,159,56,34,170,84,137,83,54,206,124,58,4,142,96,208,21,217,35,100,230,185,56,184,130,137,90,115,196,0,157,49,158,72,10,142,7,238,144,83,220,164,179,160,128,47,146,230,241,176,86,112,10,48,56,217,69,60,119,238,51,39,126,22,39,247,188,223,141,106,64,157,248,227,177,211,126,217,144,164,6,36,159,92,102,13,182,7,245,224,48,87,58,78,155,69,31,177,141, -254,195,96,91,90,132,239,45,188,142,157,0,195,101,225,195,224,95,15,167,159,110,6,15,231,7,95,34,203,89,204,252,10,44,7,168,197,87,141,125,82,212,51,206,211,241,144,93,102,5,42,145,135,156,111,8,75,208,161,214,70,234,245,208,185,54,159,40,250,129,192,133,96,111,68,60,74,58,20,69,37,221,143,196,31,1,249,72,236,138,178,71,177,39,166,64,36,125,141,250,69,148,41,10,202,153,107,90,41,160,36,3,154,73,198,68,114,129,170,182,6,10,89,220,111,168,197,136,87,106,78,95,77,127,113,76,160,29,129,9,197,227,239,105,202,98,78,158,170,160,68,121,69,45,74,90,95,210,220,82,231,75,106,172,148,16,120,44,58,183,139,23,209,50,18,90,165,241,204,67,221,25,94,190,132,206,139,57,251,132,248,219,43,118,81,11,162,182,181,66,156,220,237,247,34,2,189,198,182,251,95,37,89,177,0,238,27,203,153,19,240,117,199,99,158,200,64,56,114,159,29,76,109,202,74,102,90,76,188,93,28,225,92,47,107,23,11,185,89,145,254,20,148,146,12,193, -140,204,9,207,12,2,13,238,155,158,79,196,89,40,249,213,4,250,158,143,243,79,75,113,188,131,97,25,145,211,179,64,42,56,146,40,174,163,112,232,163,204,166,144,7,242,85,162,21,199,19,233,204,33,99,140,133,133,4,11,79,106,211,251,118,222,0,180,121,151,46,111,196,197,120,170,58,65,180,164,77,173,52,41,210,55,57,225,162,241,88,222,179,35,243,223,212,139,197,112,166,224,226,212,33,142,235,12,222,139,133,28,22,194,132,220,186,202,167,19,6,224,170,3,179,225,77,37,129,21,46,164,70,3,72,87,162,70,152,251,188,217,228,182,196,48,80,108,114,91,229,48,16,204,0,114,164,89,24,201,11,135,51,22,228,41,198,80,5,179,208,200,68,55,19,44,235,162,133,191,159,176,85,93,197,80,13,94,171,7,205,191,15,82,69,198,204,219,153,244,110,177,25,49,140,57,5,79,244,44,12,152,117,240,62,232,122,76,219,126,89,235,226,138,213,3,43,233,23,31,88,231,179,74,135,213,128,92,145,157,144,220,64,203,33,42,215,155,99,120,157,88,20,188,179,157, -123,177,146,248,12,205,52,186,214,71,58,167,109,121,60,44,110,116,97,145,123,18,125,79,55,27,117,179,75,60,21,57,98,112,135,252,194,28,53,248,97,35,128,8,64,237,140,18,23,231,40,2,201,129,68,75,68,157,86,95,21,22,79,206,9,161,80,116,150,239,13,11,211,86,186,133,238,16,139,82,81,224,73,129,123,196,206,221,39,138,103,253,241,225,79,75,20,126,126,80,151,140,37,238,24,115,192,0,193,38,39,212,134,225,55,186,161,139,197,34,117,156,77,103,54,27,191,200,155,158,76,143,171,99,97,41,183,136,145,26,62,140,221,3,198,240,151,196,230,4,252,142,55,130,109,169,68,123,217,61,67,37,9,6,118,162,4,36,201,208,202,235,192,86,110,106,133,112,195,236,225,147,56,31,28,191,155,104,229,140,236,147,56,1,92,60,26,10,197,73,13,189,201,214,138,116,179,188,228,168,117,228,186,101,86,170,88,105,89,61,80,182,132,76,115,188,146,131,89,4,116,224,142,152,56,111,47,156,99,65,225,82,243,119,74,137,118,82,66,180,147,82,162,61,138,251, -65,222,82,54,153,165,84,80,56,153,141,84,88,186,32,181,42,69,144,224,176,103,182,68,235,10,20,102,180,48,154,174,181,21,217,67,80,165,204,253,94,169,137,64,27,116,187,53,165,149,25,19,165,164,13,170,148,149,118,33,181,228,175,147,83,165,17,47,103,170,22,200,206,141,101,199,103,76,98,171,108,76,46,32,93,15,214,94,181,140,36,29,117,47,156,186,26,32,204,216,148,115,6,0,72,28,237,78,199,182,52,118,33,59,223,51,118,222,214,205,121,142,4,253,158,99,69,7,242,74,80,241,20,198,205,192,136,130,147,89,153,48,148,150,245,148,203,8,115,170,156,225,250,66,150,42,106,249,106,83,52,195,210,217,66,130,75,25,94,195,108,149,124,134,195,162,21,114,189,152,161,82,134,117,149,112,146,207,184,42,88,33,219,105,41,38,165,88,151,59,215,5,88,151,5,43,100,125,229,246,121,25,25,68,86,68,190,4,162,88,133,252,103,102,65,148,225,29,115,88,242,89,199,82,21,114,190,148,178,82,202,98,68,114,79,1,131,17,229,170,52,245,120,86,81,25, -142,241,240,40,174,192,242,121,14,74,86,198,181,167,8,174,193,181,184,214,171,24,219,97,209,202,248,198,235,189,214,228,27,49,188,112,236,2,110,60,40,89,13,215,184,28,69,184,7,239,93,160,169,70,213,53,248,143,110,231,203,151,32,42,91,25,242,52,36,89,154,247,27,87,133,22,11,46,167,131,242,37,102,189,241,83,70,25,71,23,197,20,64,20,242,77,43,220,157,184,152,251,179,121,180,173,160,206,246,195,55,206,166,204,54,61,156,253,220,58,236,27,177,113,102,52,157,194,60,121,240,79,142,27,101,80,109,13,36,190,76,237,226,48,64,225,202,49,112,200,183,169,189,176,57,67,3,60,194,11,243,192,171,193,175,64,0,11,251,230,99,61,90,238,138,208,197,138,35,114,92,156,115,246,233,55,191,155,136,143,53,245,70,163,219,234,236,182,127,194,136,210,207,173,102,179,103,127,48,118,61,248,231,127,208,155,67,248,183,175,191,151,1,196,127,201,8,34,222,200,220,197,9,144,140,152,117,187,80,161,5,21,90,80,161,5,21,90,251,134,40,78,228,171,36,173, -154,222,238,108,133,212,14,194,137,43,148,13,159,94,186,156,51,188,239,242,55,12,137,214,248,86,118,27,146,165,67,226,191,192,144,23,208,192,103,135,2,133,216,101,246,245,224,8,120,93,13,13,117,49,164,213,229,192,60,120,175,70,230,122,52,209,136,61,19,119,133,246,227,60,98,163,115,102,45,180,121,16,104,44,204,252,19,57,116,142,12,4,200,16,239,18,153,199,106,200,136,116,168,10,232,76,131,181,124,146,214,89,250,122,157,57,228,127,224,79,247,252,28,195,168,71,228,227,71,248,218,189,190,86,157,122,137,186,25,172,157,83,168,199,215,199,101,233,198,110,137,93,32,237,61,127,147,127,23,226,220,5,19,19,215,136,151,199,125,75,248,189,166,130,229,97,56,55,182,190,13,174,186,31,197,66,223,101,157,88,212,80,246,62,98,188,245,170,183,170,195,27,68,130,13,229,232,142,21,225,40,146,54,152,56,226,81,108,11,184,140,176,171,143,70,87,15,195,171,29,132,6,84,125,51,121,97,86,14,154,114,72,72,158,127,222,112,107,36,254,191,111,172,82,143,184, -147,8,190,162,51,182,232,56,57,15,82,15,227,176,252,38,36,186,39,242,179,255,83,161,35,189,63,171,179,42,130,169,16,167,36,179,114,5,32,201,6,103,158,17,167,133,221,30,66,109,241,255,232,36,230,125,2,167,126,255,255,0,205,189,118,47, +254,195,96,91,90,132,239,45,188,142,157,0,195,101,225,195,224,95,15,167,159,110,6,15,231,7,95,34,203,89,204,252,10,44,7,168,197,87,141,125,82,212,51,206,211,241,144,93,102,5,42,145,135,156,111,8,75,208,161,214,70,234,245,208,185,54,159,40,250,129,192,133,96,111,68,60,74,58,20,69,37,221,143,196,31,1,249,72,236,138,178,71,177,39,166,64,36,125,141,250,69,148,41,10,202,153,107,90,41,160,36,3,154,73,198,68,114,129,170,182,6,10,89,220,111,168,197,136,87,106,78,95,77,127,113,76,160,29,129,9,197,227,239,105,202,98,78,158,170,160,68,121,69,45,74,90,95,210,92,106,58,72,164,177,82,66,224,177,232,220,46,94,68,203,72,104,149,198,51,15,117,103,120,249,18,58,47,230,236,19,226,111,175,216,69,45,136,218,214,10,113,114,183,223,139,8,244,26,219,238,127,149,100,197,2,184,111,44,103,78,192,215,29,143,121,34,3,225,200,125,118,48,181,41,43,153,105,49,241,118,113,132,115,189,172,93,44,228,102,69,250,83,80,74,50,4, +51,50,39,60,51,8,52,184,111,122,62,17,103,161,228,87,19,232,123,62,206,63,45,197,241,14,134,101,68,78,207,2,169,224,72,162,184,142,194,161,143,50,155,66,30,200,87,137,86,28,79,164,51,135,140,49,22,22,18,44,60,169,77,239,219,121,3,208,230,93,186,188,17,23,227,169,234,4,209,146,54,181,210,164,72,223,228,132,139,198,99,121,207,142,204,127,83,47,22,195,153,130,139,83,135,56,174,51,120,47,22,114,88,8,19,114,235,42,159,78,24,128,171,14,204,134,55,149,4,86,184,144,26,13,32,93,137,26,97,238,243,102,147,219,18,195,64,177,201,109,149,195,64,48,3,200,145,102,97,36,47,28,206,88,144,167,24,67,21,204,66,35,19,221,76,176,172,139,22,254,126,194,86,117,21,67,53,120,173,30,52,255,62,72,21,25,51,111,103,210,187,197,102,196,48,230,20,60,209,179,48,96,214,193,251,160,235,49,109,251,101,173,139,43,86,15,172,164,95,124,96,157,207,42,29,86,3,114,69,118,66,114,3,45,135,168,92,111,142,225,117,98,81,240,206,118, +238,197,74,226,51,52,211,232,90,31,233,156,182,229,241,176,184,209,133,69,238,73,244,61,221,108,212,205,46,241,84,228,136,193,29,242,11,115,212,224,135,141,0,34,0,181,51,74,92,156,163,8,36,7,18,45,17,117,90,125,85,88,60,57,39,132,66,209,89,190,55,44,76,91,233,22,186,67,44,74,69,129,39,5,238,17,59,119,159,40,158,245,199,135,63,45,81,248,249,65,93,50,150,184,99,204,1,3,4,155,156,80,27,134,223,232,134,46,22,139,212,113,54,157,217,108,252,34,111,122,50,61,174,142,133,165,220,34,70,106,248,48,118,15,24,195,95,18,155,19,240,59,222,8,182,165,18,237,101,247,12,149,36,24,216,137,18,144,36,67,43,175,3,91,185,169,21,194,13,179,135,79,226,124,112,252,110,162,149,51,178,79,226,4,112,241,104,40,20,39,53,244,38,91,43,210,205,242,146,163,214,145,235,150,89,169,98,165,101,245,64,217,18,50,205,241,74,14,102,17,208,129,59,98,226,188,189,112,142,5,133,75,205,223,41,37,218,73,9,209,78,74,137,246,40,238, +7,121,75,217,100,150,82,65,225,100,54,82,97,233,130,212,170,20,65,130,195,158,217,18,173,43,80,152,209,194,104,186,214,86,100,15,65,149,50,247,123,165,38,2,109,208,237,214,148,86,102,76,148,146,54,168,82,86,218,133,212,146,191,78,78,149,70,188,156,169,90,32,59,55,150,29,159,49,137,173,178,49,185,128,116,61,88,123,213,50,146,116,212,189,112,234,106,128,48,99,83,206,25,0,32,113,180,59,29,219,210,216,133,236,124,207,216,121,91,55,231,57,18,244,123,142,21,29,200,43,65,197,83,24,55,3,35,10,78,102,101,194,80,90,214,83,46,35,204,169,114,134,235,11,89,170,168,229,171,77,209,12,75,103,11,9,46,101,120,13,179,85,242,25,14,139,86,200,245,98,134,74,25,214,85,194,73,62,227,170,96,133,108,167,165,152,148,98,93,238,92,23,96,93,22,172,144,245,149,219,231,101,100,16,89,17,249,18,136,98,21,242,159,153,5,81,134,119,204,97,201,103,29,75,85,200,249,82,202,74,41,139,17,201,61,5,12,70,148,171,210,212,227,89,69,101, +56,198,195,163,184,2,203,231,57,40,89,25,215,158,34,184,6,215,226,90,175,98,108,135,69,43,227,27,175,247,90,147,111,196,240,194,177,11,184,241,160,100,53,92,227,114,20,225,30,188,119,129,166,26,85,215,224,63,186,157,47,95,130,168,108,101,200,211,144,100,105,222,111,92,21,90,44,184,156,14,202,151,152,245,198,79,25,101,28,93,20,83,0,81,200,55,173,112,119,226,98,238,207,230,209,182,130,58,219,15,223,56,155,50,219,244,112,246,115,235,176,111,196,198,153,209,116,10,243,228,193,63,57,110,148,65,181,53,144,248,50,181,139,195,0,133,43,199,192,33,223,166,246,194,230,12,13,240,8,47,204,3,175,6,191,2,1,44,236,155,143,245,104,185,43,66,23,43,142,200,113,113,206,217,167,223,252,110,34,62,214,212,27,141,110,171,179,219,254,9,35,74,63,183,154,205,158,253,193,216,245,224,159,255,65,111,14,225,223,190,254,94,6,16,255,37,35,136,120,35,115,23,39,64,50,98,214,237,66,133,22,84,104,65,133,22,84,104,237,27,162,56,145,175,146,180, +106,122,187,179,21,82,59,8,39,174,80,54,124,122,233,114,206,240,190,203,223,48,36,90,227,91,217,109,72,150,14,137,255,2,67,94,64,3,159,29,10,20,98,151,217,215,131,35,224,117,53,52,212,197,144,86,151,3,243,224,189,26,153,235,209,68,35,246,76,220,21,218,143,243,136,141,206,153,181,208,230,65,160,177,48,243,79,228,208,57,50,16,32,67,188,75,100,30,171,33,35,210,161,42,160,51,13,214,242,73,90,103,233,235,117,230,144,255,129,63,221,243,115,12,163,30,145,143,31,225,107,247,250,90,117,234,37,234,102,176,118,78,161,30,95,31,151,165,27,187,37,118,129,180,247,252,77,254,93,136,115,23,76,76,92,35,94,30,247,45,225,247,154,10,150,135,225,220,216,250,54,184,234,126,20,11,125,151,117,98,81,67,217,251,136,241,214,171,222,170,14,111,16,9,54,148,163,59,86,132,163,72,218,96,226,136,71,177,45,224,50,194,174,62,26,93,61,12,175,118,16,26,80,245,205,228,133,89,57,104,202,33,33,121,254,121,195,173,145,248,255,190,177,74,61,226, +78,34,248,138,206,216,162,227,228,60,72,61,140,195,242,155,144,232,158,200,207,254,79,133,142,244,254,172,206,170,8,166,66,156,146,204,202,21,128,36,27,156,121,70,156,22,118,123,8,181,197,255,163,147,152,247,9,156,250,253,255,3,226,40,118,41,