From bcea21cf965a25ae7823a5b323be243b62c46847 Mon Sep 17 00:00:00 2001 From: Brad Arant Date: Sun, 29 Nov 2020 13:57:06 -0800 Subject: [PATCH] Got it compiling and somewhat working, except post. --- .vscode/launch.json | 31 ++++++++++++ .vscode/tasks.json | 84 ++++++++++++++++++++++++++++++++ Makefile | 91 +++++++++++++++++++++++++++++++++++ TCPServer.cpp | 54 ++++++++++----------- TCPServer.h | 86 ++++++++++++++++----------------- TCPSession.cpp | 61 +++++++++++------------ TCPSession.h | 13 ++--- TCPSocket.cpp | 18 +++---- TCPSocket.h | 24 ++++----- output/main | Bin 0 -> 106552 bytes src/main.cpp | 6 +++ src/workspace.code-workspace | 38 +++++++++++++++ 12 files changed, 373 insertions(+), 133 deletions(-) create mode 100644 .vscode/launch.json create mode 100644 .vscode/tasks.json create mode 100644 Makefile create mode 100755 output/main create mode 100644 src/main.cpp create mode 100644 src/workspace.code-workspace diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..1bde925 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,31 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug", + "type": "cppdbg", + "request": "launch", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "linux": { + "MIMode": "gdb", + "miDebuggerPath": "gdb", + "program": "${workspaceFolder}/output/main" + }, + "osx": { + "MIMode": "lldb", + "miDebuggerPath": "lldb-mi", + "program": "${workspaceFolder}/output/main" + }, + "windows": { + "MIMode": "gdb", + "miDebuggerPath": "gdb.exe", + "program": "${workspaceFolder}/output/main.exe" + }, + "preLaunchTask": "build" + } + ] +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..a367b6d --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,84 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "type": "shell", + "group": { + "kind": "build", + "isDefault": true + }, + "windows": { + "command": "powershell", + "args": [ + "-c", + "mingw32-make" + ] + }, + "linux": { + "command": "bash", + "args": [ + "-c", + "make" + ] + }, + "osx": { + "command": "bash", + "args": [ + "-c", + "make" + ] + } + }, + { + "label": "build & run", + "type": "shell", + "windows": { + "command": "powershell", + "args": [ + "-c", + "'mingw32-make run'" + ] + }, + "linux": { + "command": "bash", + "args": [ + "-c", + "'make run'" + ] + }, + "osx": { + "command": "bash", + "args": [ + "-c", + "'make run'" + ] + } + }, + { + "label": "clean", + "type": "shell", + "windows": { + "command": "powershell", + "args": [ + "-c", + "'mingw32-make clean'" + ] + }, + "linux": { + "command": "bash", + "args": [ + "-c", + "'make clean'" + ] + }, + "osx": { + "command": "bash", + "args": [ + "-c", + "'make clean'" + ] + } + } + ] +} \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0811f9a --- /dev/null +++ b/Makefile @@ -0,0 +1,91 @@ +# +# 'make' build executable file 'main' +# 'make clean' removes all .o and executable files +# + +# define the Cpp compiler to use +CXX = g++ + +# define any compile-time flags +CXXFLAGS := -std=c++17 -Wall -Wextra -g + +# define library paths in addition to /usr/lib +# if I wanted to include libraries not in /usr/lib I'd specify +# their path using -Lpath, something like: +LFLAGS = + +# define output directory +OUTPUT := output + +# define source directory +SRC := src + +# define include directory +INCLUDE := include + +# define lib directory +LIB := lib + +ifeq ($(OS),Windows_NT) +MAIN := main.exe +SOURCEDIRS := $(SRC) +INCLUDEDIRS := $(INCLUDE) +LIBDIRS := $(LIB) +FIXPATH = $(subst /,\,$1) +RM := del /q /f +MD := mkdir +else +MAIN := main +SOURCEDIRS := $(shell find $(SRC) -type d) +INCLUDEDIRS := $(shell find $(INCLUDE) -type d) +LIBDIRS := $(shell find $(LIB) -type d) +FIXPATH = $1 +RM = rm -f +MD := mkdir -p +endif + +# define any directories containing header files other than /usr/include +INCLUDES := $(patsubst %,-I%, $(INCLUDEDIRS:%/=%)) + +# define the C libs +LIBS := $(patsubst %,-L%, $(LIBDIRS:%/=%)) + +# define the C source files +SOURCES := $(wildcard $(patsubst %,%/*.cpp, $(SOURCEDIRS))) + +# define the C object files +OBJECTS := $(SOURCES:.cpp=.o) + +# +# The following part of the makefile is generic; it can be used to +# build any executable just by changing the definitions above and by +# deleting dependencies appended to the file from 'make depend' +# + +OUTPUTMAIN := $(call FIXPATH,$(OUTPUT)/$(MAIN)) + +all: $(OUTPUT) $(MAIN) + @echo Executing 'all' complete! + +$(OUTPUT): + $(MD) $(OUTPUT) + +$(MAIN): $(OBJECTS) + $(CXX) $(CXXFLAGS) $(INCLUDES) -o $(OUTPUTMAIN) $(OBJECTS) $(LFLAGS) $(LIBS) + +# this is a suffix replacement rule for building .o's from .c's +# it uses automatic variables $<: the name of the prerequisite of +# the rule(a .c file) and $@: the name of the target of the rule (a .o file) +# (see the gnu make manual section about automatic variables) +.cpp.o: + $(CXX) $(CXXFLAGS) $(INCLUDES) -c $< -o $@ + +.PHONY: clean +clean: + $(RM) $(OUTPUTMAIN) + $(RM) $(call FIXPATH,$(OBJECTS)) + @echo Cleanup complete! + +run: all + ./$(OUTPUTMAIN) + @echo Executing 'run: all' complete! \ No newline at end of file diff --git a/TCPServer.cpp b/TCPServer.cpp index 1164e46..a4c7668 100644 --- a/TCPServer.cpp +++ b/TCPServer.cpp @@ -6,35 +6,33 @@ namespace core { - TCPServer::TCPServer(EPoll &ePoll, IPAddress address, std::string text) - : TCPSocket(ePoll, text) { + TCPServer::TCPServer(EPoll &ePoll, IPAddress address, std::string text) + : TCPSocket(ePoll, text) { setDescriptor(socket(AF_INET, SOCK_STREAM, 0)); int yes = 1; setsockopt(getDescriptor(), SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)); - if(bind(getDescriptor(), address.getPointer(), address.addressLength) < 0) + if(bind(getDescriptor(), address.getPointer(), address.addressLength) < 0) throw coreutils::Exception("Error on bind to socket: " + std::to_string(errno)); - if(listen(getDescriptor(), 20) < 0) + if(listen(getDescriptor(), 20) < 0) throw coreutils::Exception("Error on listen to socket"); } TCPServer::~TCPServer() { - coreutils::Log(coreutils::LOG_DEBUG_2) << "Closing server socket " << getDescriptor() << "."; + coreutils::Log(coreutils::LOG_DEBUG_2) << "Closing server socket " << getDescriptor() << "."; close(getDescriptor()); } - + void TCPServer::onDataReceived(std::string data) { - coreutils::Log(coreutils::LOG_DEBUG_2) << "entering TCPServer::onDataReceived socket " << getDescriptor() << "."; lock.lock(); TCPSession *session = accept(); - if(session) - sessions.push_back(session); + if(session) + sessions.push_back(session); lock.unlock(); - coreutils::Log(coreutils::LOG_DEBUG_2) << "Leaving TCPServer::onDataReceived socket " << getDescriptor() << "."; } - - TCPSession * TCPServer::accept() { - TCPSession *session = getSocketAccept(ePoll); - session->setDescriptor(::accept(getDescriptor(), (struct sockaddr *)&session->ipAddress.addr, &session->ipAddress.addressLength)); + + TCPSession * TCPServer::accept() { + TCPSession *session = getSocketAccept(ePoll); + session->setDescriptor(::accept(getDescriptor(), (struct sockaddr *)&session->ipAddress.addr, &session->ipAddress.addressLength)); // if(blackList && blackList->contains(session->ipAddress.getClientAddress())) { // session->shutdown(); // Log(LOG_WARN) << "Client at IP address " << session->ipAddress.getClientAddress() << " is blacklisted and was denied a connection."; @@ -48,36 +46,36 @@ namespace core { coreutils::Log(coreutils::LOG_DEBUG_2) << "Session started on socket " << session->getDescriptor() << "."; return session; } - - void TCPServer::removeFromSessionList(TCPSession *session) { + + void TCPServer::removeFromSessionList(TCPSession *session) { std::vector::iterator cursor; for(cursor = sessions.begin(); cursor < sessions.end(); ++cursor) if(*cursor == session) sessions.erase(cursor); } - - void TCPServer::sessionErrorHandler(std::string errorString, std::stringstream &out) { + + void TCPServer::sessionErrorHandler(std::string errorString, std::stringstream &out) { throw coreutils::Exception(errorString); - } - + } + TCPSession * TCPServer::getSocketAccept(EPoll &ePoll) { return new TCPSession(ePoll, *this); } - - void TCPServer::output(TCPSession *session) { + + void TCPServer::output(TCPSession *session) { std::stringstream out; - out << "|" << session->ipAddress.getClientAddressAndPort(); + out << "|" << session->ipAddress.getClientAddressAndPort(); session->send(); } - - int TCPServer::processCommand(std::string command, TCPSession *session, std::stringstream &data) { - int sequence = 0; + + int TCPServer::processCommand(std::string command, TCPSession *session, std::stringstream &data) { + int sequence = 0; for(auto *sessionx : sessions) { data << "|" << ++sequence; - sessionx->output(data); + sessionx->output(data); data << "|" << std::endl; } return 1; } - + } diff --git a/TCPServer.h b/TCPServer.h index f4f951e..0a7360d 100644 --- a/TCPServer.h +++ b/TCPServer.h @@ -8,23 +8,23 @@ #include "CommandList.h" namespace core { - + /// /// TCPServer /// /// Manage a socket connection as a TCP server type. Connections to the socket are processed through - /// the accept functionality. + /// the accept functionality. /// - /// A list of connections is maintained in a vector object. + /// A list of connections is maintained in a vector object. /// /// This object extends the BMACommand object as well so it can be added to a Console object and /// process commands to display status information. /// - + class TCPServer : public TCPSocket, public Command { - + public: - + /// /// The constructor for the BMATCPSocket object. /// @@ -34,90 +34,90 @@ namespace core { /// @param commandName the name of the command used to invoke the status display for this object. /// @return the instance of the BMATCPServerSocket. /// - + TCPServer(EPoll &ePoll, IPAddress address, std::string text = ""); - + /// /// The destructor for this object. /// - + ~TCPServer(); - - /// - /// If not NULL the blacklist object can be assigned to this server socket and the server - /// IP addresses connecting to the server attempting to accept a socket are contained in - /// this list then the connection is rejected and no accept is granted. - /// - - IPAddressList *blackList; /// /// If not NULL the blacklist object can be assigned to this server socket and the server - /// IP addresses connecting to the server attempting to accept a socket are contained in - /// this list then the connection is rejected and no accept is granted. + /// IP addresses connecting to the server attempting to accept a socket are contained in + /// this list then the connection is rejected and no accept is granted. /// - + + IPAddressList *blackList; + + /// + /// If not NULL the blacklist object can be assigned to this server socket and the server + /// IP addresses connecting to the server attempting to accept a socket are contained in + /// this list then the connection is rejected and no accept is granted. + /// + IPAddressList *whiteList; void removeFromSessionList(TCPSession *session); - virtual void sessionErrorHandler(std::string errorString, std::stringstream &out); - + virtual void sessionErrorHandler(std::string errorString, std::stringstream &out); + /// /// getSocketAccept is designed to allow a polymorphic extension of this object to /// return a type of object that extends the definition of the server socket. /// Returning the appropriate session object that extends from Session provides - /// the mechanism where the server can select the protocol dialog for the desired + /// the mechanism where the server can select the protocol dialog for the desired /// service. - /// - + /// + virtual TCPSession * getSocketAccept(EPoll &epoll); - + void output(TCPSession *session); /// sessions; - + /// - /// The commands object is a CommandList and is used to store Command objects to be + /// The commands object is a CommandList and is used to store Command objects to be /// parsed and run as data comes into the session. /// - + CommandList commands; - + protected: - + /// /// Override the virtual dataReceived since for the server these /// are requests to accept the new connection socket. - /// No data is to be read or written when this method is called. It is the response to - /// the fact that a new connection is coming into the system + /// No data is to be read or written when this method is called. It is the response to + /// the fact that a new connection is coming into the system /// /// @param data the pointer to the buffer containing the received data. /// @param length the length of the associated data buffer. /// - - void onDataReceived(std::string data) override; - + + void onDataReceived(std::string data) override; + /// /// This method is called when the Command associated with this object is requested - /// because a user has typed in the associated command name on a command entry line. + /// because a user has typed in the associated command name on a command entry line. /// /// @param the session object to write the output to. /// - + int processCommand(std::string command, TCPSession *session, std::stringstream &data) override; - + private: TCPSession * accept(); std::mutex lock; - + }; - + } #endif diff --git a/TCPSession.cpp b/TCPSession.cpp index 5ea0060..fa6adf6 100644 --- a/TCPSession.cpp +++ b/TCPSession.cpp @@ -33,46 +33,41 @@ namespace core { void TCPSession::onDataReceived(char *data, int len) { if(len > 0) { - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize + len); - memcpy(lineBuffer + lineBufferSize, data, len); - lineBufferSize += len; - while(lineBufferSize > 0) { - switch(mode) { - case LINE: - lineLength = strcspn(lineBuffer, "\r\n"); - if(lineLength == lineBufferSize) - break; - onLineReceived(std::string(lineBuffer, lineLength)); - if(lineBuffer[lineLength] == '\r') - ++lineLength; - if(lineBuffer[lineLength] == '\n') - ++lineLength; - lineBufferSize -= lineLength; - if(lineBufferSize > 0) - memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize); - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); - break; - case BLOCK: - if(lineBufferSize >= blockLength) { - onBlockReceived(std::string(lineBuffer, blockLength)); - lineBufferSize -= blockLength; - if(lineBufferSize > 0) - memmove(lineBuffer, lineBuffer + blockLength, lineBufferSize); - lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); - } - break; - } - } + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize + len); + memcpy(lineBuffer + lineBufferSize, data, len); + lineBufferSize += len; + while(lineBufferSize > 0) { + if(blockSize == 0) { + lineLength = strcspn(lineBuffer, "\r\n"); + if(lineLength == lineBufferSize) + break; + onLineReceived(std::string(lineBuffer, lineLength)); + if(lineBuffer[lineLength] == '\r') + ++lineLength; + if(lineBuffer[lineLength] == '\n') + ++lineLength; + lineBufferSize -= lineLength; + if(lineBufferSize > 0) + memmove(lineBuffer, lineBuffer + lineLength, lineBufferSize); + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); + } else { + if(lineBufferSize >= blockLength) { + onBlockReceived(std::string(lineBuffer, blockLength)); + lineBufferSize -= blockLength; + if(lineBufferSize > 0) + memmove(lineBuffer, lineBuffer + blockLength, lineBufferSize); + lineBuffer = (char *)realloc(lineBuffer, lineBufferSize); + } + } + } } } - void TCPSession::setMode(core::Mode mode, int blockSize) { - this->mode = mode; + void TCPSession::setBlockSize(int blockSize) { this->blockSize = blockSize; } void TCPSession::onLineReceived(std::string line) { - coreutils::Log(coreutils::LOG_DEBUG_3) << "[" << line << "]"; protocol(line); send(); if(term) diff --git a/TCPSession.h b/TCPSession.h index 6fb4e98..53fd52c 100644 --- a/TCPSession.h +++ b/TCPSession.h @@ -7,7 +7,6 @@ namespace core { class Command; - enum Mode {LINE, BLOCK, PACKET}; class TCPServer; /// @@ -137,13 +136,12 @@ namespace core { virtual void protocol(std::string data); /// - /// Use the setMode method to set the receiving mode for the data on this socket. - /// Data can be received in LINE mode, which will receive data from the socket one - /// line at a time, or BLOCK mode where a certain specified data block is received - /// before calling the onBlockReceived method. + /// Use setBlockSize to set the amount of data that should be read at once from the + /// session data buffer. + /// If this value is set to 0 then the data will be retrieved /// - void setMode(core::Mode mode, int size = 0); + void setBlockSize(int size = 0); private: char *lineBuffer = NULL; @@ -152,8 +150,7 @@ namespace core { int blockLength = 0; std::mutex mtx; bool term = false; - core::Mode mode = LINE; - int blockSize; + int blockSize = 0; }; diff --git a/TCPSocket.cpp b/TCPSocket.cpp index 3ac3606..efd4754 100644 --- a/TCPSocket.cpp +++ b/TCPSocket.cpp @@ -4,23 +4,23 @@ #include "Exception.h" namespace core { - + TCPSocket::TCPSocket(EPoll &ePoll) : Socket(ePoll) {} TCPSocket::TCPSocket(EPoll &ePoll, std::string text) : Socket(ePoll, text) {} - + TCPSocket::~TCPSocket() {} - + void TCPSocket::connect(IPAddress &address) { setDescriptor(socket(AF_INET, SOCK_STREAM, 0)); - if(::connect(getDescriptor(), (struct sockaddr *)&address.addr, address.addressLength) == -1) - throw coreutils::Exception("Error on connect to TCP socket."); - + if(::connect(getDescriptor(), (struct sockaddr *)&address.addr, address.addressLength) == -1) + throw coreutils::Exception("Error on connect to TCP socket."); + } - + void TCPSocket::output(std::stringstream &out) { - out << "|" << ipAddress.getClientAddressAndPort(); + out << "|" << ipAddress.getClientAddressAndPort(); } - + } diff --git a/TCPSocket.h b/TCPSocket.h index a5edfc7..fd888db 100644 --- a/TCPSocket.h +++ b/TCPSocket.h @@ -9,12 +9,12 @@ namespace core { /// /// TCPSocket - /// + /// /// Provides a network TCP socket. - /// + /// /// For accessing TCP network functions use this object. The connection oriented nature of TCP - /// provides a single client persistent connection with data error correction and a durable - /// synchronous data connection. + /// provides a single client persistent connection with data error correction and a durable + /// synchronous data connection. /// class TCPSocket : public Socket { @@ -24,20 +24,20 @@ namespace core { TCPSocket(EPoll &ePoll); TCPSocket(EPoll &ePoll, std::string text); ~TCPSocket(); - + void connect(IPAddress &address); - + IPAddress ipAddress; - + /// - /// The output method is called by a socket session (BMASession) and - /// will output the detail information for the client socket. When extending - /// BMATCPSocket or BMASession you can override the method to add attributes - /// to the list. + /// The output method is called by a socket session (TCPSession) and + /// will output the detail information for the client socket. When extending + /// BMATCPSocket or BMASession you can override the method to add attributes + /// to the list. /// virtual void output(std::stringstream &out); - + }; } diff --git a/output/main b/output/main new file mode 100755 index 0000000000000000000000000000000000000000..99f2acbf1cf5fb9e8cbdb9d0c842c9faa7beb4f6 GIT binary patch literal 106552 zcmeFacYIXU_C9>hOeSZNlMDk1C4`bl3nhU-LNB2N5;_D(B;b%TKrjW9300|z^e!T( zAU04$Q9$fn?DwkIcI~}fEB4C!thLL`gv8(de&6?>-{%EBGkdMQp1t?lYd>e7bBt#6*XDX(D%w9Cd=q+#2Q&fd!wBZ33~)y3Rky$-2o&1snRV} z!-?wo|2wC&h$bePw@j%Ou$7 zUlP9?M%{J=vR&PBgv6_o#-M+B9|ubRH{(r|?c$TT8>4PHMN}KARO3xTJBrJH`%f+N zWI0|#>#$bFQzYF?5ubzIQP~X^SX=G&yqZc~=!#dXlN=v$SrM2yC_M7%fmseH#rxX>J`-QE3%k;cJhQG43Jhvn-ke*&L zx2W0|s4glC)Z~_AXHQ05ui~PbvJziaO`zIeRFONyH>HO!JFhneoIXA;(6_9r#s`Ey zBe$|FFd{vB0oPZR*JMu|IXSN?&zFsgyg+$P?tj;R$rSXS>6ibHvtgTZ&OXA&G+)VF_N`GpIsHbC39dlIk&yafQ3IkscsSn++-V3R> z7%AR93#nJWlI7cwdQ4dV`z544TGtwy*R&tSgw!9Dcp5WwU%4ZsUhP@b>|{ti?N938 z!y)y29#w{O<+%u)i@>=EoQuG@2%L++|8)`gzEPXsa#nxo&e`C4qq||`T=sClaps>n zs~>ki#&bE7S&iz`XFAlNXw=pq{9Lk}{`~zjXU=S8of4qapTDSeN;FP?{)pBo!8rZ- zQKh4|aopPogZqQtx{ltojviY_cZKTdU*)cQ@q(OnALOk5=-Y`?#%^-`1dnny#V+S! z&?6ZBOw-e8hVjGJoK1rg&^Bk2s|gkTehDQ%j}C5>9k|cDH@i_=%uBVW_^cT8F~%}#yH3qn zJ!mqJM$WpA12H)p2Caee+2? zs{X{lkNoKjv`v3g#((U((_`0tJ!0LbL(jy&o3r{cGpFC%wOZU)N3D9cekj`A?da+FtmcjnAnC|^VQ z2g>%R&zxz6%fYcI2co*+K8zUYrGl8q4-f7H_+ zVg_C-zBzM-d@(%Uk)9T#8`%rpD~us6`*-Qpo%Y8@U(`K_xrQ^JUn_q11NA2nLY-IjYBe6R1?}CyMsC?1wiEsk7Ii_Ok#PtvA{Y){HY*9cFKHIX@?OJW0bm zErxl#!#r;Oyek9o>4AREecnQWJooQh1kOd^Tm;TV;9LaGMc`Zn&PCu{1pe=hfO<|% zJ(s4QLqp2X|LT_X3>^K75ruvrE>`NV%jetpngn&~xwu4WSJy@@rLLZXqw5*^r=C6g z@vk#gr0E2qY9Bik$7?`OpP0Ou-vn#uEBA^XE;n5-+ma2d$D zdieNPsYl3u|GzHubKZ42?jaX2OO_L5IZG{U9sK`PRnI$)8a}*#Qp(ig+R8v}Qopob zX+2WY`_!_UzN}}Dv>q9qMYYilLx?De*dCHkQXXtz=>A*PllyM-=!KB;LD@l|RecQ| zcqSLu;s=WHEa<2>&>`L&8bNP;(Ywo;Wv`!23Olxp@Vo3TTwZC9;c~ZK%;i;f6_>^wxbXMm-C37#^oLMXfE%x=W%(Ly^YIb z_F*oM+o!lZVSm8o-S(ecp0rz(Q$P3EA9H!H{X3WU*@+cYf4@C|%LnX2E+4cn=kg)@ z0GE&0k8}B${T`Q(+eRg|d%{lT@=1F?)) zMifRr0!F(@iMYV?<5JY!i;AeP0Wpl|t0CJDE`zbSk+yFwTy#s1|-(?(=*<$1sBh>aUtU?N^oKcH7Hn;Ty=5$35er*<1gcbGDj*=T%S z7g(mnyt>OUa#1@$Tbc|V2unfi`>}>Woy>uyf~>!hvvEA&ENkCwn8PYmuhk8Osn{BD z1x(kV`k*p-jf-?szttaGvH1XOwABk|U&Fj)*JW1a64>8{?K5qUr1tUe?So?rtjugg z2NkA?Rxx;qK6ng)Sz_7SB&GxGJv4^t=>OyifclCtb=_EVK_p~8jXPYDk~KcYD4B5w8@D604wWq z<$51M9fW=@siJw>U?|z{7iQpgCk$SyG+KSJ1q}T)4gFh|82Vjc8yM-dp@cu@?fi&p0WoPt->xX__L z!y=P43zm`E%0p8pJZlmt;DEImik;nz932^zfgGXjZMme4i#*S<3~iH)w(sOn#l%RD z<9bviSK!S!@AO7EGAS}S3r$RbzCK@po+1!6JsY%M_w*HksJpX4Pt$?N!!<$Q$<*Ch zpmxU&C{QwWbr!%#90(3uf3>7}M$^37A6Nj7ACHP{KM3FKiEI)bYh@s4rh9Dk#W1@` zagXhK8%~pEEh?gpQ%H^Ie8?THz_#d~khui~flb5N@nxJ_qk6`6diW~n(dU^lYoo9h zO?snASJPT^nPEH$r1ur{;(e34YH@o%*xH-PvuC3uV`u+GMs#=6+IIvi3&_vZfUu%L z=kkCN-OIG%QA6ft?l5zg%C+ccfNA|P$uQ`+9zgc@sX4#Vq>U~^?gc2#I$xV7Ou2N$~F}EWfg|yw+Ek$v4kMw`AnC z-fvn{kY&(fen<@nD;n@x-(XtDQia)pkwVO3tq+>kNo<@HfKFsTL(TauWUWt_RvNZ4 zsu`w0a;+aWtjCg3mfQ00+A3p2(R_4ruEkv0XkYAh}ZfZ z(>hAwMF+2H5U(`_M6UHGrgilu5x?&UWCJbNdY73@IchZ3i?#m3v?dqf10+PK`Y*7~$*ox%>weeqiVWLk>`h>Cftfmmx=Gs9(fw|r0FMqf8uhK?O=S4?cp-lZpq~sdl%cs+6TBCXCL8mynQd1 z6YbHAn`HMy*=gU!#N~h^Cd;F^yxL(^wgdHXa`8?B#ybOVa^G6uNWKQKjV2>=`ErM~ zKUoC)c4|Oa(SW(U!D0P5UYK79Hw!Lraae=52`+z6_F`(zZy{XX54j%g;EhANCpsReV8U;WqDEFF34k z+KAXiV{y12(V5`#OAc$^Euv``=JKl!s~>u&zIv+$g3GjKMyK~0(^|jji0S54YyE}8 z`V@P~Jc0)(EKAr~-nZU%Bp*V%XfpCzf9fpjI3d>hU9zvB=KL12)~3@MRw>r{HwBVw9qqJyv+#j7nzd~d+En-;);i8gl55Jgla`@;Qpu%y7kI+S}oaE2g*odM%ZG?C((~9=IF%(3w`rh;izurZ7a%c_j8` z_e%7VcB+qIEbqP^K%;v;P9J9XnH_PHqWc>e^p(ZERU!hI{XdbTmO`gk+7 zdc6d#jOaC}w|e2^W5zxc9gXe3#|wur%nKn|Vv9Bs^UoU8H zwv@JB7eaeiwR4d6fzp2I5A9Q>ttx=_AJxkx*!g3>QQAqGB|tqSf{Dfs1{Hyt$uwq)M&FeMZqxBXN-aB(bl6hN)xRvB=?$YwF+%w zleBttG}LxleYyf_N3D*-O2u|HGii|!-cApUL=n5fjERpojC2m|Dzgj4)-=0TlvNtB zmzmZVuo0oURunBVV%M713FK!~(R0jA=x(EFMaqhFUXIOXXNtLLrt^Ai5h~`z3$o2@ zB~~PzS7e764pv^0ooe)SUXv@d%8Rl~bmcI6UI}`{US(Q`5Oa3rjY+6L_EcOYD$;q~ zt`!Z?J1^Wmt@6t4*D5dFbz0@MyWZqLpe--n4O->JyHTsWcsH4SLl^I$vi6+U5q{lj zT90p%j;tn- ztYE^6rZpUwNmL=2@Gp~@U`ZytB22_K0DiU}WUm6`B~R+$N(YL%Jrxf#ZUFSN=`_>WeZ315aY;cI0T zO!&@>X?de`l$r2@X-&hS#6e^x{A^n9B*+S8!f!a>aI|t%nF)WWE(H_*6slsvU)st{ zFdXu5PG=^VLPZ#u2@Xdn6KDvdQ|p1m1h*q51;iA4LbU2cFd-J%3oiE7>pj8iu;_Lw zRR|`;JFIS{qCzmCxg(4TErhC=kmv~86I!d`1QXh5m6_01tIUKX)sq z2^}5QHAsx8LhK1CqJd&UXRR_5x@eV|&{eC!MxJawaglera69SGfCe&(`nXo{s%!GyEOjxX}f(aKpth>sj zqs)XA4y$vLtY9Ww>abFG$O>k{T8A}evYZMtVT0;YFkz!m6%#gTm6@P;Y>KJh7)_jZCd3$;fPk53Ac-`RGx6B!z##^t}qjDjdnG1 zQ+9=!aJOinm~c|7%!GTi%1pRdtIUM^9brs(K&#Az2eryfcqp6+k0`5P!s8C>+xgN_ zX2L0l^})@uf|-EJypBjLIjYQr=N(q&gK{d&gny_m1rz=$RKHG-Eu^Y3(r$gDw>X6L10a>qb!_n2_SM-bT7X z2*HFdPTv2$k_laf8X=j`O{iEL&KOh0a8P+qNK>PWJ)yf+nF&2aTg8N4PHQ`6K_mBM zCiHe%E!Ij`m|b`8xKhbpUJ z!U(73#j>)a%!E-+EBZ=V!AuzKw7NYYE0_u6oYrN1M1^32 z-)VKdN>m6Y%n=byl1!K@RJA9R>3A~}=4mIH2^Xr-1ry4(%1o#bZ50#dJFSax)1Q13 zOsH{Mp{R+$Nxgfn58vI-`w zbXw*j=_oVdQm6I)Vp+jVxZG)#;rQaIFca20t#&f*>CA+Us!PFyO+r;n*sN7%!d9&^ z6SnEL%!KV>OrSB1PM^}XdhBjz%=GgV6ZSY|+9{ZDjnmq6g<)*dOxW+Vh8Bwo!Gs%} z)|6OLA((Kplg|!~Boht_RqYA4=y)>|4y)nh*+Hw~?4VU~b`V`DCfw=7?FH$II6FA4 zLAX6Y&I%^nEgI;vgI2}aL962IpjB~paE6~9v?|UHS`}vpXIRGgh_cGFgVV~irK95P z;IyupBrC+(!D;=pO;(7rgVS1kubhfFJE$(@*+Hm^2`_4^I6G*oI6G*oI6F8)uN^2_ zMyF$4hzV~xV@lgACcLdW5lnc`Y5j;v^vB6W>ILP3Eyj#necTmW<(eh99m^2IJL@5h=>SdLZq?^CPYP8quWVGnF+BG)`xRs z1v8;>gmnpSFz{5E2~8uchYRIYmO?T1Ji?0VkI$?9iV0N_R;gQ52qx5k3ByE%V8Vh3W`fES770}`VQDxM zF40c%p0G@fF7|}wT4g4z5M3!Itd6kSPM5AQ6V^mn2QHPaFca2_28s#mw8~6auT^Hk z2CXs^HbsOnVY61530t(vOxPOEgzd^Im~cge)eZMKD2P3o3A-b#jkp=i70iUIBdk`q zwa69Bg#8g#?i4u{X2SKVOTmO2gsPZuqgI&-H*1xda8S2pCL9W50*z^O${k5exIH3f z6;2c4D)Ol6L@?o4gmvwHJf%^om~c0IhC&sB3HL=hCDl_3p(UoGt(-Bt88tDo%;kgKFF(yL3i9F#2(LgcbA6jK5 z{8OvUgcr5SOn5mWj0ykJDl_2~tuhl{4QImZ$|{)fW`tD}Cmm%byc1!aSRgBy3GYW( z>sQDMX2M4i)(z9-RG0~$s4fK)J{78B!e`pbO!z`unF;^VR%XJNVN9TC8J$|-qZu>y zbVSU?Zi)#%s7?eEevYt;asQE?w-IND-y*D+u_aT5V8UM!)(-3_R3VsPx|j)Bk_k?s z#z`hby28#5ZkLKT?+H;t#RQoN(OP9D*rF@N1dq$=IzYO@Ola(~&c9!}!h1rTXrP!7 zuT^G3Q>`)+nrW4p(88rW<7oOla@2d|PA% zGajb4PkUT zg8Ln2>;PBHt~AAjL8=qMge;f!K%!yX3!q@aaF_MZ8%2d+!YG&Z4AM_R2quhnh3yGr zg{t<13E@nbq=plF!ep&76Y{jmOqe3NQcTEqSzB?{LL-Zeak|SY&XKM#6K048iU~8d z%1pRGtIPzSR+$M!t}rGPYn7Q$qE%)>X*d&RE305anai58K|0DzD0f-qxJ$#HGZU&@ zR_9zoF=4gpL@;5E%j!PSFg^fWFkzj`%D@dtst`=rJy%gSFNUEw`pzsuS!eG_Mg1EPUq!u48ZCfuM^ zX2OkHWhUJ03S+`Stuhl1X_c99OE?n_E306_?JmoU8?_uWX2M-AYeX|y!A!W@Wf}Mc ziV@6&`&?EwxWZ9oCOoLR6ij$XsEP>>Yn7Sss8*Q?kLk9|gvY~}KtmXv8XqJkTpSs5 zYfr_5Wsw{J^{MpANNY()!`Or^L@?pfNGtzNQ6ZSHHqtsD`xqev6E;LL6I#f#!$zS- z%Cp1fNIp9tf#mxM+thGkPuMP0EFJF&JG9D7*eSYFOt>=AdLcr(!c5o`Y4yMz9CD=> z?+I6n2CJ8wz4+GBH9{{m)0qm_3U!5<&Q#bZ)Q)C4Q{lQu842;R^Z~6h6|UDRQ{je4 zK0RP%_?d#6gw-$w6>f>Nj%P?unF_Z>TG1zD1ykXUNNYUKbmV$Zrovs3)`Cf*Lfl$9 zt_Kt!OKVkpEUgAiXDZyQRi?syT4gFc5Xq+p)8vn(X-uQjbMuG_ry^tSfuka2d|C}5 zHihRRt>UGIu@i7Xg?~g^FCo#S3PFXJBdzzQiV8u6S0kAUnUV^x2^Dvm_yL7C1Qi-f zD!iqJ6I6IxsEP{jXqBn(uINfp;e$wPJ`!wpg{kmyr1d4b3fU=N)*gOtYb-Wxal}s1R&uV_CCtrXhr2L$Vci zia1ZGDp_bR)TWXRoz!rG4JkrZZ0M|2W(|mFdt=t4xRfR@mk+P*@cmvMlQ@ zeC$hc64#T%E$bh9Wd+k=q-E`@k`+vcT+7;ayQmO!7^4SdI*ijQ(_y?CP|#tbR+$cy zw90hI3!?*hg=e&|!FxT^?e|H*rbi z30NN_lf4fb;uZDbW$335n-(?p;+Y21?1=hwW%GVc0MT}-m5ICT=1ABkX*+$_LE2YZ zdH29R8@2^ub}xBj^rdg(c-B}qjW>*M(5q=~1!}KG@<^FIk-d1zVt*t+CVfA}QyNQ; zWthSnT@kxzA&~k3N!whNGN-)Ar1jCX8>2MvGI?e zgn6GerMWaOg=uBb{4}+`-ufJ$#?t`i9=z=jnjbp}^Uc=r6luN(riX&&AFvFb+pNR5 zmqC#=Ux(?Ppqaj+;5ll2S1Qdv!}Mp+d_F#J@*KAcw@P!fe)wBMc*!92#opk#-)e_& z(sN~ICQJjgIrA%G(cD;b4F%x?aLx0mH6IZsh*^ZUa)lME-mfTNc%HFZV$m6LDa>2K zA@MzKMK}Ml79iPS%t6?XD2x$5m1z8ybr`G0=2I{|ug#g`(Y0r`U`+hFCQv@I4&V+T zLCo**_N&Im9UKnx7uMTdVe;UPTLNBu3D_Q4-e}3haQz2V0v=;p4;{gG+h`>Z0D7l} zhal;@DV})K`tE*l7wUMCj0Eir*M%UeWL*VC`)?8#3bf?lx z0(3|N@KCpToX&XO9}jJC!}HOoR5#=;K{%6YTHmghpk)B;(4e3*A@Fq5T6>R#-v;QZ z2H-M$^o1MG`S|JtCQtpD?*spxZbP#SMb0#>j|NGkJrIxZ;w9FFHkeT4EYrH}YKhDQ zYP3d@v!S727fMWPYlVcD0vb3QZuCDy&dxEdUqE(tb~8}dYGjDBjJyzE!`UH`CxLoO zBSV~JWF@{avq&O80P1Irtm`bp@r|MAnG)U@;Yh|yL_x!i{@z45TWeZRgSG7J0HDTb zWQenj#21V7hOacO#a;=25YQLSh8z7K zUkzvRm~I;|ja~Q*s9!WP#92nJH?0eC95S-WV0_gLud`^t$j$h|%`Ax=2-GBvtm`bp zx0}{HY&G2Rg@7(S8*cP(g+tx5%d}?WWXQ-XfVxp5L!4#gUL5ixCGsJl{-Kc}k!9qy zc;FLBKKJ=KP=9G;U1u47z_hZExiY*3&U-0%okfE@H=I3WS|&DqMh*jNvPOnD%Sb%b zyZ5L>mIHOMMus@cNIdQPSeiuc0_s+ctm`bpkDFG?atVI|&{xie8(l7>E%G7Ls>U5v z+Le9;DCAHbumJa|JWrcV_&X8v4A|Jj)u8MJH%FJyo5T138#w?V(I*KB^Yr73Iajp|h;R7}+#8qW(%{^EM-Z z%CgenxOo`1yS4p4@KR@4kJrNf9Bgle*}deA&a$ql!C4)>n&wZaHit?t#7HX3I*$M< z%c94d%xDjgD$6QbC|a8RP&tIUNFhH}mh~F8f9lvQz}p4dtg@^C&ev>S2-77&v&^zy zyi1yQ!F07Yt1N2^f~~WxxwxG`5c5&IJ*BZK%X%4eW%K(meHt{&EbD{r(rn-pv`DUBsvD1?Jy8WA+hEUU9$nrFgP5;V&!%ZH$H>x*Gp6*S8% zYfpQbW$lIOI&D^2RvN93%Cc_TCm`l2;9gQ#vFb9*I&@ePu9sh2jZEQ=YVvaFa$0Wr@9&Zn^|%lb5cZUU%YP9{1AgtIEkiYtPB zCv5xb*kzXW_957h!S;~06QhG!R^@UT+&2LDnn1))?{$bdk0gfES=Mp~zG6cw=^lZv z7U3n}v^)~2vaFLh_BpZX3Dh8sq{hK4>rZTo49W+fT!VCX-VivltlHKRz6Q`68-Rzp zt+K4Zb+X|@X!MM3$XkNWvL-H*ppO9fRfB@gguszyJ-@Df}GMP*s* z8_Q^q0zO~2p;?9^k!5|gQX($`YNbZf1`~=zmX(5hnh%e?K;5B{dh}2@vaHruOZYQ@ z{`+irFw2^cB!fHt0jP+PYJwrosw}JRof6pws5FfXaaLtnlMYH`4p1{SvaYi#%er8y zgf9g2^0VQ=EbGJbB=S0-j%s9xvntCo)@o#kvntEFs-;980P1dy ztm~}Gvbq&Y_=|wPe>OarWnJD$B7XNXFC9usgWVhsx0eOB-@Of z092_))^%28S&to;@MVB*J{xZIS6Pj>mvmNk1bv{zB}7G6<<)}TjqFKZ4ZQRZpX z|EX-=;RH}w)+svsG{No2)_8GSZ*I`O(n^76W>46Lh1tF2jn1+bAc>iPR;D=vs5u(R zBdIKFDgjiMMUM{SYvMqvENjF}(bC+9${VSRLh?gpSvTDz%@4x#xHhXS>(OXwejBC_ zgJzj!t!X69f57AzqdHev){h9b&azsz6%aE8xHOGbS=OQL(mV>LaY3`pvdl}Qc{WVt zL9@)VUQ3te%V63NG|Mcj|Mf^a5LxpEm~IK0WtNq`TACk&>FJCc<184pCXwL%8!o zBbfobEm0Ul-OGx_xs=U2V7f}1RhGq!QCZdtQv}3(2)HLSR%KZ;ko=neM)k*JqGLcf ztFo-wKG=VQ%{4CEF0-tnld!jht%J4`qk~yi_8}SEAplGv5b@JHM~x(g(^=Ls47HP1 zvJ%i`8cvHVkt)kNcE3zQb^~?2MpENombLMq1U&%2OB$rR^M=5YW!-$fgntRBJzhB* z4rf0?ox#1VrUzuh4rtUvH{>lrXIVRt7<0-u8UUXL1$z&HBg^`rvxF}ObVmbl>4(a) zp1wdv`!?Vo&~0dzp-5y|uV+f+Ye0Rfk+i{tB9Ucn@JpmQ0e|%dFR_B;EF(kV$g+%^ zCA=vQaMgIU&tF%oG_#9e>9#I!=3RasW`wGx>Q)KHBKaaLtnkK+D5k6sAW ze2uK@tje-p=qust0o`*pJeXyzuawARKs~OJA7}4qW?APCl;;1y^j**_v#ea49VxPAG^XptOHM;(S$84{V{>Pix(CfN z%epd7nsZ>-?rN%bEjIg*K}!YY(lD%Ce5`6cBRn#>S!G$w7?ou$juH^F11?6o;w8FLSysX( zbd!bZF=V1+Ksc+ite(eVp9R~6b?h?BdU8MPD`4B8?ZoI{mNj#S4DO8p+)E(hr+2>^ zNerj6tkKw;e#53<{tM8LG@MpXB2|`k#dMj3{6(mI)iE^=W?2&YV!>uHI7oazt4G(5nH+7fDhk^R1Mus@6vaBcXl*liD`b{H4oK;ztjr5oU z5RWaPGhQM9b)8jN)=!Nkd^n(aXTyV8R<=S`0CkB*hB<tb8mpyKp5?l(!2PLY!4u z);Bjw+|gr*%GKO8X4lO%CZjQ0AXiG05wG; zL!4DvmLpvvD}h?Ak#(I_S=P(Aq~MOP0ra-B;lV7cEA9g`@)S_7X=I4AD$Dw3Pl@~v zC=)l!&WfzcvXZPUEu4bu(m;P=_^(v4gLDEYTkMax+-5gg zOYL^rUAf$4599JG`vNZa*h{$FYwzXq8vA}O_uKDqdAvZqMU#t-XrN4fa7UH`&Ly++sh2a7sjyf$Tkaq9IzC&=TZNBC_4 zeBhqd1x_DTw(#4;SxwRSd1a%A34$NgciO!W(`dTS8S^m!{N(g5pp8!L=TrSbXH4T+ zhLKFIjq~WQUpGA>zuzCkW|iNDkHG+Azrx4vWG#{XX9K`(Zsh)>aa!j7FQWdbb$$Ia zHu14Zxbd<+nWi_g1b)FNT^B(g(xf8_(i0!0e(!8YGqg`zunmj*3dPf8+fV%-Z%5&_lOtdo9@h%R$Ao;=A^g8C+{8Yg#8DwMG}vkIc*lBYNDM`4JPtmPjTkZ-)oMX zYA0N`RaY&|Mb$Aop$7T2M5(@pMV{5y;kz|T^_6x+SE;_P@#remmxVpLj$c_vHA?k$ z5F3_sLiP1@j;>OD#Wg#tuWyh&)S2VmSi(Aet;fM3s*Kzp*5I7g%(R!|kQYBY(Sm+< z0&lnDy2$1H-4;I|5MkQl=L1}(O+O#d(Sg-!(av@ybo0=IF0O=B&j>I2`Z5Kp)v`}a ze{9O5pL64HqW4dvKSMbBuX`X55OVs3kcT9Y6Qdp5AZN88Ot((p4P72!+kVOx+xzRb z*w#O^#kT&DEw=NIZLytyYKv|DGn=;cF{Nb-@Gy>Z=Z(0@a5?@S1HACkx1RXTuzp0$ z%$B7w^hYm8U(*XC&*70rvq$rUM~`B4TV5#Y=g)&&9`ugCEMd*KL3Go$^nck6KV@%q z1vSZ=+5g*a_~~qGFV5!_^4q8z8FKmy^eW^m|6RzB0Bl%?I*4w52V4^K*eC<9sP>luW*M#+O%$@1Ks0VRu-98X*tl%cFl^bD$oGK`f1&&|uB zjA(W{j`Ufc9$2E}k@3f&%=NrRmK^qazGvcaD7mZzJnO5VjJCf2ydTO1QS>V%cX;|bp!lK>Kso72YXxN%`}VNsl>{io z?oZLd<3{2bEW>#gFUdHEwFB|Vchf-^P0tP%H0z8z2(8RU25RUhf4oeMf|ub#yH_1t zy@aai4Gs4KR`44czjrjICzbeVC4QrZ3Pw4|xCqy;3o#7I1>^5UlaEAy|3HP8Y6ZGr zKiPhB#83zP7y`e^0gq7Yi!q^gg9L(pZ-^U8PhHe{gs{8*sJzploXiXQMJ6xtMg*-Of;^fgx<5%aCJrwqshH%wh*_7lZ2&v&h*^%3#-P7E zS{GVyoLnstebH|Z)p6C!9d`NB2I_uC%!eqcEBXznpt}N8&;i+Ky9-2DqcuQuFlsk! z_c&q(qofYzh1(1I;B?V0RV)a9`+?s$(sJo(do0|B{j6OP9}o01Q^HxAxKa4yG??ab z$my4-g5DX0hr7VEnoS?nF;!yQXqV3&{#mEPrPwOk-N$64pR5Y$u;6RtR_%s4**2JL zd|c}F^->*H;XM>H0u@Hz_7=+?4;HR{l-!&BIM&)nvl8Js(;kY=ire!>ER+~lVmxb- zp~SM{_51^Of7^RliT4cL1x1`&QE6?i1P#Uw6;1mFc{Df9@W9t)?Y0{akqcpz*nqu?vt)NQxeY(xp!gW5(C z;!mqm@B<;1nI6jg=qJO3r;I49z8JPQ*h%^ou^^qiY%dsr2)8?IHm2CoE7(@-iR0WZ zA4ZBMTfsr(r0tHH{L44=8)S9Ch0XH-xSXd!zfBf08i%wXZU*d0V#lH%E#pJpC}?*T zsvV-5e#5M8s0*$`veGWnn`qi_uMqWvLZX^Kob7%sUYD?D^b{@&V}3TjP1)fPH7n-4Xof?Crr zxP^{=n7IAV)>Key`eC=wvDy4Wb1JAc{oY&X*za#g>t9<_L9OX$;DTfG+02;9n4gYC*S=! ztVRDxGK}9LK&KxLEBbcC_32`H)|n86g8fNn+mulbrg*xW?A=8c4e0M%tl&r*C%xLIQeeG9J42kOBVkhb_sV7nR+%MxjU%rc)CQ(#Rzmel} zKZN&u`7UbyibmGmYYd)$>d=%@&cqknL+;p|{_byL3eFWBI<+Lf5)b!>oYJa4RwVJ; zOCfiTr$ZxpXf-OD%|k_(W^}!fc<=<|ZV9w`B#y^H-XS%St_TuccRU$i8+&}IDl20I|?l2&J9?9q1 zkaL>wxNm?a9dgCE<4Ym$7XEyQU9-bgiHym_q&v0{{&c}aJ0=JpPGfQ%TZ(aS!CX2f zim_g9kGnoCgwID1j7|x{&lZ?_rWg5cL9@9@!`O9R;GLQQEz@$3O)a#-pW~-;h9UlRj@MCD7+A->ds3%lycB- zwD4ZY7aKmDVZW{iH@TJQ>j|)})z1<=2=Pby7dpF3} zajxK>OqiPl<{H8r5tyTdxt%eyFTrYeX(G<+iJcDOX@aC!+9>kf7o+Pr#ZC6(!9Fjx z$fzOsB|{SS48WJzNoa(l^HUNgVVnAqgf8gJ*%(3-q>GJ7xPCY87?7|w75A)3IG&4V zwMjTN4iBf0@H+O_d=hGUU@|0Zo@f{~B>aj1tRi8~P~3(i;SC&i`$@QGtYO?vLJOE4 zBw;Le^XExuKLXEKlkiY6&VD3ZlaCJ!@lh7aM-ycZ04D)ivL0GUBPnM7ng_A@w37?wC zb4l>$;S@l^k!;)@A|d%wBq1b}A((fN@Gf$>he#NPBjE)S7Hz;eiG=K)hVdl{hi=5# zj)cH8TYAfeGl z+~6nSE3E13By7X6|0xNFTi{oZNEmnt?$tJfFxSBCTM{n7>Qs_29<44RAs36Xk%TUH z;aNNqW{k(P*CZrnBK0ESbRNEMM?&pQc(#IsRoM95%^~#0d9yhQPhqp^NW!xRku;HT zJLorpgkxCKJQBXa3Ko;F+KEp+NZ7Fm_f|-F1uBUy^VP`_=CxT!er}w}dbl%bh^NulM3JF%n*=1hq&wg0Y0WoPr)C;jUdcDoGd!j?teeDSl!lsFeueVH|O-NcdtOs6|54dqFJ{eq9Y}k#KAU zs6|5M3{Z;%`pWhK5}HggjLS$^hOoR&LeG3qi-fE2_7e$r^#Zk85oSA{t|Q?oVA_#z zPe0rXCgHwzpcV-qPY1O~=zz%ILc){ShwmX_Hnz{FNXQzD#~Dbt1DyYagjDq09Be2y zt^>75xa$s3i-aK;$z)7?0H{CgG}%pcVxHcqw5`}%0g!>>&VN8Eei-gj_pcV-?E(Ntn_z3U|cdtQ2Y&6xd#aey+JJ!?#7yqC&7(noJoQ?0MsHO5e#2S z!rO=Oizg&}y95^uBsiCYS|q%LdHqhp+X#4c5`;0>#}Y{RV;T|@5@utpJ|xTlu`eLu zJnTRFNw}sE)FPqO2DM0-wI0+Wp#R(2pc{LH3;}`BwP^ywUQw`0HHq#oe`*9 z5H9z}5}Mo%YLT#G86JBip=kl0`X`}R6HtqUySsu~I5vuxUIc29 z&}u2DMS=-p_aq^813oh+VexLor!ks5@ zVkO~G3>bl^73bxGS|kiz3u=)-Hv{uX_~A;tk?`CYP>X~VaAySx8@7O2B&;2b2N+5C zPa>Y*;hN3{?!}DEfSvF2x^hw#v9#YDn4`>^2QDj)}X^7B%H$GFrI`w98xn$n1CV5 zN$@&AEfR9Ofm$ToYl2!N(C-W%Bq0{(xVuT1dM~JjzKX|Vf(azdz{Z$D!W-CE`;hQ~ z7oTgB5WO1t6bVIsJOf9%pC=(J1JoknJ|Cz>!qcNcEfRja3fFa=AgqhW z#!te1U}i1}*%+dL1Rvh!kg%&1)FNTpc2J9iHe*3864qkjt|#GI_;V)-qd=`kNci%4 zP%8z(&3iyC65iPgYLRg8K2VEY0rAkK8NulUVApcV<+ zG52dppzrS8MnZF!Vcbu`C)G$DNjRDSYIT9&ZwYFVuyQG=MM4`a_ZSkoU=x~7!bGfR z83{S-a3h|C7&oXz!f{0GeG>Ye1hq)`_!dx$gwIETS_oh9-X-|djD+k#NGeG1M1xu+ zz#J3P@SJ z3Q_Gt!kAs476~t)=cy!&y%dQV2}u~DhJ+{9;zkk)Z;c1FNceRws71ofi0W@7G{d?_ zfw;xbpm_@tykl^wNP^B;Q$Q^e7N>z)Bs8u8wMd}dXeSBg`JfgFc?Uo(5?;sR zK0?Cg`|)@t34tSq@h%CCc7j^yt9Uz-vY{lj0s$tHFdB3Bk#GTGSV_VU*itSb;i)|Q zT@(^tz`}h(f(7A6683BcwYo#tHV4!qq0=x>i-ga?jdT+JDne30!i6cI776V@>=h*Z zD;v}zVeBMOiv%LbZ6xGcpcVQ}~SbQSO~VPCgE|M`nHoW?P{E5 zNH~o({hfr{@D>f?7I$BR9g>99m7p;RZ4yCa681F*jY)`H1{#yF7YEuJ5-wej?1F@Q z2IE0s5~gCgPmr+rJRBe-JPChZA>l<#@FNoFA;IrS_^1)?sDV|*jcxQy!b(uIl!Vv| zae$C;5!kYd1Ya%EOA@o1622LY10)l|xJe!h;wq zn}kQf!zm=tqr)X6EVvT~2no+lLykm(b<8l1lW@Z!JjP8z^l{9Bgs1$N1qmw<%P(Dz;qkzx(TpJ-fqL4 z+Xo_+;J;`y!b3O34ACZ=6}OSN1DI|jUH=ws#yNW-?DSxcXfr-7^CIgsm z6I~v_S`^+6ImOv%0+f9BRJ@nbJq~(Q)w^JUd@~CAAi~}9#ODhu$VP8yum;7vE*GZ3 zTHt6xCAB`F5rwM~VDj_FKlGTZxQSDEIn~bPTQ2m_tE}BfwHNZu7kUI%)D|qmDZ5*S z(?g&2(-W~lx5OvU^Z|%>81Tl0^l(zQDNYXsnjV@J_l?LSqu}8xbhE_4_mt>CTG{)) zX{es&Y(#OsfT}6T{ALv7gDKtiIN42l)|Q*doB!KP*lrY`Fw*n4;?selb0LXOWSVvc z;2P1G9?Y!^D4&%Dz+h+WJ7lEE)tycSolUw`Ib!KKUh#3j^v%mqh2J)%IhAiB<&+sq z&-HpK5its%orJ1d4tF=IWrs+@TG4&7!jB1X2gjHm{|y4f0EG)3upi^k$mp@)y7q#a zj<9>hwCH(Z1{ejKl2Lt7go7R*7M~XKhaMsvmu>;zI?;|EI1>Q=q^aOqT7&7%HpE+c z2rcA+vci?~V4L5bXiU$giQx)|+>P3&_|p}7O0BM!g)dzJ`}6#%3O&7cwwMLcM3_M&xNR{Md`(Sp`dKY@=mZ6&zokaTZJU zIH`H%eb{o6yLzgQ45lTx1y%WOdM1b;GNR{S_#q>zJpiR@bv}tNlDMJ?iElwIpdcr{VY7 ziT|-!0j~Cvgo#rq3T~x_8R9sn2gU`_2rtL0=>ot{91VJqT&z7ECq}`~NF>tMIQSD_ zdbqsqVJRlv4_j{9AKU>wc^>RQ`uM&F_QS$QdL&)=$oq=eita|1oc5joyrcmnVG>SE zwjgUi5Jw$+n9@`1vgg?}w@*Y+A`yB~J$)n%_@&$wdSItcvz)OV$FpMJdw|~lNpBz0+fVcsRgAY*^wyo;hSA$pdYemcOX+Ph-fHffh;eZ2uE4)Vfy5U0 z+!flHGiR0;eGk_kh0?Kha3;J0PcqEfClI)a5J$un(UT!pLd+`q89hA-X?ab%S@^sc zey&)ttaf1s9EOn3EU$TR30iP9je~#77tGE=M`RWMmM^>+;pp20-ryh3_59DgdeNRF z@mU1vr>Kf~#P;_7FwGvRJT ze?w?3V05`jvHRJiM6v=LDOMcDv~6Lfe%xv1kOb}t@Ji3Xgpz~}rd?Lg#EgE)|IJk-Hv(R41p%fhpj7O}Y%FbL#4CP8% zBdYEaj#brN)9|?m^I4;j+aMYqibiS#h&0%?F_|E{(o$e;6^oNT3vjGQ-59sBh5PAs z!=VhgQ6l*sGHkE2(6OSMjI#_bVaN6ftcBN)D1oD;i!3{g2M$XlWl{%(e>kkKHN zTJYT9oN2h(pt=-C;>1P(;vzZD zRQqhDhhUSN>k3lyR4cI$Ofk(|-Up{9=KRPW%7w+9k z(ZXM2Nkh|&1Uge^wb(TbT`x)lM?z{S)Qer(iCi9WiT0HP7Sh~sM&KN8JmN$qVE&G? zsEL1Y7B8~~UwQ3bTT|V=tg@uMw$$Ifq-)pi{pzXeUR)Na39nz&x3{l%MrwIkW$mKW zIhD1dZ9PElvwNw(xOPr>55nMI6cE+rWyRg+l$3NotK)vkz3}E|;mF7CfyMLv;hz2% zt?*|zipna}O6Jd}u#{ER1giZ-6@~+RTv#%Z_VxBbp;9zM^t+Hc&+~1g$G;EBw`P zOaw&K!5K7#41y0Vt}QDMq?T3UP66nS3Ht)DU~lsIDvE0YMF9j;RMb&@zLB|OvxN!1 z)|Lc9DuO0nF`%L-_KXTth(^o}h|y%BP{WHrWmrXR-5Sx6SPmfv$|@*$=pK`Nf)Q4Vzl z(A3q)-QCsEUEng^$pLqg;fOFJXGb_(36ajnjja);%XHqq+|k(_xXO)#-Zy=GULZX~ zEsvm8ZcTO{|NNS=@~X=01qL8vfaw#;ET&s-398dW2%B4yot^2gm>*b-W@tPoiQf=B z>ZG1=in7x)%4&Qy^Zg}dMdf8n{H56qAV<`7sh-|SveSE%`YWrdD|{7Y((`&?Bg(Qf ztBXp@7V%jBgQ;bJ=B3$rJ$)4h*03y4w!rVJDVtN-fXj>jJ9idk_q(XJ%pdTLFB*@q z5xc7vmee%RDdN!U?`2Qe)y{n7;b9iNN2nMQZ%m1eR!n)jAn4R6brWVnu&aSACeuj~6VRoOA zs*3qV)&A^>V;1r<&G84sPA%vc1_up#7u8UlvL}xyn>=Pj872iXVwYavuMU(Imt)7N zqD>J8v)u3o;(+bnKfH?g-z|v^A&0_1k_RUZ?l@R)ed5>}$PW1egN;DN{MlvL%^N&4 zGAZPe(B)M%H4QCeX?9<|Fn@Qrjwq`eQ^X)Uy*JU?S6);T@Ksg?d{wg%z7b^{ zf$k&x3;g9(^DF$2^ZeD|(D172dP9b&r}so`1YK~R&7M4FUVV%%$?iid;>VIq9s_#v z9$L>nTwe%>XP^xZ0>d|svVjIzwiwjGd1p~kNq{H)KUkxT(xN~SpB@m;9_Xd0y1Hnw zZ$a+DhQfy+*WE?xJu4tQ^(;mh>#z-GR8%d%kv^gZY^|vS`*3qM^wwN}ihSQAV?7m{M6uHnyHqdPiC>;uuG3uFKFG)f-EzGEagRTB;S{-hB zz72T99H8a>uX3vNbg@&{1QwV38(QEBnq*m}W>rHtWOMZemGQAtSX=~|za>t|YNIMM25V@>#Jn2u$lMnh*M zMV%nu$|?0|U|DhM`R_K8d1o&cvYM)re*Jt4Y8KX%6jjb{V2HrqZ!UA|@j&(b_Z?%o z>T{l#n>W1bqH;>RXh#a+b^;0DBB-=zF?C2G%Jkvz4Y@~=-YZP)4UgcB3VE+y|Ho7~cXD1;wu%j! z(!tb#_p~L+eTMHhs8P<^80Z2nJPXSU@Sa&z;itr+!OQ{-QCpGfMCip$&%7 zUxy0y`+=0`zrDbq$<=k4uk1^!YH^v=KuE9?WrUtK=#+|HDym9r%d4nO15>W=u0q`d zcjA~5bq!c|cfdt$*nv?0>_N%@_vfID;-ZoZ#WFN7m-^4;b!Vftp$0msFTD@B7lE4v zfvWOSLtZK3V$Kil|39r=NsMLJS-y5>BvU)Y;1~#%fJ6p&rK`Hz?v89zZFkuz)Q(Me zBMgdk^Xd&%ul`DPoYUNQf+0Br8B5ku3|r8$=dFLadOGAR88l1w--CX`37Vx^2c3?`^E!N8a;Xo6R!e<~} z^}=6Q85vtIhNIzPIO`j_Ro2c>E_hd_Q>@u7b&Xts6?#ik$qzd~<$mDnI=|o$NoN~8 zMkTj!?zC%2pA5Phv9bAEus(5?RHMnfx2hvuTEL^gmOm-@O)Y}w^MuY^nlIZoVDj`{ z8`j4&>kFxu!^yA@W6#*6*XrBwChz^i{plHeXSKx-1w{w3l?Q!6UgiyY$nRVnM%-VM zh-ax^lP?Q=0GQj(La7$NwcVJR)?)=90DlJrU9Nou3*Lq!YO{S%8=f}5U`4f<`_R$g z6cdi=Xvup4MH$dtel1(iSjtt5Ny|Dq5G!0B?JqPN2;RHW3^-cM4;H;Cw*7$waV4%jgAG=R z@@~`yf-7ecD<@wY(u-V^p10*-@OmL#KIk%M<>wT$-meHC3y1~9)~GQ32m6-#$)W(f zZeE#QzHjHi?T(s^gfL=qI-ZGD?iWei8~eBSjiW_h9-;${cZwq zqsBL-z=jFW6gCRcoW;70grQTMgF&7-{8vuDRVKpaY7^Y#kb)7N|Sp9!Z%?#TYKk_-T7Su>vnkR$B&@O4D@fQP{j%f&Bz zq)m7hu0%ba9!=gx!o(9B59VXEC~?x6ATHas#(XxW+jUhh z#pe{Ep>r0j);@QQ&L?giL#+zq;2JfQ<0hCa&}ty)HG-Yd^#q+n@@*;6MVfp?2*u5g2C&=AyoQKCOOg& zn(&#b^fSu5*7qJ3jf6l-&wBT{80yn~5y1N9G3!~`KJM&mV$fhfXD&=fAigr3I+8HT zTiCL%dUvo2ERMyIN^LW1IMM(aI_;b6Z|Xr9!O+)y!VRMgk;0eYuog$$P}HOTd@{*> zk;}vRVzuF2pc`g0wK-=Q7zE^!q$JMtb$B}^f<0&Z;>D7+=Q(`JE_NmL6OFHcIVL8c zg+fOGwsi&l7?4s`BcpqS@UtMsy%lf>c;>JwsFvq=>M= zQ7;PG7QonpLvIV2QRL*Pz6N3};ke&Pev! zXfdCK+@#_?NPka+wenQ!Rz0rh%#1E9f7qeSk+rW;~2ak2YCcc@Hiu1mI;i(Fh1(Q6N5IIYZZ@)-Jgfl)uJFEtR2p@~F+qG2UnKR!W`Od2u(W5`dAZ zdeYzs*2E3h980I`4MeyUn8zsRbf{l!s=Zu2n4%`93J(GBC{Ze)I7qs=IJr^JH<=$) zBhfLGwfBN1;iZ|YT(qdNA=yvQ$`h;~$0Uw}AWXapZujZ_!oExuK(q`ocJPjUX5xoQ~mkitwZKY+X9Z;4I2AIB|peT62S~Ql@vIIonLet*j zwV_sOAfduo%kogo(FhNAnn&<63jb5cE#p;Wif>Q^CPO%(<5N#Di-tSo(f3FoYgjtEpwC7d+jF1m26 zs@yh3sw!GX$ZII<=cgs_?1>E|77U$rr=UaOWHmD=o+tLWB-l86T*a;w#lfqQai!3e zm^cktgBZ|(;x#qY31TQ@7{(a$68UQCJ3^|V&5PaIzOLK~-+to1!Zs5^zn`kVlU z(YBNlOJpnx&dFT0@l^5@s#cU6Mo69GRmkEs&g5+eu!Po{GKD)Q@YI5tqRokC4LO5? zoJ%-g;+uzKpvg~u@~VmeQV5i=Pr5&=cz=-V+lwm2OcxlltqLs!T%nH^MY!|3 z!ORyx$VV!k)^D>3v_=kyBB$RNl6J4btUJ^dBxMDeuGpALc%lY&N{&HAU!b8vEQ3P* z(uR>ypDsFU2>;gna)T&4RhbS`h8Pam$}{C53U@H&Q{EjCR;4OuDQYl{7r zA+V9JW|&#M=XwDns5aPiErtuQZbgte_(*1E_^wsWN#cpM$O6 zA{!`b<~~D3DUkq0lr%%w4`_=mRzqVhsG_1+%?IFHVkChOG9Phk6fH5t6gcz>Qci)^ z!Jc^U6lfG&gsN(yMC8rW6mT#>x!qeKW5gPdNARYg0$CwRfTROSqIwXU7;;q2lnF(! zsaVA; zAJ}CCyC%{rr9UkV_Yg9R@c*T{Hy9wr$aGYyC7;;vQn6$$#%O3vcups$f~`-){1k-j zm#EgUuy)m@vKD$biv^HGg6Idz=ZT!=Cx9la97K-4q zMXkn(ZskmZ{wUS(*;c^I7KJs+GKa&rC0$YsS;|+0N1(_o>ipvJ7fiiXNH)JB<+r+= zU<}}zZ}4Lmm@@#7OSvJD%_~MJSnug*VYs?N-i%C$-6O^8e%I?EX>w;SFffW{!C{}7dj$|d2x|rde5!cKS-SzJa z#mt=bAjH>H!pSU5nkcBKkGk6a128)8pKbD7G;zo>C&;Y2+$LcbfPT&7#g~_vG)AN< z6vr53@a;5js|?#w_89!D%lsiY>CC`sc)8ye`p32At_f=)DpiqtHjLS(0tm$=)THNA zhFI)~_H=3}1u1TNwV3Qykag@2A&!>LE|U8h8qf5I1;~%)$Rt_^NG=b3YpbQ~IILFE zdu%^&=OUL_pcYJlsvqm6)GCs$JWasmTt;pYRsdHQl0QOEw%Q<{g7l*prwDFzn6?mf zDt3)fMFNMko(s|2dcJ=j?P3s#Fp2-m;}H`7C6qrmnJwBLP>iz%AZL4rk@J--2)vUj zLak{yG5#VOVKg~j0>7n<@2Mh6EpEOw-ugC9#w2c#)$QJ33aT~wDK?M!CJ5l*1BfjF z)4axZ)H2Z(n?i~RKKic*aQQxc+U8OMiyEDgX-KY&I3k*U3F~1LvTiIbbH@e zvx#4*kXqvFNwxtsKjS%Y=FB9Vqjx}-aNfzzwzaBaXNzZ6{Efc(PtNQ^TKu>zEgmvB zWnv?=j1!)zpe`fRf(c8d2g(7ZnTZ&~(vruw<3Z&`dlnGWXvkKXy-t=42DgReJ$a#P zDSeVBmPnB5edVkmk~f-$Tx#)W}OY2jnQ zD(!(Girhz=l3;R4&qW@%oY)|=nbJ5a!xPym%r9|TtzeOAdiC;#wg8?>e2Gq#Y7BO4}5 z0SC?^Wt3h=*KayxX%*5^`~ijCTgK^ScH$sVCN5v$JP>83gTN0t zLfdeNm+ENb?GiHi-PWV+@8@wJ$#CF?Q!A}!R$s3z%RN|_A=M-~@4 z7jmwxZbYCr*V=N{j`&q6SU8NMEO(LpDCC2dY=X%BuHcPehi2 zWSdiK6xZ__3fQn=3TnX8_Wlo{Na=fHNlTd%mYk)wNUPzd6I)4QY|Asv6=tS9Wm&!W zgQ7iSlhD7*QYB~%b0=^RB5&NsAM7!g1^WMsWtwAtK#Y3y`$&z znKX_FwT*GxNykJd36y#_N31BYVMyXt0ANR!J)qzwVxcC1#>|e;wQ!Nx-$ibjc*3!V zak&>IyA6MySAawjptqnn+BSXj2l(h5Q8AL!4#3e?<{TS|w-I>BlEmd-C_bneMZ>x1 zh&N?l7|!~A(YugB7tWYOjUMiS|5D)x?@8fj0Z$l)Lqn2HIPopkVb_`f?XnUa7PB{v zyOzbxQbb?XFM5kdZ}sIu&#W_os6&b>WRFFIMKiO`Q0en$Ofs@HwvfrIG8u<&asja@ zjnUgS&M#4946gzK4B$+q=6R|lY$Whxh0aG~Ikdk_{WHB$ag zWV-~T(rc&+Z;;C7M1vr222xqOUb>w%RoUWc^sO2``6+1iK9{3VrdP4Rj+J91`oc5#uk_`)m3+DuX zyEM&NF#I9R#V=-6Ac^YeI618`e+KlbGTcva6!#U(+!9AeNYaf^KuV>u>t?EE&mym@ zG$E3P1z#R6yz?{%gE$kT(A$;Xr42+SDe3yql-8)$hII6NZFQhg-HTu zlw{%aEBIW{1U(>Adk++GRqSH~g(>;%^6jNX-{pbn$P$gBobX?sm4 zbBp$xUKXzryuQ7r%kofU0XS$X45SoP3Wqu5fdwT_D$8aR6GhX!KAt0m?V#O=ag@^u ziK$S|@+w1dTde zAzFey>&t;XBbCsNu)Qv+2=GgECtCn1r4_ZC>pFDn)B(#QT_>^uhk9AJv!w4{Y@u{A zv20zbo&qWgLswOx30-hnkc3Cfa7{9e)FZW|%-ZuDg3p1P12SpmPcL*XV1}d4xF7Qk z_+0F-gt(M7gb?G2urQ=-3`6^ z8Ui5lEM+}hOIzzggd-q>wlwsDcg7^dYww~GDY*T@iA(1ip1F{$WCMrUj@g>$mxS}c zDcu?egeFqhqdGVl=ZzL9r$;Z*@?0y31shB-Lp+6|Z3_x32;rQ?-gu1h7^la86DZpLrFMsD>Q5x3X4{ z-lnt1o0pygTQNVvIg7(CUH8sn<1flazv6Pd2@b+WV>m|c6l_fFiCyHqLnwPYELSLu zYkEDSMyJ4FKy!v~{lgy1bOPXk6raEi;37cKUrPH`oS-z+wi?X5J3vZ%={)FXB6;3a zD5Q#%jtabOq*-$)p2iMG<>eeO`5}oWq^MB(sPXWH!hx2$ctkHs`-^WbWNb!R=ad)T z5vobpOwmRx!ku=3>Ud?fl2jirSG6DYIcPjnWI1QC-$x zGcm~uq>L`6mvE?^BbEg2IC|c?Z%$fDcYxCcS0FD2KIbCoe8}dI#P7}z0US|3G}9WZ z>6lj|GP4uefy0*0p3uo#VNzf!9p?d&n|XQ&^g;R^T~m;$DT1I1<*bkewrPHpmgFOl12&wFL^bYoLsr zfw5i!OYfEzX3tiX*e6=%MMD#@d0psB(nDZfcx6Aa3*5xb={iFfwUzVc-o3%3t+f~9rxdC4iC!A(Yc5%yoeQF)VWuen3ujqil)@)S9Gd7V-5NY`c zeoT(1wrQ#2>F;ZHgwz|gI9F|nM8Hj#d*cv!O-u(-R^yx=PLEJ6VQt2Qp@M@1sUZ?4 zqU78IfwnViTnq3eXV~s>)wN`8G9W^M4^U7`g&3#IEuRkrS;32?S@r?KjYl|LOd)kq z3OgB>u-Q5pm+<6JGf=@Mj_^LNEoPqUqN0tbzE_*un1ulXUUSo zhmE`59YL(FjKj1oO+*k^48x$8*|}*^@r)EL@vq?*5M^y$0Bsi^4_W)f9H63-v~V*C znLyNqc$4Y>ffK2#`re{9M#iWq$}rwA6Pg^@T9UR(Dh|oO)}~YIivzNq$k}D)v0A*- z9&ZttEtQ9>lrN?H6dh`d+& zDU*<)VKbDvGz6mxGH^^q_!Hv*kEcyvb1KC+ZCCP%oyc!YwQ!7o$ZCY_|26Wq6c_H0LmsRJRu8JH1U$0F!ob5BL7;v zycxHkv_g!J%<2jlBiz?>+=QN*=*=tr>A6dP$eCoG3o4*v^k_6+AHjb{*%;VbMlSec zsT`NnRN#VsN2?)JP5+kmJOR^Lzr*2t@Pf9=MyWtCv?1WX(&P>hs^yw&BC1#qU}49F z^I4ZJ{4H(5>>S$|#FS*naCT{(ZSC&#X*+SC15eYLs%53rUl&bLZ7Klw66H~a-x4n2 zWGbLhA=}3h)!jnZQq!%-&rpgn*~$oPk&~I0Cb>i=2-| z=P?tu1KC(O5k!4-hgjCfv)5+xlUZ$2kG1zwM}`l7XbA|`8`f@uo^{Z1Oo~BdKVY9U z&+5}YSJt9)!a1@1t^un}w2n?XkmNt1fO9RMQDIvuiB!0>SliP3BGUHi!E#<7B5Q3j zRA>|H3Dy!dew*B_MxBcs)K|~}Z};?6c{+l2h0~T`*J(uj=Yw7*d=2D^(=n|Ww7P;a zQTXFCf49WLrqyPtVPxKlMAoR&z$#q(YGM1^M&6)2y3Nta@ zWgL57lvF`50%y)P+TsJrK|h$HZR{xT6k>AR!4PjEL^1ByC-cQ1za?lx-t(*gg)J^* z!MI9EWhm#ULF|O|Sh7&TD&pfyqo9(r8^u!LvWu!b683~U^8lQwZ#~zDM~Xx(Vq39RDUuhaFL26YLCJ7QQU^Y^CjllX@d|o6soog$*^Uj6 zbHO-EogtWEJ(H0*C-;cWkTlXWM-eML&Nk^tB`EywcHlfy7ej&taOcsaZ%T zju|MHW7f5WkQxjG%>$Nf4N9?xuY*IIQfwV77#bJHM<5TN!#PK1ySvB(Fo{@I4P6J0 zP3d$o7>+iilV?3arbNB!9i)Fj{k5&s>k-ZyR#*o7-JRUB;Jqmy!omp*;hAr>oB?C% zSCgbz+Zet%*Mx8`CN}bt0ewg4=t93#y@yh})1sJ*$<90(1^IhVc;oRv67T|g&IxSH z1N`@^9yf0Os_){=ypipr8C5N~1aoXd8qL8>TDTSG{&}*yt3p+nD8p^SLTx-( zc?O?Hq*95h-?9$2n@&uqTR4i$5Q4ox^2`9>SdQ38snVTmnQo#@t#7Ve;T7Gy6}Buj zl6z!bB1<|}Y;*A#m-dtABlMZrRthNCj``{n4rsF>sYy@SjwrfaMNmLduqfXyK! zfT}645E0c{(zDiJLZGfeP?IGw8MuD8>&vbnU6|ywk3sGOGR9xnyA8%)ufA-$%W_De zP${-(2r*0GH^FU?#bE5ZYU2J>)`->>$PQwQoR}ESaVYwZnTlGyM^9yJe^=jyLi;oL zxDJ{Yag-AXYi68)kqh^)xISAxs8)z?I7%}i(MLaDRE zt*}pI#f+AryRWGXWupRpNGcA*JQSCHHFBvbiv#cKO~^`o98nsUXwU!}HmiCt^6ezy z23iiaTy2Dk3Wo!-+zwWUk^zLSbBk(ZTDT~5Uli05><5{p*l(WblfiR20CkpPTYeu@ zzGCK_K4p!aeH<)8MAjtD(B>z@vPJ=*^LqFd?p`tkE#B#w6@Pc|T|;rQK@X z&xPut>ah#uT^Fi{tLyaoh3Zv${T(d+N5zDcjYtNIST{_d)JC!5cEs=>S1_4ig^ zrPqI?dXrv%U-dn_BLBHiy}zn1=2xrgLiK@agI@n&bwsa!sQN0sezAI!UVo(ehYz#& z;^GFo{-f1L==G0OhxGcR)#)?rIX_l?jb8up>J57RvFeSVXV3X)Rqe3rk5@bN`cITM zl?-Ohj8T`)%V}ZzW^ox`!81ik?q$9-Sv$}(h(nb*T0lq ze+t(hsvfUixoPj0_sP!-`1ep%!heeE^4@P|&p9*qm;3k)TxawDmbw4&>KC*3e%n3& z-`w+G!r$`qJ^YjRUUzti9W_5PU-ta}!u5x$k5qs9aeH6 zQQZGfRpQ~t%yS+s@b_eiPT(Jgfd`MFNIjU>2b1|e zRL{X`zCcRN@hMKTm>x~gLw2xv{qmES`Aszf0b`edgTo{iXBAvD(_uY0o=)X3tLQIS z>El&$s~lCc**}tA7I#;-(dl@M(}B$i1Xs7+Q|$&1+_%S7DM)_LxR_2P&jHao2^m_VBLD_3qs#YxkU2U#+ifUd21&5FP-KvXM_3zDz*}I_8%_qy*G~^ zi-1Y?Qy^LIFHLJc`CW9yEOC8n_dz~-GT!f_`^~Z07C`&nOTYk+#dy2m@I5(b6Ausf z3SRoZ&6{D)j%V)Cem9WV0F<&{V>{)^{JG^sZxs`*HkW5pbWF!5j@dPzhyFJha>K<@ zwTW2SaPwexyoo|4l#8HDu(`BCNGxqus*+ zp636u&#**nNBH0IsvfdHFgYQKO>Aw_V?kS z@_$Xnv!VYT5G0)Re3wMC1Ivd@w?E#l@SnMcC-=rbKZ8F+HTUDMgU`y3|J*QtHUGV* z`PKaPB>s=bzv{;O&!5fi_j24{-pj^&d&Ylm_#544KK_?+{lDLOYwqXo?H>R6NjJ`$ zCHee&`2KzP=f`{d$bVjU0FyP!uYUYv_+5U+_$N#Dx>g&EMNw z{_}BsFF$_%{yqNlEBNkzqw(G@^Pf917(afG{QT|Js`_30A~5yO^Y)wn+;9{2@Au>V z`hVYzf6hJdd-5Xu_|GqyzwG>FOg{cwxF)ag&xi72f81wox#au*2if=yH_m^);vVNe zvd33{n2q=LrT_HzYvaG2jsL0};6Hc#K=*J!hb&MHzphJANyC?cyHJG z&ky(;-DeKJzjoupYc|}C?lUus46e94%*S`}zwDnM@9kv&c`v>hzvu7&$85Z}r~T*W z9sc>pc>M8y{|kN*8_}_yV0WKhvUhkm`}_TP|M`7<@u6tEx6i-k#{2uU@&AJ_1b6-W zy&eCC8}9+*$RgmspVyyYtSm8%clQ1p&X735ckz#(kNw&v%j_D zzxbDK9`3`Bk3T)_#dlu(ZF|R|L%dJmOOe%nIi7#N7uWpW$Ky}GZpV+ZFa3M{y}}=| TTg+Gg^n3QsU(E(&e^&noJ`mF@ literal 0 HcmV?d00001 diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..d8e796c --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,6 @@ +#include + +int main(int argc, char *argv[]) +{ + std::cout << "Hello world!" << std::endl; +} \ No newline at end of file diff --git a/src/workspace.code-workspace b/src/workspace.code-workspace new file mode 100644 index 0000000..0221949 --- /dev/null +++ b/src/workspace.code-workspace @@ -0,0 +1,38 @@ +{ + "folders": [ + { + "path": "../../CoreUtils" + }, + { + "path": ".." + }, + { + "path": "../../HTTPServer" + } + ], + "settings": {}, + "launch": { + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "/home/barant/Development/HTTPServer/HTTPServer", + "args": [], + "stopAtEntry": false, + "cwd": "/home/barant/Development/HTTPServer/", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ] + } + ] + } +} \ No newline at end of file